;//--------------
.area  CONST  (REL,CON)
;//--------------

.include "fontdat.i"


pia_WIDGET_a		.equ	0xc804	
pia_WIDGET_b		.equ	0xc806	
pia_WIDGET_CB2		.equ	0xc807  ; bit 3
ROM_pia_PORT_A		.equ	0xc80c

VIDEO_line_position	.equ	0xCB00


; set the blitter registers
blit_start 	.equ 	0xCA00
blit_mask 	.equ 	0xCA01
blit_src	.equ 	0xCA02
blit_dst	.equ 	0xCA04
blit_size	.equ 	0xCA06
blit_H 		.equ 	0xCA06
blit_V 		.equ 	0xCA07


colr_dat0:
		.db	0x00,	0xf9,	0x07,	0x28
		.db	0x2f,	0x00,	0xa4,	0x15
		.db	0xc7,	0xff,	0x38,	0x17
		.db	0xcc,	0x81,	0x81,	0x2f



;// messages 
		
txt_ctr: .asciz "LAST :"
txt_min: .asciz "MIN :"
txt_max: .asciz "MAX :"
txt_avg: .asciz "AVG :"

txt_fast: .asciz "FAST"
txt_slow: .asciz "SLOW"


txt_IRQ_1: .asciz "IRQ1:"
txt_IRQ_2: .asciz "IRQ2:"
txt_IRQ_3: .asciz "IRQ3:"
txt_IRQ_4: .asciz "IRQ4:"


;//--------------
.area RAMDATA
;//--------------
dstn:			.dw	0
txtsrc:			.dw 	0
fntchr:			.db	0
overstrike: 		.db	0
txtclr:	   		.db	0
mclr:		   	.db	0

bad_blitter:		.ds	1

lst_bl_frame:		.ds	2
min_bl_frame:		.ds	2
max_bl_frame:		.ds	2

avg_bl_frame:		.ds	2
avg_bl_ptr:		.ds	2
avg_bl_arith:		.ds	4
clr_tst:		.ds	1
i_time_ptr:		.ds	1
i_times:		.ds 	2


.area romcode


 .module bench_test

 .globl boot_it

;// -------------------------------------------------------- 
boot_it: 
;// -------------------------------------------------------- 

	;// start is all up !!

	orcc #0xFF

	lds	#0xbffe	; point the stack somewhere

	clra	
	sta  	0xC900 	; ROM/RAM enable
	sta	0xC940	; color remap
	sta	0xC980	; rom select
	sta 	0xC9c0

	; clear all system memory !!
	ldx 	#0x0000
	stx	0xCA02	; src
	stx	0xCA04	; dest
	lda	#0x00
	sta	0xca01
	ldx	#0xffc0
	stx	0xCA06
	lda 	#0x10
	sta	0xCA00	
	;// -------------------------------------------------------- 
	;// 6821 inits
	;// -------------------------------------------------------- 
	; setup the 6821s
	clra
	sta 0xC805	; ctl A
	sta 0xC804	; input A	widget
	sta 0xC807	; ctl B		widget  ( widget_CB2 = bit 3 )
	sta 0xC806  ; input B
	sta 0xC80d	; ctl A		ROM
	sta 0xC80c	; input A
	sta 0xC80F	; ctl B	 	ROM
	lda	#0x3F	
	sta 	0xC80E  ; output B  ( sound output )
	; // PIA's port 
	lda	#0x04
	sta 0xC805	; ctl A - widget 
	sta 0xC807	; ctl B - widget
	sta 0xC80d	; ctl A - ROM 
	sta 0xC80f	; ctl A - ROM
	
	;// -------------------------------------------------------- 
	;// Load default colors
	;// -------------------------------------------------------- 
	ldx #colr_dat0
	ldy #0xC000
mclrset:
	ldd ,x++
	std ,y++
	cmpy #0xC010
	bne mclrset
	
	;// -------------------------------------------------------- 
	;// Rug Pattern
	;// -------------------------------------------------------- 
	;// LFSR
	ldd	#0xf7A9
fxlop:
	ldu	#0xc000	; 0x9800
t_lfl1:
	tfr	d,y
	ldx	#0
	clrb
	rola
	rolb
	abx	; 16
	clrb
	rola
	rola
	rolb	
	abx	; 14
	clrb
	rola
	rolb
	abx	; 13
	clrb
	rola
	rola
	rolb
	abx	; 11
	; x = add value
	tfr	x,d
	rorb
	tfr	y,d
	rolb
	rola
;	tfr	d,y
;	anda	0xb000
;	andb	#00
	std	,--u
;	tfr	y,d
	cmpu	#0x0000
	bne	t_lfl1
