;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Albatoss by mikeyk, slightly modified by piranha productions
;;
;; Description: This is a flying bird that is rideable
;;
;; Uses first extra bit: YES
;; If the first extra bit is set, the Albatoss will drop Bob-ombs
;;
;; Extra Property Byte 1
;;    bit 0 - enable spin killing (if ridable)
;;    bit 2 - pause when dropping bob-ombs
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                    EXTRA_PROP_1 = $7FAB28
                    EXTRA_BITS = $7FAB10

                    DROP_TIMER = $1540
                    TIME_TILL_DROP = $34
                    TIME_TILL_EXPLODE = $01
                    TIME_TO_PAUSE = $02
                    BOMB_PAL = $05
                    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                    dcb "INIT"
                    PHY
                    JSR SUB_HORZ_POS
                    TYA
                    STA $157C,x
                    PLY
                    RTL                 


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

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


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

X_SPEED             dcb $10,$F0
KILLED_X_SPEED      dcb $F0,$10

RETURN              RTS
SPRITE_CODE_START   JSR SPRITE_GRAPHICS       ; graphics routine
                    LDA $14C8,x             ; \ 
                    CMP #$08                ;  | if status != 8, return
                    BNE RETURN              ; /
                    JSR SUB_OFF_SCREEN_X0   ; handle off screen situation

                    LDA $9D                 ; \ if sprites locked, return
                    BNE RETURN              ; /

                    LDA EXTRA_BITS,x    ; only drop if extra bit is set
                    AND #$04
                    BNE NOMOVE		; sonikku-note: changed the opcode and branch location to add contact code below

;;;;;;;;; code i added

	LDA $13BF	; allow code to run
	CMP #$0F	; only on level #$0F
	BNE MOVEA	; otherwise it skips this code
			; i only relocated it a bit

	LDA #$09	; make it unable to
	STA $1686,x	; interact with other sprites (bypassed below)

	LDY #$0B	; loop #$0B times
LOOP	LDA $14C8,y
	CMP #$09	; if its carriable, branch
	BEQ PROSPR
	CMP #$0A	; if its kicked, branch
	BEQ PROSPR
	CMP #$0B	; if its carried, branch
	BEQ PROSPR
NXTSPR	DEY		; otherwise
	BPL LOOP	; we will loop UNTIL THE END OF TIME
	BRA MOVEA
PROSPR	LDA $167A,y
	AND #$02
	BNE NXTSPR
	PHX
	TYX
	JSL $03B6E5
	PLX
	JSL $03B69F
	JSL $03B72B
	BCC NXTSPR

	LDA #$02	; we can now kill this sprite
	STA $14C8,x	; and run the code below



WARPLANE_CODE_INC
	INC $0D9C
	LDA $0D9C
	CMP #$04
	BEQ GIVE_CODE
MOVEA	BRA MOVE

GIVE_CODE
	LDA #$01
	STA $1F2B
	LDA #$02
	STA $1426               ; DISPLAY CODE


;;;;;;;;; modified code from original sprite resumes
                    BRA MOVE

NOMOVE              LDA DROP_TIMER,x
                    CMP #TIME_TO_PAUSE
                    BCS MOVE
                    CMP #$00
                    BNE NO_RESET3           ;reset timer if it equals 0
                    LDA #TIME_TILL_DROP
                    STA DROP_TIMER,x
NO_RESET3           CMP #$01
                    BNE DONT_DROP
                    JSR SUB_HAMMER_THROW    ;drop code
DONT_DROP           STZ $B6,x

                    LDA EXTRA_PROP_1,x
                    AND #$04
                    BNE DONT_MOVE

MOVE
                    LDY $157C,x             ; \ set x speed based on direction
                    LDA X_SPEED,y           ;  |
                    STA $B6,x               ; /
                
DONT_MOVE
                    STZ $AA,x
                    JSL $01802A             ; update position based on speed values
         
                    LDA $1588,x             ; \ if sprite is in contact with an object...
                    AND #$03                ;  |
                    BEQ NO_CONTACT          ;  |
                    LDA $157C,x             ;  | flip the direction status
                    EOR #$01                ;  |
                    STA $157C,x             ; /
