;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Fire Chomp
;; Coded by SMWEdit
;; based on mikeyk's boo disassembly
;;
;; Uses first extra bit: NO
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

		FLAMESPRNUM = $93		; set this to the sprite you inserted the flame at (YOU MUST CHANGE THIS!)

		FIRESFX = $27			; sound effect for fire throwing
		EXPLODESFX = $09		; sound effect for explosion

		TIMEBETWEENSPITS = $C0		; time before fire chomp spits a flame
		EXPLODEWAIT = $40		; time after all flames thrown to flash before explosion
		EXPLOSIONDURATION = $30		; how long the explosion lasts

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
don't change these:

		SPITTIME = $20

		FREESPACE = $7F8900

		SPRITE_Y_SPEED = $AA
		SPRITE_X_SPEED = $B6
		SPRITE_STATUS = $14C8
		SPRITE_STATE = $C2
		SPRITE_OAM = $15EA
		SPRITE_DIR = $157C

		GFX_INDEX = $1504
		SPIT_COUNT = $1528
		SPIT_TIMER = $163E
		EXPLODEWAITFLAG = $1534
		DEATHINDEX = $1570

		TMP1 = $00
		TMP2 = $01
                    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; sprite init JSL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

		dcb "INIT"
		JSL $01ACF9
		STA $1570,x
		LDA #TIMEBETWEENSPITS	; \ start
		STA SPIT_TIMER,x	; / timer
		LDA $D8,x
		STA YLO_1,x
		STA YLO_2,x
		STA YLO_3,x
		STA YLO_4,x
		STA YLO_5,x
		STA YLO_6,x
		STA YLO_7,x
		STA YLO_8,x
		STA YLO_9,x
		STA YLO_10,x
		STA YLO_11,x
		STA YLO_12,x
		STA YLO_13,x
		STA YLO_14,x
		STA YLO_15,x
		STA YLO_16,x
		STA YLO_17,x
		STA YLO_18,x
		STA YLO_19,x
		STA YLO_20,x
		STA YLO_21,x
		STA YLO_22,x
		STA YLO_23,x
		STA YLO_24,x
		STA YLO_25,x
		STA YLO_26,x
		STA YLO_27,x
		STA YLO_28,x
		STA YLO_29,x
		STA YLO_30,x
		STA YLO_31,x
		STA YLO_32,x
		LDA $E4,x
		STA XLO_1,x
		STA XLO_2,x
		STA XLO_3,x
		STA XLO_4,x
		STA XLO_5,x
		STA XLO_6,x
		STA XLO_7,x
		STA XLO_8,x
		STA XLO_9,x
		STA XLO_10,x
		STA XLO_11,x
		STA XLO_12,x
		STA XLO_13,x
		STA XLO_14,x
		STA XLO_15,x
		STA XLO_16,x
		STA XLO_17,x
		STA XLO_18,x
		STA XLO_19,x
		STA XLO_20,x
		STA XLO_21,x
		STA XLO_22,x
		STA XLO_23,x
		STA XLO_24,x
		STA XLO_25,x
		STA XLO_26,x
		STA XLO_27,x
		STA XLO_28,x
		STA XLO_29,x
		STA XLO_30,x
		STA XLO_31,x
		STA XLO_32,x
		RTL

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

		dcb "MAIN"     
		PHB
		PHK
		PLB
		JSR SPRITE_CODE_START
		PLB
		RTL

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SPITGFXINDEXES	dcb $01,$01,$01,$01,$01,$01,$01,$01
		dcb $02,$02,$02,$02,$02,$02,$02,$02
		dcb $02,$02,$02,$02,$02,$02,$02,$02
		dcb $01,$01,$01,$01,$01,$01,$01,$01

FLASHPALS	dcb $02,$08 		; (palette - 8, * 2)

DEATHX		dcb $10,$30,$10,$F0,$D0,$F0

DEATHX		dcb $08,$10,$18,$18,$10,$08
		dcb $F8,$F0,$E8,$E8,$F8,$F8

T_EBB4		dcb $02,$FE		; rate of speed change
T_F8CF		dcb $10,$F0		; max speed

