; FORMAT
; $C700  Data  9 bytes per sprite
;  +0  Byte	Color (Minus->End)
;  +1  Word   Pattern Address (Always CC00)
;  +3  Word   EraseX
;  +5  Byte   EraseY
;  +6  Word   NewX
;  +8  Byte   NewY
;  +9  (Next sprite)


; Example $CC00- Sprite
;    40x16 mask patterns
;    80 bytes per pattern
;    640 bytes per sprite


SPRITE_SUBCPU_INSTALL_ADDR	EQU		$C500
SPRITE_DESC_ADDR			EQU		$C700





INSTALL_SPRITE_SUBCPU
					PSHS		X

					LEAX		SPRITE_SUBCPU_START,PCR
					STX			MAIN_TO_SUB_MAINADDR,PCR

					LDX			#SPRITE_SUBCPU_INSTALL_ADDR
					STX			MAIN_TO_SUB_SUBADDR,PCR

					LDX			#(SPRITE_SUBCPU_PROG_END-SPRITE_SUBCPU_PROG_START)
					STX			MAIN_TO_SUB_LENGTH,PCR

					LBSR		MAIN_TO_SUB

					PULS		X,PC




					; X		Data input address
					; D		(Sprite Desc) length
CALL_SPRITE_SUBCPU	PSHS	X
					STX		MAIN_TO_SUB_MAINADDR,PCR
					LDX		#SPRITE_DESC_ADDR
					STX		MAIN_TO_SUB_SUBADDR,PCR
					STD		MAIN_TO_SUB_LENGTH,PCR
					LBSR	MAIN_TO_SUB

					LDX		#SPRITE_SUBCPU_INSTALL_ADDR
					STX		CALL_SUB_CPU_ADDR,PCR
					LBSR	CALL_SUB_CPU

					PULS	X,PC





SPRITE_SUBCPU_PROG_START

SPRITE_SUBCPU_START
					PSHS	A,B,X,Y,U

					BITA	$D409	; Sub-CPU VRAM Access Flag On


					LDX		#SPRITE_DESC_ADDR

SPRITE_SUBCPU_START_NEXTSPRITE
					LDA		,X
					BMI		SPRITE_SUBCPU_LOOPOUT

					ANDA	#7
					ORA		#8
					STA		,X
					STA		SPRITE_SUBCPU_COLOR_BIT,PCR

					LEAU	3,X		; Erase X,Y
					BSR		SPRITE_SUBCPU_XY_TO_VRAMADDR
					; U is VRAM addr in Blue Plane
					; D is the pattern address
					LBSR	SPRITE_SUBCPU_ERASE

					LDA		,X
					STA		SPRITE_SUBCPU_COLOR_BIT,PCR

					LEAU	6,X

					LDA		2,U
					CMPA	#200
					BCC		SPRITE_SUBCPU_NO_WRITE

					BSR		SPRITE_SUBCPU_XY_TO_VRAMADDR
					LBSR	SPRITE_SUBCPU_WRITE

SPRITE_SUBCPU_NO_WRITE
					LEAX	9,X
					BRA		SPRITE_SUBCPU_START_NEXTSPRITE

SPRITE_SUBCPU_LOOPOUT
					STA		$D409	; Sub-CPU VRAM Access Flag Clear
					PULS	A,B,X,Y,U,PC


					; Input
					;   X register  Sprite Descriptor Pointer
					;   2 bytes		,U  x
					;   1 byte		2,U y
					; Output
					;   D reg			Offset to sprite pattern
					;   U reg			VRAM Addr
					;   Destroys		Y
SPRITE_SUBCPU_XY_TO_VRAMADDR
					LDA		#80
					LDB		2,U
					MUL
					TFR		D,Y
					LDD		,U
					LSRA
					RORB
					LSRA
					RORB
					LSRA
					RORB
					LEAY	D,Y
					LDB		1,U
					ANDB	#7
					LDA		#80
					MUL
					ADDD	1,X
					TFR		Y,U
					RTS





SPRITE_SUBCPU_ERASE
					PSHS	X
					LBSR	SPRITE_SUBCPU_FIRST_PLANE ; It also does TFR D,X

