;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; INIT and MAIN JSL targets
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DIR = $03
PROPRAM = $04

dcb "INIT"
	JSR SubSetXPos	; this actually jumps to the init routine of the exploding block
	STY $C2,x	; the Y register determines which statue it will be
	;LDA WalkTime,y
	;STA $1540,x
EndInit:
	RTL

SubSetXPos:	; this determines which kind of statue it will be based on its X position
	LDA $E4,x	; sprite X position (low byte)
	LSR
	LSR
	LSR
	LSR		; divide by 16 to get it in terms of tiles
	AND #$03	; we want only 4 possible values
	TAY		; transfer this into Y (to determine the sprite that the exploding block would spawn)
	RTS		; but since this isn't an exploding block, we can just end right here

dcb "MAIN"


	PHB
	PHK
	PLB		
	JSR Run
	PLB
	RTL

RETURN:
	RTS

Run:

	LDA $7FAB10,x
 	AND #$04
	BEQ SKIP
 	JSR GFX_COIN
	RTS
SKIP:	JSR GFX

	LDA $14C8,x	; \ 
	CMP #$08	;  | if status != 8, return
	BNE RETURN	; /
	LDA $9D		; \ if sprites locked, return
	BNE RETURN	; /

	LDA $1602,x
	BEQ KeepRunning

	LDA $1588,x	;sprite blocked status table xxxxUDLR
	AND #$04
	BEQ NoJump
	LDA #$E0
	STA $AA,x

NoJump:

	LDA $B6,x
	SEC
	SBC #$04
	BMI SetZero
	STA $B6,x
	BRA Update
	
SetZero:
	STZ $B6,x
	BRA Update
KeepRunning:

	LDA $1DEF
	CMP #$01
	BEQ GoTime
	JSR SubSetXPos	; this actually jumps to the init routine of the exploding block
	CPY #$03
	BEQ DoneWalk
	LDA #$08
	STA $B6,x
	BRA Update

Donewalk:
	LDA $1DEF
	CMP #$01
	BEQ GoTime
	STZ $B6,x
	BRA Update
	

GoTime:
	LDA $C2,x
	TAY
	LDA RunSpeed,y
	;LDA #$70
	STA $B6,x

Update:
	JSL $01802A	;update position based on speed values
	
	RTS

LevelASM:

	LDA $13C8
	BNE DecRAM
	LDA $16
	AND #$01
	BNE Move
	BRA Done
DecRAM:
	DEC $13C8
	LDA $16
	AND #$01
	BNE Boost
	BRA Done
Boost:
	LDA $7B
	CLC
	ADC #$18
	CLC
	CMP #$7F
	BCC NoSlow
	LDA #$7F
NoSlow:
	STA $7B
Move:
	LDA #$0A
	STA $13C8

Done:
	RTS

RunSpeed:
	dcb $6F,$58,$40,$00
WalkTime:
	dcb $28,$28,$28,$28
;;;;;;;;;;;;;;;;;;;;;;;
;GFX routine
;;;;;;;;;;;;;;;;;;;;;;;

TILEMAP:	dcb $A0,$4E
	dcb $A2,$82

;XDISP:	dcb $00,$00
;	dcb $00,$10

YDISP:	dcb $00,$F0
	dcb $10,$10

GFX:
	JSR SUB_OFF_SCREEN_X0
	JSL $20CA4F

	LDA $157C,x	;direction...
	STA DIR

	LDA $15F6,x	;properties...
	ORA #$64	;flip the X direction
	STA PROPRAM

	LDX #$00

OAM_Loop:

	LDA $00
	STA $0300,y	;xpos

	LDA $01
	CLC
	ADC YDISP,x
	STA $0301,y	;ypos

	PHX
	LDX $15E9
	LDA $B6,x	;general purpose timer
	PLX
	CMP #$00
	BEQ Normal	;don't animate if not moving horizontal
	CMP #$3A
	BCS RunFast	;animate quickly if running fast
	
	LDA $14		;animate medium if moving, but not quickly
	AND #$08
	BNE Normal
	

Faster:
	INX
	INX
	LDA TILEMAP,x
	STA $0302,y
	LDA $0301,y
	INC
	STA $0301,y
	DEX
	DEX
	BRA Dunn

RunFast:
	LDA $14
	AND #$02
	BNE Faster


Normal:
	LDA TILEMAP,x
	STA $0302,y	;chr

Dunn:
	LDA PROPRAM
	ORA $64
	STA $0303,y	;prop

	INY
	INY
	INY
	INY
	INX

	CPX #$02
	BNE OAM_Loop

	LDX $15E9	;restore sprite index
	LDY #$02	;16x16
	LDA #$01	;2 tiles
	JSL $01B7B3	;reserve

	RTS


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ROUTINES FROM THE LIBRARY ARE PASTED BELOW
; You should never have to modify this code
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;





TILEMAP_NUM: db $76,$77,$46,$47,$C2,$C3,$D2,$D3,$D4,$D5,$4D,$67

GFX_COIN:
	LDA #$B0
	STA $0200,y	;xpos COIN
	CLC
	ADC #$10
	STA $0204,y	;xpos NUM1
	CLC
	ADC #$08
	STA $0208,y	;xpos NUM2
	CLC
	ADC #$08
	STA $020C,y	;xpos NUM3

	LDA #$28
	CLC
	ADC #$00
	STA $0201,y	;xpos COIN
	STA $0205,y	;ypos NUM1
	STA $0209,y	;ypos NUM2
	STA $020D,y	;ypos NUM3

	LDA #$DB
	STA $0202,y
	LDA $140C
	STA $7F8888
	CMP #$64
	BCC NOHUND
	SEC
	SBC #$64
	STA $7F8888
	PHX
	LDX #$01
	LDA TILEMAP_NUM,x
	STA $206,y
	PLX
	BRA GOLOOP
NOHUND:	PHX
	LDX #$00
	LDA TILEMAP_NUM,x
	STA $206,y
	PLX
GOLOOP:	PHX
	LDA $7F8888
LOOP:	TAX
	CMP #$0A
	BCC E_LOOP
	SEC
	SBC #$0A
	BRA LOOP
E_LOOP: LDA TILEMAP_NUM,x
	STA $020E,y
	LDX #$00
	LDA $7F8888
LOOP2:	CMP #$0A
	BCC E_LP2
	SEC
	SBC #$0A
	INX
	BRA LOOP2;
E_LP2:	LDA TILEMAP_NUM,x
	STA $020A,y
	PLX

	LDA #$36
	STA $0203,y	;prop
	STA $0207,y	;prop
	STA $020B,y	;prop
	STA $020F,y	;prop

	LDX $15E9	;restore sprite index
	LDY #$00	;8X16
	LDA #$00	;2 tile
	JSL $81B7B3	;reserve
	RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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			
	LDA $94					
	SEC                     
	SBC $E4,x	 
	STA $0F					
	LDA $95	
	SBC $14E0,x				
	BPL SPR_L16  
	INY                     
SPR_L16	
	RTS                     

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_OFF_SCREEN
; This subroutine deals with sprites that have moved off screen
; It is adapted from the subroutine at $01AC0D
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
                    
SPR_T12             dcb $40,$B0
SPR_T13             dcb $01,$FF
SPR_T14             dcb $30,$C0,$A0,$C0,$A0,$F0,$60,$90		;bank 1 sizes
		            dcb $30,$C0,$A0,$80,$A0,$40,$60,$B0		;bank 3 sizes
SPR_T15             dcb $01,$FF,$01,$FF,$01,$FF,$01,$FF		;bank 1 sizes
					dcb $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
