;**************************************************************************
;*
;* multicolor sprites
;*
;**************************************************************************

	;.define	DEBUG

	org $2000			   ;prg start
	
	icl "custom.i"
	
start	;

	sei				  ;disable irqs
	lda	#$00
	sta	NMIEN			  ;NMIEN all off 
	sta	DMACTL			  ;DMACTL all off

	;set display list (use shadow regs)
	
	lda	#<displayList
	sta	DLISTL	
	lda	#>displayList
	sta	DLISTH
	
	;set display list interrupt
	  
	lda	#<dli_irq
        sta	VDSLSTL           
        lda	#>dli_irq
        sta	VDSLSTH    
	
	;vertical blank interrupt 
	
	lda 	#>vbi_irq
	sta	VVBLKIH	
	lda 	#<vbi_irq
	sta	VVBLKIL	
	
	;chbase
	
	lda	#$e0	
	sta	CHBASE
	
	;color setup
	
	lda	#$0	;black
	sta	COLBK
	lda	#$34	;red		
	sta	COLPF0
	lda	#$b6	;green	
	sta	COLPF1
	lda	#$1a	;yellow		
	sta	COLPF2
	lda	#$70	;blue (usable width GTIA mode 2)			
	sta	COLPF3
	
	;color player/missile
	
	lda 	#$1F
        sta 	COLPM0
        lda 	#$4F
        sta 	COLPM1
        lda 	#$6F
        sta 	COLPM2
        lda 	#$75
        sta 	COLPM3
        
        ;hpos players
        lda	#100
        sta	HPOSP0
        lda	#00
        sta	HPOSP1
        lda	#0
        sta	HPOSP2
        lda	#0
        sta	HPOSP3
        
        ;hpos missile
        
	lda	#0
        sta	HPOSM0
        lda	#0
        sta	HPOSM1
        lda	#0
        sta	HPOSM2
        lda	#0
        sta	HPOSM3
                
        ;width/size play 0
        lda	#0		;x1 player
        sta	SIZEP0
        sta	SIZEP1
        sta	SIZEP2
	sta	SIZEP3
	
	lda	#0		;x1 missile
	sta	SIZEM
        
        ;pmbase
        
        lda	#>playerMissleBlock
        sta	PMBASE
		
	;enable player & missile

	lda	#GRACTL_PLAYERS|GRACTL_MISSILES
	sta	GRACTL
	
	;
	
	;setup displays
	   	
	lda	#DMACTL_DL|DMACTL_X1_PM|DMACTL_PLAYER|DMACTL_MISSILE|DMACTL_PF_NORMAL
		
		;enable display list dma 
		;player dma (1 line)
		;missile dma
		;playfield normal display (40)
		
			
	sta	DMACTL	;DMACTL
	
	lda	#$0
	sta	HSCROL
	
	;enable dli
	
	lda	#0	;NMIEN_VBI|NMIEN_DLI
	sta	NMIEN	;VBI + DLI enbable
	
	;enable multicolor player/missile
	
	lda	#$21	;player forground
	sta	PRIOR
	
	;
	
	cli		;irq enable

	;
loop
	;Wait VBlank

?WaitVC0
        lda	VCOUNT		
        beq	?WaitVC0   	
?WaitVCnot0
        lda	VCOUNT		
        bne	?WaitVCnot0   

	;
	
	lda	#<playConfig1
	sta	ZA0
	lda	#>playConfig1
	sta	ZA0+1
	jsr	drawSprite01	
	
	; x move
	
	;lda	playConfig1+playerConfig_s.xpos
	;clc
	;adc	#1
	;sta	playConfig1+playerConfig_s.xpos

	;
	
	.ifdef DEBUG
	lda	#$0	;black
	sta	COLBK
	.endif
	
	jmp loop			;end

counter	.byte	0
	
	.struct	playerConfig_s
		gfxPrg		.word
		gfxClr		.word
		dest		.word
		xpos		.byte
		ypos		.byte
		ypos_old	.byte
	.ends

