incsrc definition.asm

print "MAIN ", pc
	PHB
	PHK
	PLB
	JSR SpriteMain
	LDX $15E9
	PLB
	RTL
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Various defines
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

!SpriteProps	= $38
!SpriteTile	= $3D
!CursorSFX	= $22
!CursorPort	= $1DF9
!HoldingDelay	= 20			; how many frames you have to hold down L/R to go fast
!SongLimit	= 86
!MaxPitch	= 15
!MinPitch	= -15
!MaxTempo	= 60
!MinTempo	= -20

!MuteSong	= $09
!DeathRAM	= $140A			; same RAM as deathfix
!LastSFX1	= $2B
!LastSFX2	= !LastSFX1+$35

!FreeRAM 	= $7FA000		; 0x400 bytes needed in total
!TitleField	= $A024			; !FreeRAM&$FFFF+$24
!AuthorField 	= $A067			; !FreeRAM&$FFFF+$67

!CursorIndex	= !FreeRAM		; see cursor index reference
!SongNumber	= !FreeRAM+$01		; in hex
!SFXNumber	= !FreeRAM+$02		; in hex
!GlobalPitch	= !FreeRAM+$03		; positive = sharp; negative = flat
!VolumeLeft	= !FreeRAM+$04		; each increase is 1/16 of the max
!VolumeRight	= !FreeRAM+$05		; ditto
!GlobalTempo	= !FreeRAM+$06		; signed
!ChannelStatus	= !FreeRAM+$07		; 76543210, one bit per channel

!MiscFlags	= !FreeRAM+$08		; lr--b-tc
!SurroundLBit	= %10000000		; l = unused (was surround left)
!SurroundRBit	= %01000000		; r = unused (was surround right)
!UnusedBit5	= %00100000		;
!UnusedBit4	= %00010000		;
!BarsBit	= %00001000		; b = disable bars
!UnusedBit2	= %00000100		;
!NoTimerBit	= %00000010		; t = disable timer
!ClearTimerBit	= %00000001		; c = clear timer

!Clock		= !FreeRAM+$09		; set to $3C and decreased every frame when active
!Hours		= !FreeRAM+$0A		; playtime counter (why do I have hours)
!Minutes	= !FreeRAM+$0B		; more playtime counters
!Seconds	= !FreeRAM+$0C		; ditto

!TimerL		= !FreeRAM+$0D
!TimerR		= !FreeRAM+$0E
!LRFlags	= !FreeRAM+$0F

!L3TileMap	= !FreeRAM+$20		; 0x2E0 bytes long buffer
!L3Props1	= !FreeRAM+$300		; 0xA0 bytes long buffer
!L3Props2	= !FreeRAM+$3A0		; 0x60 bytes long buffer

!HoursField	= !L3TileMap+$010A
!MinutesField	= !L3TileMap+$010D
!SecondsField	= !L3TileMap+$010F

!BarsField	= !L3TileMap+$0115	; 8 tiles
!VolumeLeftBar	= !L3TileMap+$018F	; 8
!VolumeRightBar = !L3TileMap+$01CF	; 8
!SurroundLField = !L3Props1+$1A		; 3
!SurroundRField = !L3Props1+$5A		; 3
!SongField	= !L3TileMap+$91	; 2
!PitchField	= !L3TileMap+$020D	; 2
!TempoField	= !L3TileMap+$021B	; 2

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Various tables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

BarTiles:
	db $60,$61,$62,$63,$64,$65,$66,$67
	
DestLeft:
	db $FF,$FF,$FF,$02,$FF,$04,$FF,$06
	db $FF,$08,$09,$0A,$0B,$FF,$0D,$0E
	db $0F,$10
	
DestRight:
	db $FF,$FF,$03,$FF,$05,$FF,$07,$FF
	db $09,$0A,$0B,$0C,$FF,$0E,$0F,$10
	db $11,$FF
	
DestUp:
	db $FF,$00,$01,$01,$02,$03,$04,$05
	db $06,$06,$06,$07,$07,$08,$09,$0A
	db $0B,$0C
	
DestDown:	
	db $01,$02,$04,$05,$06,$07,$08,$0B
	db $0D,$0E,$0F,$10,$11,$FF,$FF,$FF
	db $FF,$FF
	
