
                    BLUE_TIMER = $6F              ; blue p-switch timer 
                    

                    QUAKE_TIMER = $20             ; shake ground timer
                    QUAKE_TIMER2 = $20            ; shake ground timer

                    SOUND_TO_GEN = $0B
                    SOUND_TO_GEN2 = $09
		    SOUND_TO_GEN3 = $02
		    SOUND_TO_GEN4 = $10

		      
                    EXTRA_BITS = $7FAB10
                    EXTRA_PROP_1 = $7FAB28
                    NEW_SPRITE_NUM = $7FAB9E

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

                    dcb "INIT"
	            LDA $167A,x             ; \ don't hurt Mario when it touches the sprite 
	            STA $1528,x             ; / 
                    RTL                 

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

                    dcb "MAIN"                                    
                    PHB                     ; \
                    PHK                     ;  | main sprite function, just calls local subroutine
                    PLB                     ;  |
	            CMP #$09                ;  |
	            BCS HANDLE_STUNNED      ;  |
                    JSR SPRITE_CODE_START   ;  |
                    PLB                     ;  |
                    RTL                     ; /

HANDLE_STUNNED      LDA $167A,x		    ; \ set to interact with Mario
	            AND #$7F                ;  |
	            STA $167A,x             ; /
	            
	            PHX                     ; \ set carried sprite graphics
                    JSR CARRIED_GFX         ;  |
	            PLX                     ; /
	            PLB
                    RTL

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite main code 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
         
         
JUSTSPATOUT	    LDA #$08		    ; \ set normal
		    STA $14C8,x		    ; / sprite mode
		    LDA #$08	            ; \ set timer for
		    STA $1540,x	            ; / "solidification"
                    RTS                     ; return

SPRITE_CODE_START   JSR SUB_GFX             ; graphics routine
                    LDA $14C8,x             ; \ if it's a shell
		    CMP #$09		    ;  | that means yoshi
		    BCS JUSTSPATOUT	    ; /  just spat it out
		    CMP #$0B		    ; \ if it's carried
		    BCS JUSTSPATOUT	    ; /  just spat it out
                    LDA $9D                 ; \ if sprites locked, return
                    BNE RETURN              ; /

                    LDA $1558,x             ; \ if sprite not defeated (timer to show remains > 0)...
                    BEQ ALIVE               ; / ... go to ALIVE
                    STA $15D0,x             ; \ 
                    DEC A                   ;  } if sprite remains don't disappear next frame...
                    BNE RETURN              ; / ... return
                    



RETURN              RTS                     ; return

ALIVE               JSR SUB_OFF_SCREEN_X3   ; handle off screen situation
                    
                    LDA $1588,x             ; \ if sprite is in contact with an object...
                    AND #$03                ;  |
                    BEQ CEILING_CONTACT     ;  |
                    LDA $157C,x             ;  | flip the direction status
                    EOR #$01                ;  |
                    STA $157C,x             ; /
                    LDA $B6,x               ; \ flip speed
                    EOR #$FF                ;  |
                    STA $B6,x               ; /

CEILING_CONTACT     LDA $1588,x             ; \ if sprite is in contact with the ceiling...
                    AND #$08                ;  |
                    BEQ GROUND              ; /
                    STZ $AA,x               ; no y speed
                    BRA SET_GROUND_SPEED

GROUND              LDA $1588,x             ; \ if sprite is in contact with the ground...
                    AND #$04                ;  |
                    BEQ IN_AIR              ; /

SET_GROUND_SPEED    JSR GROUND_SPEED        ; ground speed routine

IN_AIR              JSL $01802A             ; update position based on speed values

	            LDA $1528,x             ; \ don't hurt Mario when it touches the sprite
	            STA $167A,x             ; /

                    JSL $01A7DC             ; check for Mario/sprite contact
                    BCC RETURN              ; return if no contact
                    JSR SUB_VERT_POS        ; vertical Mario/sprite check routine
                    LDA $0E                 ; \ if Mario isn't above sprite, and there's vertical contact...
                    CMP #$E6                ;  | ... sprite wins
                    BPL SET_CARRIED         ; /
                    LDA $7D                 ; \  if Mario's y speed < 10 ...
                    CMP #$10                ;  } ... sprite will move Mario
                    BMI SET_CARRIED         ; /                       
                   
MARIO_WINS          JSL $01AA33             ; set Mario speed
                    JSL $01AB99             ; display contact graphic

                    LDA #$FF                ; \ ... time to show defeated sprite = $20
                    STA $1558,x             ; / 
		    LDA #SOUND_TO_GEN       ; \ set sound effect
		    STA $1DF9               ; /
