	.title Sean Riddle's Williams Emulation Test Suite - blitter timing tests
	;www.seanriddle.com
	;assembled with as6809
		;del willyblittime.bin
		;del willyblittime.rel
		;del willyblitttime.s19
		;as6809 -l -o -s willyblittime.asm
		;aslink -s -m -u -b _CODEF000=0xF000 -b _VECTORS=0xfff0 willyblittime.rel
		;srec_cat willyblittime.s19 -o willyblittime.bin -binary

	;3/31/2012 - split from willyemutest.asm

	;time while screen is white / $C900 bit 7 is 1

	;game hardware
	screen_end = 0x9800			;screen memory from $0000-$97FF

	ram_end = 0xc000			;RAM from $0000-$BFFF

	color_registers = 0xC000

	widget_pia_dataa = 0xC804		;control panel
	widget_pia_ctrla = 0xC805
	widget_pia_datab = 0xC806
	widget_pia_ctrlb = 0xC807

	rom_pia_dataa = 0xC80C			;coin door and sound board
	rom_pia_ctrla = 0xC80D
	rom_pia_datab = 0xC80E
	rom_pia_ctrlb = 0xC80F

	rom_enable_scr_ctrl = 0xC900		;when D0=1, reads come from ROM, not RAM

	start_blitter = 0xCA00			;special chip registers
	blitter_mask = 0xCA01
	blitter_source = 0xCA02
	blitter_dest = 0xCA04
	blitter_w_h = 0xCA06

	vidctrs = 0xcb00			;beam vertical position (6-bit)
	
	watchdog = 0xCBFF

	stack = 0xbf00				;stack pointer

	;constants
	watchdog_data = 0x39
	EOT =   0x00				;end of text flag

	;colors are stored as BB GGG RRR
	COLOR_WHITE = 0xff
	COLOR_BLUE = 0xc0
	COLOR_GRAY = 0xa4
	COLOR_GREEN = 0x38
	
	;variables
	curpos = 0xb000				;cursor position for PSTRNG 2 bytes
	
	;for blitter speed test
	tmp_blitter_source = 0xb002		;2 bytes
	tmp_blitter_dest = 0xb004		;2 bytes
	tmp_blitter_w_h = 0xb006		;2 bytes
	tmp_blitter_mask = 0xb008		;1 byte
	tmp_start_blitter = 0xb009		;1 byte
	tmp_blitter_loops = 0xb00a		;1 byte

	tmp = 0xb00b				;1 byte
			
	.area	_CODEF000			;this area will link at $F000
	
reset:
	orcc		#0xff
	lds		#stack			;set up stack pointer
	ldb		#watchdog_data
	stb		watchdog

	clr		rom_pia_ctrla		;setup ROM PIA
	clr		rom_pia_dataa
	lda		#0x3c
	sta		rom_pia_ctrla
	clr		rom_pia_ctrlb
	lda		#0xff
	sta		rom_pia_datab
	lda		#0x35
	sta		rom_pia_ctrlb
	lda		#0x3f
	sta		rom_pia_datab

	;LED countdown
	ldb		#0x09
	jsr		set_LED
	jsr		delay_2000
	ldb		#0x08
	jsr		set_LED
	jsr		delay_2000
	ldb		#0x07
	jsr		set_LED
	jsr		delay_2000
	ldb		#0x06
	jsr		set_LED
	jsr		delay_2000
	ldb		#0x05
	jsr		set_LED
	jsr		delay_2000
	ldb		#0x04
	jsr		set_LED
	jsr		delay_2000
	ldb		#0x03
	jsr		set_LED
	jsr		delay_2000
	ldb		#0x02
	jsr		set_LED
	jsr		delay_2000
	ldb		#0x01
	jsr		set_LED
	jsr		delay_2000
	ldb		#0x00
	jsr		set_LED
	jsr		delay_2000
	
	clr		widget_pia_ctrla	;setup widget PIA
	clr		widget_pia_ctrlb
	clr		widget_pia_dataa
	clr		widget_pia_datab
	lda		#0x34
	sta		widget_pia_ctrla
	lda		#0x3c			;select B controls for joystick
	sta		widget_pia_ctrlb

	lda		#0x00			;enable RAM
	sta		rom_enable_scr_ctrl

	ldb		#0x01
	jsr		set_LED

	jsr		clear_screen

	lda		#COLOR_GRAY
	sta		color_registers
	lda		#COLOR_WHITE
	sta		color_registers+1
	sta		color_registers+2
	sta		color_registers+3
	sta		color_registers+4
	sta		color_registers+5
	sta		color_registers+6
	sta		color_registers+7
	sta		color_registers+8
	sta		color_registers+9
	sta		color_registers+10
	sta		color_registers+11
	sta		color_registers+12
	sta		color_registers+13
	sta		color_registers+14
	sta		color_registers+15

	ldx		#0x1c88
	stx		curpos
	LDX		#TITLEM1
	JSR		PSTRNG

	ldb		#watchdog_data
	jsr		delay_ffff
	jsr		delay_ffff
	jsr		delay_ffff
	jsr		clear_screen
	
	ldx		#0x1c88
	stx		curpos
	LDX		#BLITM2
	JSR		PSTRNG
	ldb		#watchdog_data
	jsr		delay_ffff