SongMap:
	db $01,$01,$01,$01,$01,$01,$01,$01	; 00 - 07
	db $01,$02,$03,$04,$05,$06,$07,$08	; 08 - 15
	db $12,$18,$2B,$49,$46,$6A,$29,$31	; 16 - 23
	db $55,$39,$4B,$56,$40,$63,$53,$6F	; 24 - 31
	db $48,$37,$27,$52,$5B,$3F,$3A,$68	; 32 - 39
	db $62,$6C,$6E,$70,$66,$43,$38,$5F	; 40 - 47
	db $3C,$59,$5E,$1F,$54,$71,$41,$57	; 48 - 55
	db $5C,$72,$60,$36,$45,$4F,$3E,$47	; 56 - 63
	db $5A,$69,$35,$61,$65,$3D,$4E,$67	; 64 - 71
	db $4D,$33,$51,$6D,$44,$5D,$4C,$28	; 72 - 79
	db $21,$42,$32,$58,$64,$6B,$34		; 80 - 86
	
ButtonsFunctions:
	db $E0,$E1,$E2,$E3,$F8
	db $E4,$E5,$E6,$E7,$F9

ButtonsOffsets:
	db $05,$0A,$0F,$14
	db $45,$4A,$4F,$54
	
MaskTable:
	db $01,$02,$04,$08,$10,$20,$40,$80
	
LRMaskRead:
	db $20,$10
	
LRMaskSet:
	db $80,$01
	
LRMaskClear:
	db $7F,$FE
	
incsrc names.asm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Init routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	
print "INIT ", pc

SpriteInit:
	PHB				; set data bank to $7F
	LDA #$7F
	PHA
	PLB
	PHX
	LDX #$20			; init values to zero
-	STZ $A000,x
	DEX
	BPL -
	LDA #$10			; except these
	STA !SongNumber
	LDA #$10
	STA !VolumeLeft
	STA !VolumeRight
	PLX
	PLB
	LDA #$FC			; tell the spc700 to send us the envelope info
	STA $1DFE
	LDA #$C0			; also set the jukebox flag
	TSB $1DFF
	LDA !MiscFlags			; don't show stuff like the bars and clear/stop the timer
	ORA #%00001011
	STA !MiscFlags
	RTL

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Main routine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SpriteMain:
	JSR SubGFX			; draw the cursor first
	LDA #$FF			; hide and stun mario
	STA $18BD
	STA $78
	LDA #$0A			; disable pausing
	STA $13D3
	
	LDA $13				; do some bg scroll
	LSR A
	BCC +
	REP #$20
	INC $1466
	INC $1468
	SEP #$20
+
	LDA $16				; check if it's time to warp
	AND #$10			; (when you press start)
	BEQ .nowarp
	
	LDA #$06
	STA $71
	STZ $89
	STZ $88
	LDA #$FC			; fade out the music and tell the spc700
	STA $1DFA			; to stop sending us the envelope info
	STA $1DFB
	LDA #$80
	TRB $1DFF
.nowarp

ControllerStuff:			; this makes holding down L/R work properly
	LDX #$01
.loop
	LDA $17
	AND LRMaskRead,x
	BEQ .not_pressing
	LDA $18
	AND LRMaskRead,x
	BEQ .not_first_time
	LDA #!HoldingDelay
	STA !TimerL,x
	BRA .set_flag
	
.not_first_time
	LDA !TimerL,x
	BNE .dec_timer
	LDA #$02
	STA !TimerL,x
.set_flag
	LDA !LRFlags
	ORA LRMaskSet,x
	STA !LRFlags
	BRA .end
	
.not_pressing
	LDA #$00
	STA !TimerL,x
	BRA .clear_flag
	
.dec_timer
	LDA !TimerL,x
	DEC
	STA !TimerL,x
.clear_flag
	LDA !LRFlags
	AND LRMaskClear,x
	STA !LRFlags
.end
	DEX
	BPL .loop
	
	LDA !CursorIndex
	ASL A
	TAX
	PEA ReturnFromCursor-1
	JMP (CursorPtrs,x)
	