NO_CONTACT          
                    JSL $01A7DC             ; check for mario/sprite contact (carry set = contact)
                    BCC RETURN_24           ; return if no contact
                    JSR SUB_VERT_POS        ; 
                    LDA $0E                 ; \ if mario isn't above sprite, and there's vertical contact...
                    CMP #$E6                ;  |     ... sprite wins
                    BPL SPRITE_WINS         ; /
                    LDA $7D                 ; \if mario speed is upward, return
                    BMI RETURN_24           ; /
                    LDA EXTRA_PROP_1,x
                    AND #$01
                    BEQ SPIN_KILL_DISABLED  ;
                    LDA $140D               ; \ if mario is spin jumping, goto SPIN_KILL
                    BNE SPIN_KILL           ; / 
SPIN_KILL_DISABLED  LDA #$01                ; \ set "on sprite" flag
                    STA $1471               ; /
                    LDA #$06                ; \ set riding sprite
                    STA $154C,x             ; / 
                    STZ $7D                 ; y speed = 0
                    LDA #$E1                ; \
                    LDY $187A               ;  | mario's y position += E1 or D1 depending if on yoshi
                    BEQ NO_YOSHI            ;  |
                    LDA #$D1                ;  |
NO_YOSHI            CLC                     ;  |
                    ADC $D8,x               ;  |
                    STA $96                 ;  |
                    LDA $14D4,x             ;  |
                    ADC #$FF                ;  |
                    STA $97                 ; /
                    LDY #$00                ; \ 
                    LDA $1491               ;  | $1491 == 01 or FF, depending on direction
                    BPL LABEL9              ;  | set mario's new x position
                    DEY                     ;  |
LABEL9              CLC                     ;  |
                    ADC $94                 ;  |
                    STA $94                 ;  |
                    TYA                     ;  |
                    ADC $95                 ;  |
                    STA $95                 ; /
RETURN_24B          RTS                     ;

SPRITE_WINS         LDA $154C,x             ; \ if riding sprite...
                    ORA $15D0,x             ;  |   ...or sprite being eaten...
                    BNE RETURN_24           ; /   ...return
                    LDA $1490               ; \ if mario star timer > 0, goto HAS_STAR 
                    BNE HAS_STAR            ; / NOTE: branch to RETURN_24 to disable star killing                  
                    JSL $00F5B7             ; hurt mario
RETURN_24           RTS                     ; final return

SPIN_KILL           JSR SUB_STOMP_PTS       ; give mario points
                    ;JSL $01AA33             ; set mario speed, NOTE: remove call to not bounce off sprite
                    JSL $01AB99             ; display contact graphic
                    LDA #$04                ; \ status = 4 (being killed by spin jump)
                    STA $14C8,x             ; /   
                    LDA #$1F                ; \ set spin jump animation timer
                    STA $1540,x             ; /
                    JSL $07FC3B             ; show star animation
                    LDA #$08                ; \ play sound effect
                    STA $1DF9               ; /

HAS_STAR            LDA #$02                ; \ status = 2 (being killed by star)
                    STA $14C8,x             ; /



                    LDA #$D0                ; \ set y speed
                    STA $AA,x               ; /
                    JSR SUB_HORZ_POS        ; get new direction
                    LDA KILLED_X_SPEED,y    ; \ set x speed based on direction
                    STA $B6,x               ; /
                    INC $18D2               ; increment number consecutive enemies killed
                    LDA $18D2               ; \
                    CMP #$08                ;  | if consecutive enemies stomped >= 8, reset to 8
                    BCC NO_RESET2           ;  |
                    LDA #$08                ;  |
                    STA $18D2               ; /   
NO_RESET2           JSL $02ACE5             ; give mario points
                    LDY $18D2               ; \ 
                    CPY #$08                ;  | if consecutive enemies stomped < 8 ...
                    BCS NO_SOUND2           ;  |
                    LDA STAR_SOUNDS,y       ;  |    ... play sound effect
                    STA $1DF9               ; /

NO_SOUND2           RTS                     ; final return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; hammer routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

X_OFFSET            dcb $0A,$07
X_OFFSET2           dcb $00,$00
Y_OFFSET = $0C

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

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

                    LDA #$0D
                    STA $9E,y

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

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

                    PHY
                    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
                    JSR SUB_HORZ_POS
                    PLX                     ; / 

                    TYA
                    PLY
                    STA $157C,y
                    
                    LDA #$0C
                    STA $1564,y
                    
                    LDA #TIME_TILL_EXPLODE
                    STA $1540,y
                    
RETURN67            RTS                     ; return


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite graphics routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

