ADDRESSTRANSFER = 1

PLAYERTRANSFER 	= 2

SIDTRANSFER 	= 0

CURRENT 	= $02

STATE 		= $03

RELOCATEDPLAYERLOW = $04

RELOCATEDPLAYERHIGH = $05

DATA_LOW	= $06

DATA_HIGH 	= $07







	*=$FF00

	JMP RESETROUTINE

; NMI ROUTINE

; It does the transfer of 0 bits.

; A, X and Y is freely used and not pushed into the stack

; Since foreground task doesn't use any of them and just

; idly wait for the overflow flag from PIC micro.

; Sid transfer takes 7 cycle for interrupt setup

; Extra 3 cycle if foreground operation is not finished

; 45 cycle for the actual process including RTI

; Total = 55 cycle... 440 times 8 Mhz Pic cycles.



NMIROUTINE

 	SEI 		

	LDA STATE	

	BNE OTHER ; Not taken branch costs 2 cycles hence we are checking for SIDTRANSFER first

SIDTRANSFERSTATE

	LDA CURRENT	

	CLC		

	ROL		

	STA CURRENT	

	DEX		

	BNE FINISH1 	; 1 bit (0) transferred in, exit

	LDX #$08	

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

	INY		

	BNE FINISH1 	

	INC DATA_HIGH   

FINISH1

	CLI		

	RTI		

	

	

OTHER	

	CMP #PLAYERTRANSFER

	BNE ADDRESSTRANSFERSTATE

PLAYERTRANSFERSTATE

	LDA CURRENT

	CLC	

	ROL	

	STA CURRENT	

	DEX		

	BNE FINISH2 	; 1 bit (0) transferred in, exit. 

	LDX #$08	

	STA (RELOCATEDPLAYERLOW), Y	; Finish one byte of transfer 

	INY		

	BNE FINISH2 	

	INC RELOCATEDPLAYERHIGH   

FINISH2

	CLI		

	RTI		





ADDRESSTRANSFERSTATE

	LDA CURRENT

	CLC		

	ROL		

	STA CURRENT	

	DEY		

	BNE FINISH3 	; 1 bit (0) transferred in, exit. 

	STA RELOCATEDPLAYERLOW, X	; Finish one byte of transfer 

	LDY #$08	

	INX		

FINISH3		

	CLI

	RTI			

	

	

; IRQ Routine

; It does the transfer of 1 bits.

; A, X and Y is freely used and not pushed into the stack

; Since foreground task doesn't use any of them and just

; idly wait for the overflow flag from PIC micro.

; Also these registers are shared with the NMI routine since

; they are used for same purposes.

; And the routine is exactly same with the NMI routine except

; it sets carry before rotating current byte instead of clearing.

IRQROUTINE		



 	SEI 	

	LDA STATE	

	BNE _OTHER ; Not taken branch costs 2 cycles hence we are checking for SIDTRANSFER first

_SIDTRANSFERSTATE

	LDA CURRENT

	SEC		

	ROL		

	STA CURRENT	

	DEX		

	BNE _FINISH1 	; 1 bit (1) transferred in, exit. 

	LDX #$08

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

	INY		

	BNE _FINISH1 	

	INC DATA_HIGH   

_FINISH1

	CLI		

	RTI		

	

	

_OTHER	

	CMP #PLAYERTRANSFER

	BNE _ADDRESSTRANSFERSTATE

_PLAYERTRANSFERSTATE

	LDA CURRENT

	SEC		

	ROL		

	STA CURRENT	

	DEX		

	BNE _FINISH2 	; 1 bit (1) transferred in, exit.

	LDX #$08	; 2 cycles

	STA (RELOCATEDPLAYERLOW), Y	; Finish one byte of transfer 

	INY		

	BNE _FINISH2 	

	INC RELOCATEDPLAYERHIGH   

_FINISH2

	CLI		

	RTI		





_ADDRESSTRANSFERSTATE

	LDA CURRENT

	SEC		

	ROL		

	STA CURRENT	

	DEY		

	BNE _FINISH3 	; 1 bit (1) transferred in, exit. 

	STA RELOCATEDPLAYERLOW, X	; Finish one byte of transfer

	LDY #$08	

	INX		

_FINISH3		

	CLI

	RTI			











RESETROUTINE

	LDA #$00	; Clear everything

	STA DATA_LOW

	STA DATA_HIGH

	STA RELOCATEDPLAYERLOW	

	STA RELOCATEDPLAYERHIGH		

	STA CURRENT



	LDA #ADDRESSTRANSFER

	STA STATE

	LDY #$08	; Init bit counting 

	LDX #$00	; Init index		

			; Roles of X and Y registers are different since we use Zero Page,X addressing 

			; in the address transfer routine

	

WAITADDRESSTRANSFER

	BVC WAITADDRESSTRANSFER

	LDA #PLAYERTRANSFER

	STA STATE

	LDX #$08	; Init bit counting 	

	LDY #$00	; Init index	

	CLV

	

WAITPLAYERTRANSFER

	BVC WAITPLAYERTRANSFER

	LDA #SIDTRANSFER

	STA STATE

	LDX #$08	; Init bit counting 	

	LDY #$00	; Init index	

	CLV

	

WAITSIDTRANSFER	

	BVC WAITSIDTRANSFER

	CLV	

	

	JMP (RELOCATEDPLAYERLOW) 

		

		

	.ORG $FFFA

	

	.DW NMIROUTINE

	.DW RESETROUTINE

	.DW IRQROUTINE