CursorPtrs:
	dw SongSelect			; 0x00
	dw SFXSelect			; 0x01
	dw VolLMod			; 0x02
	dw InvertPhaseL			; 0x03
	dw VolRMod			; 0x04
	dw InvertPhaseR			; 0x05
	dw PitchMod			; 0x06
	dw TempoMod			; 0x07
	dw Ch0Toggle			; 0x08
	dw Ch1Toggle			; 0x09
	dw Ch2Toggle			; 0x0A
	dw Ch3Toggle			; 0x0B
	dw ChFlip			; 0x0C
	dw Ch4Toggle			; 0x0D
	dw Ch5Toggle			; 0x0E
	dw Ch6Toggle			; 0x0F
	dw Ch7Toggle			; 0x10
	dw ChAll			; 0x11
	

SongSelect:
	JSR UpdateText			; update the title and author fields
	BIT $16				; if either Y or X is pressed, stop playing
	BVC .check_play
	LDA #!MuteSong
	STA $1DFB
	LDA !MiscFlags			; disable/clear timer + bars
	ORA #%00001011
	STA !MiscFlags
	BRA .check_dec
.check_play
	LDA $16				; if either A or B is pressed, play a song
	ORA $18
	BPL .check_dec
	LDA !SongNumber
	TAX				; get the right song number
	LDA SongMap,x
	CMP #$01
	BNE .not_death
	LDA #$02
	STA !DeathRAM
	STX $00
	JSL $00D0B6			; upload X death song
	BRA .update_flags
.not_death
	CMP $7FB000			; don't play if it's already playing
	BEQ .check_dec
	STA $1DFB
.update_flags
	LDA !MiscFlags			; kindly enable the bars and clear the timer
	AND #%11110101
	ORA #$01
	STA !MiscFlags
.check_dec
	LDA !LRFlags			; if pressing L, decrease song number
	BPL .check_inc
	LDA !SongNumber			; unless it's zero
	BEQ SFXSelect_return
	DEC A
	STA !SongNumber			
	BRA .update_values
.check_inc
	LDA !LRFlags			; if pressing R instead, increase it
	LSR
	BCC SFXSelect_return
	LDA !SongNumber			; unless we reached the limit
	CMP #!SongLimit
	BCS SFXSelect_return
	INC A
	STA !SongNumber
.update_values
	LDX #$06
	JMP UpdateValue

SFXSelect:
	LDA $16				; check B or A
	ORA $18
	BPL .check_dec
	LDA !SFXNumber
	CMP #!LastSFX1+1
	BCS .play_1DFC
	STA $1DF9
.return
	RTS
.play_1DFC
	SEC
	SBC #!LastSFX1
	STA $1DFC
	RTS
.check_dec
	LDA !LRFlags
	BPL .check_inc
	LDA !SFXNumber
	BEQ .return
	DEC
	STA !SFXNumber
	LDX #$00
	JMP UpdateValue
.check_inc
	LDA !LRFlags
	LSR
	BCC .return
	LDA !SFXNumber
	CMP #!LastSFX2
	BEQ .return
	INC
	STA !SFXNumber
	LDX #$00
	JMP UpdateValue

	
VolLMod:
	LDA.b #!VolumeLeftBar
	STA $00
	LDA.b #!VolumeLeftBar>>8
	STA $01
	LDA.b #!VolumeLeftBar>>16
	STA $02

	LDA !LRFlags
	LSR
	BCC .check_dec
	
	LDA !VolumeLeft			; increasing
	CMP #$10
	BEQ .return
	INC
	STA !VolumeLeft
	LDX #$F2
	STX $1DFA
	
.increase_volume
	DEC
	CMP #$0E
	BCS .last_tile
	LSR
	BNE .not_first_tile
	LDA #$69			; 1/2 full tile
	ADC #$00			; carry set -> full tile
	STA [$00]
	RTS
	
.not_first_tile
	TAY
	LDA #$6C			; 1/2 full tile
	ADC #$00			; carry set -> full tile
	STA [$00],y
	LDA #$6F			; filling previous tile
	DEY
	BNE +				; if it's the first tile use the bordered one
	INC
+	STA [$00],y
	RTS
	
.last_tile
	EOR #$01
	LSR
	LDA #$6E			; full bordered tile
	SBC #$00			; carry set -> 1/2 full bordered tile
	LDY #$07
	STA [$00],y
	LDA #$6F
	DEY
	STA [$00],y
.return
	RTS
	
	
.check_dec
	LDA !LRFlags
	BPL .return
	
	LDA !VolumeLeft			; decreasing
	BEQ .return
	DEC
	STA !VolumeLeft
	LDX #$F3
	STX $1DFA
	