HurtIT:
LDA $14AD
BNE Return22

                    LDA $15F6,x             ; \ if the sprite palette is...
                    CMP #$02                ;  | ...gray
                    BEQ SET_MUSIC           ; /
                    CMP #$04                ; \ ...yellow
                    BEQ TURN_INTO_A_COIN    ; /
                    CMP #$06                ; \ ...blue
                    BEQ SET_MUSIC           ; /
                    CMP #$08                ; \ ...red
                    BEQ QUAKE               ; /
                    BRA RETURN2

Return22:          ; / 
RTS

SET_MUSIC	    NOP
SET_TIMER	    LDA #$20                ; \ set timer
		    STA $163E,x             ; /
		    LDA #QUAKE_TIMER        ; \ shake ground timer
		    STA $1887               ; /

                    LDA $15F6,x
                    CMP #$06                ; \ ...blue
                    BEQ SET_BLUE_TIMER      ; /
                    BRA RETURN2

SET_CARRIED         BIT $15		    ; \ don't pick up sprite if not pressing button
                    BVC NO_MARIO_X_SPEED    ; /
                    LDA $1470               ; \ if carrying an enemy...
                    ORA $187A               ; / ...or on Yoshi
                    BNE NO_MARIO_X_SPEED    ; don't carry
                    LDA EXTRA_PROP_1,x      ; \ don't carry if the extra property 1 is set...
	            AND #$01                ;  |
	            BNE NO_MARIO_X_SPEED    ; / 

NO_MARIO_X_SPEED    STZ $7B                 ; no Mario x speed
		    JSR SUB_HORZ_POS        ; horizontal Mario/sprite check routine
		    TYA                     ;
		    ASL A                   ;
		    TAY                     ;
		    REP #$20                ; Accum (16 bit)
		    LDA $94                 ; \ set Mario's x position
		    CLC                     ;  |
		    ADC OFFSET,y            ;  |
		    STA $94                 ; /
		    SEP #$20                ; Accum (8 bit) 
	            RTS                     ; return


SET_BLUE_TIMER	    LDA #BLUE_TIMER         ; \ set blue P-switch timer
		    STA $14AD               ; /
                    BRA RETURN2

TURN_INTO_A_COIN    JSL $00FA80             ; change on screen sprites into a coin routine
                    BRA RETURN2

QUAKE               LDA #QUAKE_TIMER2       ; \ shake ground
                    STA $1887               ; /
                    LDA #SOUND_TO_GEN2      ; \ play sound effect
                    STA $1DFC               ; /
                    JSL $0294C1             ; earthquake routine
RETURN2             RTS                     ; return

OFFSET		    dcb $01,$00,$FF,$FF
		        


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ground speed routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


Y_SPEED_TABLE       dcb $00,$00,$00,$F8,$F8,$F8,$F8,$F8
                    dcb $F8,$F7,$F6,$F5,$F4,$F3,$F2,$E8
                    dcb $E8,$E8,$E8,$00


GROUND_SPEED        LDA $B6,x               ;
                    PHP                     ; push processor
                    BPL SKIP_FLIP           ;
                    EOR #$FF		    ; \ set A to -A
                    INC A                   ; /  
SKIP_FLIP           LSR                     ;
                    PLP                     ; pull processor
                    BPL STORE_X_SPEED       ;
                    EOR #$FF		    ; \ set A to -A
                    INC A                   ; /  
STORE_X_SPEED       STA $B6,x               ;
                    LDA $AA,x               ;
                    PHA                     ;
                    JSR SET_SOME_Y_SPEED    ; set y speed
                    PLA                     ;
                    LSR                     ;
                    LSR                     ;
                    TAY                     ;
                    LDA Y_SPEED_TABLE,y     ; y speed table
                    LDY $1588,x             ; \ if touching an object...
                    BMI SET_RETURN          ; /
                    STA $AA,x               ; store y speed
SET_RETURN          RTS                     ; return

SET_SOME_Y_SPEED    LDA $1588,x             ; \ if touching an object...
                    BMI SET_THE_Y_SPEED     ; /
                    LDA #$00                ; \ sprite Y speed = #$00 or #$18
                    LDY $15B8,x             ;  | depending on 15B8,x ???
                    BEQ STORE_Y_SPEED	    ;  | 
SET_THE_Y_SPEED     LDA #$18                ;  | 
STORE_Y_SPEED       STA $AA,x		    ; / 
                    RTS			    ; return 
	
	

                    

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

                    ;frame 1, squashed (2 bytes each)
TILE_SIZE           dcb $02,$02,$00,$00
HORZ_DISP           dcb $00,$00,$00,$08
VERT_DISP           dcb $00,$00,$08,$08
TILEMAP             dcb $42,$42,$FE,$FE
PROPERTIES          dcb $40,$00,$00,$40


