123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448 |
- ; code: language=z80-asm tabSize=8
- ; SIMULATE_ERROR = $80
- ; SIMULATE_ERROR = $3C
- .include "inc/z80.mac"
- .include "inc/spt.mac"
- ; Notes on global register allocation:
- ;
- ; This ROM doesn't work like typical Z80 code, which assumes the presence of a stack.
- ; There may in fact be no working memory in the machine for holding the stack.
- ;
- ; An overall goal for this version of the code is to run in the absence of any working
- ; ram at all. There is no stack and no RAM variables. The only storage of variables
- ; is in registers, so the registers must be carefully preserved.
- ;
- ; Without a stack, that means either saving them to other registers and restoring before
- ; jumping to other code (remembering there can be no CALLs when there is no stack)
- ; or avoiding their use altogether. These are extremely confining restrictions.
- ;
- ; Assembly purists will shudder at the extensive use of macros, but for sanity it
- ; cannot be avoided.
- ;
- ; Globally, the contents of these registers must be preserved
- ; e = bit errors in the region of memory currently being tested
- ; ix = current location in VRAM for printing messages
- ; iy = current table entry for test parameters
- ;
- VBASE equ 7c00h
- VSIZE equ 0400h
- VLINE equ 40
- .org 0000h ; z80 boot code starts at location 0
- reset:
- di ; mask INT
- im 1
- diagnostics:
- ld a,0
- out ($EC),a ; set 64 char mode
- ; ld a,0 ; byte to be written goes in A
- out ($F8),a ; blank printer port for now
- test_vram:
- SPTHREAD_BEGIN ; set up to begin running threaded code
- dw spt_playmusic, tones_welcome
- dw spt_select_test, tp_vram
- dw memtestmarch ; test the VRAM
- dw spt_check_7bit_vram
- ; dw spt_sim_error, $40
- dw spt_jp_nc, .vram_ok
- ; we have bad vram
- dw spt_chartest
- .vram_bad_loop:
- dw spt_play_testresult ; play the tones for bit errors
- dw spt_pause, $0000
- dw spt_jp,.vram_bad_loop
- .vram_7bit:
- dw spt_con_print, msg_ok7bit
- ; dw spt_play_testresult ; play the tones for bit errors
- dw spt_jp,.vram_goodtones
- .vram_ok:
- dw spt_prepare_display
- MAC_SPT_CON_GOTO 1,0
- dw spt_announcetest ; print results of VRAM tst
- ; dw print_biterrs
- dw spt_jp_e_7bit_vram, .vram_7bit
- dw spt_con_print, msg_ok8bit
- .vram_goodtones:
- dw spt_playmusic, tones_vramgood ; play the VRAM good tones
- .vram_continue:
- MAC_SPT_CON_GOTO 3,0
- dw spt_select_test, tp_16k ; load the first test
- dw spt_jp, .start
- SPT_SKIP_NMIVEC
- .start dw spt_con_goto
- MAC_SPT_CON_OFFSET 3,0
- .loop: dw spt_announcetest ; announce what test we are about to run
- dw memtestmarch ; test the current bank
- dw spt_jp_nc, .ok
-
- dw spt_con_print, msg_biterrs ; we have errors: print the bit string
- dw print_biterrs
- dw spt_play_testresult ; play the tones for bit errors
- dw spt_jp, .cont
-
- .ok: dw spt_con_print, msg_testok ; bank is good: print the OK message
- dw spt_play_testresult ; play the tones
- .cont:
- dw spt_tp_next, .start
- dw spt_jp, .loop
- ;; -------------------------------------------------------------------------------------------------
- ;; end of main program.
- spt_prepare_display:
- SPTHREAD_ENTER
- dw con_clear
- dw spt_con_print, msg_banner ; print the banner
- dw spt_print_charset
- dw spt_exit
- spt_check_vram_contents:
- pop bc
- ld a,b
- ld d,c
- ; confirm that all of VRAM contains the value in register A
- check_vram_contents:
- ld hl,VBASE
- ld bc,VSIZE
- .fillloop:
- ld (HL),a
- cpi
- jp pe,.fillloop
- ld hl,VBASE
- ld bc,VSIZE
- ld a,d
- .readloop:
- cpi
- jr nz,.bad
- jp pe,.readloop
- or a ; clear carry flag
- ret
- .bad: scf
- ret
- spt_check_7bit_vram:
- ret nc ; if carry flag is not set, do nothing
- ld a,01000000b
- cp e
- jr z,.scantests
- scf ; something other than bit 6 is bad, so this is not 7bit VRAM
- ret
- .scantests:
- SPTHREAD_ENTER
- dw spt_check_vram_contents, $0040
- dw spt_jp_c, .exit
- dw spt_check_vram_contents, $FFBF
- dw spt_jp_c, .exit
- dw spt_check_vram_contents, $AAAA
- dw spt_jp_c, .exit
- dw spt_check_vram_contents, $5555
- dw spt_jp_c, .exit
- .exit: dw spt_exit ; if carry flag is set, this is not good 7-bit VRAM
- spt_sim_error:
- pop de
- scf
- ret
- ; test if the error is $FF (all bits bad)
- spt_jp_all_bits_bad:
- pop hl ; get the address for jumping if match
- ld a,$FF ; check for all bits bad
- cp e
- ret nz ; return without jump if there is NOT a match
- ld sp,hl ; else jump to the requested location
- ret
- ; test if the e register matches 7-bit vram and jump to spt address if match
- spt_jp_e_7bit_vram:
- pop hl ; get the address for jumping if match
- ld a,01000000b ; ignore bit 6
- cp e ; see if there are other errors
- ret nz ; return without jump if there is NOT a match
- ld sp,hl ; else jump to the requested location
- ret
- ; test if the e register matches 7-bit vram and jump to spt address if match
- spt_jp_e_zero:
- pop hl ; get the address for jumping if match
- ld a,0 ; test clean
- cp e ; see if there are other errors
- ret nz ; return without jump if there is NOT a match
- ld sp,hl ; else jump to the requested location
- ret
- ; load the label string address from the current test parameter table entry into hl
- spt_ld_hl_tp_label:
- ld l,(iy+4)
- ld h,(iy+5)
- ret
- ; load the label string address from the current test parameter table entry into hl
- spt_ld_hl_tp_tones:
- ld l,(iy+6)
- ld h,(iy+7)
- ret
- spt_ld_new_line:
- ld a,(iy+9)
- ld ixh,a
- ld a,(iy+8)
- ld ixl,a
- ret
- ; move to the next test parameter table entry
- spt_tp_next: pop hl ; get the address to jump to if we are starting over
- ld bc,tp_size ; find the next entry
- add iy,bc
- ld a,(iy+0) ; is the length zero?
- add a,(iy+1)
- ret nz ; no, use it
- ld c,(iy+2) ; yes, get the address of the first entry
- ld b,(iy+3)
- ld iy,0
- add iy,bc
- ; sub a ; clear zero flag when restarting
- ld sp,hl ; jump to the next location
- ret
- spt_announcetest:
- ; pop hl ; get the message to be printed
- SPTHREAD_ENTER
- dw spt_ld_new_line
- dw spt_ld_hl_tp_label
- dw con_print ; picks up message from hl
- dw spt_con_print, msg_testing
- dw spt_con_index, -9
- dw spt_exit
- spt_play_testresult:
- SPTHREAD_SAVE ; save the stack pointer
- SPTHREAD_BEGIN
- dw spt_ld_hl_tp_tones ; play the ID tune for current bank
- dw playmusic
- dw spt_pause, $2000
- SPTHREAD_END
- ld a,$FF
- cp e
- jr z,.allbad ; if all bits bad, play shorter tune
- cpl
- cp e
- jr z,.allgood ; if all bits good, play shorter tune
- ld d,8 ; play bit tune for each bit, high to low
- .showbit:
- rlc e
- jr nc,.zero
- ld hl,tones_bitbad
- jr .msbe_cont
- .zero:
- ld hl,tones_bitgood
- .msbe_cont:
- SPTHREAD_BEGIN
- dw playmusic
- dw spt_pause, $2000
- SPTHREAD_END
- ; pause $4000
- dec d
- jr nz,.showbit
- jr .done
- .allbad:
- SPTHREAD_BEGIN
- dw spt_playmusic, tones_bytebad
- dw spt_pause, $8000
- SPTHREAD_END
- jr .done
- .allgood:
- SPTHREAD_BEGIN
- dw spt_playmusic, tones_bytegood
- dw spt_pause, $8000
- SPTHREAD_END
- .done:
- SPTHREAD_RESTORE ; restore the stack pointer
- ret
- spt_pause:
- pop bc
- ; pause by an amount specified in BC
- pause_bc:
- .loop:
- dec bc
- ld a,b
- or c
- jr nz,.loop
- ret
- print_biterrs:
- ld a,'7'
- ld b,8
- .showbit:
- rlc e
- jr nc,.zero
- ld (ix+0),a
- jr .cont
- .zero:
- ld (ix+0),'.'
- .cont:
- inc ix
- dec a
- djnz .showbit
- ret
- spt_ld_bc: pop bc
- ret
- spt_ld_line1_pos:
- ld ix,(pos_line1_text)
- ret
- spt_ld_line2_pos:
- ld ix,(pos_line2_text)
- ret
- spt_ld_line3_pos:
- ld ix,(pos_line3_text)
- ret
- spt_print_charset:
- ld a,ixh
- ld h,a
- ld a,ixl
- ld l,a
- xor a
- ld ix,(pos_char_text)
- SPTHREAD_ENTER
- ;MAC_SPT_CON_GOTO 9,24
- dw spt_con_print, msg_charset ; show a copy of the character set
- dw spt_ld_line1_pos
- dw spt_ld_bc, $e0
- dw do_charset_ix
- dw spt_exit
- spt_chartest:
- ld ix,VBASE
- ld bc,VSIZE
-
- do_charset_ix:
- ld a,32
- .charloop:
- ld (ix+0),a ; copy A to byte pointed by HL
- inc a ; increments A
- inc ix
- cp 048h
- jp nz,.cont2
- ld ix,(pos_line2_text)
- .cont2:
- cp 070h
- jp nz,.cont3
- ld ix,(pos_line3_text)
- .cont3:
- cp 098h
- jp nz,.cont4
- ld ix,(pos_line4_text)
- .cont4:
- cp 0c0h
- jp nz,.cont5
- ld ix,(pos_line5_text)
- .cont5:
- cp 0e8h
- jp nz,.cont6
- ld ix,(pos_line6_text)
- .cont6:
- cpi ; increments HL, decrements BC (and does a CP)
- jp pe, .charloop
- ret
- label_vram: dbz " 1K VRAM 7C00-7FFF "
- label_dram16k1: dbz "16K DRAM C000-FFFF "
- label_dram16k2: dbz " 8K DRAM 8000-9FFF "
- label_dram16k3: dbz " 8K DRAM A000-BFFF "
- label_sram2k1: dbz " 2K SRAM 5000-57FF "
- label_sram2k2: dbz " 2K VRAM 5800-58FF "
- msg_banner: dbz "ABC80-TEST ROM -- FRANK / DAVE / ADRIAN"
- msg_charset: dbz "-CHARACTER SET-"
- ; msg_testing: db " ", " "+$80, "t"+$80, "e"+$80, "s"+$80, "t"+$80, " "+$80, " ", 0
- msg_testing: dbz "..TEST.. "
- msg_testok: dbz "---OK--- "
- msg_biterrs: dbz "BIT ERRS "
- msg_ok7bit: dbz "OK! (7-BIT MODEL 1)"
- msg_ok8bit: dbz "OK! (8-BIT)"
- msg_banktest: dbz "TESTING BANK SIZE "
- ; test parameter table. 2-byte entries:
- ; 1. size of test in bytes
- ; 2. starting address
- ; 3. address of string for announcing test
- ; 4. address of tones for identifying the test audibly
- tp_size equ 10
- memtest_ld_bc_size .macro
- ld c,(iy+0)
- ld b,(iy+1)
- .endm
- memtest_ld_hl_base .macro
- ld l,(iy+2)
- ld h,(iy+3)
- .endm
- memtest_loadregs .macro
- memtest_ld_bc_size
- memtest_ld_hl_base
- .endm
- tp_vram: dw VSIZE, VBASE, label_vram, tones_vram,$7d00
- tp_16k: dw $4000, $C000, label_dram16k1, tones_id1,$7d80
- dw $2000, $8000, label_dram16k2, tones_id1,$7e00
- dw $2000, $A000, label_dram16k3, tones_id1,$7e80
- dw $0800, $5000, label_sram2k1 , tones_id1,$7f00
- dw $0800, $5800, label_sram2k2 , tones_id1,$7f80
- dw $0000, tp_16k
- pos_char_text: dw $7c5c
- pos_line1_text: dw $7cd0
- pos_line2_text: dw $7d50
- pos_line3_text: dw $7dd0
- pos_line4_text: dw $7e50
- pos_line5_text: dw $7ed0
- pos_line6_text: dw $7f50
- include "inc/spt.asm"
- include "inc/memtestmarch.asm"
- include "inc/abc80con.asm"
- include "inc/trs80music.asm"
|