.decrease_volume
	DEC
	BMI .all_empty
	CMP #$0E
	BNE .not_last_tile
	LDA #$6E
	LDY #$07
	STA [$00],y
	RTS
	
.not_last_tile
	LSR
	BEQ .first_tile
	TAY
	LDA #$6C			; 1/2 full tile
	ADC #$00			; carry set -> full tile
	STA [$00],y
	LDA #$6B
	INY
	CPY #$07			; if we're emptying tile 7, use the bordered tile
	BNE +
	LDA #$71
+	STA [$00],y
	RTS
	
.all_empty
	LDA #$68
	STA [$00]
	RTS
	
.first_tile
	LDA #$69			; 1/2 full bordered tile
	ADC #$00			; carry set -> full bordered tile
	STA [$00]
	LDA #$6B			; more emptiness
	LDY #$01
	STA [$00],y
	RTS
	
	
InvertPhaseL:
	LDA $16				; check B or A
	ORA $18
	BPL .return
	LDA #$F6
	STA $1DFA
	LDA !SurroundLField
	EOR #$04
	STA !SurroundLField
	STA !SurroundLField+1
	STA !SurroundLField+2
.return
	RTS

	
VolRMod:
	LDA.b #!VolumeRightBar
	STA $00
	LDA.b #!VolumeRightBar>>8
	STA $01
	LDA.b #!VolumeRightBar>>16
	STA $02

	LDA !LRFlags
	LSR
	BCC .check_dec
	
	LDA !VolumeRight
	CMP #$10
	BEQ InvertPhaseR_return
	INC
	STA !VolumeRight
	LDX #$F4
	STX $1DFA
	JMP VolLMod_increase_volume
	
.check_dec
	LDA !LRFlags
	BPL InvertPhaseR_return
	LDA !VolumeRight
	BEQ InvertPhaseR_return
	DEC
	STA !VolumeRight
	LDX #$F5
	STX $1DFA
	JMP VolLMod_decrease_volume

InvertPhaseR:
	LDA $16				; check B or A
	ORA $18
	BPL .return
	LDA #$F7
	STA $1DFA
	LDA !SurroundRField
	EOR #$04
	STA !SurroundRField
	STA !SurroundRField+1
	STA !SurroundRField+2
.return
	RTS

PitchMod:
	LDA !LRFlags
	LSR
	BCC .check_dec
	LDA !GlobalPitch
	CMP #!MaxPitch
	BEQ InvertPhaseR_return
	INC
	STA !GlobalPitch
	LDX #$F0
	STX $1DFA
	BRA .draw
	
.check_dec
	LDA !LRFlags
	BPL InvertPhaseR_return
	LDA !GlobalPitch
	CMP #!MinPitch
	BEQ InvertPhaseR_return
	DEC
	STA !GlobalPitch
	LDX #$F1
	STX $1DFA
.draw
	LDY #$29
	CMP #$00
	BPL +
	LDY #$27
	EOR #$FF
	INC
+	TAX
	TYA
	STA !PitchField-1
	TXA
	LDX #$02
	JMP UpdateValue


TempoMod:
	LDA !LRFlags
	LSR
	BCC .check_dec
	LDA !GlobalTempo
	CMP #!MaxTempo
	BEQ InvertPhaseR_return
	CLC
	ADC #$05
	STA !GlobalTempo
	LDX #$FA
	STX $1DFA
	BRA .draw
	
.check_dec
	LDA !LRFlags
	BPL InvertPhaseR_return
	LDA !GlobalTempo
	CMP #!MinTempo
	BEQ InvertPhaseR_return
	SEC
	SBC #$05
	STA !GlobalTempo
	LDX #$FB
	STX $1DFA
.draw
	LDY #$29
	CMP #$00
	BPL +
	LDY #$27
	EOR #$FF
	INC
+	TAX
	TYA
	STA !TempoField-1
	TXA
	LDX #$04
	JMP UpdateValue

Ch0Toggle:
Ch1Toggle:
Ch2Toggle:
Ch3Toggle:
ChFlip:
Ch4Toggle:
Ch5Toggle:
Ch6Toggle:
Ch7Toggle:
ChAll:
	LDA $16				; check for B
	BPL .return
	TXA
	LSR
	SEC
	SBC #$08
	TAX
	LDA ButtonsFunctions,x
	STA $1DFA
	
	TXA				; filter out SWAP and MUTE
	CMP #$04
	BCC +
	DEC
	CMP #$03
	BEQ .swap
	CMP #$08
	BEQ .mute