SUB_GFX             JSL $20CA4F       ; after: Y = index to sprite OAM ($300)      
                    LDA $151C,x             ; \
                    ASL A                   ;  | $03 = index to frame start (frame to show * 2 tile per frame)
                    STA $03                 ; /
                    LDA $157C,x             ; \ $02 = sprite direction
                    STA $02                 ; /
                    PHX                     ; push x

                    LDA $14C8,x             ; \ if the sprite is defeated...
                    CMP #$02                ;  |
                    BNE NO_STAR             ; /
                    LDA #$02                ; \ set squashed image
                    STA $03                 ; /

NO_STAR             LDA $1558,x             ; \ if time to show sprite remains > 0...
                    BEQ NOT_DEAD            ; /

Dead:
	LDA #$02                ; \ set squashed image
                    STA $03                 ; /
                    STX $15E9

LDA $1427
BNE SkipDIS

NOT_DEAD:
LDA $1427
BNE Dead

SkipDIS:
LDX #$01                ; run loop 2 times, cuz 2 tiles per frame
LOOP_START          PHX                     ; push, current tile

                    TXA                     ; \ X = index of frame start + current tile
                    CLC                     ;  |
                    ADC $03                 ;  |
                    TAX                     ; /

                    PHY                     ; set tile to be 8x8 or 16x16
                    TYA                     ;
                    LSR A                   ;
                    LSR A                   ;
                    TAY                     ;
                    LDA TILE_SIZE,x         ; 
                    STA $0460,y             ;
                    PLY                     ;
                    
                    LDA $00                 ; \ tile x position = sprite x location ($00) + tile displacement
                    CLC                     ;  | 
                    ADC HORZ_DISP,x         ;  |
                    STA $0300,y             ; /
                    
                    LDA $01                 ; \ tile y position = sprite y location ($01) + tile displacement
                    CLC                     ;  | 
                    ADC VERT_DISP,x         ;  |
                    STA $0301,y             ; /

                    LDA TILEMAP,x           ; \ store tile
                    STA $0302,y             ; /

                    PHX                     ;
                    LDX $15E9               ;
                    LDA $15F6,x             ; get palette info
                    PLX                     ;
                    ORA PROPERTIES,x        ; flip tile if necessary
                    ORA $64                 ; add in tile priority of level
                    STA $0303,y             ; store tile properties

                    PLX                     ; \ pull, current tile
                    INY                     ;  | increase index to sprite tile map ($300)...
                    INY                     ;  |    ...we wrote 1 16x16 tile...
                    INY                     ;  |    ...sprite OAM is 8x8...
                    INY                     ;  |    ...so increment 4 times
                    DEX                     ;  | go to next tile of frame and loop
                    BPL LOOP_START          ; /

                    PLX                     ; pull, X = sprite index
                    LDY #$FF                ; \ we've already set 460 so use FF
                    LDA #$01                ;  | A = number of tiles drawn - 1
                    JSL $01B7B3             ; / don't draw if offscreen
                    RTS                     ; return


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


HORZ_DISP           dcb $00,$08,$00,$08
VERT_DISP           dcb $00,$00,$08,$08
TILEMAP             dcb $42,$43,$52,$53


CARRIED_GFX         JSL $20CA4F       ; after: Y = index to sprite OAM ($300)
                    LDA $151C,x             ; \
                    ASL A                   ;  | $03 = index to frame start (frame to show * 2 tile per frame)
                    STA $03                 ; /
                    LDA $157C,x             ; \ $02 = direction
                    STA $02                 ; / 
                    PHX                     ; push x

                    LDX #$03                ; run loop 4 times, cuz 4 tiles per frame
LOOP_START_2        PHX                     ; push, current tile

                    TXA                     ; \ X = index of frame start + current tile
                    CLC                     ;  |
                    ADC $03                 ;  |
                    TAX                     ; /

                    LDA $00                 ; \ tile x position = sprite x location ($00) + tile displacement
                    CLC                     ;  |
                    ADC HORZ_DISP,x         ;  |
                    STA $0300,y             ; /
                    
                    LDA $01                 ; \
                    CLC                     ;  | tile y position = sprite y location ($01) + tile displacement
                    ADC VERT_DISP,x         ;  |
                    STA $0301,y             ; /

                    LDA TILEMAP,x           ; \ store tile
                    STA $0302,y             ; /

                    PHX                     ;
                    LDX $15E9               ;
                    LDA $15F6,x             ; get palette info
                    PLX                     ;
                    ORA $64                 ; add in tile priority of level
                    STA $0303,y             ; store tile properties

                    PLX                     ; \ pull, current tile
                    INY                     ;  | increase index to sprite tile map ($300)...
                    INY                     ;  |    ...we wrote 1 16x16 tile...
                    INY                     ;  |    ...sprite OAM is 8x8...
                    INY                     ;  |    ...so increment 4 times
                    DEX                     ;  | go to next tile of frame and loop
                    BPL LOOP_START_2        ; /

                    PLX                     ; pull, X = sprite index
                    LDY #$00                ; \ we've already set 460 so use FF
                    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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;




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