;**************************************************************************
;*
;* move four player sprite
;*
;**************************************************************************

	;.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 	#$2F
        sta 	COLPM1
        lda 	#$3F
        sta 	COLPM2
        lda 	#$70
        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
	
	;
	
	lda	#1		;player forground
	sta	PRIOR
	
	;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
	
	;
	
	cli		;irq enable

	
	
	;
loop
	;Wait VBlank

?WaitVC0
        lda	VCOUNT		
        beq	?WaitVC0   	
?WaitVCnot0
        lda	VCOUNT		
        bne	?WaitVCnot0   	                
	
	;

	inc	counter
	
	;update play configs
	
	ldx	counter
	jsr	getSinCos

	txa
	add	#124
	sta	playConfig1+playerConfig_s.xpos

	tya
	add	#124
	sta	playConfig1+playerConfig_s.ypos
	
	ldx	counter
	txa
	add	#32
	tax
	jsr	getSinCos

	txa
	add	#124
	sta	playConfig2+playerConfig_s.xpos

	tya
	add	#124
	sta	playConfig2+playerConfig_s.ypos
	
	ldx	counter
	txa
	add	#64
	tax
	jsr	getSinCos

	txa
	add	#124
	sta	playConfig3+playerConfig_s.xpos

	tya
	add	#124
	sta	playConfig3+playerConfig_s.ypos
	
	ldx	counter
	txa
	add	#93
	tax
	jsr	getSinCos

	txa
	add	#124
	sta	playConfig4+playerConfig_s.xpos

	tya
	add	#124
	sta	playConfig4+playerConfig_s.ypos

	;
	
	lda	#<playConfig1
	sta	ZA0
	lda	#>playConfig1
	sta	ZA0+1
	
	jsr	drawSprite
	
	lda	#<playConfig2
	sta	ZA0
	lda	#>playConfig2
	sta	ZA0+1
	
	jsr	drawSprite
	
	lda	#<playConfig3
	sta	ZA0
	lda	#>playConfig3
	sta	ZA0+1
	
	jsr	drawSprite
	
	.ifdef DEBUG
	lda	#$ae	
	sta	COLBK
	.endif
	
	lda	#<playConfig4
	sta	ZA0
	lda	#>playConfig4
	sta	ZA0+1

	jsr	drawSprite
	
	.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
		hposOffset	.byte
	.ends

playConfig1	.word	duckGfx				;gfx copy programm
		.word	clearGfx			;gfx clear programm
		.word	playerMissleBlock+1024+8	;destination in PGM
		.byte	120				;xpos
		.byte	40				;ypos
		.byte	1				;ypos_old
		.byte	0				;hpos reg offset
	
playConfig2	.word	alienGfx			;gfx copy programm
		.word	clearGfx			;gfx clear programm
		.word	playerMissleBlock+1280+8	;destination in PGM
		.byte	120				;xpos
		.byte	40				;ypos
		.byte	1				;ypos_old
		.byte	1				;hpos reg offset

playConfig3	.word	shieldGfx			;gfx copy programm
		.word	clearGfx			;gfx clear programm
		.word	playerMissleBlock+1536+8	;destination in PGM
		.byte	90				;xpos
		.byte	60				;ypos
		.byte	1				;ypos_old
		.byte	2				;hpos reg offset

playConfig4	.word	rocketGfx			;gfx copy programm
		.word	clearGfx			;gfx clear programm
		.word	playerMissleBlock+1792+8	;destination in PGM
		.byte	60				;xpos
		.byte	70				;ypos
		.byte	1				;ypos_old
		.byte	3				;hpos reg offset		
	
;************************************************************
;* 	
;* drawSprite
;* 
;* ZA0 = playerConfig
;*
;* trash y, ZA1-ZA3
;*
;************************************************************
	
drawSprite
			
	;get xpos and set to HPOS P0
	
	lda	#<HPOSP0
	sta	ZA1
	lda	#>HPOSP0
	sta	ZA1+1
	
	;
	
	ldy	#playerConfig_s.hposOffset
	lda	(ZA0),y
	sta	ZA2		;hposOffset
	ldy	#playerConfig_s.xpos
	lda	(ZA0),y		;y
	ldy	ZA2
	sta	(ZA1),y
	
	;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
	
	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
	rts
	