ISDYING		LDA #$18		; \ speed of
		STA $AA,x		; / moving down
		INC DEATHINDEX,x	; next index for speed
		LDA DEATHINDEX,x	; \
		CMP #$0C		;  | wrap at 12
		BCC GETSPD		;  | and load A
		LDA #$00		;  | with index
		STA DEATHINDEX,x	; /
GETSPD		TAY			; index -> Y
		LDA DEATHX,y		; get X speed
		STA $B6,x		; set X speed
		LDA #$02		; \ set head frame
		STA GFX_INDEX,x		; / for death
		LDA $15F6,x		; \
		AND #%11110001		;  | prevent death with
		ORA #%00001100		;  | the wrong palette
		STA $15F6,x		; /
		JSR LOGPOSITION		; make fireballs follow
RETURN1		RTS
                    
SPRITE_CODE_START
		JSR SUB_GFX
		LDA $9D			; \ return if
		BNE RETURN1		; / sprites locked
		LDA $14C8,x		; get sprite status
		CMP #$03		; \ less than 3
		BCC ISDYING		; / means dying
		CMP #$08		; \ else != 8 means
		BNE RETURN1		; / don't process
		JSR SUB_OFF_SCREEN_X0	; only process sprite while on screen

		LDA SPRITE_STATE,x	; \ if sprite state is
		BEQ NORMALSTATE		; / 0, then go to normal
		JMP SPITSTATE		; else go to "spitting"

NORMALSTATE
		STZ GFX_INDEX,x		; normal state has head frame 0

		JSR SUB_HORZ_POS
		LDA $1540,x
		BNE LBL_03
		LDA #$20
		STA $1540,x
LBL_03
		LDA $0F
		CLC
		ADC #$0A
		CMP #$14
		BCC LBL_04
		LDA $15AC,x
		BNE LBL_12
		TYA
		CMP SPRITE_DIR,x
		BEQ LBL_04
		LDA #$1F
		STA $15AC,x
		BRA LBL_12
LBL_04
		BRA LBL_13

LBL_12
		CMP #$10
		BNE LBL_13
		
		PHA
		LDA SPRITE_DIR,x
		EOR #%00000001
		STA SPRITE_DIR,x
		PLA 
LBL_13
		STZ $1570,x
		LDA $13
		AND #%00000111
		BNE LBL_16
		
		JSR SUB_HORZ_POS
		LDA SPRITE_X_SPEED,x
		CMP T_F8CF,y
		BEQ LBL_15
		CLC
		ADC T_EBB4,y
		STA SPRITE_X_SPEED,x
LBL_15
		LDA $D3
		PHA
		SEC
		SBC $18B6
		STA $D3
		LDA $D4
		PHA
		SBC #$00
		STA $D4
		LDA $D3			; \
		CLC			;  | add 0x20 because
		ADC #$20		;  | the boo's code
		STA $D3			;  | doesn't actually
		LDA $D4			;  | target mario,
		ADC #$00		;  | just above him
		STA $D4			; /
		JSR SUB_VERT_POS
		PLA
		STA $D4
		PLA
		STA $D3
		
		LDA SPRITE_Y_SPEED,x
		CMP T_F8CF,y
		BEQ LBL_16
		CLC
		ADC T_EBB4,y
		STA SPRITE_Y_SPEED,x
LBL_16
		JSL $018022
		JSL $01801A
		JSR LOGPOSITION		; keep logs of where it's been (for fireballs)
LBL_17
		LDA SPRITE_STATUS,x
		CMP #$08
		BNE LBL_19
		JSL $01A7DC
LBL_19
		LDA EXPLODEWAITFLAG,x	; \ if waiting for explosion
		BNE EXPLODEWAITING	; / then branch to that code
		LDA SPIT_TIMER,x	; \ if timer hasn't run out,
		BNE RETURN		; / then skip next code
		LDA SPIT_COUNT,x	; \  if all fireballs already
		CMP #$04		;  | thrown, then branch to code
		BCS BEGINEXPLODE	; /  to begin explosion wait
		INC SPRITE_STATE,x	; sprite state = spitting fireball
		LDA #SPITTIME		; \ set spit timer (this timer is also
		STA SPIT_TIMER,x	; / used as an index, so don't change it)
RETURN		RTS

