HITPOINTS = $02 ;Hit Points
TIME_TILL_THROW dcb $E8,$E8 ;Sprite spawn Timer
JUMP_TIMER = $163E
HAMMER_TIMER = $15AC
FIRE_TIMER = $1558
DIR_TIMER = $1540
SPRITE_DIR = $157C
SPRITE_IMG = $1602
SPRITE_STATUS = $14C8
SPRITE_STATE = $151C
TIME_TO_LOCK = $28
NEW_SPRITE_NUM = $7FAB9E ;08 bytes custom sprite number
EXTRA_BITS = $7FAB10
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "INIT"
JSR SUB_GET_DIR
TYA
STA $157C,x
TXA
AND #$03
ASL A
ASL A
ASL A
ASL A
ASL A
STA JUMP_TIMER,x
CLC
ADC #$22
STA FIRE_TIMER,x
RTL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main sprite JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
dcb "MAIN"
HAMMER_BRO_JSL PHB ; \
PHK ; | main sprite function, just calls local subroutine
PLB ; |
JSR START_HB_CODE ; |
PLB ; |
RTL ; /
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main sprite routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TIME_TO_LOCK = $28
TIME_TO_JUMP = $88
TIME_TO_SHOW = $12 ;time to display the boomerang before it is thrown
SpriteSpeed:
dcb $08,$10,$18,$1D,$1D,$FF,$FF,$FF ;x speed - facing right
dcb $F8,$F0,$E8,$E3,$E3,$FF,$FF,$FF ;x speed - facing left
BounceSpeed:
dcb $C0,$30 ;x speed to give mario when he stomps the sprite
KILLED_X_SPEED dcb $F0,$10
TIME_IN_POS dcb $78,$14,$74,$14 ;moving up, rest at top, moving down, rest at bottom
TIME_TILL_HAMMER dcb $0C,$0C,$0C,$0C,$0C,$43,$0C,$0C
dcb $0C,$0C,$0C,$0C,$73,$0C,$0C,$0C
dcb $0C,$0C,$63,$0C,$0C,$0C,$0C,$0C
dcb $0C,$83,$0C,$0C,$0C,$0C,$0C,$53
STAR INC FIRE_TIMER,x
RETURN RTS
START_HB_CODE JSR SUB_GFX ; draw sprite gfx
LDA SPRITE_STATUS,x ; \ if sprite status != 8...
CMP #$02 ; } ... not (killed with spin jump [4] or star[2])
BEQ STAR
CMP #$08
BNE RETURN ; / ... return
LDA $9D ; \ if sprites locked...
BNE RETURN ; / ... return
JSR SUB_OFF_SCREEN_X3 ; only process sprite while on screen
INC $1570,x ; increment number of frames sprite has been on screen
LDA $1570,x ; \ calculate which frame to show:
LSR A ; |
LSR A ; |
AND #$01 ; | update every 16 cycles if normal
STA SPRITE_IMG,x ; / write frame to show
TO_ATTACK LDA FIRE_TIMER,x ; \ if time until spit >= $10
CMP #TIME_TO_SHOW ; | just go to normal walking code
BCS STATE_RUN ; /
INC SPRITE_IMG,x
INC SPRITE_IMG,x
LDA FIRE_TIMER,x ; throw fire if it's time
BNE NO_RESET
LDY $C2,x
LDA TIME_TILL_THROW,y
STA FIRE_TIMER,x
NO_RESET CMP #$01
BNE STATE_RUN
STATE_RUN LDA DIR_TIMER,x
CMP #$01
BNE WALK_SPRITE
JMP TO_ATTACK ; time to convert to pounding koopa
WALK_SPRITE LDA $1588,x ; \ if sprite is not on ground...
AND #$04 ; } ...(4 = on ground) ...
BEQ APPLY_SPEED ; / ...goto IN_AIR
LDA #$10 ; \ y speed = 10
STA $AA,x ; /
LDA $C2,x ; \ if hits on sprite == 0...
EOR #$01
BEQ NO_FAST_SPEED ; / ...goto DONT_ADJUST_SPEED
LDA $157C,x ; load, y = sprite direction, as index for speed
ASL
ASL
ASL
CLC
ADC $1528,x ; Speed depends on hit count
TAY
LDA SpriteSpeed,y ; \ load x speed from ROM...
NO_FAST_SPEED STA $B6,x ; / ...and store it
APPLY_SPEED JSL $01802A ; update position based on speed values
FREEZE_SPR LDA $1588,x ; \ if sprite is touching the side of an object...
AND #$03 ; |
BEQ DONT_CHANGE_DIR ; |
LDA $157C,x ; |
EOR #$01 ; | ... change sprite direction
STA $157C,x ; /
DONT_CHANGE_DIR JSL $018032 ; interact with other sprites
JSL $01A7DC ; check for mario/sprite contact
BCC RETURN1 ; (carry set = contact)
LDA $1490 ; \ if mario star timer > 0 ...
BNE HAS_STAR ; / ... goto HAS_STAR
LDA $7D ; \ if mario's y speed < 10 ...
CMP #$10 ; } ... sprite will hurt mario
BMI GOOB_WINS ; /
MARIO_WINS:
JSR SUB_STOMP_PTS ; give mario points
JSR SUB_GET_DIR ; \ set new sprite direction
JSL $01AB99 ; display contact graphic
LDA $15 ; Save controller state
PHA
ORA #$C0 ; Set holding X/Y and A/B
STA $15
JSL $01AA33 ; set mario speed
PLA
STA $15
JSR SUB_GET_DIR ; If there was contact,
LDY $157C,x
LDA BounceSpeed,y ; bounce away horizontally
STA $7B
INC $1528,x ; increment sprite hit counter
LDA $1528,x ; if sprite hit counter == 5
CMP #HITPOINTS
BNE RETURN1
LDA #$02 ; Kill the sprite
STA $14C8,x
STZ $B6,x
LDA #$F0
STA $AA,x
JMP Kill
RETURN1 RTS
GOOB_WINS LDA $1497 ; \ if mario is invincible...
ORA $187A ; } ... or mario on yoshi...
ORA $15D0,x ; | ...or sprite being eaten...
BNE RETURN2 ; / ... return
JSR SUB_GET_DIR ; \ set new sprite direction
TYA ; }
STA $157C,x ; /
JSL $00F5B7 ; hurt mario
RETURN2 RTS ; return
Kill
STZ $14C8,x ; die
LDA #$3C
STA $1DFC
JSR DrawSmoke
JSL $07FC3B
RTS
DrawSmoke: LDY #$03 ; \ find a free slot to display effect
FINDFREE: LDA $17C0,y ; |
BEQ FOUNDONE ; |
DEY ; |
BPL FINDFREE ; |
RTS ; / return if no slots open
FOUNDONE: LDA #$01 ; \ set effect graphic to smoke graphic
STA $17C0,y ; /
LDA #$1B ; \ set time to show smoke
STA $17CC,y ; /
LDA $D8,x ; \ smoke y position = generator y position
STA $17C4,y ; /
LDA $E4,x ; \ load generator x position and store it for later
STA $17C8,y ; /
RTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; spin and star kill (still part of above routine)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STAR_SOUNDS dcb $00,$13,$14,$15,$16,$17,$18,$19
SPIN_KILL LDA #$04 ; \ status = 4 (being killed by spin jump)
STA $14C8,x ; /
LDA #$1F ; \ set spin jump animation timer
STA $1540,x ; /
JSL $07FC3B ; show star animation
LDA #$08 ; \ play sound effect
STA $1DF9 ; /
RTS ; return
HAS_STAR LDA #$02 ; \ status = 2 (being killed by star)
STA $14C8,x ; /
LDA #$D0 ; \ set y speed
STA $AA,x ; /
JSR SUB_GET_DIR ; get new direction
LDA KILLED_X_SPEED,y ; \ set x speed based on direction
STA $B6,x ; /
INC $18D2 ; increment number consecutive enemies killed
LDA $18D2 ; \
CMP #$08 ; | if consecutive enemies stomped >= 8, reset to 8
BCC NO_RESET2 ; |
LDA #$08 ; |
STA $18D2 ; /
NO_RESET2 JSL $02ACE5 ; give mario points
LDY $18D2 ; \
CPY #$08 ; | if consecutive enemies stomped < 8 ...
BCS NO_SOUND2 ; |
LDA STAR_SOUNDS,y ; | ... play sound effect
STA $1DF9 ; /
NO_SOUND2 RTS ; final return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; points routine - unknown
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
STAR_SOUNDS dcb $00,$13,$14,$15,$16,$17,$18,$19
SUB_STOMP_PTS PHY ;
LDA $1697 ; \
CLC ; }
ADC $1626,x ; / some enemies give higher pts/1ups quicker??
INC $1697 ; increase consecutive enemies stomped
TAY ;
INY ;
CPY #$08 ; \ if consecutive enemies stomped >= 8 ...
BCS NO_SOUND ; / ... don't play sound
LDA #$47
STA $1DFC
NO_SOUND TYA ; \
CMP #$08 ; | if consecutive enemies stomped >= 8, reset to 8
BCC NO_RESET6 ; |
LDA #$08 ; /
NO_RESET6 JSL $02ACE5 ; give mario points
PLY ;
RET RTS ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; fire routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
XF_OFFSET dcb $13,$FC
XF_OFFSET2 dcb $00,$FF
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
TILEMAP dcb $00,$02,$20,$22,$04,$06,$24,$26,$0C,$0E,$2C,$2E,$0C,$0E,$2C,$2E
dcb $00,$02,$20,$22,$04,$06,$24,$26,$0C,$0E,$2C,$2E,$0C,$0E,$2C,$2E
HORIZ_DISP dcb $00,$10,$00,$10,$00,$10,$00,$10,$00,$10,$00,$10,$00,$10,$00,$10
dcb $10,$00,$10,$00,$10,$00,$10,$00,$10,$00,$10,$00,$10,$00,$10,$00
VERT_DISP dcb $F0,$F0,$00,$00,$F0,$F0,$00,$00,$F0,$F0,$00,$00,$F0,$F0,$00,$00
dcb $F0,$F0,$00,$00,$F0,$F0,$00,$00,$F0,$F0,$00,$00,$F0,$F0,$00,$00
PROPERTIES dcb $40,$00 ;xyppccct format
HAMMER_TILE = $6D
SUB_GFX 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 SPRITE_IMG,x ; \
ASL A ; | $03 = index to frame start (frame to show * 2 tile per frame)
ASL A
STA $03 ; /
LDA SPRITE_DIR,x ; \ $02 = sprite direction
STA $02 ; /
BNE NO_ADD
LDA $03
CLC
ADC #$10
STA $03
NO_ADD PHX ; push sprite index
LDX #$03 ; loop counter = (number of tiles per frame) - 1
LOOP_START PHX ; push current tile number
TXA ; \ X = index to horizontal displacement
ORA $03 ; / get index of tile (index to first tile of frame + current tile number)
FACING_LEFT TAX ; \
LDA $00 ; \ tile x position = sprite x location ($00)
CLC ; |
ADC HORIZ_DISP,x ; |
STA $0300,y ; /
LDA $01 ; \ tile y position = sprite y location ($01) + tile displacement
CLC ; |
ADC VERT_DISP,x ; |
STA $0301,y ; /
LDA TILEMAP,x ; \ store tile
STA $0302,y ; /
LDX $02 ; \
LDA PROPERTIES,x ; | get tile properties using sprite direction
LDX $15E9 ; |
ORA $15F6,x ; | get palette info
ORA $64 ; | put in level properties
STA $0303,y ; / store tile properties
PLX ; \ pull, X = current tile of the frame we're drawing
INY ; | increase index to sprite tile map ($300)...
INY ; | ...we wrote 1 16x16 tile...
INY ; | ...sprite OAM is 8x8...
INY ; | ...so increment 4 times
DEX ; | go to next tile of frame and loop
BPL LOOP_START ; /
PLX ; pull, X = sprite index
LDA HAMMER_TIMER,x
CMP #$02
BCC NO_SHOW_HAMMER
CMP #30
BCS NO_SHOW_HAMMER
LDA SPRITE_IMG,x
CMP #$00
NO_SHOW_HAMMER LDY #$02 ; \ 02, because we didn't write to 460 yet
LDA #$03 ; | A = number of tiles drawn - 1
JSL $01B7B3 ; / don't draw if offscreen
RTS ; retur
SHOW_HAMMER_TOO PHX
LDA $00
LDX $02
CLC
ADC XF_OFFSET,x
STA $0300,y
LDA $01 ; \ tile y position = sprite y location ($01) + tile displacement
CLC ; |
ADC #$E8
STA $0301,y ; /
LDA #HAMMER_TILE ; \ store tile
STA $0302,y ; /
LDA #$03
CPX #$00
BNE NO_FLIP_HAMMER
ORA #$40
NO_FLIP_HAMMER ORA $64 ; | put in level properties
STA $0303,y ; / store tile properties
PLX
INY ; | increase index to sprite tile map ($300)...
INY ; | ...we wrote 1 16x16 tile...
INY ; | ...sprite OAM is 8x8...
INY ; | ...so increment 4 times
LDY #$02 ; \ 02, because we didn't write to 460 yet
LDA #$04 ; | A = number of tiles drawn - 1
JSL $01B7B3 ; / don't draw if offscreen
RTS ; return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; routines below can be shared by all sprites. they are ripped from original
; SMW and poorly documented
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B760 - graphics routine helper - shared
; sets off screen flags and sets index to OAM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $03B75C
TABLE1 dcb $0C,$1C
TABLE2 dcb $01,$02
GET_DRAW_INFO STZ $186C,x ; reset sprite offscreen flag, vertical
STZ $15A0,x ; reset sprite offscreen flag, horizontal
LDA $E4,x ; \
CMP $1A ; | set horizontal offscreen if necessary
LDA $14E0,x ; |
SBC $1B ; |
BEQ ON_SCREEN_X ; |
INC $15A0,x ; /
ON_SCREEN_X LDA $14E0,x ; \
XBA ; |
LDA $E4,x ; |
REP #$20 ; |
SEC ; |
SBC $1A ; | mark sprite invalid if far enough off screen
CLC ; |
ADC.W #$0040 ; |
CMP.W #$0180 ; |
SEP #$20 ; |
ROL A ; |
AND #$01 ; |
STA $15C4,x ; /
BNE INVALID ;
LDY #$00 ; \ set up loop:
LDA $1662,x ; |
AND #$20 ; | if not smushed (1662 & 0x20), go through loop twice
BEQ ON_SCREEN_LOOP ; | else, go through loop once
INY ; /
ON_SCREEN_LOOP LDA $D8,x ; \
CLC ; | set vertical offscreen if necessary
ADC TABLE1,y ; |
PHP ; |
CMP $1C ; | (vert screen boundry)
ROL $00 ; |
PLP ; |
LDA $14D4,x ; |
ADC #$00 ; |
LSR $00 ; |
SBC $1D ; |
BEQ ON_SCREEN_Y ; |
LDA $186C,x ; | (vert offscreen)
ORA TABLE2,y ; |
STA $186C,x ; |
ON_SCREEN_Y DEY ; |
BPL ON_SCREEN_LOOP ; /
LDY $15EA,x ; get offset to sprite OAM
LDA $E4,x ; \
SEC ; |
SBC $1A ; | $00 = sprite x position relative to screen boarder
STA $00 ; /
LDA $D8,x ; \
SEC ; |
SBC $1C ; | $01 = sprite y position relative to screen boarder
STA $01 ; /
RTS ; return
INVALID PLA ; \ return from *main gfx routine* subroutine...
PLA ; | ...(not just this subroutine)
RTS ; /
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B817 - horizontal mario/sprite check - shared
; Y = 1 if mario left of sprite??
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $03B817 ; Y = 1 if contact
SUB_GET_DIR LDY #$00 ;A:25D0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1020 VC:097 00 FL:31642
LDA $94 ;A:25D0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZCHC:1036 VC:097 00 FL:31642
SEC ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1060 VC:097 00 FL:31642
SBC $E4,x ;A:25F0 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizCHC:1074 VC:097 00 FL:31642
STA $0F ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1104 VC:097 00 FL:31642
LDA $95 ;A:25F4 X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1128 VC:097 00 FL:31642
SBC $14E0,x ;A:2500 X:0006 Y:0000 D:0000 DB:03 S:01ED P:envMXdiZcHC:1152 VC:097 00 FL:31642
BPL LABEL16 ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1184 VC:097 00 FL:31642
INY ;A:25FF X:0006 Y:0000 D:0000 DB:03 S:01ED P:eNvMXdizcHC:1200 VC:097 00 FL:31642
LABEL16 RTS ;A:25FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:1214 VC:097 00 FL:31642
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B85D - off screen processing code - shared
; sprites enter at different points
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;org $03B83B
TABLE3 dcb $40,$B0
TABLE6 dcb $01,$FF
TABLE4 dcb $30,$C0,$A0,$80,$A0,$40,$60,$B0
TABLE5 dcb $01,$FF,$01,$FF,$01,$00,$01,$FF
SUB_OFF_SCREEN_X0 LDA #$06 ; \ entry point of routine determines value of $03
BRA STORE_03 ; |
SUB_OFF_SCREEN_X1 LDA #$04 ; |
BRA STORE_03 ; |
SUB_OFF_SCREEN_X2 LDA #$02 ; |
STORE_03 STA $03 ; |
BRA START_SUB ; |
SUB_OFF_SCREEN_X3 STZ $03 ; /
START_SUB JSR SUB_IS_OFF_SCREEN ; \ if sprite is not off screen, return
BEQ RETURN_2 ; /
LDA $5B ; \ goto VERTICAL_LEVEL if vertical level
AND #$01 ; |
BNE VERTICAL_LEVEL ; /
LDA $D8,x ; \
CLC ; |
ADC #$50 ; | if the sprite has gone off the bottom of the level...
LDA $14D4,x ; | (if adding 0x50 to the sprite y position would make the high byte >= 2)
ADC #$00 ; |
CMP #$02 ; |
BPL ERASE_SPRITE ; / ...erase the sprite
LDA $167A,x ; \ if "process offscreen" flag is set, return
AND #$04 ; |
BNE RETURN_2 ; /
LDA $13 ; \
AND #$01 ; |
ORA $03 ; |
STA $01 ; |
TAY ; /
LDA $1A ;x boundry ;A:0101 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0256 VC:090 00 FL:16953
CLC ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZcHC:0280 VC:090 00 FL:16953
ADC TABLE4,y ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZcHC:0294 VC:090 00 FL:16953
ROL $00 ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0326 VC:090 00 FL:16953
CMP $E4,x ;x pos ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0364 VC:090 00 FL:16953
PHP ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0394 VC:090 00 FL:16953
LDA $1B ;x boundry hi ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01EC P:eNvMXdizCHC:0416 VC:090 00 FL:16953
LSR $00 ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01EC P:envMXdiZCHC:0440 VC:090 00 FL:16953
ADC TABLE5,y ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01EC P:envMXdizcHC:0478 VC:090 00 FL:16953
PLP ;A:01FF X:0006 Y:0001 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0510 VC:090 00 FL:16953
SBC $14E0,x ;x pos high ;A:01FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0538 VC:090 00 FL:16953
STA $00 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0570 VC:090 00 FL:16953
LSR $01 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0594 VC:090 00 FL:16953
BCC LABEL20 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZCHC:0632 VC:090 00 FL:16953
EOR #$80 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZCHC:0648 VC:090 00 FL:16953
STA $00 ;A:017E X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0664 VC:090 00 FL:16953
LABEL20 LDA $00 ;A:017E X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0688 VC:090 00 FL:16953
BPL RETURN_2 ;A:017E X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0712 VC:090 00 FL:16953
ERASE_SPRITE LDA $14C8,x ; \ if sprite status < 8, permanently erase sprite
CMP #$08 ; |
BCC KILL_SPRITE ; /
LDY $161A,x ;A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZCHC:0140 VC:071 00 FL:21152
CPY #$FF ;A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0172 VC:071 00 FL:21152
BEQ KILL_SPRITE ;A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0188 VC:071 00 FL:21152
LDA #$00 ; \ mark sprite to come back A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0204 VC:071 00 FL:21152
STA $1938,y ; / A:FF00 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZcHC:0220 VC:071 00 FL:21152
KILL_SPRITE STZ $14C8,x ; erase sprite
RETURN_2 RTS ; return
VERTICAL_LEVEL LDA $167A,x ; \ if "process offscreen" flag is set, return
AND #$04 ; |
BNE RETURN_2 ; /
LDA $13 ; \ only handle every other frame??
LSR A ; |
BCS RETURN_2 ; /
AND #$01 ;A:0227 X:0006 Y:00EC D:0000 DB:03 S:01ED P:envMXdizcHC:0228 VC:112 00 FL:1142
STA $01 ;A:0201 X:0006 Y:00EC D:0000 DB:03 S:01ED P:envMXdizcHC:0244 VC:112 00 FL:1142
TAY ;A:0201 X:0006 Y:00EC D:0000 DB:03 S:01ED P:envMXdizcHC:0268 VC:112 00 FL:1142
LDA $1C ;A:0201 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0282 VC:112 00 FL:1142
CLC ;A:02BD X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0306 VC:112 00 FL:1142
ADC TABLE3,y ;A:02BD X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0320 VC:112 00 FL:1142
ROL $00 ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01ED P:enVMXdizCHC:0352 VC:112 00 FL:1142
CMP $D8,x ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01ED P:enVMXdizCHC:0390 VC:112 00 FL:1142
PHP ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNVMXdizcHC:0420 VC:112 00 FL:1142
LDA.W $001D ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01EC P:eNVMXdizcHC:0442 VC:112 00 FL:1142
LSR $00 ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01EC P:enVMXdiZcHC:0474 VC:112 00 FL:1142
ADC TABLE6,y ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01EC P:enVMXdizCHC:0512 VC:112 00 FL:1142
PLP ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01EC P:envMXdiZCHC:0544 VC:112 00 FL:1142
SBC $14D4,x ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNVMXdizcHC:0572 VC:112 00 FL:1142
STA $00 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0604 VC:112 00 FL:1142
LDY $01 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0628 VC:112 00 FL:1142
BEQ LABEL22 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0652 VC:112 00 FL:1142
EOR #$80 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0668 VC:112 00 FL:1142
STA $00 ;A:027F X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0684 VC:112 00 FL:1142
LABEL22 LDA $00 ;A:027F X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0708 VC:112 00 FL:1142
BPL RETURN_2 ;A:027F X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0732 VC:112 00 FL:1142
BMI ERASE_SPRITE ;A:0280 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0170 VC:064 00 FL:1195
SUB_IS_OFF_SCREEN LDA $15A0,x ; \ if sprite is on screen, accumulator = 0
ORA $186C,x ; |
RTS ; / return