;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SMB2 Tryclyde, by Sonikku ;; Description: A boss with 3 heads (only 2 actually do anything; same as SMB2). Moves ;; slowly back and forth on a platform, occasionally shaking its tail while firing ;; flames in Mario's general direction. The flames kill any thrown sprite that touches ;; them, providing an effective barrier against thrown objects. ;; ;; Usage notes: Recommended to use on a platform 2-3 tiles wide. ;; Extra Property Byte 1 handles sprite HP. Change it in the CFG Editor. Default is 5. !SpriteNum = $1C ;; Change this to the sprite number of SMB2ProjectileA.cfg ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; print "INIT ",pc Tryclyde_Init: LDA #$20 STA $1540,x ; set initial timer JSL + ; randomize head 2's state and timer TXA CLC ADC #$0C ; randomize head 1's state and timer TAX + STZ $1510,x JSL $01ACF9 ; randomize output \ EOR $94 ; flip by mario's x position | this is done to further randomize ADC $13 ; add current frame | smw's regular routine isn't great SBC $E4,x ; decrement by sprite's x position / AND #$03 TAY LDA .time,y ; set time STA $1570,x RTL .time db $08,$0C,$10,$14 print "MAIN ",pc Tryclyde_Main: PHB PHK PLB JSR .SpriteRoutine PLB RTL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SPRITE_ROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; .SpriteRoutine JSR SUB_OFF_SCREEN_X0 JSR .subgfx ; run gfx routine LDA $14C8,x BEQ .endlevel ; check if level should end CMP #$02 BEQ .dead ; check if sprite dead CMP #$08 BNE ++ ; check if sprite -not- alive LDA $9D BEQ + ; check for sprites locked RTS .dead LDA #$10 STA $B6,x ; set killed x speed LDA $AA,x BMI ++ DEC $AA,x ; lower gravity than normal ++ LDA #$03 STA $1602,x ; set killed frame RTS .endlevel LDA $C2,x ; if "defeated" flag isn't set, sprite shouldn't actually end level BEQ .notdead INC $13C6 ; no walking LDA #$FF STA $1493 ; end level LDA #$0B STA $1DFB ; play music .notdead RTS + LDA $1FE2,x ; if hurt, return BEQ + RTS + LDA $E4,x STA $00 ; save sprite x LDA $14E0,x STA $01 ; save sprite x high REP #$20 LDA $94 ; check for mario position subtracted by sprite position SEC SBC $00 BPL .behind ; if positive, he's behind CMP #$FFE0 BCS .behind ; if #$FFE0 or further, he's still behind CMP #$FFB0 BCS .middle ; if #$FFB0 to #$FFDF, he's in the middle SEP #$20 LDA #$00 ; else he's in front BRA ++ .middle SEP #$20 LDA #$01 BRA ++ .behind SEP #$20 LDA #$02 ++ STA $187B,x ; save flag for later JSR .animate ; animate sprite LDA $1504,x ; check if movement timer is above CMP #$38 BCC ++ STZ $1504,x ; clear timer if above INC $1534,x ; increment direction ++ INC $1504,x ; constantly increment timer LDA $1534,x ; get current direction AND #$03 TAY LDA .xspd,y ; index by current movement direction STA $B6,x JSL $01802A ; run movement routine with gravity JSR .tryheads ; try to perform head-related operations LDA $1528,x CMP $7FAB28,x BCC .nothit ; if hit count isn't the same as hp count, check for contact LDA #$02 STA $14C8,x ; kill sprite STA $C2,x ; mark sprite as 'defeated' (won't end level if killed by other means) LDA #$D0 ; set killed y speed STA $AA,x LDA #$FF STA $161A,x ; prevent reloading sprite RTS .nothit JSL $03B664 ; get mario clipping JSR .getspriteclip JSL $03B72B ; check for contact BCC + JSL $00F5B7 ; hurt mario + PHX LDY #$0B - LDA $1686,y ; if sprite doesn't interact with other sprites, skip AND #$08 BNE + LDA $14C8,y CMP #$09 ; if sprite is carriable BEQ .hitspr CMP #$0A ; or thrown BEQ .hitspr ; it can hit the boss + -- DEY BPL - PLX RTS .hitspr PHX TYX JSL $03B6E5 ; get thrown sprite's clipping PLX JSR .getspriteclip JSL $03B72B ; check for contact BCC -- INC $1528,x ; increment hit counter LDA #$28 STA $1DFC ; play sound LDA #$30 STA $1FE2,x ; set stun timer LDA #$02 STA $14C8,y ; kill thrown sprite PLX RTS .getspriteclip LDA $E4,x ; get x pos SEC SBC #$08 STA $04 LDA $14E0,x ; get x pos high SBC #$00 STA $0A LDA #$20 ; get width STA $06 LDA $D8,x ; get y pos SEC SBC #$20 STA $05 LDA $14D4,x ; get y pos high SBC #$00 STA $0B LDA #$28 ; get height STA $07 RTS .tryheads JSR .shootfire ; shoot fire when needed PHX JSR .headmain ; get head 1 TXA CLC ADC #$0C TAX JSR .headmain ; get head 2 PLX RTS .headmain LDA $1510,x ; head state pointer JSL $0086DF dw .state0 ; waiting dw .state1 ; extending outward .state0 LDA $1570,x ; if timer is zero, change state BEQ + DEC $1570,x ; if not, decrement RTS + LDA #$6C ; set extending timer STA $1570,x LDA #$01 ; set extending state STA $1510,x RTS .state1 LDA $1570,x ; if timer is zero, change state BEQ + DEC $1570,x ; if not, decrement .ret RTS + JSL $01ACF9 ; randomize output \ EOR $94 ; flip by mario's x position | this is done to further randomize ADC $13 ; add current frame | smw's regular routine isn't great SBC $E4,x ; decrement by sprite's x position / AND #$03 ; get 1 of 3 values TAY LDA .time,y ; get timer from index STA $1570,x STZ $1510,x ; set waiting state RTS .animate LDA $163E,x ; if timer isn't set BNE + LDA #$5C ; re-set timer STA $163E,x + CMP #$30 ; and if it's above #$30 BCS + LDA #$00 ; frame = 00 BRA ++ + LDA $14 ; else, we get $14 and divide it LSR : LSR AND #$01 ; 2 frames ++ TAY ; transfer result to y LDA $1FE2,x ; if sprite was recently hit BEQ + INY ; we increment it's frame INY ; by 2 + LDA .frm,y STA $1602,x ; and then store the result RTS .shootfire LDY #$00 ; get index for head 1 LDA $1510,x BEQ + LDA $1570,x JSR ++ + LDY #$01 ; get index for head 2 LDA $151C,x BEQ + LDA $157C,x ++ CMP #$20 ; if timer isn't less than #$20 BCC + CMP #$40 ; or more than #$40 BCS + AND #$07 ; for 1 of every 8 frames in that span BNE .ret LDA .firey,y ; we set $00 (scratch ram) to what head is being processedd STA $00 JSR SpawnFire ; and spawn fire based on that + RTS .xspd db $00,$00,$03,$FD .time db $08,$10,$20,$28 .frm db $00,$01,$02,$03 .firey db $F1,$E0 .subgfx JSR GET_DRAW_INFO LDA $1602,x ASL : ASL ADC $1602,x STA $02 ; sprite frame * 2 + sprite frame = $02 LDA $14C8,x STA $05 ; sprite state = $05 LDA $1FE2,x STA $06 ; stunned timer = $06 BEQ + LSR AND #$07 + STA $07 ; divided by half and then divided into 8 possibilities PHX LDX #$04 - LDA $00 CLC ADC .xpos,x STA $0300,y ; set x offset LDA $01 CLC ADC .ypos,x STA $0301,y ; set y offset PHX TXA CLC ADC $02 ; index tilemap by $02 TAX LDA .tilemap,x STA $0302,y ; set tilemap PLX PHX LDX $07 ; index palette by $07 BEQ + TXA ASL INC AND #$0F BRA ++ + LDA #$0F ; $07 is 0, palette is #$0F ++ ORA $64 ; factor in priority STA $08 PLX STA $0303,y ; set palette/priority/etc. PHY TYA LSR : LSR TAY LDA .size,x STA $0460,y ; set tilesize PLY INY : INY INY : INY DEX BPL - PLX PHX LDA #$E0 ; set y pos of head 1 STA $02 JSR .head1 ; load head 1 PLX PHX LDA #$F1 ; set y pos of head 2 STA $02 JSR .head2 ; load head 2 PLX LDY #$FF LDA #$08 JSL $01B7B3 RTS .frame db $00,$00,$00,$00,$01,$01,$01 db $01,$01,$01,$01,$01,$00,$00 .xpos db $08,$08,$00,$00,$08 .ypos db $E0,$F0,$00,$08,$00 .size db $02,$02,$00,$00,$02 .tilemap db $43,$45,$47,$57,$48 db $43,$45,$47,$57,$4A db $64,$45,$47,$57,$48 db $64,$45,$47,$57,$4A .head1 TXA CLC ADC #$0C ; head 1 is just head 2 but with $1510,x and $1570,x as $151C,x and $157C,x TAX .head2 LDA $1510,x BNE + STZ $03 ; when state is #$00 (idle), head position is idle too LDA #$00 BRA ++ + LDA $1570,x ; indexed frame of head position LSR : LSR : LSR AND #$0F ; 16 possibilities TAX ASL STA $03 LDA .frame,x ; load frame based on head position ++ ASL LDX $05 CPX #$08 ; it displays hurt frame if state isn't #$08 BNE .hurt LDX $06 ; also when hurt BEQ + .hurt LDA #$04 ; display different tilemap + STA $04 PHX LDX #$01 - PHX TXA CLC ADC $03 TAX LDA .headpos,x PLX CLC ADC $00 STA $0300,y ; set head x position LDA $01 CLC ADC $02 STA $0301,y ; set head y position PHX TXA CLC ADC $04 TAX LDA .tilemap2,x STA $0302,y ; set head tilemap PLX LDA $08 ; do the same math we did earlier STA $0303,y PHY TYA LSR : LSR TAY LDA #$02 STA $0460,y ; set tile size to 16x16 PLY INY : INY INY : INY DEX BPL - PLX RTS .headpos db $FE,$F6 db $FD,$F5 db $FC,$F4 db $FB,$F3 db $FA,$F2 db $F9,$F1 db $F8,$F0 db $F9,$F1 db $FA,$F2 db $FB,$F3 db $FC,$F4 db $FD,$F5 db $FE,$F6 db $FE,$F6 .tilemap2 db $41,$40 db $41,$60 db $41,$62 SpawnFire: PHY STZ $06 LDY #$0B - LDA $14C8,y ; if sprite state is dead, it isn't counted BEQ + PHX TYX LDA $7FAB9E,x PLX CMP #!SpriteNum ; check for sprite number BNE + INC $06 ; increment it if correct sprite + DEY BPL - PLY LDA #$02 STA $0E LDA $06 CMP #$05 ; only 5 flames can exist BCS .ret JSL $02A9E6 ; find free sprite slot BPL + .ret RTS ; return if none + LDA #$17 STA $1DFC ; play sound effect PHX TYX LDA #!SpriteNum STA $7FAB9E,x ; get custom sprite number PLX LDA #$08 STA $14C8,y ; set sprite state LDA $E4,x CLC ADC #$F0 STA $00E4,y ; offset x position based on parent LDA $14E0,x ADC #$FF STA $14E0,y ; offset x position high based on parent LDA $D8,x CLC ADC $00 STA $00D8,y ; offset y position based on parent LDA $14D4,x ADC #$FF STA $14D4,y ; offset y position high based on parent PHX TYX JSL $07F7D2 JSL $0187A7 LDA #$08 STA $7FAB10,x ; mark as custom sprite PLX LDA $187B,x ; mario's position/sprite aiming data ASL : ASL STA $06 PHX JSL $01ACF9 ; factor in some random-ness EOR $13 SBC $94 AND #$03 ; only 4 possibilities CLC ADC $06 ; factor in where mario is TAX LDA .xspd,x ; set x speed STA $00B6,y JSL $01ACF9 ; factor in some random-ness EOR $13 SBC $94 AND #$03 ; only 4 possibilities CLC ADC $06 ; factor in where mario is TAX LDA .yspd,x ; set y speed STA $00AA,y LDA #$01 STA $00C2,y PLX RTS .xspd db $E6,$E8,$EA,$EC,$EC,$EE,$F0,$F2,$F8,$FA,$FC,$FE .yspd db $0E,$10,$12,$14,$14,$16,$18,$1A,$1A,$1C,$1E,$20 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; ROUTINES FROM THE LIBRARY ARE PASTED BELOW ; You should never have to modify this code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; GET_DRAW_INFO ; This is a helper for the graphics routine. It sets off screen flags, and sets up ; variables. It will return with the following: ; ; Y = index to sprite OAM ($300) ; $00 = sprite x position relative to screen boarder ; $01 = sprite y position relative to screen boarder ; ; It is adapted from the subroutine at $03B760 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SPR_T1: db $0C,$1C SPR_T2: db $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 SPR_T1,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 SPR_T2,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 ; / ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SUB_OFF_SCREEN ; This subroutine deals with sprites that have moved off screen ; It is adapted from the subroutine at $01AC0D ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SPR_T12: db $40,$B0 SPR_T13: db $01,$FF SPR_T14: db $30,$C0,$A0,$C0,$A0,$F0,$60,$90 ;bank 1 sizes db $30,$C0,$A0,$80,$A0,$40,$60,$B0 ;bank 3 sizes SPR_T15: db $01,$FF,$01,$FF,$01,$FF,$01,$FF ;bank 1 sizes db $01,$FF,$01,$FF,$01,$00,$01,$FF ;bank 3 sizes SUB_OFF_SCREEN_X1: LDA #$02 ; \ entry point of routine determines value of $03 BRA STORE_03 ; | (table entry to use on horizontal levels) SUB_OFF_SCREEN_X2: LDA #$04 ; | BRA STORE_03 ; | SUB_OFF_SCREEN_X3: LDA #$06 ; | BRA STORE_03 ; | SUB_OFF_SCREEN_X4: LDA #$08 ; | BRA STORE_03 ; | SUB_OFF_SCREEN_X5: LDA #$0A ; | BRA STORE_03 ; | SUB_OFF_SCREEN_X6: LDA #$0C ; | BRA STORE_03 ; | SUB_OFF_SCREEN_X7: LDA #$0E ; | STORE_03: STA $03 ; | BRA START_SUB ; | SUB_OFF_SCREEN_X0: STZ $03 ; / START_SUB: JSR SUB_IS_OFF_SCREEN ; \ if sprite is not off screen, return BEQ RETURN_35 ; / 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_35 ; / LDA $13 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0756 VC:176 00 FL:205 AND #$01 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0780 VC:176 00 FL:205 ORA $03 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0796 VC:176 00 FL:205 STA $01 ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0820 VC:176 00 FL:205 TAY ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0844 VC:176 00 FL:205 LDA $1A ;A:8A01 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizcHC:0858 VC:176 00 FL:205 CLC ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0882 VC:176 00 FL:205 ADC SPR_T14,y ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZcHC:0896 VC:176 00 FL:205 ROL $00 ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizcHC:0928 VC:176 00 FL:205 CMP $E4,x ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:0966 VC:176 00 FL:205 PHP ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:0996 VC:176 00 FL:205 LDA $1B ;A:8AC0 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizCHC:1018 VC:176 00 FL:205 LSR $00 ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdiZCHC:1042 VC:176 00 FL:205 ADC SPR_T15,y ;A:8A00 X:0009 Y:0001 D:0000 DB:01 S:01F0 P:envMXdizcHC:1080 VC:176 00 FL:205 PLP ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F0 P:eNvMXdizcHC:1112 VC:176 00 FL:205 SBC $14E0,x ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1140 VC:176 00 FL:205 STA $00 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1172 VC:176 00 FL:205 LSR $01 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:eNvMXdizCHC:1196 VC:176 00 FL:205 BCC SPR_L31 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1234 VC:176 00 FL:205 EOR #$80 ;A:8AFF X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdiZCHC:1250 VC:176 00 FL:205 STA $00 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1266 VC:176 00 FL:205 SPR_L31: LDA $00 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1290 VC:176 00 FL:205 BPL RETURN_35 ;A:8A7F X:0009 Y:0001 D:0000 DB:01 S:01F1 P:envMXdizCHC:1314 VC:176 00 FL:205 ERASE_SPRITE: LDA $14C8,x ; \ if sprite status < 8, permanently erase sprite CMP #$08 ; | BCC KILL_SPRITE ; / LDY $161A,x ;A:FF08 X:0007 Y:0001 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1108 VC:059 00 FL:2878 CPY #$FF ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZCHC:1140 VC:059 00 FL:2878 BEQ KILL_SPRITE ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1156 VC:059 00 FL:2878 LDA #$00 ;A:FF08 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdizcHC:1172 VC:059 00 FL:2878 STA $1938,y ;A:FF00 X:0007 Y:0000 D:0000 DB:01 S:01F3 P:envMXdiZcHC:1188 VC:059 00 FL:2878 KILL_SPRITE: STZ $14C8,x ; erase sprite RETURN_35: RTS ; return VERTICAL_LEVEL: LDA $167A,x ; \ if "process offscreen" flag is set, return AND #$04 ; | BNE RETURN_35 ; / LDA $13 ; \ LSR A ; | BCS RETURN_35 ; / LDA $E4,x ; \ CMP #$00 ; | if the sprite has gone off the side of the level... LDA $14E0,x ; | SBC #$00 ; | CMP #$02 ; | BCS ERASE_SPRITE ; / ...erase the sprite LDA $13 ;A:0000 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:1218 VC:250 00 FL:5379 LSR A ;A:0016 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1242 VC:250 00 FL:5379 AND #$01 ;A:000B X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1256 VC:250 00 FL:5379 STA $01 ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1272 VC:250 00 FL:5379 TAY ;A:0001 X:0009 Y:00E4 D:0000 DB:01 S:01F3 P:envMXdizcHC:1296 VC:250 00 FL:5379 LDA $1C ;A:001A X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0052 VC:251 00 FL:5379 CLC ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0076 VC:251 00 FL:5379 ADC SPR_T12,y ;A:00BD X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0090 VC:251 00 FL:5379 ROL $00 ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:enVMXdizCHC:0122 VC:251 00 FL:5379 CMP $D8,x ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0160 VC:251 00 FL:5379 PHP ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0190 VC:251 00 FL:5379 LDA.w $001D ;A:006D X:0009 Y:0001 D:0000 DB:01 S:01F2 P:eNVMXdizcHC:0212 VC:251 00 FL:5379 LSR $00 ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdiZcHC:0244 VC:251 00 FL:5379 ADC SPR_T13,y ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:enVMXdizCHC:0282 VC:251 00 FL:5379 PLP ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F2 P:envMXdiZCHC:0314 VC:251 00 FL:5379 SBC $14D4,x ;A:0000 X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNVMXdizcHC:0342 VC:251 00 FL:5379 STA $00 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0374 VC:251 00 FL:5379 LDY $01 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0398 VC:251 00 FL:5379 BEQ SPR_L38 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0422 VC:251 00 FL:5379 EOR #$80 ;A:00FF X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0438 VC:251 00 FL:5379 STA $00 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0454 VC:251 00 FL:5379 SPR_L38: LDA $00 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0478 VC:251 00 FL:5379 BPL RETURN_35 ;A:007F X:0009 Y:0001 D:0000 DB:01 S:01F3 P:envMXdizcHC:0502 VC:251 00 FL:5379 BMI ERASE_SPRITE ;A:8AFF X:0002 Y:0000 D:0000 DB:01 S:01F3 P:eNvMXdizcHC:0704 VC:184 00 FL:5490 SUB_IS_OFF_SCREEN: LDA $15A0,x ; \ if sprite is on screen, accumulator = 0 ORA $186C,x ; | RTS ; / return