BEGINEXPLODE
		LDA #$01		; \ set explosion
		STA EXPLODEWAITFLAG,x	; / waiting flag
		LDA #EXPLODEWAIT	; \ set explosion wait
		STA SPIT_TIMER,x	; / time to "spit timer"
		RTS

EXPLODEWAITING	LDA SPIT_TIMER,x	; \ timer ran out"
		BEQ EXPLODE		; / then explode
		LSR A			; \
		LSR A			;  | keep flipping
		AND #%00000001		;  | between palettes
		TAY			;  | when getting
		LDA $15F6,x		;  | ready to explode
		AND #%11110001		;  |
		ORA FLASHPALS,y		;  |
		STA $15F6,x		; /
		RTS

EXPLODE		LDA #$0D		; \ turn sprite
		STA $9E,x		; / into bob-omb
		JSL $07F7D2		; reset sprite tables
		LDA #$08		; \ sprite status:
		STA $14C8,x		; / normal
		LDA #$01		; \ make it
		STA $1534,x		; / explode
		LDA #EXPLOSIONDURATION	; \ set time for
		STA $1540,x		; / explosion
		LDA #EXPLODESFX		; \ play sound
		STA $1DFC		; / effect
		RTS

; ...

DONESPITTING1	JMP DONESPITTING
ENDSPIT1	RTS

SPITSTATE
		INC $1540,x		; "fight" timer used in normal code
		JSL $01A7DC		; interact w/ mario
		LDY SPIT_TIMER,x	; \
		LDA SPITGFXINDEXES,y	;  | set head frame
		STA GFX_INDEX,x		; /
		LDA SPIT_TIMER,x	; \ timer expired?
		BEQ DONESPITTING1	; / then done spitting
		CMP #$10		; \ not $10? then skip
		BNE ENDSPIT1		; / fireball generation
		INC SPIT_COUNT,x	; another fireball thrown
		LDA #FIRESFX		; \ play
		STA $1DFC		; / SFX
		JSL $02A9DE		; \ get slot or else
		BMI ENDSPIT		; / end if no slots
		LDA #$01		; \ set sprite status
		STA $14C8,y		; / as a new sprite
		PHX			; back up X
		TYX			; new sprite index to X
		LDA #FLAMESPRNUM	; \ store custom
		STA $7FAB9E,x		; / sprite number
		JSL $07F7D2		; reset sprite properties
		JSL $0187A7		; get table values for custom sprite
		LDA #%00001000		; \ mark as a
		STA $7FAB10,x		; / custom sprite
		PLX			; load backed up X
		LDA $E4,x		; \
		STA $E4,y		;  | set center
		LDA $14E0,x		;  | position for
		STA $14E0,y		;  | needlenose
		LDA $D8,x		;  | so that in next
		STA $D8,y		;  | code, it can
		LDA $14D4,x		;  | be shifted
		STA $14D4,y		; /
		LDA $96			; \
		PHA			;  | offset Y
		CLC			;  | position by
		ADC #$10		;  | #$10 and
		STA $96			;  | back it up
		LDA $97			;  | in the
		PHA			;  | process
		ADC #$00		;  |
		STA $97			; /
		PHY			; back up Y
		JSR CALCFRAME		; call "pseudo-arctangent" routine to get angle
		TAY			; -> Y
		LDA FIRE_X,y		; \ set X speed
		STA TMP1		; / to scratch RAM
		LDA FIRE_Y,y		; \ set Y speed
		STA TMP2		; / to scratch RAM
		JSR SUB_HORZ_POS	; \
		CPY #$00		;  | flip
		BEQ CHKY		;  | X if
		LDA TMP1		;  | necessary
		EOR #$FF		;  |
		INC A			;  |
		STA TMP1		; /
CHKY		JSR SUB_VERT_POS	; \
		CPY #$00		;  | flip
		BEQ ENDSIGNCHG		;  | Y if
		LDA TMP2		;  | necessary
		EOR #$FF		;  |
		INC A			;  |
		STA TMP2		; /
ENDSIGNCHG	PLY			; load backed up Y
		LDA TMP1		; \ set
		STA $B6,y		; / X
		LDA TMP2		; \ set
		STA $AA,y		; / Y
		PLA			; \
		STA $97			;  | load backed up
		PLA			;  | Y position
		STA $96			; /
ENDSPIT		RTS