+	TAX
	TXY
	LDA ButtonsOffsets,x
	TAX
	LDA !L3Props2,x
	EOR #$04			; $38 becomes $3C and vice versa
	STA !L3Props2,x
	
	TYX				; update channel flags
	LDA MaskTable,x
	STA $00
	LDA !ChannelStatus
	EOR $00
	STA !ChannelStatus
.check_states
	BNE .some_disabled		; check if some channels are disabled
	LDA #$38			; all enabled
	BRA .modify_mute_props
	
.some_disabled
	CMP #$FF			; check if all channels aren't disabled
	BNE .some_enabled
	LDA #$3C			; all muted
	BRA .modify_mute_props
	
.some_enabled
	LDA #$38
.modify_mute_props
	STA !L3Props2+$59
	STA !L3Props2+$5A
	STA !L3Props2+$5B
	STA !L3Props2+$5C
.return
	RTS
	
.swap
	LDY #$07			; basically toggle all channels
-	TYX
	LDA ButtonsOffsets,x
	TAX
	LDA !L3Props2,x
	EOR #$04
	STA !L3Props2,x
	DEY
	BPL -
	LDA !ChannelStatus
	EOR #$FF
	STA !ChannelStatus
	BRA .check_states
	
.mute
	LDA !ChannelStatus
	CMP #$FF
	BEQ .unmute
	LDA #$FF
	BRA +
.unmute
	LDA #$00
+	STA !ChannelStatus
	LDA !L3Props2+$59
	EOR #$04
	STA $00
	LDY #$07
-	TYX
	LDA ButtonsOffsets,x
	TAX
	LDA $00
	STA !L3Props2,x
	DEY
	BPL -

	BRA .modify_mute_props

	
; end of cursor subroutines


ReturnFromCursor:
	LDA !CursorIndex		; code below is to move the cursor around
	TAX
MoveX:
	LDA $16
	AND #$02
	BEQ .check_right
	LDA DestLeft,x
	BMI .check_right
	STA !CursorIndex
	LDA #!CursorSFX
	STA !CursorPort
	BRA MoveY
.check_right
	LDA $16
	LSR A
	BCC MoveY
	LDA DestRight,x
	BMI MoveY
	STA !CursorIndex
	LDA #!CursorSFX
	STA !CursorPort
MoveY:
	LDA $16
	AND #$08
	BEQ .check_down
	LDA DestUp,x
	BMI .check_down
	STA !CursorIndex
	LDA #!CursorSFX
	STA !CursorPort
	BRA .moveon
.check_down
	LDA $16
	AND #$04
	BEQ .moveon
	LDA DestDown,x
	BMI .moveon
	STA !CursorIndex
	LDA #!CursorSFX
	STA !CursorPort
.moveon


Timer:
	LDA !MiscFlags			; clear the timer if some flag tells us to	
	LSR A
	BCC .no_clear
	
	LDA #$00
	STA !Hours
	STA !Minutes
	STA !Seconds
	LDA #$3C
	STA !Clock
	LDA !MiscFlags
	AND #%11111110
	STA !MiscFlags
	BRA .skip			; don't even bother handling the timer
.no_clear
	LDA !MiscFlags			; handle timer unless some flag tells us not to
	AND #$02
	BNE .skip
	
	LDA !Clock			; time for spaghetti code >_>
	BNE .just_dec
	LDA !Seconds
	INC A
	STA !Seconds
	CMP #60
	BNE .reset_clock
	LDA #$00
	STA !Seconds
	
	LDA !Minutes
	INC A
	STA !Minutes
	CMP #60
	BNE .reset_clock
	LDA #$00
	STA !Minutes
	
	LDA !Hours
	INC A
	STA !Hours

.reset_clock
	LDA #$3D
.just_dec
	DEC A
	STA !Clock
.skip
	LDX #$02
	LDY #$06
.drawloop
	LDA !Hours,x
	PHX
	PHY
	JSR HexToDec
	STA $00
	PLX
	TYA
	STA !HoursField,x
	LDA $00
	STA !HoursField+1,x
	TXY
	PLX
	DEY
	DEY
	DEY
	DEX
	BPL .drawloop

	
