;**************************************************************************
;*
;* random (pokey) to pixel test
;*
;**************************************************************************
	
	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	
	
	;os key remove
	
	lda	#<noKeyRead
        sta	VSERINL        
        lda	#>noKeyRead
        sta	VSERINH        
		
	;color setup
	
	lda	#$0	
	sta	COLBK
	lda	#$4	
	sta	COLPF0
	lda	#$2	
	sta	COLPF1
	lda	#$6	
	sta	COLPF2
	lda	#$88				
	sta	COLPF3
				
	;disable player/missile dma
	
	lda	#$00
	sta	GRACTL
	
	;setup displays
	   
	lda	#DMACTL_DL|DMACTL_PF_NORMAL		
		
		;enable display list dma 			
		;playfield normal display (40)
			
	sta	DMACTL	;DMACTL
	
	lda	#$0
	sta	HSCROL
	
	;enable dli
	
	lda	#NMIEN_VBI|NMIEN_DLI
	sta	NMIEN	;VBI + DLI enbable
	
	lda	#$20	;1.79 MHz
	STA	AUDCTL  
	
	;
	
	cli		;irq enable
	cld		;
	

loop
	
	;Wait VBlank

;?WaitVC0
;        lda	VCOUNT		
;        beq	?WaitVC0   	
;?WaitVCnot0
;        lda	VCOUNT		
;        bne	?WaitVCnot0 

	;ldy	RANDOM
	;lda	modXTable,y
	;sta	x0
	;
	;ldy	RANDOM
	;lda	modXTable,y
	;sta	x1
	;
	;ldy	RANDOM
	;lda	modYTable,y
	;sta	y0
	;
	;ldy	RANDOM
	;lda	modYTable,y
	;sta	y1	
	
	;
	
	lda	#10
	sta	x0       
	lda	#48
	sta	y0          
	lda	#110
	sta	x1
	lda	#80
	sta	y1          
	
	jsr	drawLine
	
eloop	jmp eloop			;end
	
;* table x (0..120) y (0..80)

modXTable
	.rept	120-1
	.byte	#
	.endr
	.rept	120-1
	.byte	#
	.endr
	.rept	16-1
	.byte	#
	.endr
	
modYTable
	.rept	80-1
	.byte	#
	.endr
	.rept	80-1
	.byte	#
	.endr
	.rept	80-1
	.byte	#
	.endr
	.rept	16-1
	.byte	#
	.endr
	
	
;x0	.byte	0
;y0	.byte	0
;y0l	.byte	0
;x1	.byte	0
;y1	.byte	0	
	
	
	.define	x0    zd7
	.define	y0    zd8
	.define	y0l   zd9
	.define	x1    zd10
	.define	y1    zd11
	
	;x1>x0
	;y1>y0
	
drawLine

	lda	#<charData
	sta	za0
	lda	#>charData
	sta	za0+1
	
	;calculate sloop
	
	lda	x1
	sec
	sbc	x0	
	sta	u16_div_u8_DIV8	;dx		

	lda	y1
	sec
	sbc	y0	
	sta	u16_div_u8_DIVH	;dy
		
		
	lda	#0
	sta	y0l
	sta	u16_div_u8_DIVL	;DIVL = 0
	
	;
	lda	u16_div_u8_DIVH
	;bmi	negDivNeg
	
	
	jsr	u16_div_u8	;(dy<<8)/dx
	
	;
	
	neg16	u16_div_u8_DIVH,u16_div_u8_DIVL
		
	;x0..x1
?xLoopPositive

	;

	ldx	x0
	ldy	y0
	jsr	setPixel

	;add y0:y0l + sloop	
	
	clc	
	lda	y0l
	adc	u16_div_u8_DIVL
	sta	y0l
	lda	y0	
	adc	u16_div_u8_DIVH
	sta	y0
	
	inc	x0
	lda	x0
	cmp	x1
	bne	?xLoopPositive

	rts
		