DONESPITTING	STZ SPRITE_STATE,x	; back to chasing
		LDA #TIMEBETWEENSPITS	; \ reset
		STA SPIT_TIMER,x	; / timer
		RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

FIRE_X		dcb $10,$10,$10,$0F
		dcb $0F,$0E,$0D,$0C
		dcb $0B,$09,$08,$07
		dcb $05,$03,$02,$00

FIRE_Y		dcb $00,$02,$03,$05
		dcb $07,$08,$09,$0B
		dcb $0C,$0D,$0E,$0F
		dcb $0F,$10,$10,$10

		FC_TEMP1 = $00		; will use 2 bytes
		FC_TEMP2 = $02		; will use 2 bytes
		FC_TEMP3 = $04		; will use 2 bytes
		FC_TEMP4 = $06		; will use 2 bytes

CALCFRAME	LDA $D8,x
		SEC
		SBC $96
		STA FC_TEMP2
		LDA $14D4,x
		SBC $97
		STA FC_TEMP2+1
		BNE HORZDIST
		LDA FC_TEMP2
		BNE HORZDIST
		BRA SETHORZ
HORZDIST	LDA $E4,x
		SEC
		SBC $94
		STA FC_TEMP1
		LDA $14E0,x
		SBC $95
		STA FC_TEMP1+1
		BNE BEGINMATH
		LDA FC_TEMP1
		BNE BEGINMATH
		BRA SETVERT
BEGINMATH	PHP
		REP #%00100000
		LDA FC_TEMP1
		BPL CHKYDIST
		EOR #$FFFF
		INC A
		STA FC_TEMP1
CHKYDIST	LDA FC_TEMP2
		BPL MULT
		EOR #$FFFF
		INC A
		STA FC_TEMP2
MULT		ASL A
		ASL A
		ASL A
		ASL A
		STA FC_TEMP3
		LDA FC_TEMP1
		CLC
		ADC FC_TEMP2
		STA FC_TEMP4
		LDY #$00
		LDA FC_TEMP4
		DEC A
DIVLOOP		CMP FC_TEMP3
		BCS END_DIVIDE
		INY
		CLC
		ADC FC_TEMP4
		BRA DIVLOOP
END_DIVIDE	TYA
		PLP
		RTS
SETHORZ		LDA #$00
		RTS
SETVERT		LDA #$0F
		RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GRAPHICS ROUTINE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

		XFLIP = $02
		YFLIP = $03
		TILESDRAWN = $04
		GFXTMP1 = $05
		GFXTMP2 = $06

HEADTILES	dcb $46,$48,$4A

FBTILES		dcb $24,$26,$24,$26
FBPROPS		dcb $00,$00,$C0,$C0

SUB_GFX		JSL $20CA4F
		STZ TILESDRAWN		; zero tiles drawn so far
		LDA $157C,x		; \ set X
		STA XFLIP		; / flip
		STZ YFLIP		; \
		LDA $14C8,x		;  | Y flip
		CMP #$03		;  | depends
		BCS HEADGFX		;  | on death
		INC YFLIP		; /
HEADGFX		LDA $00			; \ set
		STA $0300,y		; / X
		LDA $01			; \ set
		STA $0301,y		; / Y
		PHY			; \
		LDY GFX_INDEX,x		;  | get tile
		LDA HEADTILES,y		;  | number
		PLY			; /
		STA $0302,y		; set tile number
		LDA $15F6,x		; get palette and GFX page
		PHX			; \
		LDX XFLIP		;  | flip
		BNE NO_FLIP_1		;  | X if
		ORA #%01000000		;  | necessary
NO_FLIP_1	;PLX			; /
		;PHX			; \
		LDX YFLIP		;  | flip
		BEQ NO_FLIP_2		;  | Y if
		ORA #%10000000		;  | necessary
NO_FLIP_2	PLX			; /
		ORA $64			; add in priority bits
		STA $0303,y		; set properties
		INY			; \
		INY			;  | next OAM
		INY			;  | index
		INY			; /
		INC TILESDRAWN		; a tile was drawn
		LDA SPIT_COUNT,x	; \  if # fireballs thrown
		CMP #$04		;  | is less than four, then
		BCC BEGINFIRE		; /  begin drawing fireballs
		JMP FINISHGFX		; else finish GFX
