I was curious about the exploding routine (JSL $028086) that the bom-ombs and some custom sprites use, so I decided to disassemble it. There's still some parts of the code that I'm not familiar with and might be labeled wrong.
Here it is:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Exploding Sprite Routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
HORZ_DISP dcb $00,$08,$06,$FA,$F8,$06,$08,$00,$F8,$FA
VERT_DISP dcb $F8,$FE,$06,$06,$FE,$FA,$02,$08,$02,$FA
EXPLODING_ROUTINE STZ $1656,x ; clear settings
LDA #$11 ; \ set sprite clipping field
STA $1662,x ; /
JSR GET_DRAW_INFO ; after: Y = index to sprite tile map ($300)
; $00 = sprite x position relative to screen boarder
; $01 = sprite y position relative to screen boarder
LDA $9D ; \ if it's locked...
BNE SET_TIMER ; /
INC $1570,x ; increment number of frames the sprite has been on screen
SET_TIMER LDA $1540,x ; \ if the timer is set...
BNE NOT_KILLED ; /
STZ $14C8,x ; disappear the sprite
RTS
NOT_KILLED LDA $1540,x ; \ if the timer is set...
LSR A ; |
AND #$03 ; |
CMP #$03 ; |
BNE SKIP_INTERACTION ; / ...skip interaction
JSR SPRITE_INTERACT ; sprite interaction routine
LDA $1540,x ; \ if the timer is set...
SEC ; |
SBC #$10 ; |
CMP #$20 ; |
BCS SKIP_INTERACTION ; / ...skip Mario/sprite contact
JSL $01A7DC ; check for Mario/sprite contact
SKIP_INTERACTION LDY #$04
STY $0F
LOOP_START LDA $1540,x
LSR A
PHA
AND #$03
STA $02
LDA $E4,x ; \ set x position
SEC ; |
SBC $1A ; |
CLC ; |
ADC #$04 ; |
STA $00 ; /
LDA $D8,x ; \ set y position
SEC ; |
SBC $1C ; |
CLC ; |
ADC #$04 ; |
STA $01 ; /
LDY $0F
PLA
AND #$04
BEQ SET_HORZ_DISP
TYA
CLC
ADC #$05
TAY
SET_HORZ_DISP LDA $00 ; \ x position for the star tiles
CLC ; |
ADC HORZ_DISP,y ; |
STA $00 ; /
LDA $01 ; \ y position for the star tiles
CLC ; |
ADC VERT_DISP,y ; |
STA $01 ; /
DEC $02
BPL SET_HORZ_DISP
LDA $0F
ASL A
ASL A
ADC $15EA,x
TAY
LDA $00 ; \ tile x position
STA $0300,y ; /
LDA $01 ; \ tile y position
STA $0301,y ; /
LDA #$BC ; \ store star tile
STA $0302,y ; /
LDA $13 ; \ calculate which frame to show palette
LSR A ; |
LSR A ; |
AND #$03 ; | number of frames/flashing palettes
SEC ; |
ROL A ; |
ORA $64 ; |
STA $0303,y ; / store palettes
TYA ; \ get index to sprite property map ($460)...
LSR A ; |
LSR A ; |
TAY ; |
LDA #$00 ; | else show a 8x8 tile
STA $0460,y ; /
DEC $0F
BPL LOOP_START
LDY #$00 ; \ 460 &= 0 8x8 tiles maintained
LDA #$04 ; | A = number of tiles drawn - 1
JSL $01B7B3 ; / don't draw if offscreen
RTS ; return
SPRITE_INTERACT LDY #$09
INTERACT_LOOP CPY $15E9
BEQ NEXT_SPRITE
PHY
LDA $14C8,y ; \ if the sprite status is...
CMP #$08 ; | ...alive
BCC DONT_PROCESS_SPRITE ; /
JSR PROCESS_SPRITE
DONT_PROCESS_SPRITE PLY
NEXT_SPRITE DEY
BPL INTERACT_LOOP
RTS
PROCESS_SPRITE PHX
TYX
JSL $03B6E5 ; get sprite clipping B routine
PLX
JSL $03B69F ; get sprite clipping A routine
JSL $03B72B ; check for contact routine
BCC RETURN ; return if no contact
LDA $167A,y ; \ if invincible to star/cape/fire/bouncing bricks...
AND #$02 ; |
BNE RETURN3 ; / ...return
LDA #$02 ; \ status = 2 (being killed by star)
STA $14C8,y ; /
LDA #$C0 ; \ set y speed
STA $00AA,y ; /
LDA #$00 ; \ no x speed
STA $00B6,y ; /
RETURN RTS
|