TILEMAP             dcb $00,$02,$00,$02,$04,$06,$04,$06,$00,$02,$00,$02,$04,$06,$04,$06
                    dcb $00,$02,$00,$02,$04,$06,$04,$06,$00,$02,$00,$02,$04,$06,$04,$06
HORZ_DISP           dcb $07,$F7,$07,$F7,$07,$F7,$07,$F7,$07,$F7,$07,$F7,$07,$F7,$07,$F7 
		    dcb $F7,$07,$F7,$07,$F7,$07,$F7,$07,$F7,$07,$F7,$07,$F7,$07,$F7,$07
                    

SPRITE_GRAPHICS     JSL $20CA4F       ; sets y = OAM offset                    
                    PHX

                    LDA $157C,x             ; \ $02 = direction
                    STA $02                 ; / 
                    
                    LDA $14C8,x
                    CMP #$02
                    BNE NO_STAR
                    LDA $15F6,x
                    ORA #$80
                    STA $15F6,x                    
                    LDA #$00
                    STA $03
                    BRA CHECK_POS
NO_STAR
                    LDA $14                 ; \ 
                    LSR A                   ;  |
                    LSR A                   ;  |
                    LSR A                   ;  |
                    CLC                     ;  |
                    ADC $15E9               ;  |
                    AND #$07                ;  |
                    ASL A

CHECK_POS           PHY
                    LDY $02
                    BEQ STORE03
                    CLC
                    ADC #$10
STORE03             STA $03                 ; $03 = index to frame start (0 or 1)
                    PLY

                    LDX #$01 
LOOP_START_2        PHX
                    TXA
                    ORA $03
                    TAX
                    
                    LDA $00                 ; tile x position = sprite x location ($00)
                    CLC
                    ADC HORZ_DISP,x
                    STA $0300,y  

                    LDA $01                 ; tile y position = sprite y location ($01)
                    STA $0301,y  

                    LDA TILEMAP,x  
                    STA $0302,y    

                    LDX $15E9 
                    LDA $15F6,x             ; tile properties xyppccct, format
                    LDX $02                 ; \ if direction == 0...
                    BNE NO_FLIP             ;  |
                    ORA #$40                ; /    ...flip tile
NO_FLIP             ORA $64                 ; add in tile priority of level
                    STA $0303,y             ; store tile properties

                    PLX
                    INY                     ; \ increase index to sprite tile map ($300)...
                    INY                     ;  |    ...we wrote 4 bytes...
                    INY                     ;  |    
                    INY                     ; /    ...so increment 4 times
                    DEX                     ;  | go to next tile of frame and loop
                    BPL LOOP_START_2        ; / 

                    PLX
                    LDA $14C8,x
                    CMP #$08
                    BNE NO_SHOW
                    LDA DROP_TIMER,x
                    CMP #$20
                    BCS NO_SHOW
                    CMP #$01
                    BCC NO_SHOW
                    BRA SHOW


NO_SHOW             LDY #$02                ; \ FF, because we wrote to 460
                    LDA #$02                ;  | A = number of tiles drawn - 1
                    JSL $01B7B3             ; / don't draw if offscreen
                    RTS   
SHOW
                    LDA $00                 ; tile x position = sprite x location ($00)
                    PHX
                    LDX $02
                    CLC
                    ADC X_OFFSET,x
                    PLX
                    STA $0300,y  

                    LDA $01                 ; tile y position = sprite y location ($01)
                    CLC
                    ADC #Y_OFFSET
                    STA $0301,y  

                    LDA #$CA
                    STA $0302,y    
                    
                    LDA #BOMB_PAL
                    PHX
                    LDX $02
                    BNE NO_FLIP2
                    ORA #$40
NO_FLIP2            PLX
                    ORA $64                 ; add in tile priority of level
                    STA $0303,y      

                    LDY #$02                ; \ FF, because we wrote to 460
                    LDA #$03                ;  | A = number of tiles drawn - 1
                    JSL $01B7B3             ; / don't draw if offscreen
                    RTS                     ; return                    



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; routines below can be shared by all sprites.  they are ripped from original
; SMW and poorly documented
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; points routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

STAR_SOUNDS         dcb $00,$13,$14,$15,$16,$17,$18,$19

