;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; !WalkTimer = $163E !FrameNum = $1510 !TurnAroundTimer = $15AC !TempDir = $02 !TilesTemp = $06 !OneTileTemp = $07 !SlashTimer = $1540 !CoolDownTimer = $163E !BeginTimer = $1558 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; INIT and MAIN JSL targets ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; print "INIT ",pc JSR SUB_HORZ_POS ;face the player every frame, TYA ;since this sprite doesn't move horizontally STA $157C,x LDA #$01 STA !FrameNum,x LDA #$02 STA !BeginTimer,x RTL speed: db $10,$F0 print "MAIN ",pc PHB PHK PLB JSR SPRITE_ROUTINE PLB RTL ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SPRITE_ROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SPRITE_ROUTINE: JSR SUB_GFX JSL $018032 LDA !SlashTimer,x CMP #$0D BCS RegClipping CMP #$07 BCC RegClipping LDA $1662,x AND #$C0 ORA #$08 STA $1662,x BRA StoredClipping RegClipping: LDA $1662,x AND #$C0 ORA #$15 STA $1662,x StoredClipping: LDA $14C8,x ; return if sprite status != 8 CMP #$02 BNE NotSetFrameD LDA #$07 STA !FrameNum,x NotSetFrameD: LDA $14C8,x ; return if sprite status != 8 CMP #$08 BEQ NOTSENDRETURN SENDRETURN: JMP RETURN NOTSENDRETURN: LDA $9D ; \ return if BNE SENDRETURN JSR SUB_OFF_SCREEN_X0 ; only process sprite while on screen LDA !SlashTimer,x BEQ NotSlashing JMP Slashing NotSlashing: LDA !CoolDownTimer,x BNE NotSlash JSR Proximity2 BEQ NotSlash LDA #$10 STA !SlashTimer,x NotSlash: JSR Proximity BEQ NotTurn LDA !TurnAroundTimer,x CMP #$01 BNE NotFaceMario JSR SUB_HORZ_POS TYA ;since this sprite doesn't move horizontally STA $157C,x NotFaceMario: LDA !TurnAroundTimer,x BNE NotTurn JSR SUB_HORZ_POS TYA ;since this sprite doesn't move horizontally CMP $157C,x BEQ NotTurn LDA #$07 STA !TurnAroundTimer,x NotTurn: LDA $1588,x ; If sprite is in contact with a wall, AND #$03 BEQ NoWallContact ; change direction LDA $157C,x EOR #$01 STA $157C,x NoWallContact: LDA $1588,x ; If the sprite is in the air ORA !TurnAroundTimer,x ; and not already turning ORA !BeginTimer,x BNE NoFlipDirection LDA $157C,x EOR #$01 STA $157C,x NoFlipDirection: LDA $157C,x TAY LDA speed,y STA $B6,x LDA !WalkTimer,x BNE skipNFrame INC !FrameNum,x LDA #$06 STA !WalkTimer,x LDA !FrameNum,x CMP #$04 BCC skipNFrame LDA #$00 STA !FrameNum,x skipNFrame: JSL $01802A JSL $01A7DC RETURN: RTS Slashing: LDA !SlashTimer,x CMP #$0D BCS S1 CMP #$07 BCS S2 CMP #$02 BCS S3 LDA #$06 STA !CoolDownTimer,x LDA #$03 STA !FrameNum,x JMP NoWallContact S1: JSR SUB_HORZ_POS TYA ;since this sprite doesn't move horizontally STA $157C,x LDA #$04 STA !FrameNum,x BRA SRet S2: LDA #$05 STA !FrameNum,x BRA SRet S3: LDA #$06 STA !FrameNum,x SRet: LDA #$00 STA $B6,x JMP skipNFrame ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; GRAPHICS ROUTINE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Tiles: db $00,$02,$20,$22 XOff: db $F8,$08,$F8,$08 YOff: db $F8,$F8,$08,$08 Frames: db $00,$01,$02,$03,$10,$11,$12,$13,$20 SUB_GFX: JSR GET_DRAW_INFO ; after: Y = index to sprite OAM ($300) ; $00 = sprite x position relative to screen boarder ; $01 = sprite y position relative to screen boarder LDA $157C,x ; $02 = sprite direction STA !TempDir STZ !TilesTemp LDA !FrameNum,x PHX TAX LDA Frames,x PLX JSR GETSLOT BEQ EndIt STA !OneTileTemp PHX LDX #$00 TileLoop: LDA $00 PHY LDY !TempDir BEQ right CLC ADC XOff,x BRA Flipped right: SEC SBC XOff,x Flipped: PLY STA $0300,y LDA $01 CLC ADC YOff,x STA $0301,y LDA !OneTileTemp CLC ADC Tiles,x STA $0302,y PHX LDX $15E9 LDA $15F6,x ORA $64 LDX !TempDir BNE left ORA #$40 left: PLX STA $0303,y INC !TilesTemp INY INY INY INY INX CPX #$04 BCC TileLoop PLX LDA !TilesTemp BEQ EndIt DEC LDY #$02 JSL $01B7B3 EndIt: RTS Proximity: ; If sprite is TOO close to Mario, return. LDA $14E0,x XBA LDA $E4,x REP #$20 ; Get sprite's X position. SEC SBC $94 ; Subtract Mario's to get the difference range. SEP #$20 PHA JSR SUB_HORZ_POS ; Determine sprite range. PLA EOR InvertAbility,y ; Apply inversion based on direction. CMP #$50 ; Range. BCS OutofRange LDA #$01 RTS OutofRange: LDA $E4,x CMP $94 BNE RangeOut LDA #$01 RTS RangeOut: LDA #$00 RTS InvertAbility: db $FF,$00 Proximity2: ; If sprite is TOO close to Mario, return. LDA $14E0,x XBA LDA $E4,x REP #$20 ; Get sprite's X position. SEC SBC $94 ; Subtract Mario's to get the difference range. SEP #$20 PHA JSR SUB_HORZ_POS ; Determine sprite range. PLA EOR InvertAbility,y ; Apply inversion based on direction. CMP #$30 ; Range. BCS OutofRange2 LDA #$01 RTS OutofRange2: LDA $E4,x CMP $94 BNE RangeOut2 LDA #$01 RTS RangeOut2: LDA #$00 RTS ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; Dynamic sprite routine ; Programmed mainly by SMKDan, but based on some of my code ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; !TEMP = $09 !SLOTPTR = $0660 ;16bit pointer for source GFX !SLOTBANK = $0662 ;bank !SLOTDEST = $0663 ;VRAM address !SLOTSUSED = $06FE ;how many slots have been used !MAXSLOTS = $04 ;maximum selected slots SLOTS: db $CC,$C8,$C4,$C0 ;avaliable slots. Any more transfers and it's overflowing by a dangerous amount. GETSLOT: PHY ;preserve OAM index PHA ;preserve frame LDA !SLOTSUSED ;test if slotsused == maximum allowed CMP #!MAXSLOTS BEQ NoneFree PLA ;pop frame REP #$20 ;16bit A AND.w #$00FF ;wipe high XBA ;<< 8 LSR A ;>> 1 = << 7 STA !TEMP ;back to scratch ;PEA SPRITEGFX ;push 16bit address, since i'm not sure how else i'm going to get the address of the label itself in TRASM ;PLA ;pull 16bit address LDA GFXPointer CLC ADC !TEMP ;add frame offset STA !SLOTPTR ;store to pointer to be used at transfer time SEP #$20 ;8bit store PHB ;push db... PLA ;pull to A... STA !SLOTBANK ;store bank to 24bit pointer LDY !SLOTSUSED ;calculate VRAM address + tile number LDA SLOTS,y ;get tile# in VRAM PHA ;preserve for eventual pull SEC SBC #$C0 ;starts at C0h, they start at C0 in tilemap REP #$20 ;16bit math AND.w #$00FF ;wipe high byte ASL A ;multiply by 32, since 32 bytes/16 words equates to 1 32bytes tile ASL A ASL A ASL A ASL A CLC ADC #$0B44 ;add 0B44, base address of buffer STA !SLOTDEST ;destination address in the buffer JSR DMABUFFER ;ROM -> RAM copy SEP #$20 ;8bit A INC !SLOTSUSED ;one extra slot has been used PLA ;return starting tile number PLY RTS NoneFree: PLA PLY LDA #$00 ;zero on no free slots RTS ;;;;;;;;;;;;;;;; ;Tansfer routine ;;;;;;;;;;;;;;;; ;DMA ROM -> RAM ROUTINE DMABUFFER: ;set destination RAM address REP #$20 LDA !SLOTDEST STA $2181 ;16bit RAM dest LDY #$7F STY $2183 ;set 7F as bank ;common DMA settings STZ $4300 ;1 reg only LDY #$80 ;to 2180, RAM write/read STY $4301 ;first line LDA !SLOTPTR STA $4302 ;low 16bits LDY !SLOTBANK STY $4304 ;bank LDY #$80 ;128 bytes STY $4305 LDY #$01 STY $420B ;transfer ;second line LDA !SLOTDEST ;update buffer dest CLC ADC #$0200 ;512 byte rule for sprites STA !SLOTDEST ;updated base STA $2181 ;updated RAM address LDA !SLOTPTR ;update source address CLC ADC #$0200 ;512 bytes, next row STA !SLOTPTR STA $4302 ;low 16bits LDY !SLOTBANK STY $4304 ;bank LDY #$80 STY $4305 LDY #$01 STY $420B ;transfer ;third line LDA !SLOTDEST ;update buffer dest CLC ADC #$0200 ;512 byte rule for sprites STA !SLOTDEST ;updated base STA $2181 ;updated RAM address LDA !SLOTPTR ;update CLC ADC #$0200 STA !SLOTPTR STA $4302 LDY !SLOTBANK STY $4304 LDY #$80 STY $4305 LDY #$01 STY $420B ;transfer ;fourth line LDA !SLOTDEST ;update buffer dest CLC ADC #$0200 ;512 byte rule for sprites STA !SLOTDEST ;updated base STA $2181 ;updated RAM address LDA !SLOTPTR CLC ADC #$0200 STA !SLOTPTR STA $4302 LDY !SLOTBANK STY $4304 LDY #$80 STY $4305 LDY #$01 STY $420B SEP #$20 ;8bit A RTS ;all done, return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; 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 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; SUB_HORZ_POS ; This routine determines which side of the sprite Mario is on. It sets the Y register ; to the direction such that the sprite would face Mario ; It is ripped from $03B817 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SUB_HORZ_POS: 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 SPR_L16 ;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 SPR_L16: RTS ;A:25FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:1214 VC:097 00 FL:31642 GFXPointer: dw SPRITEGFX SPRITEGFX: INCBIN sprites\penguin.bin ;included graphics file