abc80diag.asm 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  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 7c00h
  28. VSIZE equ 0400h
  29. VLINE equ 40
  30. .org 0000h ; z80 boot code starts at location 0
  31. reset:
  32. di ; mask INT
  33. im 1
  34. diagnostics:
  35. ld a,0
  36. out ($EC),a ; set 64 char mode
  37. ; ld a,0 ; byte to be written goes in A
  38. out ($F8),a ; blank printer port for now
  39. test_vram:
  40. SPTHREAD_BEGIN ; set up to begin running threaded code
  41. dw spt_playmusic, tones_welcome
  42. dw spt_select_test, tp_vram
  43. dw memtestmarch ; test the VRAM
  44. dw spt_check_7bit_vram
  45. ; dw spt_sim_error, $40
  46. dw spt_jp_nc, .vram_ok
  47. ; we have bad vram
  48. dw spt_chartest
  49. .vram_bad_loop:
  50. dw spt_play_testresult ; play the tones for bit errors
  51. dw spt_pause, $0000
  52. dw spt_jp,.vram_bad_loop
  53. .vram_7bit:
  54. dw spt_con_print, msg_ok7bit
  55. ; dw spt_play_testresult ; play the tones for bit errors
  56. dw spt_jp,.vram_goodtones
  57. .vram_ok:
  58. dw spt_prepare_display
  59. MAC_SPT_CON_GOTO 1,0
  60. dw spt_announcetest ; print results of VRAM tst
  61. ; dw print_biterrs
  62. dw spt_jp_e_7bit_vram, .vram_7bit
  63. dw spt_con_print, msg_ok8bit
  64. .vram_goodtones:
  65. dw spt_playmusic, tones_vramgood ; play the VRAM good tones
  66. .vram_continue:
  67. MAC_SPT_CON_GOTO 3,0
  68. dw spt_select_test, tp_16k ; load the first test
  69. dw spt_jp, .start
  70. SPT_SKIP_NMIVEC
  71. .start dw spt_con_goto
  72. MAC_SPT_CON_OFFSET 3,0
  73. .loop: dw spt_announcetest ; announce what test we are about to run
  74. dw memtestmarch ; test the current bank
  75. dw spt_jp_nc, .ok
  76. dw spt_con_print, msg_biterrs ; we have errors: print the bit string
  77. dw print_biterrs
  78. dw spt_play_testresult ; play the tones for bit errors
  79. dw spt_jp, .cont
  80. .ok: dw spt_con_print, msg_testok ; bank is good: print the OK message
  81. dw spt_play_testresult ; play the tones
  82. .cont:
  83. dw spt_tp_next, .start
  84. dw spt_jp, .loop
  85. ;; -------------------------------------------------------------------------------------------------
  86. ;; end of main program.
  87. spt_prepare_display:
  88. SPTHREAD_ENTER
  89. dw con_clear
  90. dw spt_con_print, msg_banner ; print the banner
  91. dw spt_print_charset
  92. dw spt_exit
  93. spt_check_vram_contents:
  94. pop bc
  95. ld a,b
  96. ld d,c
  97. ; confirm that all of VRAM contains the value in register A
  98. check_vram_contents:
  99. ld hl,VBASE
  100. ld bc,VSIZE
  101. .fillloop:
  102. ld (HL),a
  103. cpi
  104. jp pe,.fillloop
  105. ld hl,VBASE
  106. ld bc,VSIZE
  107. ld a,d
  108. .readloop:
  109. cpi
  110. jr nz,.bad
  111. jp pe,.readloop
  112. or a ; clear carry flag
  113. ret
  114. .bad: scf
  115. ret
  116. spt_check_7bit_vram:
  117. ret nc ; if carry flag is not set, do nothing
  118. ld a,01000000b
  119. cp e
  120. jr z,.scantests
  121. scf ; something other than bit 6 is bad, so this is not 7bit VRAM
  122. ret
  123. .scantests:
  124. SPTHREAD_ENTER
  125. dw spt_check_vram_contents, $0040
  126. dw spt_jp_c, .exit
  127. dw spt_check_vram_contents, $FFBF
  128. dw spt_jp_c, .exit
  129. dw spt_check_vram_contents, $AAAA
  130. dw spt_jp_c, .exit
  131. dw spt_check_vram_contents, $5555
  132. dw spt_jp_c, .exit
  133. .exit: dw spt_exit ; if carry flag is set, this is not good 7-bit VRAM
  134. spt_sim_error:
  135. pop de
  136. scf
  137. ret
  138. ; test if the error is $FF (all bits bad)
  139. spt_jp_all_bits_bad:
  140. pop hl ; get the address for jumping if match
  141. ld a,$FF ; check for all bits bad
  142. cp e
  143. ret nz ; return without jump if there is NOT a match
  144. ld sp,hl ; else jump to the requested location
  145. ret
  146. ; test if the e register matches 7-bit vram and jump to spt address if match
  147. spt_jp_e_7bit_vram:
  148. pop hl ; get the address for jumping if match
  149. ld a,01000000b ; ignore bit 6
  150. cp e ; see if there are other errors
  151. ret nz ; return without jump if there is NOT a match
  152. ld sp,hl ; else jump to the requested location
  153. ret
  154. ; test if the e register matches 7-bit vram and jump to spt address if match
  155. spt_jp_e_zero:
  156. pop hl ; get the address for jumping if match
  157. ld a,0 ; test clean
  158. cp e ; see if there are other errors
  159. ret nz ; return without jump if there is NOT a match
  160. ld sp,hl ; else jump to the requested location
  161. ret
  162. ; load the label string address from the current test parameter table entry into hl
  163. spt_ld_hl_tp_label:
  164. ld l,(iy+4)
  165. ld h,(iy+5)
  166. ret
  167. ; load the label string address from the current test parameter table entry into hl
  168. spt_ld_hl_tp_tones:
  169. ld l,(iy+6)
  170. ld h,(iy+7)
  171. ret
  172. spt_ld_new_line:
  173. ld a,(iy+9)
  174. ld ixh,a
  175. ld a,(iy+8)
  176. ld ixl,a
  177. ret
  178. ; move to the next test parameter table entry
  179. spt_tp_next: pop hl ; get the address to jump to if we are starting over
  180. ld bc,tp_size ; find the next entry
  181. add iy,bc
  182. ld a,(iy+0) ; is the length zero?
  183. add a,(iy+1)
  184. ret nz ; no, use it
  185. ld c,(iy+2) ; yes, get the address of the first entry
  186. ld b,(iy+3)
  187. ld iy,0
  188. add iy,bc
  189. ; sub a ; clear zero flag when restarting
  190. ld sp,hl ; jump to the next location
  191. ret
  192. spt_announcetest:
  193. ; pop hl ; get the message to be printed
  194. SPTHREAD_ENTER
  195. dw spt_ld_new_line
  196. dw spt_ld_hl_tp_label
  197. dw con_print ; picks up message from hl
  198. dw spt_con_print, msg_testing
  199. dw spt_con_index, -9
  200. dw spt_exit
  201. spt_play_testresult:
  202. SPTHREAD_SAVE ; save the stack pointer
  203. SPTHREAD_BEGIN
  204. dw spt_ld_hl_tp_tones ; play the ID tune for current bank
  205. dw playmusic
  206. dw spt_pause, $2000
  207. SPTHREAD_END
  208. ld a,$FF
  209. cp e
  210. jr z,.allbad ; if all bits bad, play shorter tune
  211. cpl
  212. cp e
  213. jr z,.allgood ; if all bits good, play shorter tune
  214. ld d,8 ; play bit tune for each bit, high to low
  215. .showbit:
  216. rlc e
  217. jr nc,.zero
  218. ld hl,tones_bitbad
  219. jr .msbe_cont
  220. .zero:
  221. ld hl,tones_bitgood
  222. .msbe_cont:
  223. SPTHREAD_BEGIN
  224. dw playmusic
  225. dw spt_pause, $2000
  226. SPTHREAD_END
  227. ; pause $4000
  228. dec d
  229. jr nz,.showbit
  230. jr .done
  231. .allbad:
  232. SPTHREAD_BEGIN
  233. dw spt_playmusic, tones_bytebad
  234. dw spt_pause, $8000
  235. SPTHREAD_END
  236. jr .done
  237. .allgood:
  238. SPTHREAD_BEGIN
  239. dw spt_playmusic, tones_bytegood
  240. dw spt_pause, $8000
  241. SPTHREAD_END
  242. .done:
  243. SPTHREAD_RESTORE ; restore the stack pointer
  244. ret
  245. spt_pause:
  246. pop bc
  247. ; pause by an amount specified in BC
  248. pause_bc:
  249. .loop:
  250. dec bc
  251. ld a,b
  252. or c
  253. jr nz,.loop
  254. ret
  255. print_biterrs:
  256. ld a,'7'
  257. ld b,8
  258. .showbit:
  259. rlc e
  260. jr nc,.zero
  261. ld (ix+0),a
  262. jr .cont
  263. .zero:
  264. ld (ix+0),'.'
  265. .cont:
  266. inc ix
  267. dec a
  268. djnz .showbit
  269. ret
  270. spt_ld_bc: pop bc
  271. ret
  272. spt_ld_line1_pos:
  273. ld ix,(pos_line1_text)
  274. ret
  275. spt_ld_line2_pos:
  276. ld ix,(pos_line2_text)
  277. ret
  278. spt_ld_line3_pos:
  279. ld ix,(pos_line3_text)
  280. ret
  281. spt_print_charset:
  282. ld a,ixh
  283. ld h,a
  284. ld a,ixl
  285. ld l,a
  286. xor a
  287. ld ix,(pos_char_text)
  288. SPTHREAD_ENTER
  289. ;MAC_SPT_CON_GOTO 9,24
  290. dw spt_con_print, msg_charset ; show a copy of the character set
  291. dw spt_ld_line1_pos
  292. dw spt_ld_bc, $e0
  293. dw do_charset_ix
  294. dw spt_exit
  295. spt_chartest:
  296. ld ix,VBASE
  297. ld bc,VSIZE
  298. do_charset_ix:
  299. ld a,32
  300. .charloop:
  301. ld (ix+0),a ; copy A to byte pointed by HL
  302. inc a ; increments A
  303. inc ix
  304. cp 048h
  305. jp nz,.cont2
  306. ld ix,(pos_line2_text)
  307. .cont2:
  308. cp 070h
  309. jp nz,.cont3
  310. ld ix,(pos_line3_text)
  311. .cont3:
  312. cp 098h
  313. jp nz,.cont4
  314. ld ix,(pos_line4_text)
  315. .cont4:
  316. cp 0c0h
  317. jp nz,.cont5
  318. ld ix,(pos_line5_text)
  319. .cont5:
  320. cp 0e8h
  321. jp nz,.cont6
  322. ld ix,(pos_line6_text)
  323. .cont6:
  324. cpi ; increments HL, decrements BC (and does a CP)
  325. jp pe, .charloop
  326. ret
  327. label_vram: dbz " 1K VRAM 7C00-7FFF "
  328. label_dram16k1: dbz "16K DRAM C000-FFFF "
  329. label_dram16k2: dbz " 8K DRAM 8000-9FFF "
  330. label_dram16k3: dbz " 8K DRAM A000-BFFF "
  331. label_sram2k1: dbz " 2K SRAM 5000-57FF "
  332. label_sram2k2: dbz " 2K VRAM 5800-58FF "
  333. msg_banner: dbz "ABC80-TEST ROM -- FRANK / DAVE / ADRIAN"
  334. msg_charset: dbz "-CHARACTER SET-"
  335. ; msg_testing: db " ", " "+$80, "t"+$80, "e"+$80, "s"+$80, "t"+$80, " "+$80, " ", 0
  336. msg_testing: dbz "..TEST.. "
  337. msg_testok: dbz "---OK--- "
  338. msg_biterrs: dbz "BIT ERRS "
  339. msg_ok7bit: dbz "OK! (7-BIT MODEL 1)"
  340. msg_ok8bit: dbz "OK! (8-BIT)"
  341. msg_banktest: dbz "TESTING BANK SIZE "
  342. ; test parameter table. 2-byte entries:
  343. ; 1. size of test in bytes
  344. ; 2. starting address
  345. ; 3. address of string for announcing test
  346. ; 4. address of tones for identifying the test audibly
  347. tp_size equ 10
  348. memtest_ld_bc_size .macro
  349. ld c,(iy+0)
  350. ld b,(iy+1)
  351. .endm
  352. memtest_ld_hl_base .macro
  353. ld l,(iy+2)
  354. ld h,(iy+3)
  355. .endm
  356. memtest_loadregs .macro
  357. memtest_ld_bc_size
  358. memtest_ld_hl_base
  359. .endm
  360. tp_vram: dw VSIZE, VBASE, label_vram, tones_vram,$7d00
  361. tp_16k: dw $4000, $C000, label_dram16k1, tones_id1,$7d80
  362. dw $2000, $8000, label_dram16k2, tones_id1,$7e00
  363. dw $2000, $A000, label_dram16k3, tones_id1,$7e80
  364. dw $0800, $5000, label_sram2k1 , tones_id1,$7f00
  365. dw $0800, $5800, label_sram2k2 , tones_id1,$7f80
  366. dw $0000, tp_16k
  367. pos_char_text: dw $7c5c
  368. pos_line1_text: dw $7cd0
  369. pos_line2_text: dw $7d50
  370. pos_line3_text: dw $7dd0
  371. pos_line4_text: dw $7e50
  372. pos_line5_text: dw $7ed0
  373. pos_line6_text: dw $7f50
  374. include "inc/spt.asm"
  375. include "inc/memtestmarch.asm"
  376. include "inc/abc80con.asm"
  377. include "inc/trs80music.asm"