playConfig1	.word	duckGfx				;gfx copy programm
		.word	clearGfx			;gfx clear programm
		.word	playerMissleBlock+1024+8	;destination in PGM
		.byte	60				;xpos
		.byte	96				;ypos
		.byte	1				;ypos_old

		
;************************************************************
;* 	
;* drawSprite01 (multicolor)
;* 
;* ZA0 = playerConfig
;*
;* trash x,y, ZA1-ZA3
;*
;************************************************************
	
drawSprite01
		
	;set hpos regs
		
	ldy	#playerConfig_s.xpos
	lda	(ZA0),y			
	sta	HPOSP0
	sta	HPOSP1
		
	;get and check y pos and y pos old
	
	ldy	#playerConfig_s.ypos
	lda	(ZA0),y
	ldy	#playerConfig_s.ypos_old
	cmp	(ZA0),y
	bne	?yChanged
	
	;not changed so no copy gfx
	
	rts
	
?yChanged
	
	;get dest -> ZA3, ZA2
 	
	ldy	#playerConfig_s.dest
	lda	(ZA0),y
	sta	ZA3
	sta	ZA2
	iny
	lda	(ZA0),y
	sta	ZA3+1
	sta	ZA2+1
	
 	;add y_old to ZA3
 	
 	clc 
	ldy	#playerConfig_s.ypos_old
	lda 	(ZA0),y	
        add 	ZA3
	sta	ZA3
 	
        lda 	ZA3+1
        adc 	#0     
        sta 	ZA3+1
 	
 	;get clear programm and execute
 	
 	ldy	#playerConfig_s.gfxClr
 	lda	(ZA0),y
 	sta	ZA1
 	iny
 	lda	(ZA0),y
 	sta	ZA1+1
 
 	lda	#>?clrReturn	;return to ?clrReturn
 	pha
 	lda	#<?clrReturn
 	pha
 	jmp	(ZA1)
?clrReturn	
	
	;add y to ZA2 (stored deset) -> ZA3
	
	clc        
	ldy	#playerConfig_s.ypos
        lda 	(ZA0),y
	add 	ZA2
        sta	ZA3

        lda 	ZA2+1
        adc 	#0     
        sta 	ZA3+1
	
	;y_old = ypos
	
	ldy	#playerConfig_s.ypos
	lda 	(ZA0),y	
	ldy	#playerConfig_s.ypos_old
	sta 	(ZA0),y
	
	;get gfx programm and execute (will rts, so jump)
	
	ldy	#playerConfig_s.gfxPrg
	lda	(ZA0),y
	sta	ZA1
	iny
	lda	(ZA0),y
	sta	ZA1+1	
	jmp	(ZA1)
		
	;gfx as programm ZA3 is dest
	
duckGfx
	
	;first
	
	ldy	#0
        lda	#%00011000
	sta	(ZA3),y	;M = (ZA3)+y ; M = A
	iny
        lda	#%00111100
	sta	(ZA3),y
	iny
        lda	#%01111110
	sta	(ZA3),y
	iny
        lda	#%11111111
	sta	(ZA3),y
	iny
        lda	#%10011001
	sta	(ZA3),y
	iny
        lda	#%10000001
	sta	(ZA3),y
	iny
        lda	#%01100110
	sta	(ZA3),y
	iny
        lda	#%00000000
	sta	(ZA3),y
	
	;second
	
	lda	ZA3+1	;high
	clc	
	adc	#1	;+256 (next player PM)
	sta	ZA3+1	
	
	ldy	#0
        lda	#%10000001
	sta	(ZA3),y	;M = (ZA3)+y ; M = A
	iny
        lda	#%00011000
	sta	(ZA3),y
	iny
        lda	#%00011000
	sta	(ZA3),y
	iny
        lda	#%00011000
	sta	(ZA3),y
	iny
        lda	#%00011000
	sta	(ZA3),y
	iny
        lda	#%00011000
	sta	(ZA3),y
	iny
        lda	#%00011000
	sta	(ZA3),y
	iny
        lda	#%10000001
	sta	(ZA3),y
	
	rts
	
	;clear program ZA3 is dest (not second player is not cleared yet)
	