;	tfr	d,y
;
;	lda	0xb000
;	tfr	a,b
;	rolb
;	rola
;	sta	0xb000
;	tfr	y,d
;	bra	fxlop


		;// -------------------------------------------------------- 
		;// Clear Memory
		;// -------------------------------------------------------- 
clr_mem:
		ldx 	#0xA000
		stx	0xCA02	; src
		stx	0xCA04	; dest
		lda	#0x00
		sta	0xca01
		ldx	#0xd024
		stx	0xca06
		lda 	#0x10
		sta	0xCA00	;clear working RAM

		; set the stack 
		lds	#0xbffe



		;// -------------------
		;// set up IRQ
		lda	#0x34
		sta	0xc80f

		lda	#0x04
		sta 	clr_tst
		ldx	#0xb700
		stx	i_times

		; IRQ's could be turned on but don't
;		andcc	#0x00

		lda	0xc80e  	; clear PIA irq flags

		lda	#0x35	
		sta	0xc80f		; turning on interrupts

		lda	0xc80e		; clear it again in case
		
		
		; blitter/special chip type 1 or 2
		lda	#0x01
		sta	bad_blitter


		;// display text messages

		lda	#0x66
		sta 	txtclr
		sta 	overstrike
		jsr	clr_scrn


		ldx	#0x0838
		stx	dstn		
		ldx	#txt_ctr
		stx	txtsrc
		jsr	print_string_8

		ldx	#0x0840
		stx	dstn		
		ldx	#txt_min
		stx	txtsrc
		jsr	print_string_8

		ldx	#0x0848
		stx	dstn		
		ldx	#txt_max
		stx	txtsrc
		jsr	print_string_8

		ldx	#0x0850
		stx	dstn		
		ldx	#txt_avg
		stx	txtsrc
		jsr	print_string_8

		;// irq timings
		ldx	#0x0880
		stx	dstn		
		ldx	#txt_IRQ_1
		stx	txtsrc
		jsr	print_string_8

		ldx	#0x0888
		stx	dstn		
		ldx	#txt_IRQ_2
		stx	txtsrc
		jsr	print_string_8

		ldx	#0x0890
		stx	dstn		
		ldx	#txt_IRQ_3
		stx	txtsrc
		jsr	print_string_8
		
		ldx	#0x0898
		stx	dstn		
		ldx	#txt_IRQ_4
		stx	txtsrc
		jsr	print_string_8


		;// special chip/blitter areas
		ldx	#0x8030
		stx	dstn		
		ldx	#txt_fast
		stx	txtsrc
		jsr	print_string_8


		ldx	#0x8078
		stx	dstn		
		ldx	#txt_slow
		stx	txtsrc
		jsr	print_string_8





		;// short delay
		lda	#20
		jsr	delayF


		;// play a sound
		lda	#12
		sta	0xc80e

		
		lda	#0x99
		sta 	txtclr
		sta 	overstrike

		;// ---------------------------------------------------
		;// ---------------------------------------------------
		;// ---------------------------------------------------
		;//
		;// ** Timing loops
		;//
		;// ---------------------------------------------------
		;// ---------------------------------------------------
		;// ---------------------------------------------------

		
		clra
		sta	0xc9c0
		sta	0xc000

		ldd	#0xFFFF
		std 	min_bl_frame

		ldd	#0x0000
		std 	max_bl_frame

		ldd	#0xb800
		std 	avg_bl_ptr


		;// wait for frame to be middle of screen

wait_BOF_mt:
		tst	VIDEO_line_position
		bpl wait_BOF_mt


		;// trigger for the LA
		lda	#0x23
		sta 	0xCBFF


		
main_timing_loop:
		

		jsr 	get_bl_timing
		std	lst_bl_frame

		cmpd	min_bl_frame
		bcc	no_set_min_bl_frame

		std	min_bl_frame

no_set_min_bl_frame:

		cmpd	max_bl_frame
		bcs	no_set_max_bl_frame

		std	max_bl_frame

no_set_max_bl_frame:

		ldy	avg_bl_ptr
		std	,y++
		tfr	y,d
		anda	#0xB9
		std	avg_bl_ptr


		ldd	lst_bl_frame
		ldx	#0x2038
		stx	dstn
		jsr 	print_hex16


		ldd	min_bl_frame
		ldx	#0x2040
		stx	dstn
		jsr 	print_hex16

		ldd	max_bl_frame
		ldx	#0x2048
		stx	dstn
		jsr 	print_hex16


		;// display avg of last 256 samples
		ldd	#0
		ldx	#0xb800
		std	avg_bl_arith
		std	avg_bl_arith+2