BEGINFIRE	LDA $15E9		; \
		ASL A			;  | set fireball
		ASL A			;  | master frame
		CLC			;  | index to
		ADC $14			;  | scratch RAM
		STA GFXTMP1		; /
FIREBALL1	;LDA GFXTMP1		; \
		LSR A			;  | get first
		LSR A			;  | fireball
		AND #%00000011		;  | index
		STA GFXTMP2		; /
		LDA $00			; \
		CLC			;  | set X
		ADC XLO_8,x		;  | position
		SEC			;  |
		SBC $E4,x		;  |
		STA $0300,y		; /
		LDA $01			; \
		CLC			;  | set Y
		ADC YLO_8,x		;  | position
		SEC			;  |
		SBC $D8,x		;  |
		STA $0301,y		; /
		PHY			; \
		LDY GFXTMP2		;  | get fireball
		LDA FBTILES,y		;  | tile number
		PLY			; /
		STA $0302,y		; set tile number
		LDA $15F6,x		; get palette and GFX page
		PHY			; \
		LDY GFXTMP2		;  | add in tile
		ORA FBPROPS,y		;  | properties
		PLY			; /
		ORA $64			; add in priority bits
		STA $0303,y		; set properties
		INY			; \
		INY			;  | next OAM
		INY			;  | index
		INY			; /
		INC TILESDRAWN		; a tile was drawn
		LDA SPIT_COUNT,x	; \  if # fireballs thrown
		CMP #$03		;  | is less than three, then
		BCC FIREBALL2		; /  draw another fireball
		JMP FINISHGFX		; else finish GFX
FIREBALL2	LDA GFXTMP1		; \
		CLC			;  | get second
		ADC #$08		;  | fireball
		LSR A			;  | index
		LSR A			;  |
		AND #%00000011		;  |
		STA GFXTMP2		; /
		LDA $00			; \
		CLC			;  | set X
		ADC XLO_16,x		;  | position
		SEC			;  |
		SBC $E4,x		;  |
		STA $0300,y		; /
		LDA $01			; \
		CLC			;  | set Y  
		ADC YLO_16,x		;  | position
		SEC			;  |
		SBC $D8,x		;  |
		STA $0301,y		; /
		PHY			; \
		LDY GFXTMP2		;  | get fireball
		LDA FBTILES,y		;  | tile number
		PLY			; /
		STA $0302,y		; set tile number
		LDA $15F6,x		; get palette and GFX page
		PHY			; \
		LDY GFXTMP2		;  | add in tile
		ORA FBPROPS,y		;  | properties
		PLY			; /
		ORA $64			; add in priority bits
		STA $0303,y		; set properties
		INY			; \
		INY			;  | next OAM
		INY			;  | index
		INY			; /
		INC TILESDRAWN		; a tile was drawn
		LDA SPIT_COUNT,x	; \  if # fireballs thrown
		CMP #$02		;  | is less than two, then
		BCC FIREBALL3		; /  draw another fireball
		JMP FINISHGFX		; else finish GFX
FIREBALL3	LDA GFXTMP1		; \
		CLC			;  | get third
		ADC #$10		;  | fireball
		LSR A			;  | index
		LSR A			;  |
		AND #%00000011		;  |
		STA GFXTMP2		; /
		LDA $00			; \
		CLC			;  | set X
		ADC XLO_24,x		;  | position
		SEC			;  |
		SBC $E4,x		;  |
		STA $0300,y		; /
		LDA $01			; \
		CLC			;  | set Y
		ADC YLO_24,x		;  | position
		SEC			;  |
		SBC $D8,x		;  |
		STA $0301,y		; /
		PHY			; \
		LDY GFXTMP2		;  | get fireball
		LDA FBTILES,y		;  | tile number
		PLY			; /
		STA $0302,y		; set tile number
		LDA $15F6,x		; get palette and GFX page
		PHY			; \
		LDY GFXTMP2		;  | add in tile
		ORA FBPROPS,y		;  | properties
		PLY			; /
		ORA $64			; add in priority bits
		STA $0303,y		; set properties
		INY			; \
		INY			;  | next OAM
		INY			;  | index
		INY			; /
		INC TILESDRAWN		; a tile was drawn
		LDA SPIT_COUNT,x	; \  if # fireballs
		CMP #$01		;  | thrown >= 1,
		BCS FINISHGFX		; /  then end GFX