;blitter timing tests
	ldy		#blit_time_start
blitloop:
	lda		#0x00			;clear a bit for external timing
	sta		rom_enable_scr_ctrl
	lda		#COLOR_BLUE
	sta		color_registers

	ldb		#watchdog_data
	jsr		delay_ffff

	lda		#COLOR_WHITE
	sta		color_registers
	lda		#0x80			;set a bit for external timing
	sta		rom_enable_scr_ctrl

	ldx		,y++
	stx		tmp_blitter_source
	lda		,y+
	sta		tmp_blitter_mask
	ldx		,y++
	stx		tmp_blitter_dest
	ldx		,y++
	stx		tmp_blitter_w_h
	lda		,y+
	sta		tmp_start_blitter	
	lda		,y+	
	sta		tmp_blitter_loops	;this many loops of 65535...
	ldx		,y++				;...plus this many more loops

	ldb		#watchdog_data
1$:
	stb		watchdog
	pshs		x			;loops remaining
	
	ldx		tmp_blitter_source
	stx		blitter_source
	lda		tmp_blitter_mask
	sta		blitter_mask
	ldx		tmp_blitter_dest
	stx		blitter_dest
	ldx		tmp_blitter_w_h
	stx		blitter_w_h
	lda		tmp_start_blitter
	sta		start_blitter	
	
	puls		x
	leax		0xffff,x
	bne		1$
	
	lda		tmp_blitter_loops
	beq		blitter_pass_done
	
	suba		#0x01
	sta		tmp_blitter_loops
	
	ldx		#0xffff
	
	bra		1$

blitter_pass_done:
	cmpy		#blit_time_end	
	blt		blitloop

	jsr		clear_screen
	lda		#COLOR_GREEN
	sta		color_registers
	
spin:
	ldb		#watchdog_data
	stb		watchdog
	bra		spin


;modes
	;Bit 0 =linear/screen source	1
	;Bit 1 =linear/screen dest		2
	;Bit 2 sync for blits from RAM, slowing 	4
	;Bit 3 tells the blitter only to blit the foreground	8
	;Bit 4 is 'solid' mode.	10
	;Bit 5 shifts the image one pixel to the right	20
	;Bit 6 says even only, bit 7 says odd only	40/80