DrawBars:				; code below handles drawing those envelope info bars
	LDA !MiscFlags			; unless some flag tells us not to
	AND #$08
	BEQ .draw
	
	LDX #$07
	LDA #$60
.clear
	STA !BarsField,x
	DEX
	BPL .clear
	BRA .move_on

.draw
	LDX #$07
	LDY #$03
.loop
	LDA $2140,y
	LSR A
	LSR A
	LSR A
	LSR A
	PHX
	TAX
	LDA BarTiles,x
	PLX
	STA !BarsField,x
	DEX
	LDA $2140,y
	AND #$0F
	PHX
	TAX
	LDA BarTiles,x
	PLX
	STA !BarsField,x
	DEX
	DEY
	BPL .loop
.move_on

ReturnMain:
	RTS



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Hex to decimal subroutine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; A = what to convert
; result is stored to YA

HexToDec:
	LDY #$00
-	CMP #$0A
	BCC +
	SEC
	SBC #$0A
	INY
	BRA -
+	RTS


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Song title & author subroutine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

UpdateText:
	STA $666D1E
	LDA !SongNumber
	ASL
	TAX
	REP #$20
	LDA SongNamePtrs,x	; $00 points to the text data
	STA $00
	LDA #!TitleField	; $03 points to the buffer
	STA $03
	SEP #$20
	LDA #SongNamePtrs>>16
	STA $02
	LDA #$7F
	STA $05
	LDY #$00
	LDA [$00],y		; $06 is the text size
	STA $06
	REP #$20		; adjust the text pointer
	INC $00
	SEP #$20
	LDY #$18		; add trailing spaces
	LDA #$FC
-	STA [$03],y
	DEY
	CPY $06
	BCS -
-	LDA [$00],y		; write the text to the buffer
	STA [$03],y
	DEY
	BPL -

	LDA !SongNumber
	TAX
	LDA AuthorIDs,x
	TAX
	REP #$20
	LDA AuthorNamePtrs,x	; again, $00 points to the text data
	STA $00
	LDA #!AuthorField	; and $03 to the buffer
	STA $03
	SEP #$20
	INY			; $FF + 1 = $00
	LDA [$00],y		; $06 is still the text size
	STA $06	
	REP #$20		; adjust the text pointer
	INC $00
	SEP #$20
	LDY #$15		; add trailing spaces
	LDA #$FC
-	STA [$03],y
	DEY
	CPY $06
	BCS -
-	LDA [$00],y		; write the text to the buffer
	STA [$03],y
	DEY
	BPL -
	RTS


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Update value subroutine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; X = index for ValueOffsets (look below)
; A = value to write

; 0x00 -> sfx number
; 0x02 -> global pitch
; 0x04 -> global tempo
; 0x06 -> song number

ValueOffsets:
	dw $00DA,$020D,$021B,$0092
	
UpdateValue:
	JSR HexToDec
	PHA
	REP #$30			; get the offset for the tilemap buffer
	LDA ValueOffsets,x
	TAX
	SEP #$20
	TYA				; Y was tens
	BNE +
	LDA #$FC			; no leading zeros
+	STA !L3TileMap,x
	PLA				; A is ones
	STA !L3TileMap+1,x
	SEP #$10
	RTS

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; GFX subroutine
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CursorX:
	db $17,$17,$17,$BF,$17,$BF,$17,$87
	db $17,$3F,$67,$8F,$B7,$17,$3F,$67
	db $8F,$B7

CursorY:
	db $37,$47,$77,$77,$87,$87,$97,$97
	db $B7,$B7,$B7,$B7,$B7,$C7,$C7,$C7
	db $C7,$C7

SubGFX:
	JSL GetDrawInfo			; we need this for the OAM index
	LDA !CursorIndex		; the cursor uses fixed X and Y positions
	TAX
	LDA CursorX,x			; set X position
	STA $0300,y
	LDA CursorY,x			; set Y position
	STA $0301,y
	LDA #!SpriteTile		; tile to draw
	STA $0302,y
	LDA #!SpriteProps		; YXPPCCCT properties
	STA $0303,y
	LDX $15E9			; maybe this helps..
	LDA #$00
	TAY
	JSL $01B7B3
	RTS
