;**************************************************************************
;*
;* move one player sprite
;*
;**************************************************************************

	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	#$03
	sta	GRACTL
	
	;init player sprite 1
	
	lda	#<playerConfig1
	sta	ZERO_ADR0
	lda	#>playerConfig1
	sta	ZERO_ADR0+1
	
	jsr	initPlayer
	
	;init player sprite 2
	
	lda	#<playerConfig2
	sta	ZERO_ADR0
	lda	#>playerConfig2
	sta	ZERO_ADR0+1
	
	jsr	initPlayer
	
	;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	#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   	                
	
	;update player configs

	inc	sinCosCounter
	inc	sinCosCounter	;2 steps
	
	ldy	sinCosCounter
	lda	scXYTable,y	
	sta	playerConfig1.x
	iny
	lda	scXYTable,y
	sta	playerConfig1.y
	
	;player sprite 1
	
	lda	#<playerConfig1
	sta	ZERO_ADR0
	lda	#>playerConfig1
	sta	ZERO_ADR0+1
	
	;play pgm 1

	lda	#<(playerMissleBlock+1024+8)
	sta	ZERO_ADR1
	lda	#>(playerMissleBlock+1024+8)
	sta	ZERO_ADR1+1
	
	jsr	drawPlayer
	
	;player sprite 2
	
	lda	#<playerConfig2
	sta	ZERO_ADR0
	lda	#>playerConfig2
	sta	ZERO_ADR0+1
	
	;play pgm 12
	
	lda	#<(playerMissleBlock+1792+8)
	sta	ZERO_ADR1
	lda	#>(playerMissleBlock+1792+8)
	sta	ZERO_ADR1+1
	
	;;
	;jsr	drawPlayer
	
	
;+--------+--------------------+--------------------+
;| +1280  |                    | Player 1           |
;|        |                    |                    |
;+--------+--------------------+--------------------+
;| +1536  |                    | Player 2           |
;|        |                    |                    |
;+--------+--------------------+--------------------+
;| +1792  |                    | Player 3           |
;|        |                    |                    |
;+--------+--------------------+--------------------+
	
	jmp loop			;end
	
sinCosCounter	.byte	0

;

	.struct	playerConfig_s
		x	.byte
		y	.byte
		y_old	.byte
		gfxAdr	.word
	.ends

;

.define	ZERO_ADR0	$c4
.define	ZERO_ADR1	$c6
.define	ZERO_ADR2	$c8
.define	ZERO_ADR3	$ca
.define	ZERO_ADR4	$cc
.define	ZERO_ADR5	$cd
.define	ZERO_ADR6	$ce
.define	ZERO_ADR7	$d0

playerConfig1	playerConfig_s
playerConfig2	playerConfig_s
playerConfig3	playerConfig_s
playerConfig4	playerConfig_s

;***************************************************************
;*
;* initPlayer
;*
;* ZERO_ADR0 = playerConfig 
;*
;***************************************************************

initPlayer
	
	lda	#120
	ldy	#playerConfig_s.x
	sta	(ZERO_ADR0),y
	
	lda	#100
	ldy	#playerConfig_s.y
	sta	(ZERO_ADR0),y
	
	lda	#<duckGfx
	ldy	#playerConfig_s.gfxAdr
	sta	(ZERO_ADR0),y
	
	lda	#>duckGfx
	ldy	#playerConfig_s.gfxAdr+1
	sta	(ZERO_ADR0),y
	
	rts
	
;***************************************************************
;*
;* drawPlayer1
;*
;* ZERO_ADR0 = playerConfig 
;* ZERO_ADR1 = sprite gfx dest (PGM) 
;*
;* waste ZERO_ADR2 - ZERO_ADR3
;*
;***************************************************************	
	
drawPlayer	

	;move x to hw

	ldy	#playerConfig_s.x
	lda	(ZERO_ADR0),y
	sta	HPOSP0
	
	;y changed ?
	
	ldy	#playerConfig_s.y
	lda	(ZERO_ADR0),y	
	ldy	#playerConfig_s.y_old
	
	cmp	(ZERO_ADR0),y		;y == y_old
	bne	?yChanged
	
	;not changed so no copy gfx
	
	rts
	
	;copy gfx
	
?yChanged	

	;clear old gfx
	
	lda	ZERO_ADR1			;dest low
	clc
	ldy	#playerConfig_s.y_old
	adc	(ZERO_ADR0),y			;+y (old for clear)
	sta	ZERO_ADR3
	
	lda	ZERO_ADR1+1			;dest high
	adc	#0				;+y (carry)
	sta	ZERO_ADR3+1
	
	lda	#0
	.rept	8
	ldy	##	
	sta	(ZERO_ADR3),y
	.endr
	
	ldy	#playerConfig_s.y
	lda	(ZERO_ADR0),y	
	ldy	#playerConfig_s.y_old
	sta	(ZERO_ADR0),y			;y_old = y
	
	;copy new gfx
	
	ldy	#playerConfig_s.gfxAdr
	lda	(ZERO_ADR0),y
	sta	ZERO_ADR3
	
	ldy	#playerConfig_s.gfxAdr+1
	lda	(ZERO_ADR0),y
	sta	ZERO_ADR3+1			;source
	
	lda	ZERO_ADR1			;dest low
	clc
	ldy	#playerConfig_s.y
	adc	(ZERO_ADR0),y			;+y
	sta	ZERO_ADR2
	
	lda	ZERO_ADR1+1			;dest high
	adc	#0				;+y (carry)
	sta	ZERO_ADR2+1			;dest
	
	.rept	8
	ldy	##
	lda	(ZERO_ADR3),y
	sta	(ZERO_ADR2),y
	.endr

	rts
		
duckGfx
        .byte %00011000
        .byte %00111100
        .byte %01111110
        .byte %11111111
        .byte %10011001
        .byte %10000001
        .byte %01100110
        .byte %00000000
        
;        
	

;************************************************
;*
;* 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)
        
scXYTable

	.byte	140,146,142,145,144,145,147,145,149,145,152,144,154,143,156,143,159,142,161,141,163,140,165,138,167,137,169,136,171,134,173,133,175,131,177,129,178,127,180,125,181,123,182,121,184,119,185,117,186,115,187,112,187,110,188,108,189,105,189,103,189,100,189,98,189,95,189,93,189,91,189,88,189,86,188,83,187,81,187,79,186,76,185,74,184,72,182,70,181,68,180,66,178,64,176,62,175,60,173,58,171,57,169,55,167,54,165,53,163,51,161,50,159,49,156,48,154,48,152,47,149,46,147,46,144,46,142,46,139,46,137,46,134,46,132,46,130,46,127,47,125,48,123,48,120,49,118,50,116,51,114,53,112,54,110,55,108,57,106,59,104,60,102,62,101,64,99,66,98,68,97,70,95,72,94,74,93,77,92,79,92,81,91,84,90,86,90,88,90,91,90,93,90,96,90,98,90,101,90,103,90,105,91,108,92,110,92,113,93,115,94,117,95,119,97,121,98,123,99,125,101,127,103,129,104,131,106,133,108,134,110,136,112,137,114,138,116,140,118,141,121,142,123,143,125,143,128,144,130,145,132,145,135,145,137,145

	

; 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                  X" ;2
	.byte	"X                  X" ;3
	.byte	"X                  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
