;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Fire/Ice Boss (Possibly for World 7's Boss in ASMWCP2)
;;
;; Description:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;----------------------------------------------------------------------------------------
;; Customizable Constants
;;----------------------------------------------------------------------------------------

                HIT_POINTS = $05        ; Customizable Hit Point Bar
                SPRITE_NUM = $BC        ; Customizable Sprite Number
                PILLAR_NUM = $BD        ; Customizable Sprite Number
                BOMB_NUM = $BE        	; Customizable Sprite Number
		THROW_BLOCK = $80
		CHANGE_BLOCK = $80
		DANGER_MODE = $03

;;----------------------------------------------------------------------------------------
;; Customizable Variables (Free Memory) 
;;		TEMP_Y = $7F888A
;;		LAST_SWITCH = $7F888B
;;		POINT_STATE = $7F888C
;;----------------------------------------------------------------------------------------
		
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


dcb "INIT"
		LDA #$88                ; \ mark as initialized
                STA $7FAB10,x        ; /
		LDA #SPRITE_NUM
               	STA $7FAB9E,x
		LDA #$01
		STA $86
		LDA #$FF
		STA $7F888C
		LDA #$00
		STA $0670
		STA $18BD
		STA $157C,x
		STA $7F888B
		STA $7F888A
		STA $1528,x
		STA $C2,x
		LDA #$30
		STA $14
		RTL                 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite code JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

dcb "MAIN"
		PHB               ; \
		PHK               ;  | main sprite function, just calls local subroutine
		PLB               ;  |
		JSR SCODE_START   ;  |
		PLB               ;  |
		RTL               ; /

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite main code 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BounceSpeed:	dcb $C8,$38

FROZ_BOUNCE:	LDA $19
		CMP $0D9C
		BEQ CON_FROZ
		STZ $18BD
		STZ $0670
		RTS
CON_FROZ:	LDA #$0F
		STA $13E0
		DEC $0670
		STZ $AA,x		; Store Sprite's Y Speed which is 0.
		LDA $0670
		CMP #$30
		BEQ DEC_TIM_670
		DEC $B6,x		; Store Sprite'x X Speed from XSPEED
		RTS
DEC_TIM_670:	LDA #$20
		STA $18BD
		RTS

RETURN2:	LDA $71
		CMP #$09
		BNE RETURN1
		STZ $1887
RETURN1:	RTS
SCODE_START	LDA $C2,x               ;Load State of the Sprite
		CMP #$09
		BNE CON_COD 
		LDA $9D                 ; \ if sprites not locked, return
		BNE NO_DRAW
CON_COD:	JSR SUB_GFX             ; graphics routine
NO_DRAW:	LDA $14C8,x 
		CMP #$04                
		BEQ RETURN1             
		LDA $9D                 
		BNE RETURN2             
		LDA $0670
		BEQ DO_REST
        	JSR FROZ_BOUNCE         ; set mario speed	
DO_REST:	JSR $018032
		JSR ENVIRONMENT
		JSR KEY_COLOR
		JSR REMOVE_FL
		LDA $C2,x 
		CMP #$03
		BEQ SKIP_HIT
		CMP #$09
		BEQ SKIP_HIT
		CMP #$0D
		BEQ SKIP_HIT
		JSR HitFunction
SKIP_HIT:	JSR CHECKTIMER
		LDA $C2,x 
		CMP #$04
		BEQ STATEMACH
		CMP #$09
		BEQ STATEMACH
		CMP #$0D
		BEQ STATEMACH
		CMP #$0E
		BEQ STATEMACH
		CMP #$0F
		BEQ STATEMACH
		JSR $01A7DC
		BCC STATEMACH
		LDA $14AF
		BEQ ICE_FREEZETH
		JSL $00F5B7
		BRA STATEMACH
ICE_FREEZETH:	LDA $1497
		BNE STATEMACH
		LDA #$50
		STA $0670 
		LDY $157C,x
		LDA BounceSpeed,y
		STA $7B
		LDA $19
		STA $0D9C
		LDA #$10
		STA $1DF9

STATEMACH:	LDA $C2,x               ;Load State of the Sprite
		BEQ STATE0              ; For State 0
		CMP #$01
		BEQ STATE1
		CMP #$02
		BEQ STATE2
		CMP #$03
		BEQ STATE3
		CMP #$04
		BEQ STATE4
		CMP #$06
		BEQ STATE6
		CMP #$07
		BEQ STATE7
		CMP #$08
		BEQ STATE8
		CMP #$09
		BEQ STATE9
		CMP #$0A
		BEQ STATEA
		CMP #$0B
		BEQ STATEB
		CMP #$0C
		BEQ STATEC
		CMP #$0D
		BEQ STATED
		CMP #$0E
		BEQ STATEE
		CMP #$0F
		BEQ STATEF

STATE0		JMP STALL
STATE1		JMP MOVEMENT
STATE2		JMP THROWING		
STATE3		JMP QUAKE
STATE4		JMP HURTORDIE
STATE6		JMP DROPDOWN
STATE7		JMP KEYSPRITE
STATE8		JMP THROW_PILLAR
STATE9		JMP START_RAGE
STATEA		JMP REV_UP
STATEB		JMP SLOW_DOWN
STATEC		JMP STATE_C
STATED		JMP REAPPEAR
STATEE		JMP DEATH_ICE
STATEF		JMP DEATH_FIRE
RETURN		RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 0 (STALL)
;;-----------------------------------------------------------------------------------------

STALL:		LDA $1564,x
		BEQ CREATE_STALL
		CMP #$01
		BEQ CHANGE_STATE0
		RTS
CHANGE_STATE0:	LDA #$0A
		STA $C2,x
		RTS
CREATE_STALL:	LDA $1528,x
		CMP #DANGER_MODE
		BCS SPEED_UP
		LDA #$60
		BRA LOAD_TIME
SPEED_UP:	LDA #$30
LOAD_TIME:	STA $1564,x
		RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 1 (WALKING)
;;-----------------------------------------------------------------------------------------

XSPEED: 	dcb $D8,$28		; Speeds of Sprite's X Speed

MOVEMENT:	LDA $14E0,x		; Load the current MAX_HIGH into A.
		BNE DONTSTOP		; If not met yet, keep walking.
		LDY $157C,x		
		TYA
		BNE RIGHT_WALK
		LDA $E4,x		; Compare to its current position.
		CMP #$19
		BCC STOP_WALK		; If not met yet, keep walking.
		BRA DONTSTOP
RIGHT_WALK:	LDA $E4,x		; Compare to its current position.
		CMP #$D8
		BCS STOP_WALK
		BRA DONTSTOP
STOP_WALK:	LDA $157C,x		;
		EOR #$01		; Flip sprite's direction to turn around.
		STA $157C,x		;
		LDA #$0B
		STA $C2,x
		RTS
DONTSTOP:	LDA XSPEED,y		; Load X speed indexed by Y (done before).
		STA $B6,x		; Store Sprite'x X Speed from XSPEED.
		STZ $AA,x		; Store Sprite's Y Speed which is 0.
		JSL $01802A		; Apply speed.
MOVERET:	RTS			; Return

;------------------------------------------------------------------------------------------

REV_UP:		LDA $1564,x
		BEQ REV_STALL
		CMP #$01
		BNE MOVERET
		LDA #$01
		STA $C2,x
		RTS

REV_STALL:	LDA #$09
		STA $1564,x
		RTS

SLOW_DOWN:	LDA $1564,x
		BEQ REV_STALL
		CMP #$01
		BNE MOVERET
		LDA #$0C
		STA $C2,x
		RTS

STATE_LIST:	db $02,$03,$08,$09	;$02,$03,$08,$09

STATE_C:	JSR SETZERO
		LDA #$40
		STA $163E,x
		LDA #$80
		STA $154C,x
		
		LDA $7F888C
		CLC
		ADC #$01
		STA $7F888C
		
		AND #$03
		PHY
		TAY
		LDA STATE_LIST,y
		PLY
		CMP #$09
		BNE STORESTATE
		PHA
		LDA $1528,x
		CMP #DANGER_MODE
		BCS NO_CHANGE
		PLA
		LDA #$03
		BRA STORESTATE
NO_CHANGE:	PLA
STORESTATE:	STA $C2,x		; Load State Into Sprite's Memory
		RTS			; Return

;;-----------------------------------------------------------------------------------------
;; Sprite State = 2 (THROW)
;;-----------------------------------------------------------------------------------------

T_SPEEDX:	db $48,$48,$40,$38,$34,$30	;,$2D,$28
T_SPEEDY:	db $04,$02,$00,$FE,$01,$F3	;,$F0,$ED 

THROWING:	LDA $14
		AND #$1F
		BEQ THROWBALL
		LDA $7F888A
		CMP #$06
		BNE THROWRET
THROWSTATE:	STZ $C2,x		; Load State Into Sprite's Memory
		JSR SETZERO
THROWRET:	RTS
THROWBALL:	LDY #$05
THROWLOOP:	LDA $170B,y
		BEQ CREATEBALL
		DEY
		BPL THROWLOOP
		RTS
CREATEBALL:	LDA #$02
		STA $170B,y
		LDA $157C,x
		BEQ ADD_FIRE
		LDA $E4,x
		CLC
		ADC #$0E
		BRA CONT_BALL
ADD_FIRE:	LDA $E4,x
		SEC
		SBC #$0C
CONT_BALL:	STA $171F,y
		LDA $14E0,x
		STA $1733,y
		LDA $D8,x
		STA $1715,y
		LDA $14D4,x
		STA $1729,y
		
		PHY
		LDA $7F888A
		ATY
		LDA T_SPEEDY,y
		PLY
		STA $173D,y

		PHY
		LDA $7F888A
		ATY
		LDA T_SPEEDX,y
		PHA
		LDA $157C,x
		AND #$01
		BNE THROWRIGHT
		PLA
		EOR #$FF
		BRA STORERIGHT
THROWRIGHT:	PLA
STORERIGHT:	PLY
		STA $1747,y

		LDA #$06
		STA $1DFC

		LDA #$FF
		STA $176F,y
		JSR INCCOUNT
		RTS 			; Return

;------------------------------------------------------------------------------------------

REMOVE_FL:	PHX
		LDX #$0B
REMOVE_LOOP:	LDA $170B,x
		CMP #$03
		BNE END_FL_LOOP
		STZ $170B,x
END_FL_LOOP:	DEX 
		BPL REMOVE_LOOP
		PLX
		RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 3 (QUAKE)
;;-----------------------------------------------------------------------------------------

MAX_YVELOCITY = $20
MAX_XVELOCITY = $30

QUAKE:		STZ $B6,x
		LDA #MAX_YVELOCITY
		SEC
		SBC $163E,x
		ASL
		STA $AA,x
		STA $13C8
		CMP #$40
		BEQ ON_FLOOR
		BNE QUAKE_DONE

ON_FLOOR:	STZ $AA,x
		STZ $B6,x

		LDA #$09                ; \ play sound effect
		STA $1DFc               ; /

		LDA $77
                AND #$04
                BEQ NOFREEZE
		LDA #$30	       ; set timer to freeze mario
                STA $18BD
NOFREEZE:	LDA #$FF
		STA $1887
		LDA #$06		; Choose State 6
		STA $C2,x		; Load State Into Sprite's Memory
QUAKE_DONE:	JSL $01801A
		RTS

;;----------------------------------------------------------------------------------------

SETZERO:	LDA #$00
		STA $7F888A
		RTS

INCCOUNT:	LDA $7F888A
		CLC
		ADC #$01
		STA $7F888A
		RTS
	
;;-----------------------------------------------------------------------------------------
;; Sprite State = 12 (BOMB RAGE)
;;-----------------------------------------------------------------------------------------
		
X_LO_LOCALE:	dcb $48,$78,$A8,$78
Y_LO_LOCALE:	dcb $20,$F0,$20,$40
Y_HI_LOCALE:	dcb $01,$00,$01,$01

SET_R_TIME:	LDA #$A1
		STA $1540,x
		LDA $E4,x 
		STA $7F8888
		LDA $D8,x 
		STA $7F8889
		RTS
START_RAGE:	LDA $1540,x
		BEQ SET_R_TIME
		AND #$F0
		BNE SET_PLACE
		LDA $1540,x
		CMP #$01
		BNE WAIT_IT_OUT
		LDA #$0D
		STA $C2,x
		LDA $7F8888
		STA $E4,x 
		LDA $7F8889
		STA $D8,x 
		LDA #$01
		STA $14D4,x 
WAIT_IT_OUT	RTS
SET_PLACE	JSL $01ACF9
		LDA $148D
		AND #$03
		TAY
		LDA X_LO_LOCALE,y
		STA $E4,x 
		LDA Y_LO_LOCALE,y       ;  |
             	STA $00D8,x             ;  |
            	LDA Y_HI_LOCALE,y       ;  |
              	STA $14D4,x             ; /
		LDA $1540,x
		AND #$1F
		BNE WAIT_IT_OUT
		JSR ANNOYBOMB
		RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 13 (MAKE BOMB)
;;-----------------------------------------------------------------------------------------

ANNOYBOMB:	PHX
		LDY #$00
		LDX #$07
LOOPIS_BMB:	TXA
		BEQ CREATEBOMB
		LDA $14C8,x             ; \ if the sprite status is..
		BEQ NEXT_BSPRITEIS
		LDA $7FAB10,x		;
		AND #$08		;
		BEQ NEXT_BSPRITEIS	
		LDA $7FAB9E,x
		CMP #BOMB_NUM
		BNE NEXT_BSPRITEIS
		INY
NEXT_BSPRITEIS:	DEX
		BRA LOOPIS_BMB	
CREATEBOMB:	PLX
		TYA
		CMP #$04
		BEQ NOROOMBOMB
		LDA $15A0,x             ; \ no egg if off screen
              	ORA $186C,x             ;  |
             	ORA $15D0,x            
		BNE NOROOMBOMB
            	JSL $02A9DE             ; \ get an index to an unused sprite slot, return if all slots full
                BMI NOROOMBOMB          ; / after: Y has index of sprite being generated

		LDA #$08                ; \ set sprite status for new sprite
              	STA $14C8,y             ; /

              	PHX
		LDA #BOMB_NUM
               	TYX
               	STA $7FAB9E,x
               	PLX

		LDA #$08
		STA $7FAB10,x

		PHY
               	LDA $157C,x
               	TAY
              	LDA $E4,x               ; \ set x position for new sprite
               	CLC
              	ADC X_OFFSET,y
              	PLY
            	STA $00E4,y

           	PHY
          	LDA $157C,x
                TAY
           	LDA $14E0,x             ;  |
              	ADC X_OFFSET2,y
             	PLY
               	STA $14E0,y             ; /

		LDA $D8,x               ; \ set y position for new sprite
               	SEC                     ;  | (y position of generator - 1)
             	SBC #$00                ;  |
             	STA $00D8,y             ;  |
            	LDA $14D4,x             ;  |
          	SBC #$00                ;  |
              	STA $14D4,y             ; /

		PHX                     ; \ before: X must have index of sprite being generated
                TYX                     ;  | routine clears *all* old sprite values...
                JSL $07F7D2             ;  | ...and loads in new values for the 6 main sprite tables
                JSL $0187A7             ;  get table values for custom sprite
             	LDA #$88
             	STA $7FAB10,x
		PLX                     ; / 
                LDA $157C,x
		EOR #$01
                STA $157C,y

		LDA #$25
		STA $1DF9
NOROOMBOMB:	RTS

;-----------------------------------------------------------------------------------------

REAPPEAR:	LDA $1540,x
		BEQ START_RP
		CMP #$01
		BNE RET_RP
		STZ $C2,x
		RTS
START_RP:	LDA #$40
		STA $1540,x
RET_RP:		RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 5 (Environment)
;;-----------------------------------------------------------------------------------------

ENVIRONMENT:	LDA $7F888B
		CMP $14AF
		BEQ NOCHANGE
		LDA $86
		EOR #$01
		STA $86
DESTROYSPR:	JSR ELIMSPRITES
NOCHANGE:	LDA $14AF
		STA $7F888B
		RTS

;;----------------------------------------------------------------------------------------

ELIMSPRITES:	PHX 
		LDX #$07
LOOPSPRITE:	TXA
		BEQ ELIMDONE
		LDA $14C8,x 
		BEQ DEC_X
		LDA $7FAB10,x		;
		AND #$08		;
		BNE CHECK_CUST
		LDA $9E,x
		CMP #THROW_BLOCK
		BEQ CLOCK_OUT
		CMP #$1D
		BEQ DESTROY
		BRA DEC_X
CLOCK_OUT:	LDA $1564,x
		BNE STOP_CLOCK
		LDA #$C0
		STA $1564,x
		LDA #CHANGE_BLOCK
		STA $9E,x
		BRA DEC_X
STOP_CLOCK:	STZ $1564,x
		LDA #CHANGE_BLOCK
		STA $9E,x
		BRA DEC_X
DESTROY:	LDA #$04
		STA $14C8,x  
		LDA #$1F
		STA $1540,x
		LDA #$08
		STA $1DF9		;
DEC_X:		STZ $170B,x
		DEX
		BRA LOOPSPRITE
CHECK_CUST:	LDA $7FAB9E,x
		CMP #$09
		BEQ DESTROY
		BRA DEC_X
ELIMDONE:	PLX
		RTS

;;-----------------------------------------------------------------------------------------

CHECKTIMER:	PHX 
		LDX #$07
LOOPKEY:	TXA
		BEQ ELIMKEY
		LDA $14C8,x 
		BEQ DEC_X2
		LDA $7FAB10,x		;
		AND #$08		;
		BNE DEC_X2
		LDA $9E,x
		CMP #THROW_BLOCK	;
		BNE DEC_X2
		LDA $1564,x
		CMP #$01
		BNE DEC_X2
		LDA #$04
		STA $14C8,x  
		LDA #$1F
		STA $1540,x
DEC_X2:		DEX	
		BRA LOOPKEY
ELIMKEY:	PLX
		RTS	

;;-----------------------------------------------------------------------------------------
;; Sprite State = 4A (HURT/DIE)
;;-----------------------------------------------------------------------------------------

HURTORDIE:	LDA $1540,x
		CMP #$01
		BEQ NORMAL
		CMP #$02
		BCS HURTEND
NORMAL:		INC $1528,x		; Load Hit Counter
		LDA $1528,x		; Store to the Hit Counter
		CMP #HIT_POINTS		; Compare with the value of MAX HIT_POINTS
		BEQ CHANGE_ST		; If they're equal end the level.
		LDA #HIT_POINTS		; Load Number of Hit Points
		SEC 			; For Subtraction
		SBC $1528,x		; Subtract Max Hit Points from Current Hit Points
		CMP #$04		; Compare to 4 points left.
		BCS NORMALSTATE		; If there's at least 4 points left, branch.
NORMALSTATE:	LDA #$01		; Choose State 1
		STA $C2,x		; Load State Into Sprite's Memory
HURTEND:	RTS 			; Return

CHANGE_ST:	LDA $14AF
		BEQ ICE_GOAL
		LDA #$0F
		BRA STORE_GOAL	
ICE_GOAL:	LDA #$0E
STORE_GOAL:	STA $C2,x
		JSR ELIMALL
		RTS

;------------------------------------------------------------------------------------------

CREATE_POOL:	LDA $15A0,x             ; \ no egg if off screen
              	ORA $186C,x             ;  |
             	ORA $15D0,x            
		BNE NOROOMPOOL
            	JSL $02A9DE             ; \ get an index to an unused sprite slot, return if all slots full
                BMI NOROOMPOOL		; / after: Y has index of sprite being generated

		LDA #$08                ; \ set sprite status for new sprite
              	STA $14C8,y             ; /

              	PHX
		LDA #PILLAR_NUM
               	TYX
               	STA $7FAB9E,x
               	PLX

		LDA #$08
		STA $7FAB10,x

              	LDA $E4,x               ; \ set x position for new sprite
            	STA $00E4,y

           	LDA $14E0,x
               	STA $14E0,y             ; /

		LDA $D8,x               ; \ set y position for new sprite
               	CLC                     ;  | (y position of generator - 1)
             	ADC #$10                ;  |
             	STA $00D8,y             ;  |
            	LDA $14D4,x             ;  |
              	STA $14D4,y             ; /

		PHX                     ; \ before: X must have index of sprite being generated
                TYX                     ;  | routine clears *all* old sprite values...
                JSL $07F7D2             ;  | ...and loads in new values for the 6 main sprite tables
                JSL $0187A7             ;  get table values for custom sprite
             	LDA #$8C
             	STA $7FAB10,x
		PLX                     ; / 
                LDA $157C,x
                STA $157C,y
NOROOMPOOL:	RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 4B (GOAL)
;;-----------------------------------------------------------------------------------------

GOAL:		LDA #$04
		STA $14C8,x             ; Destroy Sprite 
		LDA #$1F
		STA $1540,x
		LDA #$08
		STA $1DF9
		INC $13C6               ; Prevent Mario from walking.
		LDA #$FF                ; \ Set Goal
		STA $1493               ; /
		LDA #$0B                ; \ Set Ending Eusic
		STA $1DFB               ; /
		RTS                     ; return

DEATH_ICE:	LDA $14
		AND #$03
		BEQ NO_CHANGE_DT
		INC $1540,x
		RTS
NO_CHANGE_DT:	INC $D8,x
		LDA $1540,x
		STA $13C8
		BEQ SET_DEATHTIME
		CMP #$01
		BEQ GOAL
		RTS
SET_DEATHTIME:	JSR CREATE_POOL
SET_DEATHTIME2:	LDA #$21
		STA $1540,x
		RTS

DEATH_FIRE:	LDA $1540,x
		STA $13C8
		BEQ SET_DEATHTIME2
		CMP #$01
		BEQ GOAL
		RTS
;------------------------------------------------------------------------------------------

ELIMALL:	PHX 
		LDX #$07
LOOPALL:	TXA
		BEQ ELIMALLDONE
		LDA $14C8,x 
		BEQ DEC_X4
		LDA #$04
		STA $14C8,x  
		LDA #$1F
		STA $1540,x		;
DEC_X4:		STZ $170B,x
		DEX
		BRA LOOPALL
ELIMALLDONE:	PLX
		RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 6 (ICICLE/FIRE DROP)
;;-----------------------------------------------------------------------------------------

DROPDOWN:	LDA $1540,x
		BEQ SET_FALL_TIME
		CMP #$01
		BEQ END_FALL
		AND #$0F
		BEQ BALLTHROW
		RTS
END_FALL:	LDA #$07		; Choose State 1
		STA $C2,x		; Load State Into Sprite's Memory
		RTS
SET_FALL_TIME:	LDA #$C0
		STA $1540,x
		RTS
BALLTHROW:	LDY #$07
BALLLOOP:	LDA $170B,y
		BEQ THROWSPIKES
		DEY
		BPL BALLLOOP
		RTS
THROWSPIKES:	LDA #$04
		STA $170B,y
		JSL $01ACF9
		LDA $148D
		;LDA $D1
		STA $171F,y
		LDA #$D1
		STA $1715,y
		LDA #$10
		STA $173D,y
		LDA #$FF
		STA $176F,y
		LDA #$00
		STA $1733,y
		STA $1729,y
		STA $1747,y
STOPSPIKES:	RTS 			; Return

;;-----------------------------------------------------------------------------------------
;; Sprite State = 7 (MAKE KEY SPRITE)
;;-----------------------------------------------------------------------------------------

KEYSPRITE:	JSL $02A9DE             ; \ get an index to an unused sprite slot, return if all slots full
                BMI NOROOM            ; / after: Y has index of sprite being generated
		LDA #$09                ; \ set sprite status for new sprite
                STA $14C8,y             ; /
                LDA #THROW_BLOCK       ; \ set sprite number for new sprite
                STA $009E,y             ; /

		LDA $E4,X
		STA $E4,y
		LDA $14E0,X
               	STA $14E0,y            

             	LDA $D8,X               ; \ set y position for new sprite
             	STA $D8,y               ;  |
            	LDA $14D4,X            	;  |
              	STA $14D4,y             ; /

		LDA $14AF
		BEQ ICYBALL
		LDA #$0C
		STA $15F6,y
		BRA CON_KEY_MAKE
ICYBALL:	LDA #$0E
		STA $15F6,y
CON_KEY_MAKE: 	PHX                     ; \ before: X must have index of sprite being generated
            	TYX                     ;  | routine clears *all* old sprite values...
              	JSL $07F7D2             ;  | ...and loads in new values for the 6 main sprite tables
             	PLX                     ; / 
                LDA $157C,x
        	STA $00C2,y

		STZ $C2,x		; Load State Into Sprite's Memory
		JSR KEY_COLOR
		LDA $14AF
		BEQ ICESTATE
		JMP ANNOYFSPRITE
ICESTATE:	JMP ANNOYISPRITE
NOROOM:		RTS

;-------------------------------------------------------------------------

KEY_COLOR:	LDY #$0B
COLOR_LOOP:	LDA $9E,y		; \ if the sprite number is
		CMP #$80		;  | key
		BNE NEXT_LOOP		; /
		LDA $1564,y
		BEQ ON_COLOR
		LDA $14AF
		EOR #$01
		ASL
		ORA $15F6,y
		ORA #$0D
		STA $15F6,y	; / make it red (if it's gold or red)
		BRA NEXT_LOOP
ON_COLOR:	LDA $14AF
		ASL
		ORA $15F6,y
		ORA #$0D
		STA $15F6,y	; / make it red (if it's gold or red)
NEXT_LOOP:	DEY		;
		BPL COLOR_LOOP	; ...otherwise, loop
		RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 10 (HIT DETECTION)
;;-----------------------------------------------------------------------------------------

HitFunction:	LDY #$07                ; 
LOOP		LDA $14C8,y             ; \ if the sprite status is..
		BEQ NEXT_SPRITE
		LDA $9E,y
		CMP #CHANGE_BLOCK	;
		BNE NEXT_SPRITE	
		LDA $1564,y            ; \ if the sprite status is..
		CMP #$02
		BCS PROCESS_SPRITE
NEXT_SPRITE	DEY                     ;
		BPL LOOP                ; ...otherwise, loop
		RTS                     ; return
PROCESS_SPRITE	PHX                     ; push x
		TYX                     ; transfer x to y
		JSL $03B6E5             ; get sprite clipping B routine
		PLX                     ; pull x
		JSL $03B69F             ; get sprite clipping A routine
		JSL $03B72B             ; check for contact routine
		BCC NEXT_SPRITE         ;
		LDA #$04                ; \ set sprite state
		STA $C2,x               ; /
		LDA #$40                ; \ set timer
		STA $1540,x             ; /
		PHX                     ; push x
		TYX                     ; transfer x to y
		LDA #$00
		STA $14C8,y             ; destroy the sprite
BLOCK_SETUP	LDA $E4,y               ; \ setup block properties
             	STA $9A                 ;  |
              	LDA $14E0,y             ;  |
            	STA $9B                 ;  |
                LDA $D8,y               ;  |
              	STA $98                 ;  |
             	LDA $14D4,y             ;  |
              	STA $99                 ; /
EXPLODING_BLOCK	PHB                     ; \ set the exploding block routine
		LDA #$02                ;  |
		PHA                     ;  |
		PLB                     ;  |
		LDA #$FF                ;  | $FF = set flashing palette
		JSL $028663             ;  |
aftershowthing:	PLB                     ; /
		PLX                     ; pull x
		LDA #$28                ; \ sound effect
		STA $1DFC               ; /
		RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 8 (MAKE ANNOYING FIRE SPRITE)
;;-----------------------------------------------------------------------------------------

ANNOYFSPRITE:	LDY #$07
LOOPFS:		TYA
		BEQ CREATE_FS
		LDA $14C8,y             ; \ if the sprite status is..
		BEQ NEXT_SPRITEFS	
		LDA $9E,y
		CMP #$1D
		BEQ NOROOMFIRE
NEXT_SPRITEFS:	DEY
		BRA LOOPFS	

CREATE_FS:	JSL $02A9DE             ; \ get an index to an unused sprite slot, return if all slots full
                BMI NOROOMFIRE          ; / after: Y has index of sprite being generated
		LDA #$08                ; \ set sprite status for new sprite
                STA $14C8,y             ; /
                LDA #$1D                ; \ set sprite number for new sprite
                STA $009E,y             ; /

		LDA $E4,X
		CLC 
		ADC #$10
		STA $E4,y
		LDA $14E0,X
               	STA $14E0,y            

             	LDA $D8,X               ; \ set y position for new sprite
             	STA $D8,y               ;  |
            	LDA $14D4,X            	;  |
              	STA $14D4,y             ; /

		LDA #$88
		STA $7FAB10,x
	
            	PHX                     ; \ before: X must have index of sprite being generated
            	TYX                     ;  | routine clears *all* old sprite values...
              	JSL $07F7D2             ;  | ...and loads in new values for the 6 main sprite tables
             	PLX                     ; / 
                LDA $157C,x
        	STA $00C2,y
		LDA #$01		; Choose State 1
		STA $C2,x		; Load State Into Sprite's Memory
NOROOMFIRE:	RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 11 (ICE/FIRE PILLAR)
;;-----------------------------------------------------------------------------------------

THROW_PILLAR:	LDA $1540,x
		BEQ SET_PILTIME
		CMP #$01
		BEQ PIL_STATE
		CMP #$80
		BEQ CREATE_PILLAR
		CMP #$42
		BNE PILLAR_END
		LDA $1528,x
		CMP #DANGER_MODE
		BCC PILLAR_END
		JSR CREATE_PILLAR
		RTS
SET_PILTIME:	LDA #$90
		STA $1540,x
PILLAR_END:	RTS
PIL_STATE:	STZ $C2,x
		RTS

CREATE_PILLAR:	LDA $15A0,x             ; \ no egg if off screen
              	ORA $186C,x             ;  |
             	ORA $15D0,x            
		BNE NOROOMPIL
            	JSL $02A9DE             ; \ get an index to an unused sprite slot, return if all slots full
                BMI NOROOMPIL            ; / after: Y has index of sprite being generated

		LDA #$08                ; \ set sprite status for new sprite
              	STA $14C8,y             ; /

              	PHX
		LDA #PILLAR_NUM
               	TYX
               	STA $7FAB9E,x
               	PLX

		LDA #$08
		STA $7FAB10,x

		PHY
               	LDA $157C,x
               	TAY
              	LDA $E4,x               ; \ set x position for new sprite
               	CLC
              	ADC X_OFFSET,y
              	PLY
            	STA $00E4,y

           	PHY
          	LDA $157C,x
                TAY
           	LDA $14E0,x             ;  |
              	ADC X_OFFSET2,y
             	PLY
               	STA $14E0,y             ; /

		LDA $D8,x               ; \ set y position for new sprite
               	SEC                     ;  | (y position of generator - 1)
             	SBC #$00                ;  |
             	STA $00D8,y             ;  |
            	LDA $14D4,x             ;  |
          	SBC #$00                ;  |
              	STA $14D4,y             ; /

		PHX                     ; \ before: X must have index of sprite being generated
                TYX                     ;  | routine clears *all* old sprite values...
                JSL $07F7D2             ;  | ...and loads in new values for the 6 main sprite tables
                JSL $0187A7             ;  get table values for custom sprite
             	LDA #$88
             	STA $7FAB10,x
		PLX                     ; / 
                LDA $157C,x
                STA $157C,y

		LDA #$02
		STA $1528,y

		LDA #$10
		STA $1DF9
NOROOMPIL:	RTS

;;-----------------------------------------------------------------------------------------
;; Sprite State = 9 (MAKE ANNOYING ICE SPRITE)
;;-----------------------------------------------------------------------------------------

CANT_CREATEICE:	PLX
		RTS
ANNOYISPRITE:	PHX
		LDX #$07
LOOPIS:		TXA
		BEQ CREATE_IS
		LDA $14C8,x             ; \ if the sprite status is..
		BEQ NEXT_SPRITEIS
		LDA $7FAB10,x		;
		AND #$08		;
		BEQ NEXT_SPRITEIS	
		LDA $7FAB9E,x
		CMP #$09
		BEQ CANT_CREATEICE
NEXT_SPRITEIS:	DEX
		BRA LOOPIS	
CREATE_IS:	PLX
		LDA $15A0,x             ; \ no egg if off screen
              	ORA $186C,x             ;  |
             	ORA $15D0,x            
		BNE NOROOMICE
            	JSL $02A9DE             ; \ get an index to an unused sprite slot, return if all slots full
                BMI NOROOMICE            ; / after: Y has index of sprite being generated

		LDA #$08                ; \ set sprite status for new sprite
              	STA $14C8,y             ; /

              	PHX
		LDA #$09
               	TYX
               	STA $7FAB9E,x
               	PLX

		LDA #$08
		STA $7FAB10,x

		PHY
               	LDA $157C,x
               	TAY
              	LDA $E4,x               ; \ set x position for new sprite
               	CLC
              	ADC X_OFFSET,y
              	PLY
            	STA $00E4,y

           	PHY
          	LDA $157C,x
                TAY
           	LDA $14E0,x             ;  |
              	ADC X_OFFSET2,y
             	PLY
               	STA $14E0,y             ; /

		LDA $D8,x               ; \ set y position for new sprite
               	SEC                     ;  | (y position of generator - 1)
             	SBC #$00                ;  |
             	STA $00D8,y             ;  |
            	LDA $14D4,x             ;  |
          	SBC #$00                ;  |
              	STA $14D4,y             ; /

		PHX                     ; \ before: X must have index of sprite being generated
                TYX                     ;  | routine clears *all* old sprite values...
                JSL $07F7D2             ;  | ...and loads in new values for the 6 main sprite tables
                JSL $0187A7             ;  get table values for custom sprite
             	LDA #$88
             	STA $7FAB10,x
		PLX                     ; / 
                LDA $157C,x
                STA $157C,y
		
		LDA $166E,y
		ORA #$10
		STA $166E,y
		
		LDA #$01		; Choose State 1
		STA $C2,x		; Load State Into Sprite's Memory
NOROOMICE:	RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

STATE_0_TC:	db $00,$02,$20,$22,$04,$06,$24,$26
STATE_1_TC:	db $08,$0A,$28,$2A,$44,$46,$64,$66,$08,$0A,$2C,$2E,$44,$46,$64,$66
STATE_2_TC:	db $48,$4A,$68,$6A
STATE_3_TC:	db $04,$06,$24,$26,$4C,$4E,$6C,$6E,$E6,$CE,$A4,$A6
STATE_4_TC:	db $C0,$C2,$E0,$E2,$D4,$EE,$EE,$EE
STATE_5_TC:	db $C8,$CA,$E8,$EA
STATE_8_TC:	db $4C,$4E,$6C,$6E,$80,$82,$A0,$A2
STATE_AB_TC:	db $80,$82,$A0,$A2
STATE_C_TC:	db $00,$02,$20,$22
STATE_E_TC:	db $40,$42,$60,$62
STATE_F_TC:	db $C0,$C2,$E0,$E2,$D4

XDISP:  	db $F8,$08,$F8,$08,$08,$F8,$08,$F8
	
XDISP4:  	db $F8,$08,$F8,$08,$18,$00,$08,$00,$08,$F8,$08,$F8,$E8,$F8,$00,$00
YDISP4:  	db $F0,$F0,$00,$00,$F8,$E0,$E0,$00,$F0,$F0,$00,$00,$F8,$E0,$E0,$00

YDISP:  	db $F0,$F0,$00,$00,$F0,$F0,$00,$00
		
PROP:		db $0D,$4D

DISP:		db $00,$04

SUB_GFX:	JSL $20CA4F
		LDA $157C,x
		STA $04
		LDA $C2,x
		BNE S_TO1
		JMP TILE_S0C
S_TO1:		CMP #$01
		BNE S_TO2
		JMP TILE_S1C
S_TO2:		CMP #$02
		BNE S_TO3
		JMP TILE_S2C
S_TO3:		CMP #$03
		BNE S_TO4
		JMP TILE_S3C
S_TO4:		CMP #$04
		BNE S_TO6
		JMP TILE_S4C
S_TO6:		CMP #$06
		BNE S_TO8
		JMP TILE_S0C
S_TO8:		CMP #$08
		BNE S_TO9
		JMP TILE_S8C
S_TO9:		CMP #$09
		BNE S_TOA
		JMP TILE_S9C
S_TOA:		CMP #$0A
		BNE S_TOB
		JMP TILE_SABC
S_TOB:		CMP #$0B
		BNE S_TOC
		JMP TILE_SABC
S_TOC:		CMP #$0C
		BNE S_TOD
		JMP TILE_SCC
S_TOD:		CMP #$0D
		BNE S_TOE
		JMP TILE_SDC
S_TOE:		CMP #$0E
		BNE S_TOF
		JMP TILE_SEC
S_TOF:		CMP #$0F
		BNE S_TORET
		JMP TILE_SFC
S_TORET:	RTS

;-----------------------------------------------------------------------------------------------

TILE_S0C:	LDA $14			;\ Frame counter ..
		LSR A			; |
		LSR A			; |
		LSR A			; |
		LSR A			; | Add in frame animation rate; More LSRs for slower animation.
		AND #$01
		ASL
		ASL
		STA $03
		PHX			;\ Push sprite index ..
		LDX #$03		;/ And load X with number of tiles to loop through.
LoopS0C:	PHX
		LDA $04
		BEQ SKIP0C
		INX
		INX
		INX
		INX
SKIP0C:		LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP,x		; |
		STA $0300,y		;/ 
		PLX 
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		PHX
		TXA 
		CLC
		ADC $03
		TAX
		LDA STATE_0_TC,x
		STA $0302,y
		PLX
	
		PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
	
		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopS0C		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$03		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
		RTS			; Never forget this!		

;-----------------------------------------------------------------------------------------------

TILE_S1C:	LDA $14			;\ Frame counter ..
		LSR A			; |
		LSR A			; |
		LSR A			; | Add in frame animation rate; More LSRs for slower animation.
		AND #$03
		ASL
		ASL
		STA $03
		PHX			;\ Push sprite index ..
		LDX #$03		;/ And load X with number of tiles to loop through.
LoopS1C:	PHX
		LDA $04
		BEQ SKIP1C
		INX
		INX
		INX
		INX
SKIP1C:		LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP,x		; |
		STA $0300,y		;/ 
		PLX
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		PHX
		TXA 
		CLC
		ADC $03
		TAX
		LDA STATE_1_TC,x
		STA $0302,y
		PLX
	
		PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
	
		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopS1C		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$03		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
		RTS			; Never forget this!	

;-----------------------------------------------------------------------------------------------

TILE_SABC:	PHX			;\ Push sprite index ..
		LDX #$03		;/ And load X with number of tiles to loop through.
LoopSABC:	PHX
		LDA $04
		BEQ SKIPABC
		INX
		INX
		INX
		INX
SKIPABC:	LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP,x		; |
		STA $0300,y		;/ 
		PLX 
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		
		LDA STATE_AB_TC,x
		STA $0302,y
	
		PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
	
		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopSABC		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$03		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
		RTS			; Never forget this!		

;-----------------------------------------------------------------------------------------------

TILE_SCC:	PHX			;\ Push sprite index ..
		LDX #$03		;/ And load X with number of tiles to loop through.
LoopSCC:	PHX
		LDA $04
		BEQ SKIPCC
		INX
		INX
		INX
		INX
SKIPCC:		LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP,x		; |
		STA $0300,y		;/
		PLX 
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		
		LDA STATE_C_TC,x
		STA $0302,y
	
		PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
	
		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopSCC		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$03		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
END_TILE:	RTS			; Never forget this!		

;-----------------------------------------------------------------------------------------------

TILE_SDC:	LDA $14
		LSR A
		LSR A
		AND #$01
		BEQ END_TILE
		JMP TILE_S0C
	
;-----------------------------------------------------------------------------------------------

TILE_S2C:	PHX			;\ Push sprite index ..
		LDX #$03		;/ And load X with number of tiles to loop through.
LoopS2C:	PHX
		LDA $04
		BEQ SKIP2C
		INX
		INX
		INX
		INX
SKIP2C:		LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP,x		; |
		STA $0300,y		;/
		PLX 
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		
		LDA STATE_2_TC,x
		STA $0302,y
	
		PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
	
		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopS2C		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$03		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
		RTS			; Never forget this!		

;-----------------------------------------------------------------------------------------------

TILE_S3C:	PHX			;\ Push sprite index ..
		LDX #$03		;/ And load X with number of tiles to loop through.
LoopS3C:	PHX
		LDA $04
		BEQ SKIP3C
		INX
		INX
		INX
		INX
SKIP3C:		LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP,x		; |
		STA $0300,y		;/
		PLX 
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		PHX
		LDA $13C8
		STA $0DBF
		BEQ NO_ADD_3C
		CMP #$80
		BCC DOWN_3C
		TXA
		CLC
		ADC #$04
		TAX
		BRA NO_ADD_3C
DOWN_3C:	TXA
		CLC
		ADC #$08
		TAX
NO_ADD_3C:	LDA STATE_3_TC,x
		STA $0302,y
		PLX
	
		PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
	
		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopS3C		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$03		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
		RTS			; Never forget this!		

;-----------------------------------------------------------------------------------------------

TILE_S4C:	PHX			;\ Push sprite index ..
		LDX #$06		;/ And load X with number of tiles to loop through.
LoopS4C:	PHX
		LDA $04
		BEQ SKIP4C
		TXA
		CLC
		ADC #$08
		TAX
SKIP4C:		LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP4,x		; |
		STA $0300,y		;/
		PLX 
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP4,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		
		LDA STATE_4_TC,x
		STA $0302,y
	
		TXA
		CMP #$05
		BCC SKIP_67
		PHX
		LDX $04
		LDA $14
		LSR A
		LSR A
		LSR A
		AND #$01
		ASL
		ASL
		ASL
		ASL
		ASL
		ASL
		EOR PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
		BRA IN_4
SKIP_67:	PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
	
IN_4:		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopS4C		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$06		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
		RTS			; Never forget this!		

;-----------------------------------------------------------------------------------------------

COLOR_SWAP:	db $07,$08

TILE_S8C:	LDA $1540,x
		AND #$F0
		CMP #$80
		BEQ CREATE_8
		CMP #$90
		BEQ CREATE_8
		LDA $1528,x
		CMP #DANGER_MODE
		BCC GO_TO_0
		LDA $1540,x
		AND #$F0
		CMP #$50
		BEQ CREATE_8
		CMP #$60
		BEQ CREATE_8
GO_TO_0:	JMP TILE_S0C

CREATE_8:	LDA $14			;\ Frame counter ..
		LSR A			; |
		LSR A			; |
		LSR A			; | Add in frame animation rate; More LSRs for slower animation.
		AND #$01
		ASL
		ASL
		STA $03
TILE_S9C:	PHX			;\ Push sprite index ..
		LDX #$03		;/ And load X with number of tiles to loop through.
LoopS8C:	PHX
		LDA $04
		BEQ SKIP8C
		INX
		INX
		INX
		INX
SKIP8C:		LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP,x		; |
		STA $0300,y		;/ 
		PLX 
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		PHX
		TXA 
		CLC
		ADC $03
		TAX
		LDA STATE_8_TC,x
		STA $0302,y
		PLX
	
		PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.	
		AND #$F1
		STA $13C8
		LDA $14
		AND #$01
		TAX
		LDA $13C8
		ORA COLOR_SWAP,x
		STA $0303,y		;/
		PLX
	
		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopS8C		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$03		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
		RTS			; Never forget this!

TILE_SEC:	PHX			;\ Push sprite index ..
		LDX #$03		;/ And load X with number of tiles to loop through.
LoopSEC:	PHX
		LDA $04
		BEQ SKIPEC
		INX
		INX
		INX
		INX
SKIPEC:		LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP,x		; |
		STA $0300,y		;/
		PLX 
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		
		LDA STATE_E_TC,x
		STA $0302,y
	
		LDA #$00
		STA $64

		LDA $14
		AND #$02
		STA $13C8
		PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.
		;EOR $13C8
		;AND #$CF
		STA $0303,y		;/
		PLX
	
		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopSEC		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$03		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
		RTS			; Never forget this!		

;-----------------------------------------------------------------------------------------------

TILE_SFC:	PHX			;\ Push sprite index ..
		LDX #$04		;/ And load X with number of tiles to loop through.
LoopSFC:	PHX
		LDA $04
		BEQ SKIPFC
		TXA
		CLC
		ADC #$08
		TAX
SKIPFC:		LDA $00			;\
		CLC			; | Apply X displacement of the sprite.
		ADC XDISP4,x		; |
		STA $0300,y		;/
		PLX 
		LDA $01			;\
		CLC			; | Y displacement is added for the Y position, so one tile is higher than the other.
		ADC YDISP4,x		; | Otherwise, both tiles would have been drawn to the same position!
		STA $0301,y		; | If X is 00, i.e. first tile, then load the first value from the table and apply that
					;/ as the displacement. For the second tile, F0 is added to make it higher than the first.
		
		LDA STATE_F_TC,x
		STA $0302,y
	
		TXA
		CMP #$05
		BCC SKIP_FC
		PHX
		LDX $04
		LDA $14
		LSR A
		LSR A
		LSR A
		AND #$01
		ASL
		ASL
		ASL
		ASL
		ASL
		ASL
		EOR PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
		BRA IN_F
SKIP_FC:	PHX
		LDX $04
		LDA $14AF
		ASL
		ORA PROP,x		; | Set properties based on direction.
		STA $0303,y		;/
		PLX
		ORA #$02
		AND #$F3
		STA $0303,y		;/
	
IN_F:		INY			;\
		INY			; | The OAM is 8x8, but our sprite is 16x16 ..
		INY			; | So increment it 4 times.
		INY			;/
		DEX			; After drawing this tile, decrease number of tiles to go through loop. If the second tile
					; is drawn, then loop again to draw the first tile.

		BPL LoopSFC		; Loop until X becomes negative (FF).
	
		PLX			; Pull back the sprite index! We pushed it at the beginning of the routine.

		LDY #$02		; Y ends with the tile size .. 02 means it's 16x16
		LDA #$04		; A -> number of tiles drawn - 1.
					; I drew 2 tiles, so 2-1 = 1. A = 01.

		JSL $01B7B3		; Call the routine that draws the sprite.
		RTS			; Never forget this!	

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


SUB_SMOKE           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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $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
                    





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; hammer routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
NEW_SPRITE_NUM = $7FAB9E
EXTRA_BITS = $7FAB10
X_OFFSET            dcb $06,$FA
X_OFFSET2           dcb $00,$FF
                    
SUB_HAMMER_THROW    LDA $15A0,x             ; \ no egg if off screen
                    ORA $186C,x             ;  |
                    ORA $15D0,x
                    BNE RETURN67
                    
                    JSL $02A9DE             ; \ get an index to an unused sprite slot, return if all slots full
                    BMI RETURN67            ; / after: Y has index of sprite being generated

                    lda #$10
		    sta $1df9 
                    
                    LDA #$08                ; \ set sprite status for new sprite
                    STA $14C8,y             ; /

                    PHX
                    LDA NEW_SPRITE_NUM,x
                    INC A
                    TYX
                    STA NEW_SPRITE_NUM,x
                    PLX

                    PHY
                    LDA $157C,x
                    TAY
                    LDA $E4,x               ; \ set x position for new sprite
                    CLC
                    ADC X_OFFSET,y
                    PLY
                    STA $00E4,y

                    PHY
                    LDA $157C,x
                    TAY
                    LDA $14E0,x             ;  |
                    ADC X_OFFSET2,y
                    PLY
                    STA $14E0,y             ; /

                    LDA $D8,x               ; \ set y position for new sprite
                    SBC #$00                ;  |
                    STA $00D8,y             ;  |
                    LDA $14D4,x             ;  |
                    SBC #$00                ;  |
                    STA $14D4,y             ; /

                    PHX                     ; \ before: X must have index of sprite being generated
                    TYX                     ;  | routine clears *all* old sprite values...
                    JSL $07F7D2             ;  | ...and loads in new values for the 6 main sprite tables
                    JSL $0187A7             ;  get table values for custom sprite
                    LDA #$88
                    STA EXTRA_BITS,x
                    PLX                       ; / 

                    LDA $157C,x
                    STA $157C,y
                
                    
                    
RETURN67            RTS                     ; return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 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