FIREBALL4	LDA GFXTMP1		; \
		CLC			;  | get fourth
		ADC #$18		;  | fireball
		LSR A			;  | index
		LSR A			;  |
		AND #%00000011		;  |
		STA GFXTMP2		; /
		LDA $00			; \
		CLC			;  | set X
		ADC XLO_32,x		;  | position
		SEC			;  |
		SBC $E4,x		;  |
		STA $0300,y		; /
		LDA $01			; \
		CLC			;  | set Y
		ADC YLO_32,x		;  | position
		SEC			;  |
		SBC $D8,x		;  |
		STA $0301,y		; /
		PHY			; \
		LDY GFXTMP2		;  | get fireball
		LDA FBTILES,y		;  | tile number
		PLY			; /
		STA $0302,y		; set tile number
		LDA $15F6,x		; get palette and GFX page
		PHY			; \
		LDY GFXTMP2		;  | add in tile
		ORA FBPROPS,y		;  | properties
		PLY			; /
		ORA $64			; add in priority bits
		STA $0303,y		; set properties
		INY			; \
		INY			;  | next OAM
		INY			;  | index
		INY			; /
		INC TILESDRAWN		; a tile was drawn
FINISHGFX	LDY #$02		; tiles are 16x16
		LDA TILESDRAWN		; \ A must be # of
		DEC A			; / tiles drawn - 1
		JSL $01B7B3		; don't draw if offscreen, set sizes
		RTS



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





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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; SUB_VERT_POS
; This routine determines if Mario is above or below the sprite.  It sets the Y register
; to the direction such that the sprite would face Mario
; It is ripped from $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 SPR_L11            ;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
SPR_L11				RTS                    ;A:25FF X:0007 Y:0001 D:0000 DB:03 S:01EA P:envMXdizcHC:0324 VC:085 00 FL:924

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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

