incsrc CoinDefines.asm
print "INIT ",pc
RTL
print "MAIN ",pc
PHB        ;\
PHK        ; | Change the data bank to the one our code is running from.
PLB        ; | This is a good practice.
JSR SpriteCode    ; | Jump to the sprite's function.
PLB        ; | Restore old data bank.
RTL        ;/ And return.
;===================================
;Sprite Function
;===================================
RETURN: RTS
SpriteCode:
    LDA $1534,x
    CMP #$01
    BEQ FROZEN
    LDA $14
    STA $1510,x
    BRA BAH
    FROZEN:
    LDA $1528,x
    CMP #$20
    BCS PAUSE
    INC $1528,x
    LDA $D8,x
    CMP #$00
    BEQ SCREENUP
    DEC $D8,x
    BRA BAH
    SCREENUP:
    LDA #$FF
    STA $D8,x
    LDA #$00
    STA $14D4,x
    BAH:
    JSR Graphics
    
    LDA $14C8,x            ;\
    CMP #$08            ; | If sprite dead,
    BNE RETURN            ;/ Return.
    LDA $9D                ;\
    BNE RETURN            ;/ If locked, return.
    
    JSR SUB_OFF_SCREEN_X0        ; Handle offscreen.
    JSL $01A7DC
    BCC NoContact
    Rising:
    LDA #$14
    sta $1dfc
    LDA #$04
    sta $1dfb
    LDA #$01
    STA $1534,x
    JSL $07FC3B   
    INC $9D
    RTS
    
    NoContact:
    RTS
    PAUSE:
    JSR Graphics
    LDA $1528,x
    CMP #$30
    BEQ DECIDE
    INC $1528,x
    RTS
    DECIDE:
    
    LDA $7FAB10,x
    AND #$04
    BNE +
    
    DEC $13C6
    
+   LDA $1510,x
    LSR
    LSR
    LSR
    AND #$07
    CMP #$00
    BEQ MUSHROOM
    CMP #$01
    BEQ COIN10
    CMP #$02
    BEQ NOTHING
    CMP #$03
    BEQ COIN
    CMP #$04
    BEQ FLOWER
    CMP #$05
    BEQ Coin302
    CMP #$06
    BEQ LIFE
    CMP #$07
    BEQ COIN20
    RTS
    Coin302:
    JSR COIN30
    RTS
    MUSHROOM:
    lda #$0A
    STA $1DF9
    LDA $19
    CMP #$01
    BCS RAWRG
    LDA #$01
    STA $19
    RAWRG:
    STZ $14C8,x
    LDA #$FF
    STA $1493
    RTS
    FLOWER:
    lda #$0A
    STA $1DF9
    LDA #$03
    STA $19
    STZ $14C8,x
    LDA #$FF
    STA $1493
    RTS
    NOTHING:
    LDA #$2A
    STA $1DFC
    STZ $14C8,x
    LDA #$FF
    STA $1493
    RTS
    COIN:
    LDA #$01
    STA $1DFC
    INC $0DBF
    STZ $14C8,x
    LDA #$FF
    STA $1493
    RTS
    COIN10:
    LDA #$01
    STA $1DFC
    LDA $0DBF
    CLC 
    ADC #$0A
    STA $0DBF
    STZ $14C8,x
    LDA #$FF
    STA $1493
    RTS
    LIFE:
    LDA #$05
    STA $1DFC
    INC $0DBE
    STZ $14C8,x
    LDA #$FF
    STA $1493
    RTS
    COIN20:
    LDA #$01
    STA $1DFC
    LDA $0DBF
    CLC 
    ADC #$14
    STA $0DBF
    STZ $14C8,x
    LDA #$FF
    STA $1493
    RTS
    COIN30:
    LDA #$01
    STA $1DFC
    LDA $0DBF
    CLC 
    ADC #$1E
    STA $0DBF
    STZ $14C8,x
    LDA #$FF
    STA $1493
    RTS
;===================================
;Graphics Code
;===================================
TILEMAP: db $24,$E8,$44,$E8,$26,$E8,$24,$E8
PROPERTIES: db $38,$34,$3A,$34,$3A,$34,$3A,$34 ; NOTE: Flip the X direction when going right.
Graphics:
    JSR GET_DRAW_INFO     ; Before actually coding the graphics, we need a routine that will get the current sprite's value 
                  ; into the OAM.
                  ; The OAM being a place where the tile data for the current sprite will be stored.
    LDA $157C,x
    STA $02            ; Store direction to $02 for use with property routine later.
    LDA $00            ;\
    STA $0300,y        ;/ Draw the X position of the sprite
    LDA $01            ;\
    STA $0301,y        ;/ Draw the Y position of the sprite
    LDA $1510,x
    PHX
    LSR
    LSR
    LSR
    AND #$07
    TAX
    LDA TILEMAP,x
    STA $0302,y
    LDA PROPERTIES,x    ; Get properties indexed by direction ..
    ORA $64
    STA $0303,y        ; Store to properties byte.
    PLX            ; Pull back X.
    INY            ;\
    INY            ; | The OAM is 8x8, but our sprite is 16x16 ..
    INY            ; | So increment it 4 times.
    INY            ;/
    LDY #$02        ; Y ends with the tile size .. 02 means it's 16x16
    LDA #$00        ; A -> number of tiles drawn - 1.
                ; I drew only 1 tile so I put in 1-1 = 00.
    JSL $01B7B3        ; Call the routine that draws the sprite.
    RTS            ; Never forget this!
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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 #$0040            ;  |
    CMP #$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            ;  | OMG YOU FOUND THIS HIDDEN z0mg place!111 you win a cookie!
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 $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
;
; $B817 - horizontal mario/sprite check - shared
; Y = 1 if mario left of sprite??
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                    ;org $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 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