123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633 |
- ; 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 03000h
- VSIZE equ 0ffeh
- VLINE equ 80
- .org 0000h ; z80 boot code starts at location 0
- reset:
- di ; mask INT
- im 1
- diagnostics:
- xor a
- out (0c0h),a ;0046 clear io, floppy control
- out (0c4h),a ;0048 clear io,Program map A base
- out (0c5h),a ;004a clear io,Program map B base
- out (0c6h),a ;004c clear io,DMA map A base
- out (0c7h),a ;004e clear io,DMA map B base
- out (0d4h),a ;0050 clear io,Hi-res color
- out (0d8h),a ;0052 clear io,Hi-res start
- ld hl,set_regs_start
- jp set_monroe_regs
- init_continue:
- jp setupclearscreen
- screen_clear_continue:
- ld a,080h ;
- out (0d4h),a ; Setup Screen
- ld a,005h ;
- out (0a3h),a ; DART B command
- ld a,068h ;
- out (0a3h),a ; DART B command
- ld a,0f0h ; ?????
- out (0c8h),a ; Map and system control
- ;select screen memory
- ld a,004h ; Select display memory
- out (0c8h),a ; Output to screen Map and system control
- test_vram:
- SPTHREAD_BEGIN ; set up to begin running threaded code
- SPT_SKIP_NMIVEC
- 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_prepare_display
- dw spt_chartest
- .vram_bad_loop:
- ;dw spt_play_testresult ; play the tones for bit errorssetupcrt
- ;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 2,0
- dw spt_announcetest2 ; 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 1,0
- dw spt_check_size
- dw spt_jp_256_fail, .skip256
- dw spt_con_print, msg_256k
- dw spt_select_test, tp_16k_256 ; load the first test
- dw spt_jp, .start
- .skip256:
- dw spt_con_print, msg_128k
- dw spt_select_test, tp_16k ; load the first test
- dw spt_jp, .start
- .start: dw spt_con_goto
- MAC_SPT_CON_OFFSET 3,0
- .loop: dw spt_announcetest ; announce what test we are about to run
- dw memtestmarch2 ; 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_size:
- ; Check if 256k memory or 128k
- ld hl,0c000h ; Point to test address
- ld a,0a0h ; Memory bank
- ld b,$FF ; B = FF
- out (0c5h),a ;
- ld (hl),b ;
- inc a ; A = A1
- out (0c5h),a ;
- ld (hl),b ;
- dec a ; A = A0
- add b ; B = 00
- out (0c5h),a ; Select memory bank 9
- ld (hl),b ;
- dec b ; B = FF
- inc a ; A = A1
- out (0c5h),a ; Select memory bank 1
- ld (hl),b ;
- dec a ; A = A0
- out (0c5h),a ; Select memory bank 9
- ld b,(hl) ; If 256kb B should be 0
- ret
- 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_256_fail:
- pop hl ; get the address for jumping if match
- inc b
- 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 con_NL
- dw spt_ld_hl_tp_label
- dw con_print ; picks up message from hl
- dw spt_con_print, msg_testing
- dw spt_con_index, -18
- dw spt_exit
- spt_announcetest2:
- ; pop hl ; get the message to be printed
- SPTHREAD_ENTER
- dw spt_ld_hl_tp_label
- dw con_print ; picks up message from hl
- dw spt_con_print, msg_testing
- dw spt_con_index, -18
- 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,004h ; Select display memory
- out (0c8h),a ; Output to screen Map and system control
- ld a,'7'
- ld b,8
- .showbit:
- rlc e
- jr nc,.zero
- ld (ix+1),a
- jr .cont
- .zero:
- ld (ix+1),'.'
- .cont:
- inc ix
- inc ix
- dec a
- djnz .showbit
- xor a ;054b Reset map
- out (0c8h),a ;054c Reset to memory Map and system control
- ret
- spt_ld_bc: pop bc
- ret
- spt_print_charset:
-
- ld a,ixh
- ld h,a
- ld a,ixl
- ld l,a
- ld a,0
- SPTHREAD_ENTER
- MAC_SPT_CON_GOTO 15,24
- dw spt_con_print, msg_charset ; show a copy of the character set
- MAC_SPT_CON_GOTO 16,0
- dw spt_ld_bc, $100
- dw do_charset_ix
- dw spt_exit
- spt_chartest:
- ld ix,VBASE
- ld bc,VSIZE
- do_charset_ix:
- ld a,004h ; Select display memory
- out (0c8h),a ; Output to screen Map and system control
- ld a,32
- .charloop:
- ld (ix+1),a ; copy A to byte pointed by HL
- inc a ; increments A
- inc ix
- inc ix
- cpi ; increments HL, decrements BC (and does a CP)
- jp pe, .charloop
- xor a ;054b Reset map
- out (0c8h),a ;054c Reset to memory Map and system control
- ret
- screenclearloop:
- otir ;0560 out B bytes from (HL) to (C)
- set_monroe_regs:
- ld c,(hl) ; get register
- inc hl ; bump
- ld b,(hl) ;get count
- inc hl ; bump
- ld a,b ;
- and a ;
- jr nz,screenclearloop ;0568 if count not 0 loop $-8
- jp init_continue
- setupclearscreen:
- ;entry during initiation w
- xor a ; start A=0
- ld bc,00eb9h ; C=B9 B=14
- ld hl,set_up_crt ;
- setupclearloop:
- out (0b8h),a ;CRT register select
- inc a ; A++
- outi ; C)=(HL++) and B--
- jr nz,setupclearloop ; loop until B==0 (14 bytes to write) $-5
- jp screen_clear_continue
- label_vram: dbz " 4K VRAM 3000-3FFE "
- label_dram16k1: dbz "16K DRAM 0 C000-FFFF "
- label_dram16k2: dbz "16K DRAM 1 "
- label_dram16k3: dbz "16K DRAM 2 "
- label_dram16k4: dbz "16K DRAM 3 "
- label_dram16k5: dbz "16K DRAM 4 "
- label_dram16k6: dbz "16K DRAM 5 "
- label_dram16k7: dbz "16K DRAM 6 "
- label_dram16k8: dbz "16K DRAM 7 "
- label_dram64k1: dbz " 0K DRAM 0 C000-FFFF "
- label_dram64k2: dbz "16K DRAM 0 "
- label_dram64k3: dbz "32K DRAM 0 "
- label_dram64k4: dbz "48K DRAM 0 "
- label_dram64k5: dbz " 0K DRAM 1 "
- label_dram64k6: dbz "16K DRAM 1 "
- label_dram64k7: dbz "32K DRAM 1 "
- label_dram64k8: dbz "48K DRAM 1 "
- label_dram64k9: dbz " 0K DRAM 2 "
- label_dram64k10: dbz "16K DRAM 2 "
- label_dram64k11: dbz "32K DRAM 2 "
- label_dram64k12: dbz "48K DRAM 2 "
- label_dram64k13: dbz " 0K DRAM 3 "
- label_dram64k14: dbz "16K DRAM 3 "
- label_dram64k15: dbz "32K DRAM 3 "
- label_dram64k16: dbz "48K DRAM 3 "
- msg_banner: dbz "Monroe OC8820 TEST ROM -- FRANK IZ8DWF / DAVE KI3V / ADRIAN BLACK"
- msg_charset: dbz "-CHARACTER SET-"
- ; msg_testing: db " ", " "+$80, "t"+$80, "e"+$80, "s"+$80, "t"+$80, " "+$80, " ", 0
- msg_testing: dbz "..TEST.. "
- msg_128k: dbz "128K machine"
- msg_256k: dbz "256K machine"
- msg_testok: dbz "---OK--- "
- msg_biterrs: dbz "BIT ERRS "
- msg_ok7bit: dbz "OK! (7-BIT MODEL 1)"
- msg_ok8bit: dbz "OK! (8-BIT)"
- ; 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
- spt_ld_iya6 .macro
- ld a,(iy+6)
- .endm
- spt_ld_iya7 .macro
- ld a,(iy+7)
- .endm
- tp_vram: dw VSIZE, VBASE, label_vram, tones_vram
- tp_16k: dw $4000, $C000, label_dram16k1, $a100,$31e0
- dw $4000, $C000, label_dram16k2, $c100,$3280
- dw $4000, $C000, label_dram16k3, $e100,$3320
- dw $4000, $C000, label_dram16k4, $0000,$33c0
- dw $4000, $C000, label_dram16k5, $2000,$3460
- dw $4000, $C000, label_dram16k6, $4000,$3500
- dw $4000, $C000, label_dram16k7, $6000,$35a0
- dw $4000, $C000, label_dram16k8, $8000,$3640
- dw $0000, tp_16k
- tp_16k_256: dw $4000, $C000, label_dram64k1, $a100,$31e0
- dw $4000, $C000, label_dram64k2, $c100,$3280
- dw $4000, $C000, label_dram64k3, $e100,$3320
- dw $4000, $C000, label_dram64k4, $0000,$33c0
- dw $4000, $C000, label_dram64k5, $2000,$3460
- dw $4000, $C000, label_dram64k6, $4000,$3500
- dw $4000, $C000, label_dram64k7, $6000,$35a0
- dw $4000, $C000, label_dram64k8, $8000,$3640
- dw $4000, $C000, label_dram64k9, $a000,$3230
- dw $4000, $C000, label_dram64k10, $c000,$32d0
- dw $4000, $C000, label_dram64k11, $e000,$3370
- dw $4000, $C000, label_dram64k12, $0100,$3410
- dw $4000, $C000, label_dram64k13, $2100,$34b0
- dw $4000, $C000, label_dram64k14, $4120,$3550
- dw $4000, $C000, label_dram64k15, $6100,$35f0
- dw $4000, $C000, label_dram64k16, $8100,$3690
- dw $0000, tp_16k_256
-
- set_regs_start:
- defb 0b5h ;005a io port CRT register select
- defb 004h ;005b count 4
- defb 0cfh ;005c
- defb 0b8h ;005d
- defb 037h ;005e
- defb 0efh ;005f
- ;
- defb 0b4h ;0060 io port PIO A data
- defb 001h ;0061 count 1
- defb 001h ;0062
- ;
- defb 0a1h ;0063 io port DART A command
- defb 006h ;0064 count 6
- defb 048h ;0065
- defb 048h ;0066
- defb 004h ;0067
- defb 044h ;0068
- defb 005h ;0069
- defb 0eah ;006a
- ;
- defb 0a3h ;006b io port DART B command
- defb 008h ;006c count 8
- defb 048h ;006d
- defb 048h ;006e
- defb 004h ;006f
- defb 044h ;0070
- defb 001h ;0071
- defb 000h ;0072
- defb 003h ;0073
- defb 0c1h ;0074
- ;
- defb 0a5h ;0075 io port SIO A command
- defb 002h ;0076 count 2
- defb 048h ;0077
- defb 048h ;0078
- ;
- defb 0a7h ;0079 io port SIO B command
- defb 002h ;007a count 2
- defb 048h ;007b
- defb 048h ;007c
- ;
- defb 0a8h ;007d io port CTC CHANNEL 0 - Communications baud rate
- defb 002h ;007e count 2
- defb 003h ;007f
- defb 003h ;0080
- ;
- defb 0a9h ;0081 io port CTC CHANNEL 1 - AUX RS-232C baud rate
- defb 002h ;0082 count 2
- defb 003h ;0083
- defb 003h ;0084
- ;
- defb 0aah ;0085 io port CTC CHANNEL 2 - Printer baud rate
- defb 002h ;0086 count 2
- defb 057h ;0087
- defb 04eh ;0088
- ;
- defb 000h ;0089 io port reset
- defb 000h ;008a count 0 terminator
- set_up_crt:
- ;data to be output to io port B9 14 byte CRT data register
- defb 069h ;054f
- defb 050h ;0550
- defb 056h ;0551
- defb 00bh ;0552
- defb 019h ;0553
- defb 003h ;0554
- defb 018h ;0555
- defb 018h ;0556
- defb 000h ;0557
- defb 00bh ;0558
- defb 020h ;0559
- defb 000h ;055a
- defb 000h ;055b
- defb 000h ;055c
- include "inc/spt.asm"
- include "inc/memtestmarch.asm"
- include "inc/monroecon.asm"
- include "inc/trs80music.asm"
|