;**************************************************************************
;*
;* gtia modes 0 with blur
;*
;**************************************************************************
	
	org $2000			   ;prg start

;.define	DEBUG	1	;raster debug


.define	SCREEN_HIGHT 48	;>96 not possible ??
.define SCREEN_WIDTH 40	;dont change

.define BLUR_START_Y		0	;??
.define BLUR_OFFSET		BLUR_START_Y*40

.define	RANDOM_PIXEL_MIN_Y	48-4 ;(HEIGHT-MIN_Y > 128)
.define RANDOM_PIXEL_Y_LSR	4
.define RANDOM_PIXEL_COUNT	8
	
	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        
	
	;chbase
	
	lda	#$E0
	sta	CHBASE
	
	;color setup
	
	lda	#$0	
	sta	COLBK
	lda	#$a	
	sta	COLPF0
	lda	#$e	
	sta	COLPF1
	lda	#$8	
	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
	
	;
	
	cli		;irq enable
	
	lda	#$40		;GTIA Mode 1
	sta	PRIOR

	lda	#$10		;color to modify luminance
	sta	COLBK		
	
	;
	
loop
	
	;Wait VBlank

;?WaitVC0
;        lda	VCOUNT		
;        beq	?WaitVC0   	
;?WaitVCnot0
;        lda	VCOUNT		
;        bne	?WaitVCnot0  

	.ifdef	DEBUG
	lda	#$40	
	sta	COLBK
	.endif

	;draw random pxiels
	
	jsr	drawRandomPixels
	
	;blur screen
	
	jsr	blurScreen
	
	.ifdef	DEBUG
	lda	#$10	
	sta	COLBK
	.endif
	
	
	jmp loop			;end
		
;************************************************
;*
;* 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)
	
;************************************************
;*
;* blurScreen
;*
;* 
;*
;************************************************

blurScreen

	lda	#<(charData+BLUR_OFFSET)
	sta	za0
	lda	#>(charData+BLUR_OFFSET)
	sta	za0+1
	
	lda	#<(charData+1+BLUR_OFFSET)	
	sta	za1
	lda	#>(charData+1+BLUR_OFFSET)
	sta	za1+1
	
	lda	#<(charData+2+BLUR_OFFSET)
	sta	za2
	lda	#>(charData+2+BLUR_OFFSET)
	sta	za2+1
	
	lda	#<(charData+1+SCREEN_WIDTH+BLUR_OFFSET)
	sta	za3
	lda	#>(charData+1+SCREEN_WIDTH+BLUR_OFFSET)
	sta	za3+1
	
	;columns
	
	lda	#SCREEN_HIGHT-1-BLUR_START_Y
	sta	zd15
?columnLoop
	

	;row
	
	ldy	#0
?rowLoop

	clc
	lda	(za0),y
	and	#$f
	sta	zd0
	lda	(za1),y
	and	#$f
	sta	zd1
	lda	(za2),y
	and	#$f
	sta	zd2
	lda	(za3),y
	and	#$f
	sta	zd3
	
	clc
	lda	zd0
	adc	zd1
	adc	zd1
	adc	zd1
	adc	zd2
	adc	zd3
	adc	zd3
	
	tax
	lda	?divCurveAndExpand,x
	sta	(za1),y
	
	iny
	cpy	#SCREEN_WIDTH
	bne	?rowLoop
	
	;
	
	lda	za0
	clc
	adc	#SCREEN_WIDTH
	sta	za0
	lda	za0+1
	adc	#0
	sta	za0+1
	
	lda	za1
	clc
	adc	#SCREEN_WIDTH
	sta	za1
	lda	za1+1
	adc	#0
	sta	za1+1
	
	lda	za2
	clc
	adc	#SCREEN_WIDTH
	sta	za2
	lda	za2+1
	adc	#0
	sta	za2+1
	
	lda	za3
	clc
	adc	#SCREEN_WIDTH
	sta	za3
	lda	za3+1
	adc	#0
	sta	za3+1
	
	;
	
	lda	zd15
	sec
	sbc	#1
	sta	zd15
	bne	?columnLoop
	
	
	rts
	
?divCurveAndExpand	
	.byte   $00,$00,$00,$00,$00,$00,$00,$11,$11,$11,$11,$11,$11,$11,$22,$22
        .byte   $22,$22,$22,$22,$22,$33,$33,$33,$33,$33,$33,$33,$44,$44,$44,$44
        .byte   $44,$44,$55,$55,$55,$55,$55,$55,$55,$66,$66,$66,$66,$66,$66,$66
        .byte   $77,$77,$77,$77,$77,$77,$77,$88,$88,$88,$88,$88,$88,$88,$99,$99
        .byte   $99,$99,$99,$99,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$bb,$bb,$bb,$bb,$bb
        .byte   $bb,$bb,$cc,$cc,$cc,$cc,$cc,$cc,$cc,$dd,$dd,$dd,$dd,$dd,$dd,$dd
        .byte   $ee,$ee,$ee,$ee,$ee,$ee,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
        .byte   $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff

;************************************************
;*
;* drawRandomPixels
;*
;* waste x,y,za0
;*
;************************************************	
	
drawRandomPixels

	ldx	#RANDOM_PIXEL_COUNT
	
?pixelLoop	

	;calc y

	lda	RANDOM
	.rept	RANDOM_PIXEL_Y_LSR
	lsr	
	.endr
	clc
	adc	#RANDOM_PIXEL_MIN_Y	;->y
	asl				;y*2
	tay
		
	lda	mul40,y
	sta	za0		;low
	lda	mul40+1,y
	sta	za0+1		;high
		
	;add charData
	
	clc
	lda	#<charData
	adc	za0
	sta	za0
	lda	#>charData
	adc	za0+1
	sta	za0+1
	

	;calc x
	
	ldy	RANDOM
	lda	rand255_0to80,y
	lsr			;a=x
	tay
	   	
	lda	#$ff		;color
	sta	(za0),y
	
	dex
	bne	?pixelLoop

	rts
	
	
dliCounter	.byte	0

rand255_0to80

	.byte	14, 3, 35, 31, 28, 17, 13, 69, 11, 75, 54, 4, 3, 11, 27, 29
	.byte	64, 77, 3, 71, 25, 69, 53, 28, 57, 75, 35, 0, 20, 54, 43, 35
	.byte	19, 27, 43, 13, 11, 48, 12, 45, 44, 77, 33, 5, 58, 68, 15, 48
	.byte	10, 70, 37, 46, 24, 8, 5, 29, 37, 10, 29, 12, 48, 35, 58, 46
	.byte	20, 47, 45, 26, 34, 78, 33, 20, 19, 36, 42, 12, 62, 2, 74, 35
	.byte	72, 23, 72, 21, 69, 52, 60, 19, 38, 44, 59, 53, 7, 15, 29, 48
	.byte	58, 68, 75, 71, 21, 73, 56, 58, 34, 42, 73, 26, 16, 2, 28, 38
	.byte	74, 26, 79, 14, 49, 0, 72, 75, 58, 76, 36, 58, 21, 17, 30, 74
	.byte	21, 33, 6, 12, 40, 11, 54, 7, 28, 74, 52, 26, 51, 38, 5, 66
	.byte	31, 36, 0, 4, 75, 62, 38, 29, 76, 28, 44, 58, 37, 48, 68, 74
	.byte	41, 0, 51, 42, 69, 15, 75, 72, 66, 78, 4, 18, 59, 43, 71, 63
	.byte	45, 72, 14, 61, 29, 26, 47, 68, 71, 40, 68, 58, 37, 60, 29, 39
	.byte	2, 57, 41, 26, 76, 0, 66, 59, 38, 79, 72, 31, 58, 41, 69, 11
	.byte	51, 73, 21, 40, 70, 29, 10, 69, 35, 72, 41, 7, 72, 40, 67, 76
	.byte	34, 31, 14, 23, 74, 29, 12, 77, 35, 67, 42, 58, 43, 42, 9, 61
	.byte	4, 75, 11, 27, 71, 13, 78, 39, 44, 41, 21, 59, 70, 77, 67, 78
	.byte	38, 35, 72, 49, 33, 73, 76, 71, 34, 67, 75, 72, 74, 9, 60, 6
	.byte	56, 79, 6, 27, 11, 70, 39, 75, 69, 54, 68, 59, 58, 17, 72, 75
	
mul40	.rept	96
	.word	#*40
	.endr
		
; 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
	
	.rept	SCREEN_HIGHT-1
	.byte $4f,<(charData+#*40),>(charData+#*40) 	;repeat lines
	.byte $4f,<(charData+#*40),>(charData+#*40) 
	.byte $4f,<(charData+#*40),>(charData+#*40)
	.byte $4f,<(charData+#*40),>(charData+#*40)
	.endr
	
	.byte $41,<displayList,>displayList ; wait vblank, restart same display list on next frame	
	
	org	$4000
	 
	;note here its a 8x16 pixel mode
	
charData
	
	;a nibble is the luminance based on hue of colbk (so always same hue)
	
	.rept	SCREEN_HIGHT
	.rept	SCREEN_WIDTH
	.byte	$0
	.endr
	.endr	
	
	;.rept	SCREEN_HIGHT
	;.byte	$00,$11,$22,$33,$44,$55,$66,$77,$88,$99,$aa,$bb,$cc,$dd,$ee,$ff	; 16 byte = 32 pixel
	;.byte	$01,$23,$45,$67,$89,$ab,$cd,$ef,$dc,$ba,$98,$76,$54,$32,$10,$ff	;+16 byte = 64 pixel
	;.byte	$00,$00,$00,$00,$00,$00,$00,$00	;+8 byte = 80 pixel (total 40 byte)
	;.endr
	
	
	
	