;blitter timing parameters
blit_time_start:

		;source addr,	mask, 	dest addr, 	w/ht,		mode,	#loops
	.byte	0xf0, 0x00, 	0xff,	0x3c,0x99,	0x24,0x24,	0x02,	0x00,0xd0,0x68
		;ROM-RAM, lin src, scr dst - 60.2s actual, 60.2s in MAME0145 64-bit
			
	.byte	0x00, 0x00, 	0xff,	0x3c,0x99,	0x24,0x24,	0x06,	0x00,0x6d,0x2a
		;RAM-RAM, RAM, lin src, scr dst - 60.4s actual, 32.0s in MAME0145 64-bit
			
	.byte	0x00, 0x00, 	0xff,	0x3c,0x99,	0x24,0x24,	0x07,	0x00,0x6d,0x2a
		;RAM-RAM, RAM, scr src, scr dst - 60.4s actual, 32.0s in MAME0145 64-bit
			
	.byte	0xd0, 0x00, 	0xff,	0x3c,0x99,	0x24,0x24,	0x02,	0x00,0xd0,0x68
		;Sin SRAM-RAM, lin src, scr dst - 60.2s actual, 60.2s in MAME0145 64-bit
			
	.byte	0xd0, 0x00, 	0xff,	0x3c,0x99,	0x24,0x24,	0x03,	0x00,0xd0,0x68
		;Sin SRAM-RAM, scr src, scr dst - 60.2s actual, 60.2s in MAME0145 64-bit
			
	.byte	0xf0, 0x00, 	0x11,	0x3c,0x99,	0x24,0x24,	0x02,	0x00,0xd0,0x68
		;ROM-RAM, lin src, scr dst - 60.2s actual, 60.2s in MAME0145 64-bit

;the following masks, widths/heights and modes are taken from a MAME log for a Robotron game
;so they should be a representative sample

		;source addr,	mask, 	dest addr, 	w/ht,		mode,	#loops
	.byte	0xf0, 0x00, 	0x99,	0x3c,0x99,	0x07,0x02,	0x1a,	0x08,0x9a,0xa4
		;ROM-RAM, solid FG, lin src, scr dst - 60.2s actual, 60.2s MAME0145 64-bit
	
	.byte	0xf0, 0x00, 	0x00,	0x3c,0x99,	0x01,0x09,	0x0a,	0x05,0xf3,0xc8
		;ROM-RAM, FG, lin src, scr dst - 60.2s actual, 60.2s in MAME0145 64-bit
	
	.byte	0xf0, 0x00, 	0x00,	0x3c,0x99,	0x0c,0x0b,	0x2a,	0x04,0x5d,0x01
		;ROM-RAM, Shift FG, lin src, scr dst - 60.2s actual, 60.2s MAME0145 64-bit
														
	.byte	0x00, 0x00, 	0x00,	0x3c,0x99,	0x05,0x09,	0x56,	0x08,0x06,0xa2
		;RAM-RAM, Even Solid RAM, lin src, scr dst - 60.2s actual, 54.5s MAME0145 64-bit
														
	.byte	0x00, 0x00, 	0x46,	0x3c,0x99,	0x05,0x08,	0x46,	0x08,0x44,0x8b
		;RAM-RAM, Even RAM, lin src, scr dst - 60.2s actual, 54.5s in MAME0145 64-bit
	
blit_time_end:


	;subroutines


;delays - must ldb #watchdog_data before calling
delay_ffff:
	ldx		#0xffff
	bra		delay_x
delay_2000:
	ldx		#0x2000
	bra		delay_x
delay_600:
	ldx		#0x0600
	bra		delay_x
delay_300:
	ldx		#0x0300
delay_x:
	stb		watchdog
	leax		0xffff,x
	bne		delay_x
	rts
	

clear_screen:						;write 0x00 to 0x0000-0x97ff
	lda		#0x00
fill_screen:
	ldx		#0x0000
1$:
	sta		,x+
	stb		watchdog
	cmpx		#screen_end
	bne		1$
	rts


set_LED:
	andb		#0x0f
	tfr		b,a
	lsla
	lsla
	lsla
	lsla
	lsla
	lsla
	sta		rom_pia_datab			;set bits A & B
	tfr		b,a
	anda		#0x08
	ora		#0x34					;select Cx2 as output
	sta		rom_pia_ctrla			;set bit D
	tfr		b,a
	lsla
	anda		#0x08
	ora		#0x34
	sta		rom_pia_ctrlb			;set bit C
	ldb		#watchdog_data
	rts


