INITIALIZED 	= 1

TRANSFERRED 	= 2

PLAYERINIT	= $40

RELOCATEDPLAYERLOW = $03

RELOCATEDPLAYERHIGH = $04

STATE 		= $05

BITCOUNT 	= $06

COUNT 		= $07

CURRENT 	= $08

DATA_LOW	= $09

DATA_HIGH 	= $0A





	*=$FF40

	JMP RESETROUTINE

; NMI ROUTINE

; Keeps state of the transfer

; Doesn't save X,Y on stack since cold reset routine 

; will not use them.

; Instead X and Y registers will be passed to normal IRQ routine

; to save some cycles otherwise might be needed on the IRQ routine to set

; them up. No escape from reserving Accumulator too since foreground task in the rom

; should have a means to jump from waiting transfer to the sid player.



NMIROUTINE

 	SEI

 	PHA		

	LDA STATE

	CMP #INITIALIZED

	BEQ TRANSFER

	CMP #TRANSFERRED

	BEQ PLAY

	

INIT

	LDA #INITIALIZED	; Set State as Initialized

	STA STATE

	LDA #$00	; Clear everything

	STA DATA_LOW

	STA DATA_HIGH

	STA CURRENT

	STA COUNT

	LDA #$08

	STA BITCOUNT	

	CLV

	PLA

	CLI

	RTI			

	

TRANSFER	

	LDA CURRENT

	BVS T_1

T_0

	CLC	

	BVC CONT	; Unconditional jump (since we already know overflow flag is clear)

T_1	

	SEC

CONT	

	ROL

	STA CURRENT

	DEC BITCOUNT

	BNE EXIT 	; 1 bit transferred in, exit

	LDY #$08

	STY BITCOUNT	; Refill BITCOUNT to 8 for next 8 bit of transfer	

	LDX COUNT

	INX

	STX COUNT

	CPX #$02	; Check if low byte is already transferred

	BEQ FINISH	; if so finalize transfer

	STA DATA_LOW	; Low byte transferred

		



EXIT	

	CLV		; Clear Overflow flag for next bit of transfer	

	PLA

	CLI

	RTI		; Return from interrupt

	

FINISH			; We've filled DATA_LOW and will fill DATA_HIGH with the starting address of transfer

	CLV		; Clear Overflow flag for next bit of transfer	

	STA DATA_HIGH

	LDA #TRANSFERRED

	STA STATE	; Set State as Transferred

	LDA #$00	; Fill accumulator with zero for IRQ routine

	STA CURRENT

	LDX #$08	; BITCOUNT Initialization for IRQ routine

	LDY #$00	; Y starts from 0 for memory transfer for indirect indexed addressing for IRQ routine

	PLA

	CLI	

	RTI

	

PLAY

			; Everything is ok, let control to the player.

	LDA #PLAYERINIT

	STA STATE

	

; IRQ Routine

; This routine does the bulk of actual transfer

; Before the very first call into this routine X is set as 8 and Y is set as 0

IRQROUTINE		; 7 cycles itself plus 2-7 for the unfinished operation in foreground

	SEI		; 2 cycles

	PHA		; 3 cycles

	BVS AT_1	; 2 if not taken, 3 if taken

AT_0

	CLC		; 2 cycles

	BVC ACONT	; Unconditional jump (since we already know overflow flag is clear) ; 2 cycles

AT_1	

	SEC		; 2 cycles

ACONT	

	LDA CURRENT	; 3 cycles

	ROL		; 2 cycles

	STA CURRENT	; 3 cycles

	DEX		; 2 cycles

	BNE AFINISH 	; 1 bit transferred in, exit. 2 if not taken, 3 if taken

	

	LDX #$08	; 2 cycles

	STA (DATA_LOW), Y	; Finish one byte of transfer ; 6 cycles

	INY		; 2 cycles

	BEQ AFINISH 	; 2 if not taken, 3 if taken

	INC DATA_HIGH   ; 5 cycles

AFINISH

	CLV		; 2 cycles

	PLA		; 4 cycles

	CLI		; 2 cycles

	RTI		; 6 cycles



; MIN = 52 cycle for bits D7..D1 

; 

; MAX = 69 cycle for end of each page



RESETROUTINE

	LDA STATE

	CMP #PLAYERINIT

	BNE RESETROUTINE

	JMP (RELOCATEDPLAYERLOW) ; Nmi routine should be changed to get the player address

		

		

	.ORG $FFFA

	

	.DW NMIROUTINE

	.DW RESETROUTINE

	.DW IRQROUTINE