nxt_bl_arith:
		pshs	a
		ldd	avg_bl_arith+2
		addd	,x++
		std	avg_bl_arith+2
		lda	#0	;// preserve carry
		adca	avg_bl_arith+1
		sta	avg_bl_arith+1

		puls a
		inca
		bne	nxt_bl_arith


		ldd	avg_bl_arith+1
		ldx	#0x2050
		stx	dstn
		jsr 	print_hex16


		lda	avg_bl_arith+3
		ldx	#0x3850
		stx	dstn
		jsr 	print_hex


		;// IRQ timings

		ldd	0xb700
		ldx	#0x2080
		stx	dstn
		jsr 	print_hex16


		ldd	0xb702
		ldx	#0x2088
		stx	dstn
		jsr 	print_hex16


		ldd	0xb704
		ldx	#0x2090
		stx	dstn
		jsr 	print_hex16


		ldd	0xb706
		ldx	#0x2098
		stx	dstn
		jsr 	print_hex16

		jmp 	main_timing_loop



;// ---------------------------------------------------
get_bl_timing:
;// ---------------------------------------------------

		; do the timing measurements


		lda 	#0xCB
		tfr 	a,dp										   
		ldx	#0		
		lda	#0xEF
wait_BOF:
		cmpa	VIDEO_line_position
		bcc wait_BOF		         	







wait_TOF:
		lda	*0x00		; zero page 'CB'00
		bmi 	wait_TOF



		;// 1kb blit
		;// to setup takes
		;// ROM to RAM 0x400 bytes
					;// cycles for reference
		
		ldx 	#0x8038		;// 3
		stx	blit_dst	;// 6  = dest

		ldx	#0xd000		;// 3
		stx	blit_src	;// 6	 = src

		ldx	#0x1414		;// 3	= 16 bytes X 16 bytes BOX
		stx	blit_size	;// 6

		lda	#0xFF		;// 2
		sta	blit_mask	;// 5

		lda 	#0x02		;// 2
		sta	blit_start	;// 5

		nop		        ;/2 
		nop		        ;/2
		nop		        ;/2


		;// slow blit 1
		ldx 	#0x8080		;// 3
		stx	blit_dst	;// 6  = dest
		
		nop		        ;/2
		nop		        ;/2
		nop		        ;/2

		;// slow blit
		lda 	#0x06		;// 2
		sta	blit_start	;// 5


		nop		        ;/2
		nop		        ;/2
		nop		        ;/2

		
		;// slow blit 1
		ldx 	#0x80A0		;// 3
		stx	blit_dst	;// 6  = dest
		
		;// slow blit
		lda 	#0x06		;// 2
		sta	blit_start	;// 5



		; // clear pending IRQ
		; // start up IRQ counting

		lda 	0xc80e	
		andcc 	#0x00
		ldx	#0xb700
		stx	i_times



		ldx	#0		;// 3
		ldb	#1		;// 2
		lda	#3		;// 2


wait_BOF2:
		abx			;// 3 increment X counting		
		cmpa	*0x00		;// 4 direct page = $CB00  
		bcs wait_BOF2		;// 3
					;// 10 cycles per count

		tfr	x,d		
		orcc #0xFF	        ;// STOP the IRQ now !!
		rts

;/* ------------------------------------------------------- */
;// irqrtn()
;/* ------------------------------------------------------- */
irq_rtn:
	pshs cc,a,b,x,y

	lda 	0xc80e		;// clear the PIA IRQ

	;// lda	clr_tst		;// flash backgroun ( not used )
	;// eora #0x6
	;// sta 0xc000


	tfr	x,y		;// save the value of 'X' counter
	ldb	i_time_ptr
	ldx	i_times
	abx
	incb
	incb
	andb	#0x07
	stb	i_time_ptr
	sty	,x	
	sta	clr_tst

	puls a,b,cc,x,y
	rti

;/* -------------------------------------------------------- */
;/* Print HEX */
;/* -------------------------------------------------------- */
print_hex16:
	pshs	b
	bsr	print_hex
	puls	a
	bsr	print_hex
	rts
;/* -------------------------------------------------------- */
;/* Print HEX */
;/* -------------------------------------------------------- */
print_hex:
	; A= number
	pshs	x,y,b,a
	ldx 	#hexstr
	tfr	a,b
	lsrb
	lsrb
	lsrb
	lsrb
	andb	#0x0f
	ldb	b,x
	anda	#0x0f
	lda	a,x
	pshs	a
	stb	fntchr
	ldb	#0xFF
	stb 	txtclr
	stb 	overstrike
	bsr	print_chr
	ldx	dstn
	leax	0x400,x
	stx	dstn
	puls	a
	sta	fntchr
	lda	#0xFF
	sta 	txtclr
	sta 	overstrike
	bsr	print_chr
	ldx	dstn
	leax	0x400,x
	stx	dstn
	puls	a,b,y,x
	rts
hexstr:
	.asciz "0123456789ABCDEF";