SUB_STOMP_PTS       PHY                     ; 
                    LDA $1697               ; \
                    CLC                     ;  | 
                    ADC $1626,x             ; / some enemies give higher pts/1ups quicker??
                    INC $1697               ; increase consecutive enemies stomped
                    TAY                     ;
                    INY                     ;
                    CPY #$08                ; \ if consecutive enemies stomped >= 8 ...
                    BCS NO_SOUND            ; /    ... don't play sound 
                    LDA STAR_SOUNDS,y       ; \ play sound effect
                    STA $1DF9               ; /   
NO_SOUND            TYA                     ; \
                    CMP #$08                ;  | if consecutive enemies stomped >= 8, reset to 8
                    BCC NO_RESET            ;  |
                    LDA #$08                ; /
NO_RESET            JSL $02ACE5             ; give mario points
                    PLY                     ;
                    RTS                     ; return
                
                    


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B829 - vertical mario/sprite position check - shared
; Y = 1 if mario below sprite??
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                    ;org $03B829 

SUB_VERT_POS        LDY #$00               ;A:25A1 X:0007 Y:0001 D:0000 DB:03 S:01EA P:envMXdizCHC:0130 VC:085 00 FL:924
                    LDA $96                ;A:25A1 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdiZCHC:0146 VC:085 00 FL:924
                    SEC                    ;A:2546 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizCHC:0170 VC:085 00 FL:924
                    SBC $D8,x              ;A:2546 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizCHC:0184 VC:085 00 FL:924
                    STA $0F                ;A:25D6 X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0214 VC:085 00 FL:924
                    LDA $97                ;A:25D6 X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0238 VC:085 00 FL:924
                    SBC $14D4,x            ;A:2501 X:0007 Y:0000 D:0000 DB:03 S:01EA P:envMXdizcHC:0262 VC:085 00 FL:924
                    BPL LABEL11            ;A:25FF X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0294 VC:085 00 FL:924
                    INY                    ;A:25FF X:0007 Y:0000 D:0000 DB:03 S:01EA P:eNvMXdizcHC:0310 VC:085 00 FL:924
LABEL11             RTS                    ;A:25FF X:0007 Y:0001 D:0000 DB:03 S:01EA P:envMXdizcHC:0324 VC:085 00 FL:924


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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; $B85D - off screen processing code - shared
; sprites enter at different points
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                    ;org $03B83B             

TABLE3              dcb $40,$B0
TABLE6              dcb $01,$FF 
TABLE4              dcb $30,$C0,$A0,$80,$A0,$40,$60,$B0 
TABLE5              dcb $01,$FF,$01,$FF,$01,$00,$01,$FF

SUB_OFF_SCREEN_X0   LDA #$06                ; \ entry point of routine determines value of $03
                    BRA STORE_03            ;  | 
SUB_OFF_SCREEN_X1   LDA #$04                ;  |
                    BRA STORE_03            ;  |
SUB_OFF_SCREEN_X2   LDA #$02                ;  |
STORE_03            STA $03                 ;  |
                    BRA START_SUB           ;  |
SUB_OFF_SCREEN_X3   STZ $03                 ; /

START_SUB           JSR SUB_IS_OFF_SCREEN   ; \ if sprite is not off screen, return
                    BEQ RETURN_2            ; /    
                    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_2            ; /
                    LDA $13                 ; \ 
                    AND #$01                ;  | 
                    ORA $03                 ;  | 
                    STA $01                 ;  |
                    TAY                     ; /
                    LDA $1A                 ;x boundry ;A:0101 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0256 VC:090 00 FL:16953
                    CLC                     ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZcHC:0280 VC:090 00 FL:16953
                    ADC TABLE4,y            ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZcHC:0294 VC:090 00 FL:16953
                    ROL $00                 ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0326 VC:090 00 FL:16953
                    CMP $E4,x               ;x pos ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0364 VC:090 00 FL:16953
                    PHP                     ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0394 VC:090 00 FL:16953
                    LDA $1B                 ;x boundry hi ;A:01C0 X:0006 Y:0001 D:0000 DB:03 S:01EC P:eNvMXdizCHC:0416 VC:090 00 FL:16953
                    LSR $00                 ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01EC P:envMXdiZCHC:0440 VC:090 00 FL:16953
                    ADC TABLE5,y            ;A:0100 X:0006 Y:0001 D:0000 DB:03 S:01EC P:envMXdizcHC:0478 VC:090 00 FL:16953
                    PLP                     ;A:01FF X:0006 Y:0001 D:0000 DB:03 S:01EC P:eNvMXdizcHC:0510 VC:090 00 FL:16953
                    SBC $14E0,x             ;x pos high ;A:01FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0538 VC:090 00 FL:16953
                    STA $00                 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0570 VC:090 00 FL:16953
                    LSR $01                 ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0594 VC:090 00 FL:16953
                    BCC LABEL20             ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZCHC:0632 VC:090 00 FL:16953
                    EOR #$80                ;A:01FE X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZCHC:0648 VC:090 00 FL:16953
                    STA $00                 ;A:017E X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0664 VC:090 00 FL:16953