PSTRNG:			;print string in X terminated with null
	lda		,x+
	beq		$pexit
	pshs 		x
	jsr		pchar
	puls		x
	bra		PSTRNG
$pexit:			rts


PHEX:			;print value in A in hex
	sta		tmp
	rora		
	rora		
	rora		
	rora		
	anda		#0x0f
	cmpa		#0x0a
	blt		$1a
	adda		#0x07
$1a:
	adda		#0x30
	jsr		pchar
	
	lda		tmp
	anda		#0x0f
	cmpa		#0x0a
	blt		$2a
	adda		#0x07
$2a:
	adda		#0x30
	jmp		pchar


pchar:			;a=ascii char to print, from space to underscore
	ldx		#badchar
	cmpa		#0x20
	blt		blitchar
	cmpa		#0x60
	bge		blitchar
	
	ldx		#font
	suba		#0x20					;space is first char
	ldb		#0x0a
	mul							;index into font table; 2 bytes wide, 5 bytes tall = 10 bytes per char
	leax		d,x
	
blitchar:
	stx		blitter_source
	lda		#0xff					;replace the current contents
	sta		blitter_mask
	ldx		curpos
	stx		blitter_dest
	ldx		#0x0601					;width and height XOR 0x04 - 2 x 5 bytes = 4 x 5 pixels, 3x5 active w/spaces
	stx		blitter_w_h
	lda		#0x1a					;start blit solid, foreground, linear to screen layout
	sta		start_blitter
	ldx 		curpos
	leax		0x0300,x				;move cursor right 1 char
	stx		curpos
	rts


	;data
	