LOGPOSITION
		LDA YLO_31,x
		STA YLO_32,x
		LDA YLO_30,x
		STA YLO_31,x
		LDA YLO_29,x
		STA YLO_30,x
		LDA YLO_28,x
		STA YLO_29,x
		LDA YLO_27,x
		STA YLO_28,x
		LDA YLO_26,x
		STA YLO_27,x
		LDA YLO_25,x
		STA YLO_26,x
		LDA YLO_24,x
		STA YLO_25,x
		LDA YLO_23,x
		STA YLO_24,x
		LDA YLO_22,x
		STA YLO_23,x
		LDA YLO_21,x
		STA YLO_22,x
		LDA YLO_20,x
		STA YLO_21,x
		LDA YLO_19,x
		STA YLO_20,x
		LDA YLO_18,x
		STA YLO_19,x
		LDA YLO_17,x
		STA YLO_18,x
		LDA YLO_16,x
		STA YLO_17,x
		LDA YLO_15,x
		STA YLO_16,x
		LDA YLO_14,x
		STA YLO_15,x
		LDA YLO_13,x
		STA YLO_14,x
		LDA YLO_12,x
		STA YLO_13,x
		LDA YLO_11,x
		STA YLO_12,x
		LDA YLO_10,x
		STA YLO_11,x
		LDA YLO_9,x
		STA YLO_10,x
		LDA YLO_8,x
		STA YLO_9,x
		LDA YLO_7,x
		STA YLO_8,x
		LDA YLO_6,x
		STA YLO_7,x
		LDA YLO_5,x
		STA YLO_6,x
		LDA YLO_4,x
		STA YLO_5,x
		LDA YLO_3,x
		STA YLO_4,x
		LDA YLO_2,x
		STA YLO_3,x
		LDA YLO_1,x
		STA YLO_2,x
		LDA $D8,x
		STA YLO_1,x
		LDA XLO_31,x
		STA XLO_32,x
		LDA XLO_30,x
		STA XLO_31,x
		LDA XLO_29,x
		STA XLO_30,x
		LDA XLO_28,x
		STA XLO_29,x
		LDA XLO_27,x
		STA XLO_28,x
		LDA XLO_26,x
		STA XLO_27,x
		LDA XLO_25,x
		STA XLO_26,x
		LDA XLO_24,x
		STA XLO_25,x
		LDA XLO_23,x
		STA XLO_24,x
		LDA XLO_22,x
		STA XLO_23,x
		LDA XLO_21,x
		STA XLO_22,x
		LDA XLO_20,x
		STA XLO_21,x
		LDA XLO_19,x
		STA XLO_20,x
		LDA XLO_18,x
		STA XLO_19,x
		LDA XLO_17,x
		STA XLO_18,x
		LDA XLO_16,x
		STA XLO_17,x
		LDA XLO_15,x
		STA XLO_16,x
		LDA XLO_14,x
		STA XLO_15,x
		LDA XLO_13,x
		STA XLO_14,x
		LDA XLO_12,x
		STA XLO_13,x
		LDA XLO_11,x
		STA XLO_12,x
		LDA XLO_10,x
		STA XLO_11,x
		LDA XLO_9,x
		STA XLO_10,x
		LDA XLO_8,x
		STA XLO_9,x
		LDA XLO_7,x
		STA XLO_8,x
		LDA XLO_6,x
		STA XLO_7,x
		LDA XLO_5,x
		STA XLO_6,x
		LDA XLO_4,x
		STA XLO_5,x
		LDA XLO_3,x
		STA XLO_4,x
		LDA XLO_2,x
		STA XLO_3,x
		LDA XLO_1,x
		STA XLO_2,x
		LDA $E4,x
		STA XLO_1,x

		RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

		YLO_1 = FREESPACE+0
		YLO_2 = FREESPACE+12
		YLO_3 = FREESPACE+24
		YLO_4 = FREESPACE+36
		YLO_5 = FREESPACE+48
		YLO_6 = FREESPACE+60
		YLO_7 = FREESPACE+72
		YLO_8 = FREESPACE+84
		YLO_9 = FREESPACE+96
		YLO_10 = FREESPACE+108
		YLO_11 = FREESPACE+120
		YLO_12 = FREESPACE+132
		YLO_13 = FREESPACE+144
		YLO_14 = FREESPACE+156
		YLO_15 = FREESPACE+168
		YLO_16 = FREESPACE+180
		YLO_17 = FREESPACE+192
		YLO_18 = FREESPACE+204
		YLO_19 = FREESPACE+216
		YLO_20 = FREESPACE+228
		YLO_21 = FREESPACE+240
		YLO_22 = FREESPACE+252
		YLO_23 = FREESPACE+264
		YLO_24 = FREESPACE+276
		YLO_25 = FREESPACE+288
		YLO_26 = FREESPACE+300
		YLO_27 = FREESPACE+312
		YLO_28 = FREESPACE+324
		YLO_29 = FREESPACE+336
		YLO_30 = FREESPACE+348
		YLO_31 = FREESPACE+360
		YLO_32 = FREESPACE+372

		XLO_1 = FREESPACE+384
		XLO_2 = FREESPACE+396
		XLO_3 = FREESPACE+408
		XLO_4 = FREESPACE+420
		XLO_5 = FREESPACE+432
		XLO_6 = FREESPACE+444
		XLO_7 = FREESPACE+456
		XLO_8 = FREESPACE+468
		XLO_9 = FREESPACE+480
		XLO_10 = FREESPACE+492
		XLO_11 = FREESPACE+504
		XLO_12 = FREESPACE+516
		XLO_13 = FREESPACE+528
		XLO_14 = FREESPACE+540
		XLO_15 = FREESPACE+552
		XLO_16 = FREESPACE+564
		XLO_17 = FREESPACE+576
		XLO_18 = FREESPACE+588
		XLO_19 = FREESPACE+600
		XLO_20 = FREESPACE+612
		XLO_21 = FREESPACE+624
		XLO_22 = FREESPACE+636
		XLO_23 = FREESPACE+648
		XLO_24 = FREESPACE+660
		XLO_25 = FREESPACE+672
		XLO_26 = FREESPACE+684
		XLO_27 = FREESPACE+696
		XLO_28 = FREESPACE+708
		XLO_29 = FREESPACE+720
		XLO_30 = FREESPACE+732
		XLO_31 = FREESPACE+744
		XLO_32 = FREESPACE+756