monroeoc8800diag.asm 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634
  1. ; code: language=z80-asm tabSize=8
  2. ; SIMULATE_ERROR = $80
  3. ; SIMULATE_ERROR = $3C
  4. .include "inc/z80.mac"
  5. .include "inc/spt.mac"
  6. ; Notes on global register allocation:
  7. ;
  8. ; This ROM doesn't work like typical Z80 code, which assumes the presence of a stack.
  9. ; There may in fact be no working memory in the machine for holding the stack.
  10. ;
  11. ; An overall goal for this version of the code is to run in the absence of any working
  12. ; ram at all. There is no stack and no RAM variables. The only storage of variables
  13. ; is in registers, so the registers must be carefully preserved.
  14. ;
  15. ; Without a stack, that means either saving them to other registers and restoring before
  16. ; jumping to other code (remembering there can be no CALLs when there is no stack)
  17. ; or avoiding their use altogether. These are extremely confining restrictions.
  18. ;
  19. ; Assembly purists will shudder at the extensive use of macros, but for sanity it
  20. ; cannot be avoided.
  21. ;
  22. ; Globally, the contents of these registers must be preserved
  23. ; e = bit errors in the region of memory currently being tested
  24. ; ix = current location in VRAM for printing messages
  25. ; iy = current table entry for test parameters
  26. ;
  27. VBASE equ 03000h
  28. VSIZE equ 0ffeh
  29. VLINE equ 80
  30. .org 0000h ; z80 boot code starts at location 0
  31. reset:
  32. di ; mask INT
  33. im 1
  34. diagnostics:
  35. xor a
  36. out (0c0h),a ;0046 clear io, floppy control
  37. out (0c4h),a ;0048 clear io,Program map A base
  38. out (0c5h),a ;004a clear io,Program map B base
  39. out (0c6h),a ;004c clear io,DMA map A base
  40. out (0c7h),a ;004e clear io,DMA map B base
  41. out (0d4h),a ;0050 clear io,Hi-res color
  42. out (0d8h),a ;0052 clear io,Hi-res start
  43. ld hl,set_regs_start
  44. jp set_monroe_regs
  45. init_continue:
  46. jp setupclearscreen
  47. screen_clear_continue:
  48. ld a,080h ;
  49. out (0d4h),a ; Setup Screen
  50. ld a,005h ;
  51. out (0a3h),a ; DART B command
  52. ld a,068h ;
  53. out (0a3h),a ; DART B command
  54. ld a,0f0h ; ?????
  55. out (0c8h),a ; Map and system control
  56. ;select screen memory
  57. ld a,004h ; Select display memory
  58. out (0c8h),a ; Output to screen Map and system control
  59. test_vram:
  60. SPTHREAD_BEGIN ; set up to begin running threaded code
  61. SPT_SKIP_NMIVEC
  62. dw spt_playmusic, tones_welcome
  63. dw spt_select_test, tp_vram
  64. dw memtestmarch ; test the VRAM
  65. dw spt_check_7bit_vram
  66. ; dw spt_sim_error, $40
  67. dw spt_jp_nc, .vram_ok
  68. ; we have bad vram
  69. dw spt_prepare_display
  70. dw spt_chartest
  71. .vram_bad_loop:
  72. ;dw spt_play_testresult ; play the tones for bit errorssetupcrt
  73. ;dw spt_pause, $0000
  74. dw spt_jp,.vram_bad_loop
  75. .vram_7bit:
  76. dw spt_con_print, msg_ok7bit
  77. ; dw spt_play_testresult ; play the tones for bit errors
  78. ;dw spt_jp,.vram_goodtones
  79. .vram_ok:
  80. dw spt_prepare_display
  81. MAC_SPT_CON_GOTO 2,0
  82. dw spt_announcetest2 ; print results of VRAM tst
  83. ; dw print_biterrs
  84. dw spt_jp_e_7bit_vram, .vram_7bit
  85. dw spt_con_print, msg_ok8bit
  86. .vram_goodtones:
  87. ;dw spt_playmusic, tones_vramgood ; play the VRAM good tones
  88. .vram_continue:
  89. MAC_SPT_CON_GOTO 1,0
  90. dw spt_check_size
  91. dw spt_jp_256_fail, .skip256
  92. dw spt_con_print, msg_256k
  93. dw spt_select_test, tp_16k_256 ; load the first test
  94. dw spt_jp, .start
  95. .skip256:
  96. dw spt_con_print, msg_128k
  97. dw spt_select_test, tp_16k ; load the first test
  98. dw spt_jp, .start
  99. .start: dw spt_con_goto
  100. MAC_SPT_CON_OFFSET 3,0
  101. .loop: dw spt_announcetest ; announce what test we are about to run
  102. dw memtestmarch2 ; test the current bank
  103. dw spt_jp_nc, .ok
  104. dw spt_con_print, msg_biterrs ; we have errors: print the bit string
  105. dw print_biterrs
  106. ;dw spt_play_testresult ; play the tones for bit errors
  107. dw spt_jp, .cont
  108. .ok: dw spt_con_print, msg_testok ; bank is good: print the OK message
  109. ;dw spt_play_testresult ; play the tones
  110. .cont:
  111. dw spt_tp_next, .start
  112. dw spt_jp, .loop
  113. ;; -------------------------------------------------------------------------------------------------
  114. ;; end of main program.
  115. spt_prepare_display:
  116. SPTHREAD_ENTER
  117. dw con_clear
  118. dw spt_con_print, msg_banner ; print the banner
  119. dw spt_print_charset
  120. dw spt_exit
  121. spt_check_size:
  122. ; Check if 256k memory or 128k
  123. ld hl,0c000h ; Point to test address
  124. ld a,0a0h ; Memory bank
  125. ld b,$FF ; B = FF
  126. out (0c5h),a ;
  127. ld (hl),b ;
  128. inc a ; A = A1
  129. out (0c5h),a ;
  130. ld (hl),b ;
  131. dec a ; A = A0
  132. inc b ; B = 00
  133. out (0c5h),a ; Select memory bank 9
  134. ld (hl),b ;
  135. dec b ; B = FF
  136. inc a ; A = A1
  137. out (0c5h),a ; Select memory bank 1
  138. ld (hl),b ;
  139. dec a ; A = A0
  140. out (0c5h),a ; Select memory bank 9
  141. ld b,(hl) ; If 256kb B should be 0
  142. ret
  143. spt_check_vram_contents:
  144. pop bc
  145. ld a,b
  146. ld d,c
  147. ; confirm that all of VRAM contains the value in register A
  148. check_vram_contents:
  149. ld hl,VBASE
  150. ld bc,VSIZE
  151. .fillloop:
  152. ld (HL),a
  153. cpi
  154. jp pe,.fillloop
  155. ld hl,VBASE
  156. ld bc,VSIZE
  157. ld a,d
  158. .readloop:
  159. cpi
  160. jr nz,.bad
  161. jp pe,.readloop
  162. or a ; clear carry flag
  163. ret
  164. .bad: scf
  165. ret
  166. spt_check_7bit_vram:
  167. ret nc ; if carry flag is not set, do nothing
  168. ld a,01000000b
  169. cp e
  170. jr z,.scantests
  171. scf ; something other than bit 6 is bad, so this is not 7bit VRAM
  172. ret
  173. .scantests:
  174. SPTHREAD_ENTER
  175. dw spt_check_vram_contents, $0040
  176. dw spt_jp_c, .exit
  177. dw spt_check_vram_contents, $FFBF
  178. dw spt_jp_c, .exit
  179. dw spt_check_vram_contents, $AAAA
  180. dw spt_jp_c, .exit
  181. dw spt_check_vram_contents, $5555
  182. dw spt_jp_c, .exit
  183. .exit: dw spt_exit ; if carry flag is set, this is not good 7-bit VRAM
  184. spt_sim_error:
  185. pop de
  186. scf
  187. ret
  188. ; test if B indicates 128k machine (B=$FF) and jump if so
  189. ; Note: Despite the name, this jumps on 128k detection, not 256k failure
  190. spt_jp_256_fail:
  191. pop hl ; get the address for jumping if match
  192. inc b ; B=FF becomes B=0, B=0 becomes B=1
  193. ret nz ; return without jump if B was 0 (256k machine)
  194. ld sp,hl ; else jump to the requested location (128k machine)
  195. ret
  196. ; test if the e register matches 7-bit vram and jump to spt address if match
  197. spt_jp_e_7bit_vram:
  198. pop hl ; get the address for jumping if match
  199. ld a,01000000b ; ignore bit 6
  200. cp e ; see if there are other errors
  201. ret nz ; return without jump if there is NOT a match
  202. ld sp,hl ; else jump to the requested location
  203. ret
  204. ; test if the e register matches 7-bit vram and jump to spt address if match
  205. spt_jp_e_zero:
  206. pop hl ; get the address for jumping if match
  207. ld a,0 ; test clean
  208. cp e ; see if there are other errors
  209. ret nz ; return without jump if there is NOT a match
  210. ld sp,hl ; else jump to the requested location
  211. ret
  212. ; load the label string address from the current test parameter table entry into hl
  213. spt_ld_hl_tp_label:
  214. ld l,(iy+4)
  215. ld h,(iy+5)
  216. ret
  217. ; load the label string address from the current test parameter table entry into hl
  218. spt_ld_hl_tp_tones:
  219. ld l,(iy+6)
  220. ld h,(iy+7)
  221. ret
  222. spt_ld_new_line:
  223. ld a,(iy+9)
  224. ld ixh,a
  225. ld a,(iy+8)
  226. ld ixl,a
  227. ret
  228. ; move to the next test parameter table entry
  229. spt_tp_next: pop hl ; get the address to jump to if we are starting over
  230. ld bc,tp_size ; find the next entry
  231. add iy,bc
  232. ld a,(iy+0) ; is the length zero?
  233. add a,(iy+1)
  234. ret nz ; no, use it
  235. ld c,(iy+2) ; yes, get the address of the first entry
  236. ld b,(iy+3)
  237. ld iy,0
  238. add iy,bc
  239. ; sub a ; clear zero flag when restarting
  240. ld sp,hl ; jump to the next location
  241. ret
  242. spt_announcetest:
  243. ; pop hl ; get the message to be printed
  244. SPTHREAD_ENTER
  245. dw spt_ld_new_line
  246. ;dw con_NL
  247. dw spt_ld_hl_tp_label
  248. dw con_print ; picks up message from hl
  249. dw spt_con_print, msg_testing
  250. dw spt_con_index, -18
  251. dw spt_exit
  252. spt_announcetest2:
  253. ; pop hl ; get the message to be printed
  254. SPTHREAD_ENTER
  255. dw spt_ld_hl_tp_label
  256. dw con_print ; picks up message from hl
  257. dw spt_con_print, msg_testing
  258. dw spt_con_index, -18
  259. dw spt_exit
  260. spt_play_testresult:
  261. SPTHREAD_SAVE ; save the stack pointer
  262. SPTHREAD_BEGIN
  263. dw spt_ld_hl_tp_tones ; play the ID tune for current bank
  264. ;dw playmusic
  265. dw spt_pause, $2000
  266. SPTHREAD_END
  267. ld a,$FF
  268. cp e
  269. jr z,.allbad ; if all bits bad, play shorter tune
  270. cpl
  271. cp e
  272. jr z,.allgood ; if all bits good, play shorter tune
  273. ld d,8 ; play bit tune for each bit, high to low
  274. .showbit:
  275. rlc e
  276. jr nc,.zero
  277. ld hl,tones_bitbad
  278. jr .msbe_cont
  279. .zero:
  280. ld hl,tones_bitgood
  281. .msbe_cont:
  282. SPTHREAD_BEGIN
  283. ;dw playmusic
  284. dw spt_pause, $2000
  285. SPTHREAD_END
  286. ; pause $4000
  287. dec d
  288. jr nz,.showbit
  289. jr .done
  290. .allbad:
  291. SPTHREAD_BEGIN
  292. ;dw spt_playmusic, tones_bytebad
  293. dw spt_pause, $8000
  294. SPTHREAD_END
  295. jr .done
  296. .allgood:
  297. SPTHREAD_BEGIN
  298. ;dw spt_playmusic, tones_bytegood
  299. dw spt_pause, $8000
  300. SPTHREAD_END
  301. .done:
  302. SPTHREAD_RESTORE ; restore the stack pointer
  303. ret
  304. spt_pause:
  305. pop bc
  306. ; pause by an amount specified in BC
  307. pause_bc:
  308. .loop:
  309. dec bc
  310. ld a,b
  311. or c
  312. jr nz,.loop
  313. ret
  314. print_biterrs:
  315. ld a,004h ; Select display memory
  316. out (0c8h),a ; Output to screen Map and system control
  317. ld a,'7'
  318. ld b,8
  319. .showbit:
  320. rlc e
  321. jr nc,.zero
  322. ld (ix+1),a
  323. jr .cont
  324. .zero:
  325. ld (ix+1),'.'
  326. .cont:
  327. inc ix
  328. inc ix
  329. dec a
  330. djnz .showbit
  331. xor a ;054b Reset map
  332. out (0c8h),a ;054c Reset to memory Map and system control
  333. ret
  334. spt_ld_bc: pop bc
  335. ret
  336. spt_print_charset:
  337. ld a,ixh
  338. ld h,a
  339. ld a,ixl
  340. ld l,a
  341. ld a,0
  342. SPTHREAD_ENTER
  343. MAC_SPT_CON_GOTO 15,24
  344. dw spt_con_print, msg_charset ; show a copy of the character set
  345. MAC_SPT_CON_GOTO 16,0
  346. dw spt_ld_bc, $100
  347. dw do_charset_ix
  348. dw spt_exit
  349. spt_chartest:
  350. ld ix,VBASE
  351. ld bc,VSIZE
  352. do_charset_ix:
  353. ld a,004h ; Select display memory
  354. out (0c8h),a ; Output to screen Map and system control
  355. ld a,32
  356. .charloop:
  357. ld (ix+1),a ; copy A to byte pointed by HL
  358. inc a ; increments A
  359. inc ix
  360. inc ix
  361. cpi ; increments HL, decrements BC (and does a CP)
  362. jp pe, .charloop
  363. xor a ;054b Reset map
  364. out (0c8h),a ;054c Reset to memory Map and system control
  365. ret
  366. screenclearloop:
  367. otir ;0560 out B bytes from (HL) to (C)
  368. set_monroe_regs:
  369. ld c,(hl) ; get register
  370. inc hl ; bump
  371. ld b,(hl) ;get count
  372. inc hl ; bump
  373. ld a,b ;
  374. and a ;
  375. jr nz,screenclearloop ;0568 if count not 0 loop $-8
  376. jp init_continue
  377. setupclearscreen:
  378. ;entry during initiation w
  379. xor a ; start A=0
  380. ld bc,00eb9h ; C=B9 B=14
  381. ld hl,set_up_crt ;
  382. setupclearloop:
  383. out (0b8h),a ;CRT register select
  384. inc a ; A++
  385. outi ; C)=(HL++) and B--
  386. jr nz,setupclearloop ; loop until B==0 (14 bytes to write) $-5
  387. jp screen_clear_continue
  388. label_vram: dbz " 4K VRAM 3000-3FFE "
  389. label_dram16k1: dbz "16K DRAM 0 C000-FFFF "
  390. label_dram16k2: dbz "16K DRAM 1 "
  391. label_dram16k3: dbz "16K DRAM 2 "
  392. label_dram16k4: dbz "16K DRAM 3 "
  393. label_dram16k5: dbz "16K DRAM 4 "
  394. label_dram16k6: dbz "16K DRAM 5 "
  395. label_dram16k7: dbz "16K DRAM 6 "
  396. label_dram16k8: dbz "16K DRAM 7 "
  397. label_dram64k1: dbz " 0K DRAM 0 C000-FFFF "
  398. label_dram64k2: dbz "16K DRAM 0 "
  399. label_dram64k3: dbz "32K DRAM 0 "
  400. label_dram64k4: dbz "48K DRAM 0 "
  401. label_dram64k5: dbz " 0K DRAM 1 "
  402. label_dram64k6: dbz "16K DRAM 1 "
  403. label_dram64k7: dbz "32K DRAM 1 "
  404. label_dram64k8: dbz "48K DRAM 1 "
  405. label_dram64k9: dbz " 0K DRAM 2 "
  406. label_dram64k10: dbz "16K DRAM 2 "
  407. label_dram64k11: dbz "32K DRAM 2 "
  408. label_dram64k12: dbz "48K DRAM 2 "
  409. label_dram64k13: dbz " 0K DRAM 3 "
  410. label_dram64k14: dbz "16K DRAM 3 "
  411. label_dram64k15: dbz "32K DRAM 3 "
  412. label_dram64k16: dbz "48K DRAM 3 "
  413. msg_banner: dbz "Monroe OC8820 TEST ROM -- FRANK IZ8DWF / DAVE KI3V / ADRIAN BLACK"
  414. msg_charset: dbz "-CHARACTER SET-"
  415. ; msg_testing: db " ", " "+$80, "t"+$80, "e"+$80, "s"+$80, "t"+$80, " "+$80, " ", 0
  416. msg_testing: dbz "..TEST.. "
  417. msg_128k: dbz "128K machine"
  418. msg_256k: dbz "256K machine"
  419. msg_testok: dbz "---OK--- "
  420. msg_biterrs: dbz "BIT ERRS "
  421. msg_ok7bit: dbz "OK! (7-BIT MODEL 1)"
  422. msg_ok8bit: dbz "OK! (8-BIT)"
  423. ; test parameter table. 2-byte entries:
  424. ; 1. size of test in bytes
  425. ; 2. starting address
  426. ; 3. address of string for announcing test
  427. ; 4. address of tones for identifying the test audibly
  428. tp_size equ 10
  429. memtest_ld_bc_size .macro
  430. ld c,(iy+0)
  431. ld b,(iy+1)
  432. .endm
  433. memtest_ld_hl_base .macro
  434. ld l,(iy+2)
  435. ld h,(iy+3)
  436. .endm
  437. memtest_loadregs .macro
  438. memtest_ld_bc_size
  439. memtest_ld_hl_base
  440. .endm
  441. spt_ld_iya6 .macro
  442. ld a,(iy+6)
  443. .endm
  444. spt_ld_iya7 .macro
  445. ld a,(iy+7)
  446. .endm
  447. tp_vram: dw VSIZE, VBASE, label_vram, tones_vram
  448. tp_16k: dw $4000, $C000, label_dram16k1, $a100,$31e0
  449. dw $4000, $C000, label_dram16k2, $c100,$3280
  450. dw $4000, $C000, label_dram16k3, $e100,$3320
  451. dw $4000, $C000, label_dram16k4, $0000,$33c0
  452. dw $4000, $C000, label_dram16k5, $2000,$3460
  453. dw $4000, $C000, label_dram16k6, $4000,$3500
  454. dw $4000, $C000, label_dram16k7, $6000,$35a0
  455. dw $4000, $C000, label_dram16k8, $8000,$3640
  456. dw $0000, tp_16k
  457. tp_16k_256: dw $4000, $C000, label_dram64k1, $a100,$31e0
  458. dw $4000, $C000, label_dram64k2, $c100,$3280
  459. dw $4000, $C000, label_dram64k3, $e100,$3320
  460. dw $4000, $C000, label_dram64k4, $0000,$33c0
  461. dw $4000, $C000, label_dram64k5, $2000,$3460
  462. dw $4000, $C000, label_dram64k6, $4000,$3500
  463. dw $4000, $C000, label_dram64k7, $6000,$35a0
  464. dw $4000, $C000, label_dram64k8, $8000,$3640
  465. dw $4000, $C000, label_dram64k9, $a000,$3230
  466. dw $4000, $C000, label_dram64k10, $c000,$32d0
  467. dw $4000, $C000, label_dram64k11, $e000,$3370
  468. dw $4000, $C000, label_dram64k12, $0100,$3410
  469. dw $4000, $C000, label_dram64k13, $2100,$34b0
  470. dw $4000, $C000, label_dram64k14, $4120,$3550
  471. dw $4000, $C000, label_dram64k15, $6100,$35f0
  472. dw $4000, $C000, label_dram64k16, $8100,$3690
  473. dw $0000, tp_16k_256
  474. set_regs_start:
  475. defb 0b5h ;005a io port CRT register select
  476. defb 004h ;005b count 4
  477. defb 0cfh ;005c
  478. defb 0b8h ;005d
  479. defb 037h ;005e
  480. defb 0efh ;005f
  481. ;
  482. defb 0b4h ;0060 io port PIO A data
  483. defb 001h ;0061 count 1
  484. defb 001h ;0062
  485. ;
  486. defb 0a1h ;0063 io port DART A command
  487. defb 006h ;0064 count 6
  488. defb 048h ;0065
  489. defb 048h ;0066
  490. defb 004h ;0067
  491. defb 044h ;0068
  492. defb 005h ;0069
  493. defb 0eah ;006a
  494. ;
  495. defb 0a3h ;006b io port DART B command
  496. defb 008h ;006c count 8
  497. defb 048h ;006d
  498. defb 048h ;006e
  499. defb 004h ;006f
  500. defb 044h ;0070
  501. defb 001h ;0071
  502. defb 000h ;0072
  503. defb 003h ;0073
  504. defb 0c1h ;0074
  505. ;
  506. defb 0a5h ;0075 io port SIO A command
  507. defb 002h ;0076 count 2
  508. defb 048h ;0077
  509. defb 048h ;0078
  510. ;
  511. defb 0a7h ;0079 io port SIO B command
  512. defb 002h ;007a count 2
  513. defb 048h ;007b
  514. defb 048h ;007c
  515. ;
  516. defb 0a8h ;007d io port CTC CHANNEL 0 - Communications baud rate
  517. defb 002h ;007e count 2
  518. defb 003h ;007f
  519. defb 003h ;0080
  520. ;
  521. defb 0a9h ;0081 io port CTC CHANNEL 1 - AUX RS-232C baud rate
  522. defb 002h ;0082 count 2
  523. defb 003h ;0083
  524. defb 003h ;0084
  525. ;
  526. defb 0aah ;0085 io port CTC CHANNEL 2 - Printer baud rate
  527. defb 002h ;0086 count 2
  528. defb 057h ;0087
  529. defb 04eh ;0088
  530. ;
  531. defb 000h ;0089 io port reset
  532. defb 000h ;008a count 0 terminator
  533. set_up_crt:
  534. ;data to be output to io port B9 14 byte CRT data register
  535. defb 069h ;054f
  536. defb 050h ;0550
  537. defb 056h ;0551
  538. defb 00bh ;0552
  539. defb 019h ;0553
  540. defb 003h ;0554
  541. defb 018h ;0555
  542. defb 018h ;0556
  543. defb 000h ;0557
  544. defb 00bh ;0558
  545. defb 020h ;0559
  546. defb 000h ;055a
  547. defb 000h ;055b
  548. defb 000h ;055c
  549. include "inc/spt.asm"
  550. include "inc/memtestmarch.asm"
  551. include "inc/monroecon.asm"
  552. include "inc/trs80music.asm"