;simple monospace 4x5 font
font:
	.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00	;space
	.byte 0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x01,0x00	;!
	.byte 0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00	;"
	.byte 0x10,0x10,0x11,0x10,0x10,0x10,0x11,0x10,0x10,0x10	;#
	.byte 0x11,0x10,0x11,0x00,0x11,0x10,0x01,0x10,0x11,0x10	;$
	.byte 0x10,0x00,0x00,0x10,0x01,0x00,0x10,0x00,0x00,0x10	;%
	.byte 0x01,0x10,0x10,0x00,0x01,0x00,0x10,0x10,0x01,0x00	;&
	.byte 0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00	;'
	.byte 0x00,0x10,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x10	;(
	.byte 0x10,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x10,0x00	;)
	.byte 0x01,0x00,0x10,0x10,0x01,0x00,0x10,0x10,0x00,0x00	;*
	.byte 0x00,0x00,0x01,0x00,0x11,0x10,0x01,0x00,0x00,0x00	;+
	.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x10,0x00	;,
	.byte 0x00,0x00,0x00,0x00,0x11,0x10,0x00,0x00,0x00,0x00	;-
	.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00	;.
	.byte 0x00,0x10,0x00,0x10,0x01,0x00,0x10,0x00,0x10,0x00	;/

	.byte 0x11,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x10	;0
	.byte 0x01,0x00,0x11,0x00,0x01,0x00,0x01,0x00,0x11,0x10
	.byte 0x11,0x10,0x00,0x10,0x11,0x10,0x10,0x00,0x11,0x10
	.byte 0x11,0x10,0x00,0x10,0x11,0x10,0x00,0x10,0x11,0x10 
	.byte 0x10,0x10,0x10,0x10,0x11,0x10,0x00,0x10,0x00,0x10
	.byte 0x11,0x10,0x10,0x00,0x11,0x10,0x00,0x10,0x11,0x10	;5
	.byte 0x11,0x10,0x10,0x00,0x11,0x10,0x10,0x10,0x11,0x10
	.byte 0x11,0x10,0x00,0x10,0x01,0x00,0x01,0x00,0x01,0x00 
	.byte 0x11,0x10,0x10,0x10,0x11,0x10,0x10,0x10,0x11,0x10
	.byte 0x11,0x10,0x10,0x10,0x11,0x10,0x00,0x10,0x00,0x10	;9
	
	.byte 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00	;:
	.byte 0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x10,0x00	;;
	.byte 0x00,0x10,0x01,0x00,0x10,0x00,0x01,0x00,0x00,0x10	;<
	.byte 0x00,0x00,0x11,0x10,0x00,0x00,0x11,0x10,0x00,0x00	;=
	.byte 0x10,0x00,0x01,0x00,0x00,0x10,0x01,0x00,0x10,0x00	;>
	.byte 0x01,0x00,0x10,0x10,0x00,0x10,0x01,0x00,0x01,0x00	;?
	.byte 0x01,0x00,0x10,0x10,0x11,0x00,0x10,0x00,0x01,0x10	;@
	
	.byte 0x11,0x10,0x10,0x10,0x11,0x10,0x10,0x10,0x10,0x10 ;A
	.byte 0x11,0x10,0x10,0x10,0x11,0x00,0x10,0x10,0x11,0x10
	.byte 0x11,0x10,0x10,0x00,0x10,0x00,0x10,0x00,0x11,0x10
	.byte 0x11,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x00
	.byte 0x11,0x10,0x10,0x00,0x11,0x00,0x10,0x00,0x11,0x10 
	.byte 0x11,0x10,0x10,0x00,0x11,0x00,0x10,0x00,0x10,0x00 
	.byte 0x11,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x11,0x10
	.byte 0x10,0x10,0x10,0x10,0x11,0x10,0x10,0x10,0x10,0x10
	.byte 0x11,0x10,0x01,0x00,0x01,0x00,0x01,0x00,0x11,0x10
	.byte 0x00,0x10,0x00,0x10,0x00,0x10,0x10,0x10,0x11,0x10
	.byte 0x10,0x10,0x10,0x10,0x11,0x00,0x10,0x10,0x10,0x10
	.byte 0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x11,0x10	;L
	.byte 0x11,0x10,0x11,0x10,0x11,0x10,0x10,0x10,0x10,0x10	;my skinny M
	.byte 0x11,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10
	.byte 0x11,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x10	;O same as 0
	.byte 0x11,0x10,0x10,0x10,0x11,0x10,0x10,0x00,0x10,0x00
	.byte 0x11,0x10,0x10,0x10,0x10,0x10,0x01,0x00,0x00,0x10
	.byte 0x11,0x10,0x10,0x10,0x11,0x00,0x10,0x10,0x10,0x10
	.byte 0x11,0x10,0x10,0x00,0x11,0x10,0x00,0x10,0x11,0x10	;S same as 5
	.byte 0x11,0x10,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00
	.byte 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x11,0x10
	.byte 0x10,0x10,0x10,0x10,0x10,0x10,0x01,0x00,0x01,0x00 
	.byte 0x10,0x10,0x10,0x10,0x11,0x10,0x11,0x10,0x11,0x10 ;my skinny W	 
	.byte 0x10,0x10,0x10,0x10,0x01,0x00,0x10,0x10,0x10,0x10
	.byte 0x10,0x10,0x10,0x10,0x11,0x10,0x01,0x00,0x01,0x00
	.byte 0x11,0x10,0x00,0x10,0x01,0x00,0x10,0x00,0x11,0x10	;Z

	.byte 0x11,0x00,0x10,0x00,0x10,0x00,0x10,0x00,0x11,0x00	;[
	.byte 0x10,0x00,0x10,0x00,0x01,0x00,0x00,0x10,0x00,0x10	;\
	.byte 0x01,0x10,0x00,0x10,0x00,0x10,0x00,0x10,0x01,0x10	;]
	.byte 0x01,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x00,0x00	;^
	.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x11,0x10	;_
	
badchar:
	.byte 0x11,0x10,0x00,0x00,0x11,0x10,0x00,0x00,0x11,0x10	;lines
		
	
TITLEM1:.FCC   'WILLIAMS EMULATION TEST SUITE V0.6'
        .byte	EOT
BLITM2:	.FCC   '       BLITTER TIMING TESTS'
        .byte	EOT

;unused space from end of code to FFEF

	.area	_VECTORS				;CPU vectors at FFF0

	.word	#reset,#reset,#reset,#reset,#reset,#reset,#reset,#reset	;point them all to start of code

	.end
