home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / utils / asmutl / asmlib.lbr / TESTALL.AZM / TESTALL.ASM
Encoding:
Assembly Source File  |  1991-06-25  |  37.3 KB  |  1,673 lines

  1. ;----------------------------------------------------------------
  2. ; This program tests some of the SME Systems boards and is used
  3. ; in the technical area for this purpose.
  4. ; The tests supported so far are.
  5. ;
  6. ; 1) Test SPC-29 PARALLEL ports
  7. ; 2) Test SPC-29 SERIAL port 1
  8. ; 3) Test SPC-29 SERIAL port 2
  9. ; 4) Test FDC-3  SERIAL port
  10. ; 5) Test SBC-800 Centronic printer port
  11. ; 6) Test SBC-800 Serial port 2
  12. ; 7) Test MPC-6 serial channels
  13. ; 8) Display ADC-32 analogue and bit channels
  14. ; 9) Tests DRC-II with interrupts, LDIR, LDDR, walking bit, barber pole,
  15. ;     bank switching and bank decoding.
  16. ;
  17. ; Since this program uses the ASMLIB library, it is easily modified and
  18. ; added to. All the rouines and code have been written as simply and as
  19. ; linearly as possible to allow mods and additions.
  20. ;
  21. ; As an aid to the user, this program checks itself and if there is any change
  22. ; in the executable portion then an error message will be reported. This is to
  23. ; detect faulty copies.
  24. ;
  25. ; Note: The MPC-6 test requires an I/O library capable of supporting it.
  26. ;       There are two such, CPMMPC and SBCMPC with iomun's of 3 and 4
  27. ;       respectively. If these are not used then this test displays an
  28. ;    error then exits back to the menu immediately. The actual name of
  29. ;       the i/o driver is displayed with the 'C' command.
  30. ;
  31. ;            Written        R.C.H.        23/11/83
  32. ;            Last Update    R.C.H.        20/02/84
  33. ;----------------------------------------------------------------
  34. ;
  35. ;        ASMLIB library routine names
  36. ;
  37.     extrn    prolog,nibasc,pdacc,dispatch,inline
  38.     extrn    quit,listout,consout,crlf,clear,ihhl
  39.     extrn    pdde,delay,cst,bell,cie,coe,caps,portset
  40.     extrn    randinit,rand8,pmenu,phde,hexasc,phacc
  41.     extrn    clrcrc,addcrc,getcrc,xyinline,setxy,atoasc
  42.     extrn    ionum,tname,pstring,cursor,pstr
  43.     extrn    setatt,ramwbt,rambpt,datstart,datend
  44.     extrn    lzb,nolzb,blzb,clkrd,getyorn
  45. ;
  46.     maclib    z80
  47. ;
  48. ; HARDWARE EQUATES
  49. ;
  50. ; SPC-29 PARALLEL PORTS
  51. ;
  52. data0    equ    054h
  53. data1    equ    data0 + 1
  54. data2    equ    data0 + 2
  55. stat0    equ    data0 + 3
  56. ;
  57. data3    equ    078h
  58. data4    equ    data3 + 1
  59. data5    equ    data3 + 2
  60. stat1    equ    data3 + 3
  61. ;
  62. data6    equ    098h
  63. data7    equ    data6 + 1
  64. data8    equ    data6 + 2
  65. stat2    equ    data6 + 3
  66. ;
  67. ; SPC-29 SERIAL PORTS
  68. ;
  69. spc1$st    equ    011h        
  70. spc1$dt    equ    010h
  71. spc2$st    equ    035h
  72. spc2$dt    equ    034h
  73. ;
  74. ; FDC-3 equates
  75. ;
  76. fdc3$st    equ    059h    
  77. fdc3$dt    equ    058h
  78. ;
  79. ; SBC-800 Centronic port equates
  80. ;
  81. cp$st1     equ    084h
  82. cp$st2     equ    086h
  83. cp$dt     equ    085h
  84. ;
  85. sbc$st2    equ    08bh
  86. sbc$dt2    equ    08ah
  87. ;
  88. ; Base for logging on to MPC-6 channels
  89. ;
  90. base    equ    0f8h
  91. ;
  92. ; ADC-32 port allocations
  93. ;
  94. aBASE    EQU    40h
  95. PORT0    EQU    aBASE+0
  96. PORT1    EQU    aBASE+1
  97. ;
  98. ; Memory test equates
  99. ;
  100. t9t1    equ    50000            ; interrupts iteration size
  101. t9t2    equ    1000               ; port addressing iteration size
  102. t9t3    equ    1            ; walking bit iteration size
  103. t9t4    equ    1            ; barber pole test iteration size
  104. t9t5    equ    50              ; ldir / lddr iteration test size
  105. ctc0    equ    08ch
  106. ctc1    equ    ctc0+1
  107. ctc2    equ    ctc0+2
  108. ctc3    equ    ctc0+3
  109. ;
  110. prgcrc    equ    00000h            ; Program CRC for checking and display
  111. ;
  112. ; Lets go
  113. ;
  114. start:    ; Errors jump us here
  115.     call    prolog
  116. ; Get a CRC of the program to display to the user for 3 seconds
  117. st1:
  118.     call    clrcrc            ; clear users CRC code
  119. ; Put the program size into BC
  120.     lxi    b,progend-st4        ; get program size
  121.     lxi    h,st4            ; get program start
  122. ; Now read all bytes till BC = 0 and get the CRC code
  123. st2:
  124.     mov    a,m
  125.     call    addcrc
  126.     dcx    b            ; one less byte to do later
  127.     mov    a,b
  128.     ora    c            ; does b = c = 0
  129.     jrz    st3
  130.     inx    h            ; point to next byte to do
  131.     jr    st2            ; keep on for all program
  132. ;
  133. st3:
  134.     call    clear
  135.     call    xyinline
  136.     db    25,10,'Program CRC = $'
  137.     call    getcrc            ; get the users CRC into HL
  138.     xchg                ; put into DE
  139.     call    phde            ; print the hex value of de
  140.     call    xyinline
  141.     db    25,11,'Correct CRC = $'
  142.     lxi    d,prgcrc        ; get original
  143.     call    phde
  144. ;
  145.     call    getcrc            ; get CRC of this program again
  146.     lxi    d,prgcrc        ; get supposed correct version
  147. ; If the prgcrc = 00 then skip the next bit
  148.     mov    a,d
  149.     ora    a            ; does D = E = 00 ??
  150.     jz    st4            ; skip the message display then
  151. ;
  152.     mov    a,l            ; else get the returned low 8 bit crc
  153.     cmp    e
  154.     jrnz    crc$error
  155.     mov    a,h
  156.     cmp    d
  157.     jz    st4
  158. ; Here and the CRC values do not match
  159. crc$error:
  160.     mvi    d,20            ; X screen address for error message
  161.     mvi    e,13            ; Y screen address
  162.     call    cursor
  163. ;
  164.     mvi    a,03
  165.     call    setatt            ; select reverse video characters
  166. ;
  167.     call    inline
  168.     db    07,'CRC MISMATCH - Faulty Copy$'
  169. ;
  170.     xra    a
  171.     call    setatt
  172. ;
  173. ; Now display the name of the I/O driver module that this has been set for
  174. st4:
  175.     call    xyinline
  176.     db    19,15,'I/O Drivers are for $'
  177. ;
  178.     call    ionum            ; get the i/o driver number
  179.     dcr    l            ; make in the range 0..N
  180.     mvi    h,00            ; clear top byte
  181.     lxi    d,names
  182.     xchg                ; DE = driver number, HL -> addresses
  183.     dad    d
  184.     dad    d            ; add twice since WORD addresses
  185. ; Here and HL-> the address of the I/O driver name string
  186.     mov    e,m            ; low address byte
  187.     inx    h
  188.     mov    d,m            ; high address
  189. ; Now DE -> the string to print
  190.     call    pstring
  191. ;
  192. ; Now do a delay of 3 seconds to show the CRC
  193.     lxi    d,3000
  194.     call    delay            ; all done 
  195. ;
  196. ;
  197. ; Jump here to do a new test
  198. start1:
  199.     call    clear
  200.     lxi    d,menu
  201.     call    pmenu
  202.     call    cie
  203.     call    caps
  204.     call    coe
  205.     cpi    'Q'            ; Exit to the CP/M
  206.     jz    quit
  207.     cpi    'C'            ; display the CRC codes ??
  208.     jz    st1
  209.  
  210. ;
  211.     ani    07fh            ; mask off parity
  212.     cpi    '1'            ; less than 1 ??
  213.     jc    start1
  214.     cpi    '9'+1            ; greater than a 9 (maximum) ?
  215.     jnc    start1
  216.     sta    testno
  217. ;
  218.     call    init            ; do the initialization
  219.     call    test
  220.     jmp    start1
  221. ;
  222. ;
  223. ; initialize
  224. ; This routine must initialize one of the many devices that are
  225. ; possible. This is done with the TESTNO byte.
  226. ;
  227. init:
  228.     lda    testno
  229.     cpi    '1'        ; SPC-29 parallel ports ?
  230.     jz    init1
  231.     cpi    '2'        ; SPC-29 serial port 1
  232.     jz    init2
  233.     cpi    '3'        ; SPC-29 serial port 2
  234.     jz    init3
  235.     cpi    '4'
  236.     jz    init4
  237.     cpi    '5'
  238.     jz    init5        ; Centronic printer on SBC-800
  239.     cpi    '6'
  240.     jz    init6
  241.     cpi    '7'
  242.     jz    init7
  243.     cpi    '8'
  244.     jz    init8
  245.     cpi    '9'
  246.     jz    init9
  247. ; All else is not supported
  248.     call    inline
  249.     db    0dh,0ah,07,'NOT SUPPORTED DEVICE SELECTED$'
  250.     lxi    d,5000
  251.     call    delay
  252.     pop    h        ; drop the return off the stack
  253.     jmp    start1        ; exit quickly
  254. ;
  255. ;
  256. init1:    ; SET up SPC-29 parallel ports
  257.     mvi    a,080h        ; all outputs
  258.     out    stat0
  259.     out    stat1
  260.     out    stat2
  261.     ret
  262. ;
  263. init2:    ; initialize serial port 0 of SPC-29
  264.     mvi    a,0aah        
  265.     out    spc1$st
  266.     mvi    a,040h
  267.     out    spc1$st
  268.     mvi    a,0cfh
  269.     out    spc1$st
  270.     mvi    a,027h
  271.     out    spc1$st
  272.     ret
  273. ;
  274. init3:    ; initialize serial port 2 of SPC-29
  275.     mvi    a,0aah        
  276.     out    spc2$st
  277.     mvi    a,040h
  278.     out    spc2$st
  279.     mvi    a,0cfh
  280.     out    spc2$st
  281.     mvi    a,027h
  282.     out    spc2$st
  283.     ret
  284. ;
  285. init4:    ; initialize serial port of FDC-3
  286.     mvi    a,0aah        
  287.     out    fdc3$st
  288.     mvi    a,040h
  289.     out    fdc3$st
  290.     mvi    a,0ceh
  291.     out    fdc3$st
  292.     mvi    a,027h
  293.     out    fdc3$st
  294.     ret
  295. ;
  296. init5:    ;Initialize the centronic printer
  297.     ret
  298.  
  299. ;
  300. init6:    ; Set up SBC-800 serial port 2 to 9600 baud
  301.     lxi    d,in6
  302.     call    portset
  303.     ret
  304. ;
  305. ; Byte initialization strings
  306. ;
  307. in6:    db    2,08Dh,045h,0Dh            ; set up the ctc to / by 13dec
  308.     db    08,08Bh,4,044h,1,0,3,0C1h,5,0EAh
  309.     db    00
  310. ;
  311. init7:
  312.     ret
  313. ;
  314. init8:
  315.     ret
  316. ;
  317. init9:
  318.     ret                    ; no setups required for DRC-II
  319. ;
  320. ;----------------------------------------------------------------
  321. ;             THE TESTS
  322. ;
  323. ;----------------------------------------------------------------
  324. ;
  325. test:    ; decode the users number then jump to the required test
  326.     lda    testno
  327.     cpi    '1'        ; parallel ports on SPC-29 ??
  328.     jz    test1
  329.     cpi    '2'
  330.     jz    test2        ; serial port 1
  331.     cpi    '3'
  332.     jz    test3
  333.     cpi    '4'
  334.     jz    test4
  335.     cpi    '5'
  336.     jz    test5        ; SBC-800 printer
  337.     cpi    '6'
  338.     jz    test6        ; sbc-800 serial port 2
  339.     cpi    '7'
  340.     jz    test7        ; test the MPC-6 serial channels
  341.     cpi    '8'
  342.     jz    test8        ; display analogue input channels
  343.     cpi    '9'
  344.     jz    test9
  345.     ret            ; ignore all else
  346. ;
  347. ;----------------------------------------------------------------
  348. ;         THE SPC-29 PARALLEL PORT TESTER
  349. ;
  350. ; Turn on all bytes then turn off all bytes. This is done with a 1 second
  351. ; clock
  352. ;
  353. test1:
  354.     call    clear
  355.     call    inline
  356.     db    0dh,0ah,0ah,0ah
  357.     db    0dh,0ah,'  --- PARALLEL PORT TESTER FOR SPC-29 ---'
  358.     db    0dh,0ah
  359.     db    0dh,0ah,'Ports must be addressed at 54h, 78h and 98h'
  360.     db    0dh,0ah,0ah
  361.     db    0dh,0ah,'Starting - enter a ^C to exit this test'
  362.     db    0dh,0ah,0ah,'All leds on for 1 second$'
  363.     mvi    a,0ffh
  364.     call    sendall
  365.     lxi    d,1000            ; 1 second delay
  366.     call    delay
  367. ;
  368.     call    inline
  369.     db    0dh,0ah,'All leds off for 1 second$'
  370. ;
  371.     mvi    a,00h
  372.     call    sendall
  373.     lxi    d,1000
  374.     call    delay
  375. ; Now strobe each light on by itself for .25 second so as to simulate the
  376. ; effect of motion.
  377.     call    inline
  378.     db    0dh,0ah,'Walking bit across all channels$'
  379. ;
  380.     mvi    a,1
  381.     mvi    b,8            ; do 8 times
  382.     lxi    d,1000            ; 1.0 second delays
  383. walkbit:
  384.     call    sendall
  385.     push    psw
  386.     call    delay
  387.     pop    psw
  388.     add    a
  389.     djnz    walkbit
  390. ;
  391.     xra    a
  392.     call    sendall            ; turn all off
  393. ;
  394. ; Now walk a single bit along all the ports in each channel
  395. ;
  396.     call    inline
  397.     db    0dh,0ah,'Single channel sequential walking bit$'
  398. ;
  399.     lxi    d,1000            ; 1 second delay still
  400.     mvi    a,1
  401.     mvi    b,8            ; 8 loops also
  402. walk2:
  403.     call    send0
  404.     push    psw
  405.     call    delay
  406.     pop    psw
  407.     add    a
  408.     djnz    walk2
  409. ; Now do the next port(s) so as to walk the bit along
  410.     xra    a
  411.     call    sendall            ; turn all off
  412.     mvi    a,1
  413.     mvi    b,8            ; 8 loops also
  414. walk3:
  415.     call    send1
  416.     push    psw
  417.     call    delay
  418.     pop    psw
  419.     add    a
  420.     djnz    walk3
  421. ;
  422. ; Do the last port
  423. ;
  424.     xra    a
  425.     call    sendall
  426.     mvi    a,1
  427.     mvi    b,8            ; 8 loops also
  428. walk4:
  429.     call    send2
  430.     push    psw
  431.     call    delay
  432.     pop    psw
  433.     add    a
  434.     djnz    walk4
  435. ; turn all bits off
  436.     xra    a
  437.     call    sendall
  438. ; Random bits on / off for 100ms each for 10 seconds
  439. ;
  440.     call    inline
  441.     db    0dh,0ah,'10 Seconds of random chaff$'
  442.     mvi    b,200            ; 100 * 100 = 10 seconds
  443.     lxi    d,seed
  444.     call    randinit
  445. chaff:
  446.     push    b
  447.     lxi    d,seed            ; random number seed
  448.     call    rand8
  449.     call    send0
  450. ; next channel
  451.     lxi    d,seed
  452.     call    rand8
  453.     call    send1
  454. ; last channel
  455.     lxi    d,seed
  456.     call    rand8
  457.     call    send2
  458. ; restor delay counter
  459.     lxi    d,50
  460.     call    delay
  461.     pop    b
  462.     djnz    chaff            ; loop on till all done
  463. ;
  464.     xra    a
  465.     call    sendall            ; clear
  466. ;
  467. asktoquit:
  468.     call    inline
  469.     db    0dh,0ah,'Do again ? $'
  470.     call    cie
  471.     call    caps
  472.     cpi    'Y'
  473.     jz    test1            ; start again
  474.     cpi    'N'
  475.     ret                ; back to the main loop
  476. ;
  477. ;
  478. ; All done, the following are subroutines
  479. ;
  480. send0:
  481.     out    data0
  482.     out    data3
  483.     out    data6
  484.     jmp    send$end
  485. ;
  486. send1:
  487.     out    data1
  488.     out    data4
  489.     out    data7
  490.     jmp    send$end
  491. ;
  492. send2:
  493.     out    data2
  494.     out    data5
  495.     out    data8
  496.     jmp    send$end
  497. ;
  498. sendall:
  499.     out    data0
  500.     out    data1
  501.     out    data2
  502.     out    data3
  503.     out    data4
  504.     out    data5
  505.     out    data6
  506.     out    data7
  507.     out    data8
  508. ;
  509. ; Check of the user wants to exit this test to the menu
  510. ;
  511. send$end:
  512.     push    psw
  513.     call    cst
  514.     jrz    no$send$end
  515. ;
  516. ; Check for a control c
  517.     call    cie            ; get a key if pressed
  518.     cpi    03            ; control C ??
  519.     jrnz    no$send$end        ; ignore if not control c
  520.      pop    psw            ; drop off the accumulator
  521.     pop    h            ; drop the test routine return address
  522.      ret                ; return to the start loop
  523. ;
  524. no$send$end:
  525.     pop    psw
  526.     ret
  527. ;
  528. ;----------------------------------------------------------------
  529. ;        TEST the SPC-29 SERIAL PORTS
  530. ;
  531. ; Tell the operator to swap top connectors and to press a return
  532. ; then print a string. After the string, go into echo mode
  533. ; and echo all characters till a control C.
  534. ; All characters entered are displayed as hex and decimal so as to
  535. ; pick a missing bit etc.
  536. ;----------------------------------------------------------------
  537. ;
  538. test2:
  539.     call    clear
  540.     call    inline
  541.     db    0dh,0ah,'Connect terminal to channel 1 of SPC-29 then'
  542.     db    0dh,0ah,'Press the return key$'
  543.     jmp    test$234$com
  544. test3:
  545.     call    clear
  546.     call    inline
  547.     db    0dh,0ah,'Connect terminal to channel 2 of SPC-29 then'
  548.     db    0dh,0ah,'Press the return key$'
  549.     jmp    test$234$com
  550. ;
  551. test4:
  552.     call    clear
  553.     call    inline
  554.     db    0dh,0ah,'Connect terminal serial channel to FDC-III then'
  555.     db    0dh,0ah,'Press the return key$'
  556.     jmp    test$234$com
  557. ;
  558. test6:
  559.     call    clear
  560.     call    inline
  561.     db    0dh,0ah,'Connect 9600 baud terminal to SBC-800 serial port 2'
  562.     db    0dh,0ah,'then Press the return key$'
  563. ;
  564. ;
  565. ; All code is common now, the only difference is the I/O driver section
  566. ; which uses TESTNO to decide where to put characters.
  567. ;
  568. test$234$com:
  569.     call    cst
  570.     jrz    test$234$com1
  571.     call    cie
  572.     cpi    03            ; control C ?
  573.     ret                ; back to the main menu then
  574. ;
  575. test$234$com1:
  576.     call    cie$234            ; get a character
  577.     ani    07fh
  578.     cpi    0dh            ; a carriage return ?
  579.     jrnz    test$234$com        ; wait for it
  580. ;
  581.  
  582.     lxi    d,test$234$msg        ; a little message for the terminal
  583.     call    print$234
  584. ;
  585. t234$com2:
  586.     call    cie$234            ; get a character
  587.     ani    07fh
  588.     cpi    03            ; control C ?
  589.     jz    exit$234        ; exit 
  590.     call    coe$234            ; echo the character
  591.     jr    t234$com2
  592. ;
  593. exit$234:
  594.     lxi    d,test$234$msg2
  595.     call    print$234
  596. exit$234$2:
  597.     call    cie            ; get system console character
  598.     cpi    0dh
  599.     jrnz    exit$234$2
  600.     ret                ; goto the main loop / menu
  601. ;
  602. ;
  603. print$234:
  604.     ldax    d
  605.     cpi    '$'
  606.     rz
  607.     call    coe$234
  608.     inx    d
  609.     jr    print$234
  610. ;
  611. ; Get a character from one of 3 serial channels
  612. ;
  613. cie$234:
  614.     lda    testno
  615.     cpi    '2'            ; spc channel 1
  616.     jrz    cie$spc1
  617.     cpi    '3'
  618.     jrz    cie$spc2
  619.     cpi    '4'
  620.     jrz    cie$fdc3
  621.     cpi    '6'
  622.     jrz    cie$sbc2
  623.     ret
  624. ;
  625. cie$spc1:
  626.     call    cst
  627.     jrz    cie$spc15
  628.     call    cie
  629.     cpi    03
  630.     jz    cie$exit
  631. cie$spc15:
  632.     in    spc1$st
  633.     ani    02            ; receiver status
  634.     jrz    cie$spc1
  635.     in    spc1$dt            ; get the data
  636.     ret
  637. ;
  638. ;
  639. cie$spc2:
  640.     call    cst
  641.     jrz    cie$spc25
  642.     call    cie
  643.     cpi    03
  644.     jz    cie$exit
  645. cie$spc25:
  646.     in    spc2$st
  647.     ani    02            ; receiver status
  648.     jrz    cie$spc2
  649.     in    spc2$dt            ; get the data
  650.     ret
  651. ;
  652. ;
  653. cie$fdc3:
  654.     call    cst
  655.     jrz    cie$fdc35
  656.     call    cie
  657.     cpi    03
  658.     jz    cie$exit
  659. cie$fdc35:
  660.     in    fdc3$st
  661.     ani    02            ; receiver status
  662.     jrz    cie$fdc3
  663.     in    fdc3$dt            ; get the data
  664.     ret
  665. cie$sbc2:
  666.     call    cst
  667.     jrz    cie$sbc25
  668.     call    cie
  669.     cpi    03
  670.     jz    cie$exit
  671. cie$sbc25:
  672.     in    sbc$st2
  673.     ani    1
  674.     jrz    cie$sbc2
  675.     in    sbc$dt2
  676.     ret
  677. ;
  678. cie$exit:
  679. ;    pop    h            ; drop off return address to test loop
  680.     pop    h            ; drop off return address to cie
  681.     ret                ; return from the test 2 3 4 6
  682. ;
  683. ;------------------------------------------------
  684. ; Put a character from one of 3 serial channels
  685. ;------------------------------------------------
  686. coe$234:
  687.     mov    c,a            ; save the character
  688.     lda    testno
  689.     cpi    '2'            ; spc channel 1
  690.     jrz    coe$spc1
  691.     cpi    '3'
  692.     jrz    coe$spc2
  693.     cpi    '4'
  694.     jrz    coe$fdc3
  695.     cpi    '6'
  696.     jrz    coe$sbc2
  697.     ret
  698. ;
  699. coe$spc1:
  700.     in    spc1$st
  701.     ani    01            ; transmitter status
  702.     jrz    coe$spc1
  703.     mov    a,c
  704.     out    spc1$dt            ; put the data
  705.     ret
  706. ;
  707. ;
  708. coe$spc2:
  709.     in    spc2$st
  710.     ani    01            ; transmitter status
  711.     jrz    coe$spc2
  712.     mov    a,c
  713.     out    spc2$dt            ; put the data
  714.     ret
  715. ;
  716. ;
  717. coe$fdc3:
  718.     in    fdc3$st
  719.     ani    01            ; transmitter status
  720.     jrz    coe$fdc3
  721.     mov    a,c
  722.     out    fdc3$dt            ; get the data
  723.     ret
  724. ;
  725. coe$sbc2:
  726.     in    sbc$st2
  727.     ani    4
  728.     jrz    coe$sbc2
  729.     mov    a,c
  730.     out    sbc$dt2
  731.     ret
  732. ;
  733. ;----------------------------------------------------------------
  734. ; Display the status bits of the centronic printer
  735. ; port and offer to output a byte to the port.
  736. ;----------------------------------------------------------------
  737. ;
  738. test5:
  739.     call    clear
  740.     call    xyinline
  741.     db    18,05,'---- SBC-800 Centronic Printer Port Test ----$'
  742. ;
  743. test5$loop:
  744.     call    inline
  745.     db    0dh,0ah,0ah,'Enter a byte to send (hex) : $'
  746.     call    ihhl
  747.     mov    a,l
  748.     out    cp$dt            ; send to centronic data port
  749. ;
  750.     call    inline
  751.     db    0dh,0ah,'Busy = $'
  752.     in    cp$st1            ; get centronic status byte
  753.     call    phacc            ; display as hex
  754. ;
  755.     call    inline
  756.     db    0dh,0ah,' Ack = $'
  757.     in    cp$st2
  758.     call    phacc
  759. ;
  760. ; Continue ??
  761.     call    inline
  762.     db    0dh,0ah,'Again ? $'
  763.     call    cie
  764.     call    caps
  765.     call    coe
  766.     cpi    'Y'
  767.     jz    test5$loop
  768.     ret                ; all done
  769. ;
  770. ;----------------------------------------------------------------
  771. ;         T e s t   T h e   M P C - 6
  772. ;        ---------------------------
  773. ;
  774. ; This routine reads the status of all MPC-6 channels and if a character
  775. ; is there it echoes it to the screen (back to the MPC-6). This is a good
  776. ; indication that the MPC-6 is in fact working. A test is done at the start
  777. ; of the program to see if the correct I/O driver module has been linked
  778. ; in, and if not then an error is reported.
  779. ; More than one terminal can be connected at a time, this program simply
  780. ; scans ALL channels and when a character is there, it echoes it.
  781. ;----------------------------------------------------------------
  782. ;
  783. test7:
  784. ; Check that an MPC-6 is in the bus. This is done by reading the port
  785. ; which is the transmitter status. If bits incorrectly set then no MPC-6
  786. ;
  787.     call    clear
  788.     out    3            ; perform a software reset
  789.     call    xyinline
  790.     db    1,10,'Checking for MPC-6 in bus - $'
  791. ; read the port
  792.     in    1            ; read the port
  793.     cpi    03fh            ; check the status (transmitter ready)
  794.     jz    test7$mpcok
  795. ;
  796.     call    bell            ; hey
  797.     mvi    a,3            ; reverse video
  798.     call    setatt
  799.     call    inline
  800.     db    'MPC-6 NOT VISIBLE at ports 0..3$'
  801.     xra    a
  802.     call    setatt
  803.     lxi    d,2000
  804.     call    delay
  805.     ret                ; return to main menu
  806. ;
  807. test7$mpcok:
  808.     call    inline
  809.     db    ' MPC-6 all present and correct$'
  810.     lxi    d,2000            ; 2 second delay
  811.     call    delay
  812. ;
  813. ; Progress on to the next bit.
  814.     call    clear
  815.     call    ionum            ; get the I/O driver number
  816.     mov    a,l            ; get the number
  817.     cpi    3            ; CP/M and MPC-6
  818.     jrz    test7$ok
  819.     cpi    4            ; SBC-800 & mpc-6
  820.     jrz    test7$ok        
  821. ; Display a message
  822.     call    bell
  823.     call    xyinline
  824.     db    15,10,'WRONG I/O DRIVER MODULE, SEE R.C.H.$'
  825.     lxi    d,3000
  826.     call    delay
  827.     ret                ; return to main menu
  828. ;
  829. test7$ok:
  830.     call    clear
  831. ;
  832.     call    xyinline
  833.     db    15,10,'Enter characters on any MPC-6 channel$'
  834.     call    xyinline
  835.     db    18,11,'Enter control F to fill screen$'
  836.     call    xyinline
  837.     db    20,12,'Enter a control C to exit$'
  838. ;
  839.     call    crlf
  840. ;
  841. test7$start:
  842.     xra    a            ; clear the byte
  843. test7$loop:
  844.     sta    channel            ; save
  845.     adi    base            ; add the log in vector
  846.     call    coe            ; do the log on
  847.     call    cst
  848.     jz    test7$ignore
  849. ; There is a character there
  850.     call    cie
  851.     cpi    03            ; control C ??
  852.     jz    test7$end
  853.     cpi    6            ; control F ??
  854.     jnz    test7$loop3
  855. ; Load some counters to fill the screen, after a cursor addressing etc
  856.     lxi    d,0
  857.     call    cursor            ; dont' bother to clear
  858.     mvi    b,24            ; Do all lines
  859. test7$fl1:
  860.     push    b
  861.     mvi    b,80            ; all characters on a line
  862. test7$fl2:
  863.     mvi    a,'X'
  864.     call    coe
  865.     call    xonof            ; do a little handshake
  866.     djnz    test7$fl2
  867.     pop    b            ; get number of lines done
  868.     djnz    test7$fl1
  869. ; Now a little message in the middle
  870.     call    xyinline
  871.     db    35,11,'Like That ?$'
  872.     call    getyorn
  873.     jz    test7$ignore
  874.     call    clear
  875.     jmp    test7$ignore
  876. ;
  877. ;
  878. test7$loop3:
  879.     call    coe
  880. ;
  881. test7$ignore:
  882.     lda    channel
  883.     inr    a
  884.     cpi    7            ; past end ??
  885.     jz    test7$start        ; if past end then re-load a 00
  886.     jmp    test7$loop
  887. ;
  888. test7$end:
  889.     call    clear
  890.     call    xyinline
  891.     db    14,10,'Connect back to main port and press return$'
  892.     mvi    a,base            ; log back onto main port
  893.     call    coe
  894. ; wait for a return now
  895. test7$wait:
  896.     call    cie
  897.     cpi    0dh
  898.     jrnz    test7$wait
  899.     ret                ; return to main menu
  900. ;
  901. xonof:
  902.     call    cst
  903.     rz
  904.     call    cie
  905.     cpi    19
  906.     rnz                ; exit if not an X-off
  907. xonwait:
  908.     call    cie
  909.     cpi    17            ; x-on again ?
  910.     rz
  911.     call    bell
  912.     jr    xonwait
  913. ;
  914. ;----------------------------------------------------------------
  915. ;          D I S P L A Y    A D C - 3 2   D A T A
  916. ;       --------------------------------------
  917. ;
  918. ; This test displays all data that is on the A-TO-D card. This is
  919. ; done using the ANAIN library entry for the analogue channels, then
  920. ; reading the bit channels directly.
  921. ;----------------------------------------------------------------
  922. ;
  923. test8:
  924. ;
  925.     call    clear
  926.     call    xyinline
  927.     db    23,1,'A-TO-D Card Display$'
  928.     call    xyinline
  929.     db    00,23,'Press a key to exit$'
  930. ;
  931. ; LOOP THROUGH ALL 32 CHANNELS THEN DO AGAIN TILL STOPPED BY A KEY PRESS
  932. ;
  933. test8$start:
  934.     LXI    H,BTAB            ; USE A LITTLE MEMORY TO STORE BIT DATA
  935.     call    xyinline
  936.     db    1,4,'A TO D =$'
  937.     MVI    B,00
  938. LOOP:
  939.     ; CHECK FOR 16 ENTRIES
  940.     MOV    A,B
  941.     CPI    16            ; HALF WAY THERE
  942.     JNZ    NOLF
  943.     call    xyinline
  944.     db    1,5,'A TO D =$'
  945. NOLF:
  946.     MOV    A,B
  947.     OUT    PORT0
  948.     CALL    DELAY$8            ; A LITTLE DELAY FOR SAFETY SAKE
  949.     ORI    80H
  950.     OUT    PORT0
  951.     CALL    DELAY$8
  952.     ANI    07FH            ; MASK OFF TOP BIT
  953.     OUT    PORT0
  954.     NOP
  955.     NOP                ; SMALL DELAY
  956. LOOP1:
  957.     IN    PORT1
  958.     ANI    080H
  959.     JZ    LOOP1
  960. ;
  961.     IN    PORT0
  962.     MOV    C,A            ; SAVE VALUE INTO C
  963.     IN    PORT1
  964.     ANI    1            ; MASK BIT OF OPTO CHANNEL
  965.     MOV    M,A
  966.     INX    H
  967. ;
  968. ; DISPLAY THE VALUE OF THE A TO D CHANNEL
  969. ;
  970.     mvi    a,' '
  971.     call    dispatch
  972.     mov    a,c            ; GET A TO D VALUE
  973.     call    phacc            ; display hex value
  974. ;
  975.     inr    b
  976.     mov    a,b
  977.      cpi    32
  978.     jnz    loop
  979. ;
  980. ; HERE ALL THE ANALOG CHANNELS HAVE BEEN PRINTED
  981. ; NOW DO THE DIGITAL BIT CHANNELS
  982. ;
  983.     call    xyinline
  984.     db    1,15,'BITS  = $'
  985.     lxi    h,btab            ; POINT TO BIT TABLE
  986.     mvi    b,16            ; COUNT
  987. loop3:
  988.     mvi    a,' '
  989.     call    dispatch
  990.     mov    a,m
  991.     inx    h
  992. ; A 00 MEANS THE CHANNEL IS ON (REMENBER ??)
  993.     CPI    0
  994.     jrz    p1
  995.     mvi    a,'0'
  996.     call    dispatch
  997.     jr     loop4
  998. p1:
  999.     mvi    a,'1'
  1000.     call    dispatch
  1001. loop4:
  1002.     dcr    b
  1003.     mov    a,b
  1004.     ora    a
  1005.     jnz    loop3
  1006. ;
  1007.     call    cst
  1008.     jz    test8$start
  1009.     ret                ; return to main menu
  1010. ;
  1011. ; Subroutines for this test
  1012. DELAY$8:
  1013.     push    b
  1014.     push    psw
  1015.     mvi    b,03        ; WAIT A WHILE
  1016. DLOOP:
  1017.     call    cst
  1018.     jrnz    dloop2        ; end of
  1019.     djnz    dloop
  1020.     pop    psw
  1021.     pop    b
  1022.     ret
  1023. dloop2:
  1024.     call    cie
  1025.     pop    h        ; was psw
  1026.     pop    h        ; was bc
  1027.     pop    h        ; call delay
  1028.     ret            ; all done, return from the test
  1029. ;
  1030. ;----------------------------------------------------------------
  1031. ; This section tests the DRC-II dynamic memory board by doing the
  1032. ; following.
  1033. ;
  1034. ; 1) Fast interrupts from a CTC on SBC-800. This can cause problems
  1035. ;    if DRC-II decoding and refresf circuitry is faulty.
  1036. ; 2) Port decoding by quickly writing to ports F0..FE to check for
  1037. ;    a faulty port decoder chip of excess glitches on the bus.
  1038. ; 3) Walking bit test up memory and down memory.
  1039. ; 4) Barber pole memory test up and down memory.
  1040. ; 5) Test with a repeated number of LDIR Z-80 instructions.
  1041. ; 6) Test with a number of LDDR instructions.
  1042. ;
  1043. ; These tests are meant to be the most demanding that the DRC-II can
  1044. ; ever experience. This is meant to show up marginal boards.
  1045. ;----------------------------------------------------------------
  1046. ;
  1047. test9:           
  1048.     call    clear
  1049.     call    t9$overlay        ; display the overlay
  1050.     lxi    d,140bh
  1051.     sded    cur$cur            ; save the current cursor address
  1052.     call    cursor            ; set up
  1053.     mvi    a,'*'
  1054.     call    dispatch
  1055.     xra    a
  1056.     sta    t9$no            ; save the test number as 00
  1057. ;
  1058. test9$start:
  1059.     call    do$test9        ; do the actual test
  1060. ;
  1061. ;     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1062. ; This section must bump the number of loops counter
  1063. ; then must display it on the screen.
  1064. ; After this it must move the test indicator star to the next
  1065. ; test in the loop.
  1066. ;
  1067.     lded    cur$cur
  1068.     push    d            ; save for later use
  1069.     mov    a,d            ; get X value
  1070.     adi    16            ; point to the loop counter x value
  1071.     mov    d,a            ; save back
  1072.     call    cursor            ; set it up
  1073. ; Get the loop value, bump, save, write
  1074.     lda    t9$no            ; get test 9 test number, 0..4
  1075.     lxi    h,t9$loops        ; point to the loop counters
  1076.     mov    e,a
  1077.     mvi    d,00            ; use t9$no to index into loop values
  1078.     dad    d
  1079.     dad    d            ; Now HL -> an individual loop value
  1080.     mov    e,m
  1081.     inx    h
  1082.     mov    d,m
  1083.     inx    d            ; Bump the value
  1084.     mov    m,d        ; save
  1085.     dcx    h
  1086.     mov    m,e        ; save all
  1087. ; DE = loops done
  1088.     call    pdde            ; print as a decimal
  1089. ;
  1090. ; Move the test indicator star.
  1091.     pop    d            ; restore cursor address
  1092.     call    cursor            ; set up
  1093.     mvi    a,' '
  1094.     call    dispatch        ; clear it
  1095. ; Go to the next test position.
  1096.     lded    cur$cur
  1097.     mov    a,e            ; get y address
  1098.     cpi    19            ; last ??
  1099.     jrz    t9$restart
  1100.     inr    e
  1101.     inr    e            ; points to next test
  1102. ; Bump the test number
  1103.     lda    t9$no
  1104.     inr    a            ; indicate next test in progress
  1105.     jr    t9$restart$over
  1106. t9$restart:
  1107.     lxi    d,140bh
  1108.     xra    a            ; re-set to test number 00
  1109. t9$restart$over:
  1110.     sta    t9$no            ; save the test number
  1111.     sded    cur$cur            ; save the address
  1112.     call    cursor            ; set the cursor
  1113.     mvi    a,'*'
  1114.     call    dispatch
  1115. ; Now check for the end of tests.
  1116. ;
  1117.     call    cst
  1118.     jz    test9$start        ; 00 = No character there
  1119.     call    cie            ; Else we get the typed character
  1120.     ret                ; return to main menu
  1121. ;
  1122. ; This is the actual memory testing section
  1123. ; This decodes the test that must be done then jumps to it.
  1124. ; A return is done from the test if all is well else the test
  1125. ; will jump to test9$fail for an error.
  1126. ;
  1127. ;
  1128. do$test9:
  1129.     lxi    h,test9$table
  1130.     lda    t9$no            ; get the test number
  1131.     mov    e,a
  1132.     mvi    d,00
  1133.     dad    d
  1134.     dad    d            ; Now HL -> and address to go to
  1135.     mov    e,m            ; get low address
  1136.     inx    h
  1137.     mov    d,m            ; get high address
  1138.     push    d            ; put address on stack
  1139.     ret                ; goto the address
  1140. ;
  1141. test9$table:    ; A table of routine addresses
  1142.     dw    test9$test1        ; Interrupts
  1143.     dw    test9$test2        ; Port decoding
  1144.     dw    test9$test3        ; Walking Bit
  1145.     dw    test9$test4        ; Barber pole
  1146.     dw    test9$test5        ; LDIR / LDDR
  1147. ;
  1148. ;----------------~~~~~~~~~~~~~~~~----------------
  1149. ;    The memory test routines
  1150. ;~~~~~~~~~~~~~~~~----------------~~~~~~~~~~~~~~~~
  1151. ;
  1152. ; Do an interrupt response test. This initializes the
  1153. ; SBC-800 CTC channel 3 for fast interrupts then counts for
  1154. ; the iteration size to complete the test. When done the interrupts
  1155. ; are disabled.
  1156. ; If no SBC-800 there then this test returns immediately.
  1157. ;
  1158. vtab:
  1159.     org    ((vtab - start) and 0fff0h) + 10h
  1160. vectors:
  1161.     dw    int0
  1162.     dw    int1
  1163.     dw    int2
  1164.     dw    int3            ; interrupt address vectors
  1165. ;
  1166. ;
  1167. test9$test1:
  1168. ; Check for SBC-800. Read CTC-0 which is running the 9600 baud terminal
  1169. ; and see if we get an incrementing value. If not then no SBC-800 so return
  1170.     in    ctc0            ; read CTC-0
  1171.     mov    b,a            ; save
  1172. ; Do 1 Ms delay
  1173.     lxi    d,1
  1174.     call    delay
  1175. ; Re-get the CTC count and check if different
  1176.     in    ctc0            ; read CTC channel 0 again
  1177.     cmp    b
  1178.     jnz    t9t1$start
  1179. ; Here and NO SBC-800
  1180.     call    xyinline
  1181.     db    40,23,'SBC-800 Required for interrupt test$'
  1182.     ret
  1183. ; Start the Interrupt test by enabling interrupts on channel 3
  1184. ;
  1185. ; Set up interrupt vectors.
  1186. t9t1$start:
  1187.     lxi    h,t9t1            ; get iteration size
  1188.     shld    int$count        ; clear the interrupt counter
  1189.     lxi    d,vectors
  1190.     mov    a,e            ; low 8 bits of address
  1191.     out    ctc0            ; send. This is accepted as a vector
  1192.     mov    a,d            ; high 8 bits
  1193.     stai                ; put into interrupt register of Z80
  1194. ; Initialize the CTC for interrupts on channel 3 only
  1195.     mvi    a,085h            ; timer mode with interrupts
  1196.     out    ctc3            ; in timer mode, clk is from the bus
  1197.     mvi    a,20            ; count down value
  1198.     out    ctc3            ; put in the value
  1199.     im2                ; enable interrupts NOW
  1200.     ei
  1201. ;
  1202. ; Perform wait till int$count = 00 and exit then.
  1203. ;
  1204. t9t1$loop:
  1205.     lhld    int$count
  1206.     mov    a,h
  1207.     ora    l            ; H = L = 0 ??
  1208.     rz
  1209.     jmp    t9t1$loop
  1210. ;
  1211. ; These are the interrupt service routines
  1212. int0:
  1213. int1:
  1214. int2:
  1215.     call    stop$ctc        ; stop the CTC
  1216.     call    inline            ; display a message now
  1217.     db    0dh,0ah,'SBC-800 Illegal Interrupt$'
  1218.     ret                ; return to the main loop
  1219. ;
  1220. int3:
  1221.     lhld    int$count
  1222.     dcx    h
  1223.     shld    int$count
  1224. ; Check if this is the end of the cycle
  1225.     mov    a,l
  1226.     ora    h            ; does H = L = 00 ??
  1227.     jz    stop$ctc
  1228. ; If not a stop then keep on.
  1229.     ei                ; re-enable interrupts
  1230.     reti                ; return from interrupt
  1231. ;
  1232. stop$ctc:    ; Clear the CTC 
  1233.     di                ; stop interrupts
  1234.     call    dumret
  1235.     mvi    a,2
  1236.     out    ctc3            ; stop the timer NOW
  1237.     mvi    a,45            ; tell it a time constant follows
  1238.     out    ctc3
  1239.     mvi    a,13            ; the constant
  1240.     out    ctc3            ; this starts it counting ONLY
  1241.     ei                ; re-enable interrupts for any pending
  1242.     ret
  1243. ;
  1244. dumret:
  1245.     reti                ; clear pending CTC status
  1246. ;
  1247. ;
  1248. ; ~~~~~~~~~~~~~~~~----------------~~~~~~~~~~~~~~~~
  1249. ; This test does many output instructions to port addresses close to the
  1250. ; bank select port of the DRC-II in the hope that this will trigger the 
  1251. ; DRC-II to glithc and de-select itself. This is usually caused by faulty
  1252. ; port decoding logic.
  1253. ; ports user are f0..fe
  1254. ; ----------------~~~~~~~~~~~~~~~~----------------
  1255. ;
  1256. test9$test2:
  1257.     lxi    h,t9t2            ; port iteration size
  1258. test9$test2$loop:
  1259.     push    h            ; save loop counter
  1260.     mvi    b,0eh            ; number of ports
  1261.     mvi    c,0f0h            ; start port address
  1262. port$loop:
  1263.     call    send$port        ; send port (HL) times
  1264.     inr    c
  1265.     djnz    port$loop
  1266. ; Check for end of tests
  1267.     pop    h            ; restore counter
  1268.     dcx    h
  1269.     mov    a,l
  1270.     ora    h            ; see if H = L = 0 ???
  1271.     jrnz    test9$test2$loop
  1272.     ret                ; keep on till done
  1273. ;
  1274. ; Now the subroutine
  1275. send$port:
  1276.     push    b            ; save
  1277.     mvi    b,255            ; loop size
  1278.     outir                ; send m(HL) -> p(C) for (B) times
  1279.     pop    b
  1280.     ret
  1281. ;
  1282. ; This is the walking bit test. This is taken from the
  1283. ; ASMLIB library which is a routine by Leventhals' book 'Z-80 Subroutines'
  1284. ;
  1285. test9$test3:
  1286.     lxi    b,t9t3            ; number of loops
  1287. ; the loop. Load registers, call the routine, exit if an error.
  1288. test9$test3$loop:
  1289.     push    b            ; save it
  1290.     lded    mem$start        ; start of memory
  1291.     lhld    mem$end            ; end of memory
  1292.     call    ramwbt            ; do the test
  1293.     pop    b
  1294.     jc    test9$fail         ; error exit if a failure.
  1295.     dcx    b
  1296.     mov    a,c
  1297.     ora    b            ; does B = C = 00 ????
  1298.     jrnz    test9$test3$loop
  1299.     ret                ; do a return when all loop pass
  1300. ;
  1301. ; ~~~~ Barber Pole Test ~~~~
  1302. ;
  1303. ; This is the barber pole test. This is taken from the
  1304. ; ASMLIB library which is a routine by Leventhals' book 'Z-80 Subroutines'
  1305. ;
  1306. test9$test4:
  1307.     lxi    b,t9t4            ; number of loops
  1308. ; the loop. Load registers, call the routine, exit if an error.
  1309. test9$test4$loop:
  1310.     push    b            ; save it
  1311.     lded    mem$start        ; start of memory
  1312.     lhld    mem$end            ; end of memory
  1313.     call    rambpt            ; do the test
  1314.     pop    b
  1315.     jc    test9$fail         ; error exit if a failure.
  1316.     dcx    b
  1317.     mov    a,c
  1318.     ora    b            ; does B = C = 00 ????
  1319.     jrnz    test9$test4$loop
  1320.     ret                ; do a return when all loops pass
  1321. ;
  1322. ; ~~~~ LDIR / LDDR test. ~~~~
  1323. ; This moves a byte up and down the total available memory and then checks
  1324. ; is for accuracy. On each iteration the byte is loaded from the random number
  1325. ; generator so that a wide range of test values is checked. 
  1326. ; Each iteration does an LDIR then a check, an LDDR then a check.
  1327. ;
  1328. test9$test5:
  1329.     lxi    b,t9t5            ; get the number of loops
  1330. t9t5$loop:
  1331.     push    b            ; save
  1332. ; Do the LDIR test first
  1333.     lxi    d,seed            ; get a random number 
  1334.     call    rand8            ; A = random number
  1335.     lbcd    mem$size        ; get size of memory to test
  1336.     dcx    b            ; one less
  1337.     lhld    mem$start        ; get start address
  1338.     mov    m,a            ; load the seed
  1339.     mov    e,l
  1340.     mov    d,h            ; copy into DE for the destination
  1341.     inx    d            ; bump by one to propogate up ram
  1342.     ldir                ; do the move.
  1343.     lhld    mem$start
  1344.     lbcd    mem$size
  1345.     mov    e,a            ; save this value
  1346. ; Now the check of the byte in memory. Use a Z-80 auto check.
  1347.     mvi    a,'I'
  1348.     call    coe
  1349.     mvi    a,8
  1350.     call    coe
  1351. t9t5$loop2:
  1352.     mov    a,e            ; restore checking value
  1353.     cci                ; check m(HL) = A
  1354.     jnz    t9t5$error
  1355.     mov    e,a            ; save
  1356.     mov    a,c
  1357.     ora    b            ; does B = C = 0 ??
  1358.     jnz    t9t5$loop2
  1359. ;
  1360. ; **** Now do the LDDR checking. This is done in a similar way ****
  1361. ;
  1362.     lxi    d,seed            ; get a random number 
  1363.     call    rand8            ; A = random number
  1364.     lbcd    mem$size        ; get size of memory to test
  1365. ;    dcx    b            ; one less
  1366.     lhld    mem$end          ; get start address
  1367.     mov    m,a            ; load the seed
  1368.     mov    e,l
  1369.     mov    d,h            ; copy into DE for the destination
  1370.     dcx    d            ; deduct one to propogate down ram
  1371.     lddr                ; do the move.
  1372.     lhld    mem$start
  1373.     lbcd    mem$size
  1374.     mov    e,a            ; save the random check value
  1375. ;
  1376.     mvi    a,'D'            ; indicate a Decrementing test
  1377.     call    coe
  1378.     mvi    a,8            ; backspace
  1379.     call    coe
  1380. ; Now the check of the byte in memory. Use a Z-80 auto check.
  1381. t9t5$loop3:
  1382.     mov    a,e            ; restore checking value
  1383.     cci                ; check m(HL) = A
  1384.     jnz    t9t5$error
  1385.     mov    e,a            ; save
  1386.     mov    a,c
  1387.     ora    b            ; does B = C = 0 ??
  1388.     jnz    t9t5$loop3
  1389. ; Decrement the iteration counter and check for end of this test.
  1390.     pop    b            ; restore iteration counter
  1391.     dcx    b            ; one less loop to do
  1392.     mov    a,c
  1393.     ora    b            ; check if the iteration is done
  1394.     jnz    t9t5$loop
  1395. ; Clear old I or D when here
  1396.     mvi    a,' '            ; blank it
  1397.     call    coe
  1398.     ret                ; exit if all done
  1399. ;
  1400. ;
  1401. ;
  1402. t9t5$error:
  1403.     pop    b            ; restore stack
  1404.     jmp    test9$fail
  1405. ;
  1406. ; If a test fails then this routine is called. It increments the
  1407. ; fail counter, displays the value and also the address where the fail
  1408. ; occurred. This is the error section.
  1409. ;
  1410. ; On calling here HL -> error address in memory
  1411. ;
  1412. test9$fail:
  1413.     push    h            ; save the address
  1414. ; Index to the fail column
  1415.     lded    cur$cur            ; get current cursor address
  1416.     mov    a,d            ; get X address
  1417.     adi    23            ; add 23 to get to the fail column
  1418.     mov    d,a
  1419.     call    cursor            ; get there
  1420. ; Now get the number of fails, bump, save, display
  1421.     lxi    h,t9$fails        ; point to start of fail table
  1422.     lda    t9$no            ; get the test number
  1423.     mov    e,a
  1424.     mvi    d,00            ; load an index
  1425.     dad    d
  1426.     dad    d            ; now HL -> fail number for this test
  1427.     mov    e,m
  1428.     inx    h
  1429.     mov    d,m            ; now DE = number of fails
  1430.     inx    d            ; bump
  1431.     mov    m,d
  1432.     dcx    h
  1433.     mov    m,e            ; saved now
  1434. ; Now display it
  1435.     call    pdde            ; display as a decimal.
  1436. ; Now we need to display the address where the fail occurred
  1437.     call    inline
  1438.     db    '      $'        ; Use spaces to get there
  1439.     pop    d            ; restore HL -> DE for display
  1440.     call    pdde            ; display it
  1441. ; After all this, bump the total number of fails, save and then display.
  1442.     lxi    d,0d15h            ; col 13, line 21
  1443.     call    cursor
  1444.     lhld    t9$total$fails
  1445.     inx    h
  1446.     shld    t9$total$fails
  1447.     xchg
  1448.     call    pdde            ; display as a decimal
  1449.     ret                ; all done
  1450. ;
  1451. ;----------------------------------------------------------------
  1452. ; Major section to display the test 9 overlay that has all the parameters 
  1453. ; etc on it. This also displays the time start and a few other things to 
  1454. ; improve the niceness of the program.
  1455. ;----------------------------------------------------------------
  1456. ;
  1457. t9$overlay:
  1458.     lxi    d,t9$menu
  1459.     call    pmenu            ; display the text in one go
  1460. ; Put a line under the double line test headings
  1461.     lxi    d,010ah            ; col 1 , line 10
  1462.     call    cursor
  1463.     mvi    b,61            ; do 61 times
  1464.     mvi    a,'-'            ; send this character
  1465.     call    pstr            ; print a string of characters entry
  1466. ;
  1467. ; Now display the iteration size values
  1468.     call    blzb            ; select standard blanking
  1469.     lxi    d,1c0bh            ; X=28, Y=11
  1470.     call    cursor
  1471.     lxi    d,t9t1            ; first test size display
  1472.     call    pdde            ; display as a decimal
  1473. ;
  1474.     lxi    d,1c0dh            ; X=28, Y=13
  1475.     call    cursor
  1476.     lxi    d,t9t2            ; second test size display
  1477.     call    pdde            ; display as a decimal
  1478. ;
  1479.     lxi    d,1c0fh            ; X=28, Y=15
  1480.     call    cursor
  1481.     lxi    d,t9t3            ; third test size display
  1482.     call    pdde            ; display as a decimal
  1483. ;
  1484.     lxi    d,1c11h            ; X=28, Y=17
  1485.     call    cursor
  1486.     lxi    d,t9t4            ; fourth test
  1487.     call    pdde
  1488. ;
  1489.     lxi    d,1c13h            ; X=28, Y=19
  1490.     call    cursor
  1491.     lxi    d,t9t5            ; fourth test
  1492.     call    pdde
  1493. ;
  1494. ; Put a line under the tests, this places them in a table
  1495.     lxi    d,0114h
  1496.     call    cursor
  1497.     mvi    a,'-'
  1498.     mvi    b,61
  1499.     call    pstr
  1500. ;
  1501. ; Display the time now
  1502.     lxi    d,03004h
  1503.     call    cursor
  1504.     lxi    d,tim$buf        ; locate a time string buffer
  1505.     call    clkrd
  1506. ;
  1507.     call    nolzb            ; display time without lzb
  1508.     lda    hrs
  1509.     call    phacc
  1510.     mvi    a,':'            ; a spacer
  1511.     call    dispatch
  1512.     lda    mins
  1513.     call    phacc
  1514.     mvi    a,':'
  1515.     call    dispatch
  1516.     lda    secs
  1517.     call    phacc
  1518. ; Now get memory start address and save
  1519.     lxi    d,datend        ; data end variable in ASMLIB
  1520.     lxi    h,0200h            ; a little margin for error
  1521.     dad    d
  1522.     shld    mem$start        ; save as the test area memory start
  1523.     lxi    d,01a04h        ; 
  1524.     call    cursor
  1525.     xchg                ; memory start is now in DE
  1526.     call    phde            ; display without LZB
  1527.     push    d            ; save the end address
  1528. ; Get the memory end address, display, save then calculate the memory size 
  1529. ; to be tested.
  1530.     lxi    d,01a05h
  1531.     call    cursor
  1532. ; Load 0bfffh as the memory end address
  1533.     lxi    d,0bfffh
  1534.     sded    mem$end
  1535.     call    phde
  1536. ; Now the memory size
  1537.     ora    a
  1538.     xchg                ; HL = memory end address
  1539.     pop    d            ; DE = memory start
  1540.     dsbc    d
  1541.     shld    mem$size        ; save the memory size
  1542. ;
  1543.     call    blzb
  1544.     ret
  1545. ;
  1546. ;----------------------------------------------------------------
  1547. ; TESTNO is loaded from the users keypress. It is used to vector
  1548. ; around this program and is a little vital. It is also used for
  1549. ; input / output testing of serial devices to decode which
  1550. ; i/O driver to be used. It is in ASCII not hex (easier).
  1551. ;----------------------------------------------------------------
  1552. ;
  1553. menu:
  1554.     db    10,03,'SME Systems Board Test Program V1.2$'
  1555.     db    10,04,'--------------20/01/84-------------$'
  1556.  
  1557.     db    10,06,'       Enter an option$'
  1558.  
  1559.  
  1560.     db    10,08,' 1) Test SPC-29 PARALLEL ports$'
  1561.     db    10,09,' 2) Test SPC-29 SERIAL port 1$'
  1562.     db    10,10,' 3) Test SPC-29 SERIAL port 2$'
  1563.     db    10,11,' 4) Test FDC-3  SERIAL port$'
  1564.     db    10,12,' 5) Test SBC-800 Centronic printer port$'
  1565.     db    10,13,' 6) Test SBC-800 Serial port 2$'
  1566.     db    10,14,' 7) Test MPC-6 serial channels$'
  1567.     db    10,15,' 8) Display ADC-32 data$'
  1568.     db    10,16,' 9) Test DRC-II memory$'
  1569.     db    10,17,' C) Display program CRC$'
  1570.     db    10,19,' Q) Quit to CP/M$'
  1571.     db    10,21,'?$'
  1572.     db    0ffh            ; signal end
  1573. ;
  1574. progend:
  1575.     db    00        ; used to get the CRC code of the program
  1576. ;
  1577. ;
  1578. ; The next addresses point to the names of the I/O drivers. This is used
  1579. ; to display the name of the I/O device that ASMLIB has been linked for
  1580. ; and is also used to check if the user has the correct driver to suit the
  1581. ; application.
  1582. ;
  1583. names:
  1584.     dw    io1            ; CP/M io
  1585.     dw    io2            ; SBC800 io
  1586.     dw    io3            ; CPMMPC
  1587.     dw    io4            ; SBCMPC
  1588. ;
  1589. io1:    db    'CP/M$'
  1590. io2:    db    'SBC-800$'
  1591. io3:    db    'CP/M & MPC-6$'
  1592. io4:    db    'SBC-800 & MPC-6$'
  1593. ;
  1594. channel    db    00            ; channel to log onto (see mpc-6)
  1595. ;
  1596. test$234$msg:
  1597.     db    0dh,0ah,'Entering Echo mode, press ^C to exit $'
  1598. ;
  1599. test$234$msg2:
  1600.     db    0dh,0ah,'Connect terminal back to main port then'
  1601.     db    ' PRESS A RETURN - BYE$'
  1602. ;
  1603. seed    db    5,89,90,198,5,245
  1604. testno    db    00            ; This is used by the initializer
  1605. ;
  1606. btab    db    16
  1607. ;
  1608. ;~~~~ Test 9 data and variable 
  1609. ;
  1610. t9$no:    db    00            ; test 9 section #
  1611. t9$bnk:    db    00            ; memory board bank number
  1612. t9$loops:
  1613.     db    00,00            ; section loop counter
  1614.     db    00,00            ; section loop counter
  1615.     db    00,00            ; section loop counter
  1616.     db    00,00            ; section loop counter
  1617.     db    00,00            ; section loop counter
  1618. ;
  1619. t9$fails:
  1620.     db    00,00            ; number of fails
  1621.     db    00,00            ; number of fails
  1622.     db    00,00            ; number of fails
  1623.     db    00,00            ; number of fails
  1624.     db    00,00            ; number of fails
  1625. ;
  1626. t9$total$fails:
  1627.     db    00,00            ; total number of fails
  1628. ;
  1629. mem$start:
  1630.     db    00,00
  1631. ;
  1632. mem$end:
  1633.     db    00,00
  1634. ;
  1635. mem$size:
  1636.     db    00,00
  1637. ;
  1638. int$count:
  1639.     db    00,00            ; number of interrupt cycles
  1640. ;
  1641. cur$cur:
  1642.     db    00,00            ; current cursor position
  1643. ;
  1644. tim$buf:
  1645.     db    00,00,00,00
  1646. hrs    db    00
  1647. mins    db    00
  1648. secs    db    00
  1649. ;
  1650. t9$menu:
  1651.     db    30,01,'Memory Test Section$'
  1652.     db    21,04,'From$'
  1653.     db    23,05,'To$'
  1654.     db    36,04,'Time Start$'
  1655.     db    38,05,'Time End$'
  1656.     db    03,08,'Test$'
  1657.     db    16,08,'Current  Iterations  Loops  Fails  Fail Address$'
  1658.     db    18,09,'Test      Size$'
  1659.     db    01,11,'Interrupts$'
  1660.     db    01,13,'Port Addressing$'
  1661.     db    01,15,'Walking Bit$'
  1662.     db    01,17,'Barber Pole$'
  1663.     db    01,19,'LDIR / LDDR$'
  1664.     db    01,21,'Total Fails$'
  1665.     db    01,23,'Press Any Key To Quit$'
  1666.     db    0ffh
  1667. ;
  1668. ;
  1669.     end
  1670.