; Berzerk Benchmark tester
; -----------------------
;
; JROK 2013
;
; Purpose
; -------
;
; Run a series of tests on the berzerk hardware to count # of op-codes
; can be executed in a given frame.
;
; Use the internal 1/2 frame interrupts as a fixed time references
; and R register as the counter (R is incremented after each op-code )
;
; Actual values are not as significant as the values are for comparison
; to FPGA based hardware.
;
; The other use is to compare against a bus execution dump of the two
; hardwares boards and compare how the code is executed.
;
;
; What this does
; --------------
;
; Each area of memory had a different z80 /WAIT characterstic
;
; 1. Video frame memory
; 2. Color RAM memory
; 3. CMOS ( aka. NVRAM ) memory
;
; When accessing 1 & 2 the CPU will be halted when the video generation
; logic needs the memory for the display, so the number of opcodes that
; can be executed in the fixed 1/2 frame time period is reduced because
; of the forced wait.
;
;
; for area 3 the CPU has free unrestricted access
;
;
; Results
; -------
;
; When used for comparison purposes, the results of the counts
; from memory access must be identical. Otherwise bus timings
; are incorrectly implemented.
;
; THERE CAN BE NO VARIANCE OR SOMETHING IS VERY WRONG !!!!!
;
;
; This can be compiled TASM Z80 Assembler.Version 3.1
; http://home.comcast.net/~tasm/
;
; all the source needed is here, just burn to 2716 EPROM or
; DS1220 and replace "ROM0" on a berzerk boardset
;
CMOS_base .equ $0000
timing_ptr .equ $B00+CMOS_base
irq_flag .equ $B02+CMOS_base
nmi_count .equ $B04+CMOS_base
run_count .equ $B06+CMOS_base
timer_ptr_start .equ $a00+CMOS_base
stack_start .equ $bff+CMOS_base
IRQ_ACK .equ $4e
NMI_TEST_COUNT .equ 24
.org $0
di
xor a
out ($4d),a ; -- Clear NMI
out ($67),a ; -- Clear LED
jp start_up
; ------------
; Interrupt
; ------------
.org $38
push af
push hl
ld a, ( irq_flag )
xor 1
ld (irq_flag),a
in a, ( IRQ_ACK )
pop hl
pop af
; enable ints
ei
reti
.org $66
; -----------------
; NMI testing code
; -----------------
push af
push hl
ld a, ( nmi_count )
cp NMI_TEST_COUNT ; do a number of NMI counts
jr z, nmi_all_done
inc a
ld (nmi_count),a
ld hl, ( timing_ptr )
ld a,r
ld (hl), a
inc l
inc l
ld ( timing_ptr), hl
; reset R
xor a
ld r,a
nmi_all_done:
pop hl
pop af
retn
; ------------
; main code
; ------------
.org $100
start_up:
ld sp, stack_start ; end of SRAM area
ld hl, $4000
ld de, $4001
ld bc, $2000
ld (hl),$aa
ldir
ld hl, $8000
ld de, $8001
ld bc, $1000
ld (hl),$FF
ldir
; uncomment for looping version
;
;ld hl, 0
;ld (run_count), hl
RESTART_TESTING:
; 256 entry circular buffer
ld hl, timer_ptr_start
ld ( timing_ptr), hl
ld b,0
xor a
clr_record_mem:
ld (hl),a
inc hl
djnz clr_record_mem
; wait for BoF
; as the next IRQ would then be Top of Frame
wt_BOF:
in a, ( IRQ_ACK ) ; ALSO include frame V256
rra
jr nc, wt_BOF
; bottom of frame start up IRQ's
im 1
ld a, $ff
out ($4f),a ; IRQ's are a go
ei
; interrupts are ON
; Next IRQ will be the mid screen ( line 128 interrupt )
halt
nop
; mid screen IRQ has happened
; next interrupt will be the lower 'blanking' end of display IRQ
; at line 256
; system is now at the starting point for comparison purposes
; any comparisons should by synchronized by this point
; out to a dummy port for easier triggering of the analyzer
out ($98),a
; -----------------------------
; test 1
; ------------------------------
; memory access includes timing of hitting
; display fetch /WAIT condition
; the video frame buffer VRAM test
ld hl,( timing_ptr )
ld (hl),$AA
inc hl
ld (hl),$AA
inc hl
ld ( timing_ptr),hl
ld b,8 ; 8 tests
test1_lop1:
ld a,( irq_flag )
ld c,a
xor a
ld r,a
; each loop takes 35 cycles
; waiting for the 1/2 frame interrupt
test1_EOF:
ld de,( $4400 ) ; in VRAM space
ld a,( irq_flag )
cp c
jr z, test1_EOF
ld a,r
ld (hl),a
inc hl
inc hl
halt ; skip second IRQ in the frame
djnz test1_lop1
ld ( timing_ptr ),hl
; -----------------------------
; test 1A
; ------------------------------
; test the mid-screen IRQ
halt ; skip End-of-frame IRQ
; now waiting for mid-screen IRQ
ld hl,( timing_ptr )
ld (hl),$5A
inc hl
ld (hl),$5A
inc hl
ld ( timing_ptr),hl
ld b,8 ; 8 tests
test1a_lop1:
ld a,( irq_flag )
ld c,a
xor a
ld r,a
test1a_EOF:
ld de,( $4400 ) ; in VRAM space
ld a, ( irq_flag )
cp c
jr z, test1a_EOF
ld a,r
ld (hl),a
inc hl
inc hl
halt
djnz test1a_lop1
ld (timing_ptr),hl
; -------------------------------
; test 2
; memory access CMOS ram
; will not incur timing penalty
; --------------------------------
halt ; skip mid-screen, back to EoF irq
ld hl,( timing_ptr )
ld (hl),$44
inc hl
ld (hl),$44
inc hl
ld ( timing_ptr),hl
ld b,8 ; 8 tests
test2_lop1:
ld a,( irq_flag )
ld c,a
xor a
ld r,a
test2_EOF:
ld de,( $0800 ) ; in CMOS
ld a, ( irq_flag )
cp c
jr z, test2_EOF
ld a,r
ld (hl),a
inc hl
inc hl
halt
djnz test2_lop1
ld ( timing_ptr),hl
; -------------------------------
; test 2A mid IRQ
; memory access CMOS ram
; will not incur timing penalty
; --------------------------------
halt ; skip EOF, back to mid-screen
ld hl,( timing_ptr )
ld (hl),$4A
inc hl
ld (hl),$4A
inc hl
ld ( timing_ptr),hl
ld b,8 ; 8 tests
test2a_lop1:
ld a,( irq_flag )
ld c,a
xor a
ld r,a
test2a_EOF:
ld de,( $0800 ) ; in CMOS
ld a, ( irq_flag )
cp c
jr z, test2a_EOF
ld a,r
ld (hl),a
inc hl
inc hl
halt
djnz test2a_lop1
ld ( timing_ptr),hl
; -----------------------------
; test 3
; ------------------------------
; memory access includes timing of hitting
; COLOR RAM display fetch /WAIT
; testing the BSC board
halt ; skip mid-screen, back to EoF irq
ld hl,( timing_ptr )
ld (hl),$66
inc hl
ld (hl),$66
inc hl
ld ( timing_ptr),hl
out ($98),a
ld b,8 ; 8 tests
test3_lop1:
ld a,( irq_flag )
ld c,a
xor a
ld r,a
test3_EOF:
ld de,( $8800 ) ; in Color RAM ( BSC board )
ld a, ( irq_flag )
cp c
jr z, test3_EOF
ld a,r
ld (hl),a
inc hl
inc hl
halt
djnz test3_lop1
ld ( timing_ptr),hl
; -------------------------------
; test 3A odd
; --------------------------------
halt ; skip EOF, back to mid-screen
ld hl,( timing_ptr )
ld (hl),$6C
inc hl
ld (hl),$6C
inc hl
ld ( timing_ptr),hl
ld b,8 ; 8 tests
test3a_lop1:
ld a,( irq_flag )
ld c,a
xor a
ld r,a
test3a_EOF:
ld de,( $8800 ) ; in Color RAM ( BSC board )
ld a, ( irq_flag )
cp c
jr z, test3a_EOF
ld a,r
ld (hl),a
inc hl
inc hl
halt
djnz test3a_lop1
ld ( timing_ptr),hl
; -------------------------------
; test NMI
; NMI counting
; --------------------------------
; # of instructions that can execute
; during each NMI period
; NMI every 32 vertical lines
; except for the 7th & 8th which is 37 lines
; test 18 NMI's
; NMI timer stuff
di ; kill normal interrupts
; dummy port for analyzer triggering
out ($97),a
ld (hl), $FF
inc hl
ld (hl), $FF
inc hl
ld ( timing_ptr),hl
; # of nmi's to record
xor a
ld (nmi_count),a
; wait for bottom of frame
wt_BOF2:
in a, ( IRQ_ACK ) ; ALSO include frame V256
rra
jr nc, wt_BOF2
out ($4c),a ; -- power up the NMI
xor a
ld r,a
test7_wt_nmi_end:
ld a, ( nmi_count)
cp NMI_TEST_COUNT
jr nz,test7_wt_nmi_end
xor a
out ($4d),a ; -- no more NMI's
done_testing:
; ------------------------
; display the results
; ------------------------
di
ld l, $23 ; 2nd line of display area
ld de, timer_ptr_start + 2
ld b,3
dt_show_lop:
ld h, $45 ; screen upper
push hl
ld a,8
call show_results_hex
ld h, $4F ; lower screen
inc de
inc de
ld a,8
call show_results_hex
pop hl
inc de
inc de
ld a,l
add a, $06
ld l,a
ld h, $45
djnz dt_show_lop
; show the NMI results
ld a, NMI_TEST_COUNT
call show_results_hex
pop hl
; VRAM
ld hl, $4421
ld de, Vtxt
call print_str
; vRAM
ld hl, $4e21
ld de, Vtxt
call print_str
; CMOS
ld hl, $4427
ld de, Ctxt
call print_str
; CMOS
ld hl, $4e27
ld de, Ctxt
call print_str
; BSC color RAM
ld hl, $442d
ld de, Btxt
call print_str
; BSC color RAM
ld hl, $4e2d
ld de, Btxt
call print_str
; NMI
ld hl, $4433
ld de, Ntxt
call print_str
ld hl,(run_count)
inc hl
ld (run_count),hl
; uncomment for loopin version
; results come out the same...
;
;
;ld de, run_count
;ld hl, $5a03 ; lower screen
;ld a,1
;call show_results_hex
lopit:
; uncomment for loopin version
; results come out the same...
;
; jp RESTART_TESTING
jr lopit
; -----------------------------------------
show_results_hex:
; -----------------------------------------
push hl
push bc
ld b, a
dis_all_vals:
push hl
ld a,(de)
call print_hex
dec hl
dec hl
dec hl
inc de
ld a,(de)
call print_hex
inc de
pop hl
inc h
djnz dis_all_vals
pop bc
pop hl
ret
; -----------------------------------------
print_hex:
; -----------------------------------------
push af
rra
rra
rra
rra
and $0f
call print_char
pop af
and $0f
inc hl
call print_char
ret
; -----------------------------------------
print_str:
; -----------------------------------------
; HL = position
; DE = string (Zero terminated )
ld a,(de)
and a
ret z
call print_char
inc hl
inc de
jr print_str
; -----------------------------------------
print_char:
; -----------------------------------------
push af
push bc
push de
push hl
; HL = position on screen
; A = character to print
;
; (font) = 8 bytes
ld b,0
ld c,a
ex de,hl
ld hl, font
add hl,bc
add hl,bc
add hl,bc
add hl,bc
add hl,bc
add hl,bc
add hl,bc
add hl,bc
ld bc,32 ; add value
ex de,hl
ld a,8
pc_nc1_wr_NR:
push af
ld a,(de)
ld (hl),a
inc de
add hl,bc
pop af
dec a
jr nz, pc_nc1_wr_NR
pop hl
pop de
pop bc
pop af
ret
Vtxt: .db "VRAM",0
Btxt: .db "BSC ",0
Ctxt: .db "CMOS",0
Ntxt: .db "NMI ",0
font:
.db $00, $3C, $66, $6E, $76, $66, $3C, $00, $00, $18, $78, $18, $18, $18, $7E, $00 ; 0 1 = 0x30
.db $00, $3C, $66, $06, $3C, $60, $7E, $00, $00, $3C, $66, $1C, $06, $66, $3C, $00 ; 2 3
.db $00, $6C, $6C, $6C, $6C, $3E, $0C, $00, $00, $7E, $60, $7C, $06, $66, $3C, $00 ; 4 5
.db $00, $3C, $60, $7C, $66, $66, $3C, $00, $00, $7E, $06, $0C, $18, $18, $18, $00 ; 6 7
.db $00, $3C, $66, $3C, $66, $66, $3C, $00, $00, $3C, $66, $66, $3E, $06, $3C, $00 ; 8 9
.db $00, $3C, $66, $66, $7E, $66, $66, $00, $00, $7C, $66, $7C, $66, $66, $7C, $00 ; A B
.db $00, $3C, $66, $60, $60, $66, $3C, $00, $00, $7C, $66, $66, $66, $66, $7C, $00 ; C D
.db $00, $7E, $60, $78, $60, $60, $7E, $00, $00, $7E, $60, $78, $60, $60, $60, $00 ; E F
; @10
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $10
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $12
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $14
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $16
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $18
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $1A
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $1C
.db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 ; $1E
; @20
.db $00, $00, $00, $00, $00, $00, $00, $00, $18, $18, $18, $18, $00, $18, $18, $00 ; space !
.db $36, $36, $6C, $00, $00, $00, $00, $00, $00, $36, $7F, $36, $7F, $36, $00, $00 ; " #
.db $00, $18, $3E, $60, $3C, $06, $7C, $18, $00, $22, $74, $28, $14, $2E, $44, $00 ; $ %
.db $00, $3C, $60, $3F, $66, $66, $3C, $00, $18, $18, $30, $00, $00, $00, $00, $00 ; & '
.db $0C, $10, $30, $30, $30, $30, $10, $0C, $30, $08, $0C, $0C, $0C, $0C, $08, $30 ; ( )
.db $00, $24, $18, $7E, $18, $24, $00, $00, $00, $18, $18, $7E, $18, $18, $00, $00 ; * +
.db $00, $00, $00, $00, $00, $18, $18, $30, $00, $00, $00, $7E, $00, $00, $00, $00 ; ` -
.db $00, $00, $00, $00, $00, $18, $18, $00, $02, $06, $0C, $18, $30, $60, $40, $00 ; . /
.db $00, $3C, $66, $6E, $76, $66, $3C, $00, $00, $18, $78, $18, $18, $18, $7E, $00 ; 0 1 = 0x30
.db $00, $3C, $66, $06, $3C, $60, $7E, $00, $00, $3C, $66, $1C, $06, $66, $3C, $00 ; 2 3
.db $00, $6C, $6C, $6C, $6C, $3E, $0C, $00, $00, $7E, $60, $7C, $06, $66, $3C, $00 ; 4 5
.db $00, $3C, $60, $7C, $66, $66, $3C, $00, $00, $7E, $06, $0C, $18, $18, $18, $00 ; 6 7
.db $00, $3C, $66, $3C, $66, $66, $3C, $00, $00, $3C, $66, $66, $3E, $06, $3C, $00 ; 8 9
.db $00, $00, $18, $18, $00, $18, $18, $00, $00, $00, $18, $18, $00, $18, $18, $30 ; : ;
.db $00, $0C, $18, $30, $18, $0C, $00, $00, $00, $00, $7E, $00, $7E, $00, $00, $00 ; < =
.db $00, $30, $18, $0C, $18, $30, $00, $00, $3C, $66, $06, $1C, $00, $18, $18, $00 ; > ?
.db $00, $1E, $23, $4F, $5B, $4F, $20, $1E, $00, $3C, $66, $66, $7E, $66, $66, $00 ; @ A = 0x40
.db $00, $7C, $66, $7C, $66, $66, $7C, $00, $00, $3C, $66, $60, $60, $66, $3C, $00 ; B C
.db $00, $7C, $66, $66, $66, $66, $7C, $00, $00, $7E, $60, $78, $60, $60, $7E, $00 ; D E
.db $00, $7E, $60, $78, $60, $60, $60, $00, $00, $3C, $66, $60, $6E, $66, $3C, $00 ; F G
.db $00, $66, $66, $7E, $66, $66, $66, $00, $00, $7E, $18, $18, $18, $18, $7E, $00 ; H I
.db $00, $06, $06, $06, $06, $66, $3C, $00, $00, $66, $6C, $78, $78, $6C, $66, $00 ; J K
.db $00, $60, $60, $60, $60, $60, $7E, $00, $00, $63, $77, $7F, $6B, $63, $63, $00 ; L M
.db $00, $66, $76, $7E, $6E, $66, $66, $00, $00, $3C, $66, $66, $66, $66, $3C, $00 ; N O
.db $00, $7C, $66, $66, $7C, $60, $60, $00, $00, $3C, $66, $66, $66, $6E, $3C, $06 ; P Q = 0x50
.db $00, $7C, $66, $66, $7C, $6C, $66, $00, $00, $3C, $60, $3C, $06, $66, $3C, $00 ; R S
.db $00, $7E, $18, $18, $18, $18, $18, $00, $00, $66, $66, $66, $66, $66, $3C, $00 ; T U
.db $00, $66, $66, $66, $66, $3C, $18, $00, $00, $63, $63, $63, $6B, $7F, $36, $00 ; V W
.db $00, $66, $3C, $18, $18, $3C, $66, $00, $00, $66, $66, $3C, $18, $18, $18, $00 ; X Y
.db $00, $7E, $0C, $18, $30, $60, $7E, $00, $3C, $30, $30, $30, $30, $30, $30, $3C ; Z [
.db $40, $60, $30, $18, $0C, $06, $02, $00, $3C, $0C, $0C, $0C, $0C, $0C, $0C, $3C ; \ ]
.db $18, $2C, $46, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $7E ; ^ _
.db $00, $1C, $30, $7C, $30, $32, $7C, $00, $00, $00, $3C, $06, $3E, $66, $3E, $00 ; ` a
.db $60, $60, $7C, $66, $66, $66, $7C, $00, $00, $00, $3C, $66, $60, $66, $3C, $00 ; b c
.db $06, $06, $3E, $66, $66, $66, $3E, $00, $00, $00, $3C, $66, $7C, $60, $3C, $00
.db $1C, $36, $30, $7E, $30, $30, $30, $00, $00, $00, $3C, $66, $66, $3E, $06, $3C
.db $60, $60, $7C, $66, $66, $66, $66, $00, $18, $00, $38, $18, $18, $18, $3C, $00
.db $0C, $00, $0C, $0C, $0C, $0C, $6C, $38, $60, $60, $66, $6C, $78, $6C, $66, $00
.db $18, $18, $18, $18, $18, $18, $0E, $00, $00, $00, $FE, $DB, $DB, $DB, $DB, $00
.db $00, $00, $7C, $66, $66, $66, $66, $00, $00, $00, $3C, $66, $66, $66, $3C, $00
.db $00, $00, $7C, $66, $66, $7C, $60, $60, $00, $00, $3E, $66, $66, $3E, $06, $06
.db $00, $00, $3C, $66, $60, $60, $60, $00, $00, $00, $3C, $60, $3C, $06, $7C, $00
.db $00, $30, $7E, $30, $30, $36, $1C, $00, $00, $00, $66, $66, $66, $66, $3C, $00
.db $00, $00, $66, $66, $66, $3C, $18, $00, $00, $00, $DB, $DB, $DB, $DB, $7E, $00
.db $00, $00, $66, $3C, $18, $3C, $66, $00, $00, $00, $66, $66, $66, $3E, $06, $3C
.db $00, $00, $7E, $0C, $18, $30, $7E, $00, $1C, $30, $30, $60, $30, $30, $30, $1C
.db $08, $08, $08, $08, $08, $08, $08, $00, $38, $0C, $0C, $06, $0C, $0C, $0C, $38
.db $00, $00, $30, $5A, $0C, $00, $00, $00, $00, $1C, $22, $5D, $71, $5D, $22, $1C
; char 128 onwares
; DIP off
.db $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
.end
|
|