.macro neg16 vhigh,vlo
	SEC           ; 0 - value  (Carry setzen für Subtraktion)
	LDA #$00
	SBC :vlo
	STA :vlo

	LDA #$00
	SBC :vhigh+1
	STA :vhigh+1
.endm		
		
		
;************************************************
;*
;* u16_div_u8
;* 
;* DIVH:DIVL / DIV8 -> DIVH:DIVL / REM
;*
;* waste zd12..15,a,x
;*
;************************************************

	.define	u16_div_u8_DIVH    ZD12 ;in high byte Dividend / out high Quotient
	.define	u16_div_u8_DIVL    ZD13 ;in low byte Dividend / out low Quotient	
	.define	u16_div_u8_DIV8    ZD14 ;Divisor
	.define	u16_div_u8_REM     ZD15 ;Rest

u16_div_u8
	lda	u16_div_u8_DIV8
	beq	?div_by_zero        
	
	lda	#$00                
	
	; remove comments for trace
	/*;##TRACE "DIVH:DIVL = $%02X:%02X / DIV8 = $%02X" db($db) db($dc) db($dd)*/
	
	ldx	#16    
?dloop	
	asl	u16_div_u8_DIVL     
	rol	u16_div_u8_DIVH
	rol	         
	cmp	u16_div_u8_DIV8
	bcc	?no_sub  
	sbc	u16_div_u8_DIV8     
	inc	u16_div_u8_DIVL   	
?no_sub:
	dex	
	bne ?dloop
	
	sta	u16_div_u8_REM
	
	/*;##TRACE "QH:QL = $%02X:%02X (REM = $%02X)" db($db) db($dc) db($de)*/

	clc	;all fine
	rts

?div_by_zero:
	sec	;error div by 0
	rts
	
;************************************************
;*
;* setPixel
;* 
;* x   = xpos (0..159)
;* y   = ypos (0..95)
;* za0 = dest (gfx)
;*
;* waste x,y,za1
;*
;************************************************

setPixel
	
	tya			;a = y
	asl			;* 2
	tay
	lda	?pixelYTable,y	;get y offset low
	clc
	adc	za0
	sta	za1
	iny
	lda	?pixelYTable,y	;get y offset high
	adc	za0+1
	sta	za1+1		;16 bit add to dest address
	
	txa
	and	#$7		;&7	
	tay			;store (y = x)
	
	txa
	lsr
	lsr
	lsr			;x / 8
	
	clc
	adc	za1
	sta	za1
	lda	za1+1
	adc	#0
	sta	za1+1		;add to dest address
	
	;set pixel
	
	ldx	#0
	lda	(za1,x)	
	ora	?pixelMask,y
	sta	(za1,x)	
	rts

?pixelMask

    .byte %10000000
    .byte %01000000
    .byte %00100000
    .byte %00010000
    .byte %00001000
    .byte %00000100
    .byte %00000010
    .byte %00000001
    
?pixelYTable 	.rept	96-1
		.word	#*20
		.endr
			


;************************************************
;*
;* dummy
;*
;************************************************
	
noKeyRead	
	rts
	
;************************************************
;*
;* vertical blank interrupt (immidiate, x,y regs save bei os rom)
;*
;************************************************

vbi_irq

	;
	
	lda	#0
	sta	dliCounter
	
	;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)
	
	
dliCounter	.byte	0

; 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		;8 blank lines	
	.byte $70		;8 blank lines
	.byte $70  		;DLI 8 blank lines
	.byte $4b,<charData,>charData   	;Mode b + LMS
	.rept 95
	.byte $b
	.endr
	.byte $41,<displayList,>displayList ; wait vblank, restart same display list on next frame	
	
	org	$4000
	 	
charData

	;160 x 96 (1bit)
	
	.byte	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
	.rept	94
	.byte	0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01
	.endr
	.byte	0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
	
	