clearGfx
	lda	#0
	ldy	#0
	.rept	8
	sta	(ZA3),y
	iny
	.endr
	
	rts

;************************************************
;*
;* vertical blank interrupt (immidiate, x,y regs save bei os rom)
;*
;************************************************

vbi_irq

	;
	
	;prolog (like XITVBL)
	
	pla					  
	tay
	pla					  
	tax
	pla					  
	rti
		
;************************************************
;*
;* display list interrupt
;*
;************************************************

dli_irq

	;prolog

        pha 
	txa	
	pha
	tya	
	pha
	
	;
	
	;epilog
	
        pla					  
	tay
	pla					  
	tax
	pla
        rti   	;direct (no stack used)
        
	
; display list

	;7	6	5	4	3	2	1	0
	;DLI	LMS	VSCROLL	HSCOLL	Mode
	;
	;Mode 0 Blank lines 7..4 is count+1 of blank lines
	;Mode 1 JMP (use with LMS to set destination)
	;Mode $2-$f is ANTIC mode
		
	 .align $400
	 
displayList	 
	.byte 0			   ; Mode 0
	.byte $70,$70,$70  ; 8 blank lines (mode 0) * 3
	.byte $47,<charData,>charData  ; Mode 7 + LMS, setting screen memory to $4000
	.byte $7 ;1
	.byte $7 ;2
	.byte $7 ;3
	.byte $7 ;4
	.byte $7 ;5
	.byte $7 ;6
	.byte $7 ;7
	.byte $7 ;8 
	.byte $7 ;9 
	.byte $7 ;10
	.byte $7 ;11
	.byte $41,<displayList,>displayList ; wait vblank, restart same display list on next frame	
	
	
	org	$4000
	 
	;note here its a 8x16 pixel mode
	
charData

	;20 chars per screen width (20*8 = 160Pixel)
	;12 char height (12*16 = 192 (/2))

	;        --------------------
	.byte	"/------------------\" ;0
	.byte	"                    " ;1
	.byte	" multicolor sprites " ;2
	.byte	" test               " ;3
	.byte	"                    " ;4
	.byte	"                    " ;4
	.byte	"                    " ;5
	.byte	"                    " ;6
	.byte	"                    " ;7
	.byte	"                    " ;8
	.byte	"                    " ;9
	.byte	"                    " ;10
	.byte	"\------------------/" ;11        
        
	
	;there are 4 player and 4 missile "sprites"
	;player width is 8 pixel
	;missile width is 2 pixels
	;player missile pair have unique color (0,1,2,3)
	;height is 128 or 256 lines
	
	org	$4800
	
;+--------+--------------------+--------------------+
;| Offset | Double Line        | Single Line        |
;+--------+--------------------+--------------------+
;| +128   | unused             | unused             |
;+--------+--------------------+--------------------+
;| +256   |                    |                    |
;+--------+--------------------+--------------------+
;| +384   | M3   M2   M1   M0  |                    |
;+--------+--------------------+--------------------+
;| +512   | Player 0           |                    |
;+--------+--------------------+--------------------+
;| +640   | Player 1           |                    |
;+--------+--------------------+--------------------+
;| +768   | Player 2           | M3   M2   M1   M0  |
;+--------+--------------------|                    |
;| +896   | Player 3           |                    |
;+--------+--------------------+--------------------+
;| +1024  |                    | Player 0           |
;|        |                    |                    |
;+--------+--------------------+--------------------+
;| +1280  |                    | Player 1           |
;|        |                    |                    |
;+--------+--------------------+--------------------+
;| +1536  |                    | Player 2           |
;|        |                    |                    |
;+--------+--------------------+--------------------+
;| +1792  |                    | Player 3           |
;|        |                    |                    |
;+--------+--------------------+--------------------+

playerMissleBlock