SPRITE_SUBCPU_ERASE_PER_PLANE
					LSR		SPRITE_SUBCPU_COLOR_BIT,PCR
					BEQ		SPRITE_SUBCPU_ERASE_OR_WRITE_COMMON_END
					BCC		SPRITE_SUBCPU_ERASE_NEXT_PLANE

					PSHS	X,U

					LDA		#16
					STA		SPRITE_SUBCPU_NLINE_LEFT,PCR

SPRITE_SUBCPU_ERASE_PER_LINE
					CMPU	SPRITE_SUBCPU_VRAM_MIN,PCR
					BMI		SPRITE_SUBCPU_ERASE_SKIP_LINE
					CMPU	SPRITE_SUBCPU_VRAM_MAX,PCR
					BGE		SPRITE_SUBCPU_ERASE_SKIP_LINE

					LDD		,X
					COMA
					COMB
					ANDA	,U
					ANDB	1,U
					STD		,U

					LDD		2,X
					COMA
					COMB
					ANDA	2,U
					ANDB	3,U
					STD		2,U

					LDA		4,X
					COMA
					ANDA	4,U
					STA		4,U

SPRITE_SUBCPU_ERASE_SKIP_LINE
					LEAU	80,U
					LEAX	5,X

					DEC		SPRITE_SUBCPU_NLINE_LEFT,PCR
					BNE		SPRITE_SUBCPU_ERASE_PER_LINE

					PULS	X,U
SPRITE_SUBCPU_ERASE_NEXT_PLANE
					BSR		SPRITE_SUBCPU_NEXT_PLANE
					BRA		SPRITE_SUBCPU_ERASE_PER_PLANE




SPRITE_SUBCPU_ERASE_OR_WRITE_COMMON_END
					PULS	X,PC




SPRITE_SUBCPU_WRITE
					PSHS	X
					BSR		SPRITE_SUBCPU_FIRST_PLANE ; It also does TFR D,X

SPRITE_SUBCPU_WRITE_PER_PLANE
					LSR		SPRITE_SUBCPU_COLOR_BIT,PCR
					BEQ		SPRITE_SUBCPU_ERASE_OR_WRITE_COMMON_END
					BCC		SPRITE_SUBCPU_WRITE_NEXT_PLANE

					LDA		#16
					STA		SPRITE_SUBCPU_NLINE_LEFT,PCR

					PSHS	X,U

SPRITE_SUBCPU_WRITE_PER_LINE
					; Min check is redundant because 0<=Ycoord<200
					; CMPU	SPRITE_SUBCPU_VRAM_MIN,PCR
					; BMI		SPRITE_SUBCPU_WRITE_SKIP_LINE
					CMPU	SPRITE_SUBCPU_VRAM_MAX,PCR
					BGE		SPRITE_SUBCPU_WRITE_SKIP_LINE

					LDD		,X
					ORA		,U
					ORB		1,U
					STD		,U

					LDD		2,X
					ORA		2,U
					ORB		3,U
					STD		2,U

					LDA		4,X
					ORA		4,U
					STA		4,U

SPRITE_SUBCPU_WRITE_SKIP_LINE
					LEAU	80,U
					LEAX	5,X

					DEC		SPRITE_SUBCPU_NLINE_LEFT,PCR
					BNE		SPRITE_SUBCPU_WRITE_PER_LINE

					PULS	X,U

SPRITE_SUBCPU_WRITE_NEXT_PLANE
					BSR		SPRITE_SUBCPU_NEXT_PLANE
					BRA		SPRITE_SUBCPU_WRITE_PER_PLANE




SPRITE_SUBCPU_FIRST_PLANE
					LDX		#0
					STX		SPRITE_SUBCPU_VRAM_MIN,PCR
					LDX		#$3E80
					STX		SPRITE_SUBCPU_VRAM_MAX,PCR
					TFR		D,X
					RTS

SPRITE_SUBCPU_NEXT_PLANE
					LEAU	$4000,U
					LDD		#$4000
					ADDD	SPRITE_SUBCPU_VRAM_MIN,PCR
					STD		SPRITE_SUBCPU_VRAM_MIN,PCR
					ADDD	#$3E80
					STD		SPRITE_SUBCPU_VRAM_MAX,PCR
					RTS



SPRITE_SUBCPU_COLOR_BIT		FCB		0
SPRITE_SUBCPU_NLINE_LEFT	FCB		0
SPRITE_SUBCPU_VRAM_MIN		FDB		80
SPRITE_SUBCPU_VRAM_MAX		FDB		$3E80



SPRITE_SUBCPU_PROG_END