LABEL20             LDA $00                 ;A:017E X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0688 VC:090 00 FL:16953
                    BPL RETURN_2            ;A:017E X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0712 VC:090 00 FL:16953
ERASE_SPRITE        LDA $14C8,x             ; \ if sprite status < 8, permanently erase sprite
                    CMP #$08                ;  |
                    BCC KILL_SPRITE         ; /
                    LDY $161A,x             ;A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZCHC:0140 VC:071 00 FL:21152
                    CPY #$FF                ;A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizCHC:0172 VC:071 00 FL:21152
                    BEQ KILL_SPRITE         ;A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0188 VC:071 00 FL:21152
                    LDA #$00                ; \ mark sprite to come back    A:FF08 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0204 VC:071 00 FL:21152
                    STA $1938,y             ; /                             A:FF00 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdiZcHC:0220 VC:071 00 FL:21152
KILL_SPRITE         STZ $14C8,x             ; erase sprite
RETURN_2            RTS                     ; return

VERTICAL_LEVEL      LDA $167A,x             ; \ if "process offscreen" flag is set, return
                    AND #$04                ;  |
                    BNE RETURN_2            ; /
                    LDA $13                 ; \ only handle every other frame??
                    LSR A                   ;  | 
                    BCS RETURN_2            ; /
                    AND #$01                ;A:0227 X:0006 Y:00EC D:0000 DB:03 S:01ED P:envMXdizcHC:0228 VC:112 00 FL:1142
                    STA $01                 ;A:0201 X:0006 Y:00EC D:0000 DB:03 S:01ED P:envMXdizcHC:0244 VC:112 00 FL:1142
                    TAY                     ;A:0201 X:0006 Y:00EC D:0000 DB:03 S:01ED P:envMXdizcHC:0268 VC:112 00 FL:1142
                    LDA $1C                 ;A:0201 X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0282 VC:112 00 FL:1142
                    CLC                     ;A:02BD X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0306 VC:112 00 FL:1142
                    ADC TABLE3,y            ;A:02BD X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0320 VC:112 00 FL:1142
                    ROL $00                 ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01ED P:enVMXdizCHC:0352 VC:112 00 FL:1142
                    CMP $D8,x               ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01ED P:enVMXdizCHC:0390 VC:112 00 FL:1142
                    PHP                     ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNVMXdizcHC:0420 VC:112 00 FL:1142
                    LDA.W $001D             ;A:026D X:0006 Y:0001 D:0000 DB:03 S:01EC P:eNVMXdizcHC:0442 VC:112 00 FL:1142
                    LSR $00                 ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01EC P:enVMXdiZcHC:0474 VC:112 00 FL:1142
                    ADC TABLE6,y            ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01EC P:enVMXdizCHC:0512 VC:112 00 FL:1142
                    PLP                     ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01EC P:envMXdiZCHC:0544 VC:112 00 FL:1142
                    SBC $14D4,x             ;A:0200 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNVMXdizcHC:0572 VC:112 00 FL:1142
                    STA $00                 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0604 VC:112 00 FL:1142
                    LDY $01                 ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizcHC:0628 VC:112 00 FL:1142
                    BEQ LABEL22             ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0652 VC:112 00 FL:1142
                    EOR #$80                ;A:02FF X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0668 VC:112 00 FL:1142
                    STA $00                 ;A:027F X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0684 VC:112 00 FL:1142
LABEL22             LDA $00                 ;A:027F X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0708 VC:112 00 FL:1142
                    BPL RETURN_2            ;A:027F X:0006 Y:0001 D:0000 DB:03 S:01ED P:envMXdizcHC:0732 VC:112 00 FL:1142
                    BMI ERASE_SPRITE        ;A:0280 X:0006 Y:0001 D:0000 DB:03 S:01ED P:eNvMXdizCHC:0170 VC:064 00 FL:1195

SUB_IS_OFF_SCREEN   LDA $15A0,x             ; \ if sprite is on screen, accumulator = 0 
                    ORA $186C,x             ;  |  
                    RTS                     ; / return
