subttl '(c) 1981 Morrow Designs' title 'Mult I/O test' aseg org 0100h .z80 ACR equ 0Dh ;carriage return ALF equ 0Ah ;line feed ASP equ ' ' ;space AFF equ 0Ch ;form feed BEl equ 07H ;bell BSP equ 08H ;backspace CLEAR equ 01ah ; ascii clear screen ESC equ 01bh ; ascii escape char ANUL equ 0 ; ascii null bdos equ 5 AQU equ 027h ;ascii quote ;**************************************************************** ;* * ;* Wunderbus I/O equates: * ;* * ;**************************************************************** base equ 048h ;I/O base address of wunderbus ports group0 equ 00h group1 equ 01h ;serial port 1 group2 equ 02h ;serial port 2 Šgroup3 equ 03h ;serial port 3 grpctl equ base+7 ;I/O group select port ; primary UART equates dll equ base ;divisor latch lsb dlm equ base+1 ;divisor latch msb ier equ base+1 ;interupt enable register lcr equ base+3 ;line control register mcr equ base+4 ;modem control register lsr equ base+5 ;line status register rbr equ base ;read data buffer thr equ base ;transmitter data buffer ; secondary i/o equates sbase equ 058h ;I/O base address of wunderbus ports sgrpctl equ sbase+7 ;I/O group select port sdll equ sbase ;divisor latch lsb sdlm equ sbase+1 ;divisor latch msb sier equ sbase+1 ;interupt enable register slcr equ sbase+3 ;line control register smcr equ sbase+4 ;modem control register slsr equ sbase+5 ;line status register srbr equ sbase ;read data buffer sthr equ sbase ;transmitter data buffer dlab equ 80h ;divisor latch access bit thre equ 20h ;status line TBE dr equ 01 ;line status DR bit wls0 equ 01 ;word length select bit 0 wls1 equ 02 ;word length select bit 1 (for 8 bit word) stb equ 04 ;stop bit count (2 stop bits) imask equ 00 ;non interupt mode loop equ 010h ;UART loop mode ;************************ ;* B E G I N * ;************************ init: ld sp,1000h ld e,CLEAR call printf ;clear screen ld de,signon call pstring ; announce test ld a,9 ;select group 1 out (sgrpctl),a in a,(sthr) ; read the buffer cp 0ffh ; should be 0 if present jr nz,init1 ld de,ports3 jr init2 init1: ld de,ports6 init2: call pstring call uartst ; initialize the uarts call bufill ; initialize buffers call test0 main: call test0 call test2 ld hl,qbf ld (pattern),hl call test1 ; quick brown fox call test2 ld hl,lqbf ld (pattern),hl ; again with lower case call test1 main2: call pbuffs ; print the buffers ld de,8000h main3: push de call test2 ; check for character input pop de dec de ld a,d or e jp nz,main3 jp main2 ;******************************************************** ;* * ;* The following code intitializes the I/O for * ;* the Decision 1 Motherboard and the Mult I/O. * ;* * ;******************************************************** Š uartst: ld d,1 ;start with uart 1 uarts0: ld a,d out (grpctl),a out (sgrpctl),a xor a out (lsr),a ;clear line status register out (slsr),a out (ier),a ;initialialize interupt mask (off) out (sier),a dec d jr nz,uarts0 out (grpctl),a ;select sense switch port out (sgrpctl),a in a,(base+1) rlca rlca rlca and 07h ;mask insignificant bits cp 07h ;all off? ld d,0 jr z,default ;default if all off ld hl,btable ;point to baud rate table add a,a ld e,a add hl,de ;offset to selected baud rate ld c,(hl) inc hl ld b,(hl) ;bc = baud rate divisor value (D) jr setit default: ld bc,12 ;default baud rate is 9600 setit: inc d ld a,d cp 04h ;all UARTS initialized?? jr nz,setit1 ; keep going till done ld a,1 out (grpctl),a ;set group back to ttyA ret setit1: out (grpctl),a out (sgrpctl),a ld a,dlab+wls1+wls0+stb out (lcr),a ;divisor access bit is on out (slcr),a ld a,b out (dlm),a ;load high divisor register out (sdlm),a ld a,c out (dll),a ;load low divisor register out (sdll),a ld a,wls1+wls0+stb out (lcr),a ;divisor access bit is off out (slcr),a ld a,03h out (ier),a ;enable the interrupts out (sier),a jr setit ;loop till all UARTS initialized ; initialize the tty input buffers with an ASCII null bufill: ld a,ANUL ; fill character ld hl,bufend ; point to beginning of buffer ld de,abuff ; point to end of buffer bufl0: ld (hl),a dec hl ; next location push hl sbc hl,de ; check for end of buffer pop hl jr nz,bufl0 ret ; send the barber pole pattern test0: ld c,3 test00: ld a,c ld b,'0' ;start with ascii zero out (grpctl),a ;select uart out (sgrpctl),a test01: call tmout ;print it call stmt inc b ld a,b cp 'z' + 1 jr nz,test01 call acrlf call scrlf dec c jr nz,test00 ;next uart ret ; send the character to primary I/O all resgisters preserved tmout: push de push af ld d,0h ;retry count tmout1: dec d jp z,tmret ;keep trying (255 times) conout: in a,(lsr) and thre jr z,conout ld a,b out (thr),a ;send char./clear interrupt tmret: pop af pop de ret ; send character to secondary I/O all resgisters preserved stmt: push de push af ld d,0h stmt1: dec d jp z,scret scout: in a,(slsr) cp 0ffh ;check for mio present jr z,scret ; return if none present and thre jr z,scout ld a,b out (sthr),a scret: pop af pop de ret ; a carriage return / line feed with direct I/O acrlf: push bc ld b,ALF call tmout pop bc pacr: push bc ld b,ACR call tmout pop bc ret scrlf: push bc ld b,ALF call stmt pop bc psacr: push bc ld b,ACR call stmt pop bc ret ; send the string test1: ld c,3 strng1: ld hl,(pattern) ;get the pattern address strng2: ld a,c out (grpctl),a ;select uart out (sgrpctl),a strng3: ld a,(hl) cp '$' ; loop till end of string jp z,strng4 inc hl ld b,a call tmout ;print it call stmt jp strng3 strng4: call acrlf ; new line call scrlf dec c jr nz,strng1 ; loop for all uarts ret ; check for uart character received test2: ld a,0 ld (board),a ; save for storit routine ld c,3 getchr: ld a,c out (grpctl),a ; select the next uart ld (uart),a ; save for storit routine call cstat ; was key pressed cp 0 ; returns zero if not call nz,storit ; save it in buffer dec c jp nz,getchr ; check second board tst2: ld a,1 ld (board),a ; save for storit routine ld c,3 sgtchr: ld a,c out (sgrpctl),a ; select the next uart ld (uart),a ; save for storit routine call scstat ; was key pressed cp 0 ; returns zero if not call nz,storit ; save it in buffer dec c jp nz,sgtchr ret ; check 1st 3 ports for data ready cstat: in a,(lsr) and dr ; check for character present ret z in a,(rbr) and 07fh ld b,a cp 03 ; check for ^C to quit jp z,0 ; quit if escape typed cp ESC jp z,init out (thr),a ; echo it ret ; check second 3 ports for data ready scstat: in a,(slsr) cp 0ffh jr nz,scst1 ld a,0 ret scst1: and dr ; check for character present ret z in a,(srbr) and 07fh ld b,a cp 03 ; check for ^C to quit jp z,0 ; quit if escape typed cp ESC jp z,init out (sthr),a ; echo it ret ; routine entered with character in the b register ; and uart # and board expected in memory storage ; uart, board. Character stored in the apropriate ; line buffer location. Only the bc registers preserved. storit: push bc ld hl,abuff ; offset for first board ld de,80 ; buffer size ld a,(board) cp 0 jp z,calcit ld hl,dbuff ;offset for second board calcit: ld a,(uart) ; make it a number ld c,a ; -from 0 - 5 calc1: dec c jp z,calc2 adc hl,de ; get the right buffer jp calc1 ; loop till right offset calc2: ld a,(hl) ; get the byte count inc a cp 79 ; end of line? jp nz,calc3 ld a,0 calc3: ld (hl),a ; update byte counter inc hl ; point to data buffer push de ld e,a ld d,0 adc hl,de ; offset to right byte pop de ld (hl),b pop bc ret ; pbuffs uses prints the buffer contents ; ... first select and print the first 3 ports pbuffs: ld hl,abuff ;point to beginning of buffers pbuf1: ld c,1 ; uart count pbuf2: ld a,c out (grpctl),a ; select uart call pacr ld d,79 ; byte count pbuf3: inc hl ld b,(hl) ; get character call tmout ; print it dec d jp nz,pbuf3 ;print the whole buffer inc c ld a,c cp 4 jp z,spbuf inc hl ; skip the size byte jp pbuf2 ; ...then select and print the 2nd three ports spbuf: ld hl,dbuff ;point to beginning of buffers spbf1: ld c,1 ; uart count spbf2: ld a,c out (sgrpctl),a ; select uart call psacr ld d,79 ; byte count spbf3: inc hl ld b,(hl) ; get character call stmt ; print it dec d jp nz,spbf3 ;print the whole buffer inc c ld a,c cp 4 ret z inc hl ; skip the size byte jp spbf2 ;*************************** ;* CP/M related stuff * ;*************************** ; print a crlf through cp/m crlf: ld e,ACR printf: ld c,2 call bdos ld c,2 ld e,ALF call bdos ret ; Print string (de = string on entry) pstring: ld c,9 call bdos call crlf ret ; wait for an "ESCAPE" to be typed escape: ld c,0bh ; check for key pressed call bdos cp 0 ret z ; return if not pressed ld c,1 call bdos ; get character cp ESC ; was it the escape key? ret nz jp 0 ; return to cp/m ; Baud rate selection table for Mult I/o or WB I/O btable: dw 1047 ;110 baud 0 0 0 dw 384 ;300 baud 0 0 1 dw 96 ;1200 baud 0 1 0 dw 48 ;2400 baud 0 1 1 dw 24 ;4800 baud 1 0 0 dw 12 ;9600 baud 1 0 1 dw 6 ;19200 baud 1 1 0 signon: db ' Morrow Designs serial port quick test (Rev.0)' db ACR,ALF db ' for testing Decision 1 computers (including D220).' db ACR,ALF db ' (c) 1984, Morrow Designs ' db ACR,ALF,ALF,ALF db 'Type on any terminal: => control C to return to CP/M.' db ACR,ALF,ALF db ' => ESC to redraw the test patterns.' db ACR,ALF,ALF db ' => any other key will be echoed, then captured ' db ACR,ALF db ' in a read buffer. The buffer will be sent to ' db ACR,ALF db ' the appropriate port at 10 second intervals. ' db ACR,ALF,ALF, '$' ports6: db ' Now testing 6 ports... ' db ACR,ALF,'$' ports3: db ' Now testing 3 ports... ' db ACR,ALF,'$' qbf: db ACR,ALF,ALF db ' THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG', AQU, 'S BACK 0123456789 $' lqbf: db ' the quick brown fox jumped over the lazy dog', AQU, 's back 0123456789 ' db ACR,ALF, '$' uart: db 0 board: db 0 pattern: dw 0 ; first byte is buffer position ; next 80 are the characters to print abuff: ds 80 bbuff: ds 80 cbuff: ds 80 dbuff: ds 80 ebuff: ds 80 fbuff: ds 80 bufend equ $ end MIOCHECK Instructions Thå prograí MIOCHECK.COÍ provideó á quicë anä easù waù oæ testinç alì  thå  seriaì portó iî thå Morro÷ Designó Decisioî ±  computeò including the 6 serial port model D220® Thió  tesô  wilì verifù thaô eacè porô caî transmiô  anä  receivå characteró aô thå correcô bauä rate® However¬ thió tesô wilì noô checë  operatioî oæ auxilliarù UARÔ functionó  (e.g®  interrupts¬ modeí controì anä modeí status). Thå  tesô  runó undeò CP/Í 8° anä sendó á messagå tï thå  consolå aô thå beginninç oæ execution®  Thió messagå printó thå  versioî number of the test and the instructions. Thå tesô theî printó ouô ² lineó oæ thå entirå displayablå  ASCIÉ characteò  seô  startinç  witè "space¢ tï verifù  thå  porô  caî transmiô alì characters® Nexô thå tesô printó thå now ubiquitous pattern: THE QUICK BROWN FOX JUMPED OVER THE LAZY DOG'S BACK 0123456789 the quick brown fox jumped over the lazy dog's back 0123456789 Thå  tesô theî waitó foò keyboarä input®  Aó sooî aó á characteò ió typed¬  iô ió displayeä oî thå screen®  Thå characteò ió alsï storeä  iî  á  linå buffeò anä  transmitteä  tï  thå  appropriatå terminaì  aô  1° seconä intervals®  Thå buffeò ió 8°  characteró long®  Iæ yoõ typå iî morå thaî 8° characters¬ thå characteró aô thå beginninç oæ thå buffeò geô overwritten®  Thió allowó yoõ tï check correct reception of all characters from a terminal. Wheî yoõ arå satisfieä thå consolå porô workó correctly¬ pluç thå seriaì  cablå  intï thå nexô seriaì porô anä presó  thå  "ESCAPE¢ key®  Thå  twï  tesô patternó wilì bå senô tï thå  terminaì  anä agaiî thå prograí waitó foò terminaì input® Continuå thå procesó for all 6 ports. SPECIAL KEYS Wheî  thå prograí beginó iô printó thå followinç messagå  oî  thå console: Type on any terminal: => control C to return to CP/M. => ESC to redraw the test patterns. => any other key will be echoed, then captured in a read buffer. The buffer will be sent to the appropriate port at 10 second intervals. ŠPressinç  thå  "ESCAPE¢ keù anytimå durinç thå tesô wilì  restarô thå tesô froí thå beginning®  Pressinç thå "CONTROL¢ keù anä thå "c¢ keù simaltaneouslù wilì returî tï CP/M®  Alì otheò keyó wilì be printed on the terminal and stored in the line buffer. BAUD RATES The default serial settings are: baud rate = 9600 baud stop bits = 2 start bits = 1 data bits = 8 These settings are common for all 6 serial ports. Thå  test¬  aô beginninç oæ executioî oò iæ thå "ESCAPE¢  keù  ió typed¬ wilì reaä thå senså switcheó oî thå Decisioî ± motherboarä anä set the baud rates as follows: SWITCH 10A POSITION BAUD RATE 1 2 3 4 5 6 7 8 on on on - - - - - 9600 * on on off - - - - - 19200 on off on - - - - - 9600 on off off - - - - - 4800 off on on - - - - - 2400 off on off - - - - - 1200 off off on - - - - - 300 off off off - - - - - 110 NOTE: - indicates a don't care * indicates factory switch setting