alienGfx

	ldy	#0
        lda	#%00111100
	sta	(ZA3),y
	iny
        lda	#%01111110
	sta	(ZA3),y
	iny
        lda	#%11011011
	sta	(ZA3),y
	iny
        lda	#%11111111
	sta	(ZA3),y
	iny
        lda	#%10111101
	sta	(ZA3),y
	iny
        lda	#%00100100
	sta	(ZA3),y
	iny
        lda	#%01000010
	sta	(ZA3),y
	iny
        lda	#%10000001
	sta	(ZA3),y
	rts
        
shieldGfx

	ldy	#0
        lda	#%00011000
	sta	(ZA3),y
	iny
        lda	#%00111100
	sta	(ZA3),y
	iny
        lda	#%01111110
	sta	(ZA3),y
	iny
        lda	#%11111111
	sta	(ZA3),y
	iny
        lda	#%11111111
	sta	(ZA3),y
	iny
        lda	#%01111110
	sta	(ZA3),y
	iny
        lda	#%00111100
	sta	(ZA3),y
	iny
        lda	#%00011000
	sta	(ZA3),y
	rts
      
        
rocketGfx
	
	ldy	#0
        lda	#%00011000
	sta	(ZA3),y
	iny
        lda	#%00111100
	sta	(ZA3),y
	iny
        lda	#%01111110
	sta	(ZA3),y
	iny
        lda	#%11011011
	sta	(ZA3),y
	iny
        lda	#%11111111
	sta	(ZA3),y
	iny
        lda	#%00111100
	sta	(ZA3),y
	iny
        lda	#%01111110
	sta	(ZA3),y
	iny
        lda	#%00100100
	sta	(ZA3),y
	rts
	
	;clear program ZA3 is dest
	
clearGfx
	lda	#0
	ldy	#0
	.rept	8
	sta	(ZA3),y
	iny
	.endr
	rts

;************************************************************
;*
;* getSinCos
;*
;* x is pos
;*
;* return x in x and y in y
;*
;************************************************************

getSinCos

	txa
	and	#$7f
	tax
	lda	yTable,x
	tay
	lda	xTable,x
	tax
	rts

;128
xTable	.byte	0,3,6,9,12,15,18,21,24,27,30,32,35,38,40,42,45,47,49,51,53,54,56,57,59,60,61,62,62,63,63,63,63,63,63,63,62,62,61,60,59,57,56,54,53,51,49,47,45,42,40,38,35,32,30,27,24,21,18,15,12,9,6,3,0,-3,-6,-9,-12,-15,-18,-21,-24,-27,-30,-32,-35,-38,-40,-42,-45,-47,-49,-51,-53,-54,-56,-57,-59,-60,-61,-62,-62,-63,-63,-63,-63,-63,-63,-63,-62,-62,-61,-60,-59,-57,-56,-54,-53,-51,-49,-47,-45,-42,-40,-38,-35,-32,-30,-27,-24,-21,-18,-15,-12,-9,-6,-3
yTable	.byte	64,63,63,63,62,62,61,60,59,57,56,54,53,51,49,47,45,42,40,38,35,32,30,27,24,21,18,15,12,9,6,3,0,-3,-6,-9,-12,-15,-18,-21,-24,-27,-30,-32,-35,-38,-40,-42,-45,-47,-49,-51,-53,-54,-56,-57,-59,-60,-61,-62,-62,-63,-63,-63,-63,-63,-63,-63,-62,-62,-61,-60,-59,-57,-56,-54,-53,-51,-49,-47,-45,-42,-40,-38,-35,-32,-30,-27,-24,-21,-18,-15,-12,-9,-6,-3,0,3,6,9,12,15,18,21,24,27,30,32,35,38,40,42,45,47,49,51,53,54,56,57,59,60,61,62,62,63,63,63
	
;************************************************
;*
;* 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	"XXXXXXXXXXXXXXXXXXXX" ;0
	.byte	"X                  X" ;1
	.byte	"X  lets move       X" ;2
	.byte	"X  the player      X" ;3
	.byte	"X  SpriteS         X" ;4
	.byte	"X                  X" ;5
	.byte	"X                  X" ;6
	.byte	"X                  X" ;7
	.byte	"X                  X" ;8
	.byte	"X                  X" ;9
	.byte	"X                  X" ;10
	.byte	"XXXXXXXXXXXXXXXXXXXX" ;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