;/* -------------------------------------------------------- */
;/* Print 8 pixel string 
;/* -------------------------------------------------------- */
print_string_8:
	pshs	x,a	
	ldx	txtsrc
pt_nxch:
	lda	,x+
	tsta
	beq	pt_done
	sta fntchr
	pshs x
	bsr print_chr
	puls x
	lda	dstn
	adda	#0x04
	sta	dstn
	bra	pt_nxch
pt_done:
	stx	txtsrc
	puls a,x
	rts
;/* -------------------------------------------------------- */
;/* Print 8 pixel character FONT */
;/* -------------------------------------------------------- */
print_chr:
	ldx	dstn
	stx	0xCA04
	ldx	#0
	ldb fntchr
	clra
	cmpb	#0x20
	bne	pc8_not_space
	ldb	#0x3b
pc8_not_space:
	subb #0x30
	lslb
	rola ; x2
	lslb
	rola ; x4
	lslb
	rola ; x8
	lslb
	rola ; x16
	lslb
	rola ; x32
	addd	#fonta
	std 0xCA02
	ldd 	#0x0408
	jsr	do_ca06_d
	clra	
	sta 	0xCA01  ; MASK
	lda #0x12
	sta 0xCA00
pch_novs:
	lda	txtclr
	sta 0xCA01  ; MASK
	lda #0x1A
	sta 0xCA00
	rts
;/* -------------------------------------------------------- */
do_ca06_d:
;/* -------------------------------------------------------- */
	pshs 	a
	lda	bad_blitter
	tsta	
	bne	no_bad_b
	puls 	a
	std	0xCA06
	rts
no_bad_b:
	puls	a
	eora	#0x04
	eorb	#0x04
	std	0xCA06
	rts
;/* -------------------------------------------------------- */
do_ca06_x:
;/* -------------------------------------------------------- */
	pshs	a
	lda	bad_blitter
	tsta	
	bne	no_bad_bx
	puls	a
	stx	0xCA06
	rts
no_bad_bx:
	pshs d
	tfr x,d
	eora	#0x04
	eorb	#0x04
	std	0xCA06
	puls d
	rts
;// -------------------------------------------------------- */
;// Print a character 'A' to 'X' onscreen
;// -------------------------------------------------------- */
;print_a_x
pr_a_x:
	stx	0xCA04
	; addr = ( chr - 0x32 ) * 32
	clra	
	subb #0x30 ; start at '1'
	lslb
	rola 	; x2
	lslb
	rola 	; x4
	lslb
	rola 	; x8
	lslb
	rola 	; x16
	lslb
	rola 	; x32
	addd	#fonta
	std 	0xCA02
	lda #0xFF	; white text
	sta 0xCA01  ; MASK
	ldd #0x0408	
	jsr do_ca06_d
	lda #0x1A
	sta 0xCA00
	jmp	,u		; u = return address
clrscn:
	ldx #0
	ldy #0
	ldd #0
clritlop:
	std  ,x++
	sty  ,x++
	cmpx	#0xC000
	bne clritlop
  	rts
;/* ------------------------------------------------------- */
;/* Clear screen and attribs RAM
;/* ------------------------------------------------------- */
clr_scrn:
		; effects RAM
		ldx 	#0x0000
		stx	blit_src	; src
		stx	blit_dst	; dest
		lda	#0x00
		sta	blit_mask       ; mask
		ldx	#0x9CFB
		stx	blit_H		; size
		lda 	#0x16
		sta	blit_start	; clear
		rts
;/* -------------------------------------------------------- */
wait_for_frame:
;/* -------------------------------------------------------- */
wtf_tof:
		lda VIDEO_line_position
		anda #0xF0
		tsta
		bne wtf_tof
		rts
;/* ------------------------------------------------------- */
;/* Delay 'A' frames
;/* ------------------------------------------------------- */
delayF:
		ldb 	VIDEO_line_position
		andb 	#0xF0
		cmpb	#0xF0
		bne delayF
delayFl1:
		ldb 	VIDEO_line_position
		andb 	#0xF0
		bne delayFl1
		deca
		bne	delayF
		rts


.area  BOOT (REL,CON)

  	.globl reset		; fffe
  	.globl nmi_addr		; fffc
  	.globl swi_addr		; fffa
  	.globl irq_addr		; fff8
  	.globl firq_addr	; fff6
  	.globl swi2_addr	; fff4
  	.globl swi3_addr	; fff2
		

reserved:
	.dw boot_it
swi3_addr:
	.dw boot_it
swi2_addr:
	.dw boot_it
firq_addr:
	.dw boot_it
irq_addr:
	.dw irq_rtn
swi_addr:
	.dw boot_it
nmi_addr:
	.dw boot_it
reset:
	.dw boot_it