home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / MEX / MXO-S511.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  17KB  |  657 lines

  1.     TITLE    'MEX overlay for SSM IO5  v1.0'
  2.  
  3. ; MXO-S511.ASM -- SSM IO5 overlay for MEX     86/10/20
  4.  
  5. VERSION    equ    11        ;version number
  6.  
  7. ; NOTE 1: This overlay is designed for use with either MEXPLUS or MEX.
  8. ;    Edit this file for your preferences, then follow the 'TO USE'
  9. ;    example shown below.
  10. ;
  11. ; NOTE 2: The SSM IO-5 board supports two Intel 8251s plus 3 parallel ports.
  12. ;    Extensive configuration options are supported by the many jumpers on
  13. ;    this board, but only a few of them relate to software.  These are
  14. ;    supported by the SET command, as follows:
  15. ;        SET BASE    sets base port number of board
  16. ;        SET PORT    selects which serial port (A or B)
  17. ;        SET DATA    select position of data port (0 or 1); the
  18. ;                status port will be at the other address
  19. ;    Other SET commands supported:
  20. ;        SET DIAL    select pulse/touch dialing
  21.  
  22.  
  23. ; TO USE: First edit this file filling in answers for your own equipment,
  24. ;    then assemble with ASM.COM or equivalent assembler.  Finally,
  25. ;    depending on the version of Mex, create an executable module:
  26. ;
  27. ;    For MEX (v1.1x), use MLOAD (v2.3 or later) to overlay the base
  28. ;    .COM file:
  29. ;        A>MLOAD MEX.COM=MEX114.COM,[MXO-SMxx,]MXO-S5xx
  30. ;            where MXO-SMxx is an optional modem overlay.
  31. ;
  32. ;    For MEXPLUS (v1.2 or greater), use MLOAD to create an overlay
  33. ;    file (.OVR), boot MEXPLUS, and use its builtin LOAD command to
  34. ;    install the overlay:
  35. ;        A>MLOAD MXO-MMxx.OVR=MXO-S5xx.HEX
  36. ;        A>MEXPLUS
  37. ;        [MEX] A0>>LOAD MXO-S5XX.OVR
  38. ;
  39. ; =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
  40. ;
  41. ; 86.10.20 - v1.1: fixed bad generation of port    - Roger Burrows
  42. ;           addresses if DEFPORT is 'B'
  43. ; 86.10.03 - v1.0: created first version    - Roger Burrows
  44. ;
  45. ; =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
  46.  
  47. YES    equ    0FFH
  48. NO    equ    0
  49.  
  50. BELL    equ    07H        ;bell
  51. TAB    equ    09H        ;tab
  52. LF    equ    0AH        ;linefeed
  53. CR    equ    0DH        ;carriage return
  54. ESC    equ    1BH        ;escape
  55.  
  56. ; Change the following information to match your equipment
  57.  
  58. DEFBASE    equ    090H        ;Default base address for IO5 board
  59. DEFPORT    equ    'A'        ;Default serial port
  60. DEFDATA    equ    0        ;Default data port
  61.  
  62. ; End of information to change
  63.  
  64. DEFSTAT    equ    1-DEFDATA    ;Default status port
  65.  
  66. DATA    equ    DEFBASE+(DEFPORT-'A')*2+DEFDATA    ;8251 data port
  67.  
  68. STATUS    equ    DEFBASE+(DEFPORT-'A')*2+DEFSTAT    ;8251 status port
  69. RXRDY    equ    02H        ;  Receiver Ready
  70. MDRCVB    equ    RXRDY        ;    Bit to test for Receive
  71. MDRCVR    equ    RXRDY        ;    & value when ready
  72. TXEMPTY    equ    04H        ;  Transmitter Empty
  73. MDSNDB    equ    TXEMPTY        ;    Bit to test for Send
  74. MDSNDR    equ    TXEMPTY        ;    & value when ready
  75.  
  76. COMMAND    equ    STATUS        ;8251 command port
  77. TXEN    equ    01H        ;  Transmit Enable
  78. DTR    equ    02H        ;  Data Terminal Ready
  79. RXEN    equ    04H        ;  Receive Enable
  80. SBRK    equ    08H        ;  Send Break
  81. ER    equ    10H        ;  Error Reset
  82. RTS    equ    20H        ;  Request To Send
  83. IR    equ    40H        ;  Internal Reset
  84. STDMODE    equ    4EH        ;Standard Mode Value (see 8251 spec):
  85.                 ;  bits: 8 data, 1 stop, no parity
  86.                 ;  baud rate factor = 16x
  87.  
  88. ; MEX service processor
  89.  
  90. MEX    equ    0D00h        ;address of the service processor
  91. INMDM    equ    255        ;get char from port to A, CY=no more in 100 ms
  92. TIMER    equ    254        ;delay 100ms * reg B
  93. TMDINP    equ    253        ;B=# secs to wait for char, cy=no char
  94. CHEKCC    equ    252        ;check for ^C from KBD, Z=present
  95. SNDRDY    equ    251        ;test for modem-send ready
  96. RCVRDY    equ    250        ;test for modem-receive ready
  97. SNDCHR    equ    249        ;send a character to the modem (after sndrdy)
  98. RCVCHR    equ    248        ;recv a char from modem (after rcvrdy)
  99. LOOKUP    equ    247        ;table search: see CMDTBL comments for info
  100. PARSFN    equ    246        ;parse filename from input stream
  101. BDPARS    equ    245        ;parse baud-rate from input stream
  102. SBLANK    equ    244        ;scan input stream to next non-blank
  103. EVALA    equ    243        ;evaluate numeric from input stream
  104. LKAHED    equ    242        ;get nxt char w/o removing from input
  105. GNC    equ    241        ;get char from input, cy=1 if none
  106. ILP    equ    240        ;inline print
  107. DECOUT    equ    239        ;decimal output
  108. PRBAUD    equ    238        ;print baud rate
  109.  
  110. CONOUT    equ    2        ;simulated BDOS function 2: console char out
  111. PRINT    equ    9        ;simulated BDOS function 9: print string
  112. INBUF    equ    10        ;input buffer, same structure as BDOS 10
  113.  
  114.  
  115.     org    100h        ;we begin
  116.  
  117.     ds    3        ;for the "JMP START" instruction
  118. PMODEM:    db    NO        ;yes=PMMI modem \ / These 2 locations are not
  119. SMODEM:    db    NO        ;yes=Smartmodem / \ referenced by MEX
  120. TPULSE:    db    'T'        ;T=touch, P=pulse (referenced by MXO-SMxx)
  121. CLOCK:    db    40        ;clock speed x .1, up to 25.5 mhz.
  122. MSPEED:    db    5        ;sets display time for sending a file
  123.                 ;0=110    1=300  2=450  3=600  4=710
  124.                 ;5=1200 6=2400 7=4800 8=9600 9=19200
  125. BYTDLY:    db    5        ;default time to send character in
  126.                 ;terminal mode file transfer (0-9)
  127.                 ;0=0 delay, 1=10 ms, 5=50 ms, 9=90 ms
  128. CRDLY:    db    5        ;end-of-line delay after CRLF in terminal
  129.                 ;mode file transfer for slow BBS systems
  130.                 ;0=0 delay, 1=100 ms, 5=500 ms, 9=900 ms
  131. COLUMS:    db    5        ;number of directory columns
  132. SETFL:    db    YES        ;yes=user-defined SET command
  133. SCRTST:    db    YES        ;yes=if home cursor and clear screen
  134.                 ;routine at CLRSCRN
  135.     db    0        ;was once ACKNAK, now spare
  136. BAKFLG:    db    NO        ;yes=make .BAK file
  137. CRCDFL:    db    YES        ;yes=default to CRC checking
  138.                 ;no=default to Checksum checking
  139. TOGCRC:    db    YES        ;yes=allow toggling of Checksum to CRC
  140. CVTBS:    db    NO        ;yes=convert backspace to rub
  141. TOGLBK:    db    YES        ;yes=allow toggling of bksp to rub
  142. ADDLF:    db    NO        ;no=no LF after CR to send file in
  143.                 ;terminal mode (added by remote echo)
  144. TOGLF:    db    YES        ;yes=allow toggling of LF after CR
  145. TRNLOG:    db    YES        ;yes=allow transmission of logon
  146.                 ;write logon sequence at location LOGON
  147. SAVCCP:    db    YES        ;yes=do not overwrite CCP
  148. LOCNXT:    db    NO        ;yes=local cmd if EXTCHR precedes
  149.                 ;no=not local cmd if EXTCHR precedes
  150. TOGLOC:    db    YES        ;yes=allow toggling of LOCNXTCHR
  151. LSTTST:    db    YES        ;yes=allow toggling of printer on/off
  152.                 ;in terminal mode. Set to no if using
  153.                 ;the printer port for the modem
  154. XOFTST:    db    NO        ;yes=allow testing of XOFF from remote
  155.                 ;while sending a file in terminal mode
  156. XONWT:    db    NO        ;yes=wait for XON after sending CR while
  157.                 ;transmitting a file in terminal mode    
  158. TOGXOF:    db    YES        ;yes=allow toggling of XOFF testing
  159. IGNCTL:    db    NO        ;yes=do not send control characters
  160.                 ;above CTL-M to CRT in terminal mode
  161.                 ;no=send any incoming CTL-char to CRT
  162. EXTRA1:    db    0        ;for future expansion
  163. EXTRA2:    db    0        ;for future expansion
  164. BRKCHR:    db    '@'-40h        ;^@ = Send a 300 ms. break tone
  165. NOCONN:    db    'N'-40h        ;^N = Disconnect from phone line
  166. LOGCHR:    db    'L'-40h        ;^L = Send logon
  167. LSTCHR:    db    'P'-40h        ;^P = Toggle printer
  168. UNSVCH:    db    'R'-40h        ;^R = Close input text buffer
  169. TRNCHR:    db    'T'-40h        ;^T = Transmit file to remote
  170. SAVCHR:    db    'Y'-40h        ;^Y = Open input text buffer
  171. EXTCHR:    db    '^'-40h        ;^^ = Send next character
  172.     ds    2        ;used for PMMI (not referenced by MEX)
  173.  
  174. INSTAT:                ;in modem status port
  175. ST1:    in    STATUS
  176.     ret
  177.  
  178. ; We have 7 free bytes here, so let's use them (for modem stuff)
  179.  
  180. OUTCMD:                ;mex doesn't know about this
  181. ST2:    out    COMMAND
  182.     ret
  183.  
  184. ; Default values for BASE, PORT, DATA
  185.  
  186. BASEVAL:db    DEFBASE        ;or this
  187. PORTVAL:db    DEFPORT
  188. DATAVAL:db    DEFDATA
  189.  
  190.     db    0
  191.  
  192. OTDATA:                ;out modem data port
  193. DA1:    out    DATA
  194.     ret
  195.     db    0,0,0,0,0,0,0
  196.  
  197. INDATA:                ;in modem data port
  198. DA2:    in    DATA
  199.     ret
  200.     db    0,0,0,0,0,0,0
  201.  
  202. MASKR:    ani    MDRCVB        ;bit to test for receive ready
  203.     ret
  204. TESTR:    cpi    MDRCVR        ;value of receive bit when ready
  205.     ret
  206. MASKS:    ani    MDSNDB        ;bit to test for send ready
  207.     ret
  208. TESTS:    cpi    MDSNDR        ;value of send bit when ready
  209.     ret
  210.  
  211. DCDTST:    jmp    DCDVEC        ;data carrier detect (MEXPLUS)
  212. RNGDET:    jmp    RNGVEC        ;ring detect (MEXPLUS)
  213.     db    0,0,0,0,0    ;reserved
  214. SMDISC:    ds    3        ;smartmodem disconnect (MEXPLUS)
  215.  
  216. DIALV:    ds    3        ;dial digit in A
  217. DISCV:    jmp    PDISC        ;disconnect modem (with DTR)
  218. GOODBV:    jmp    GOODBY        ;call just before exit to CP/M
  219. INMODV:    jmp    INITMD        ;called on entry from CP/M
  220. NEWBDV:    jmp    DUMMY        ;set new baud rate
  221. NOPARV:    jmp    DUMMY        ;set modem for no parity
  222. PARITV:    jmp    DUMMY        ;set modem for parity
  223. SETUPV:    jmp    SETCMD        ;process SET cmd
  224.     ds    3        ;reserved, not used by MEX
  225. VERSNV:    jmp    SYSVER        ;sign-on message from overlay
  226. BREAKV:    jmp    PBREAK        ;send a break
  227.  
  228. ; Do not change the following six lines
  229. ; (jump vectors, not supported in MEX 2.0)
  230.  
  231.     ds    3        ;replace with MEX function 9
  232.     ds    3        ;replace with MEX function 10
  233.     ds    3        ;replace with MEX function 247
  234.     ds    3        ;replace with MEX function 255
  235.     ds    3        ;not supported by MEX
  236.     ds    3        ;replace with MEX function 254
  237.  
  238. ; Routines to clear screen & clear to end of screen.  If using
  239. ; these routines, set SCRTST to YES at 010AH (above).
  240.  
  241. CLREOS:    mvi    c,PRINT
  242.     lxi    d,TCLEOS
  243.     call    MEX
  244.     ret
  245.  
  246. CLS:    mvi    c,PRINT
  247.     lxi    d,TCLSCR
  248.     call    MEX
  249.     ret
  250.  
  251. ; End of fixed area ... from here to 1FFH is reserved (MEXPLUS)
  252.  
  253.     org    200H
  254.  
  255. ;..........    start of free-format user routines    ..........
  256.  
  257. ; Return data carrier detect status (MEXPLUS)
  258.  
  259. DCDVEC:    mvi    a,254        ;not supported - no DCD on 8251s
  260.     ret
  261.  
  262. ; Return ring indicator status (MEXPLUS)
  263.  
  264. RNGVEC:    mvi    a,254        ;not supported - no RI on 8251s
  265.     ret
  266.  
  267. ; Disconnect modem
  268.  
  269. PDISC:    call    INDATA        ;clear any pending data
  270.     mvi    A,TXEN+RXEN+ER+RTS    ;turn off DTR
  271.     call    OUTCMD        ;clear DTR in command reg
  272.     mvi    b,3        ;delay 300 milliseconds
  273.     mvi    c,TIMER
  274.     call    MEX
  275.     mvi    a,TXEN+DTR+RXEN+ER+RTS    ;set DTR to modem again
  276.     call    OUTCMD
  277.     ret
  278.  
  279. ; Exit to CP/M
  280.  
  281. GOODBY:    call    INDATA        ;clear any pending data
  282.     xra    a        ;turn off everything (DTR, RTS etc)
  283.     call    OUTCMD
  284.     ret
  285.  
  286. ; Enter from CP/M (also called from FIXIO)
  287.  
  288. INITMD:    mvi    b,3        ;send 3 nulls
  289.     xra    a        ; to force to command state
  290. INITLP:    call    OUTCMD
  291.     dcr    b
  292.     jnz    INITLP
  293.     mvi    a,IR        ;reset to mode level
  294.     call    OUTCMD
  295.     mvi    a,STDMODE     ;set standard mode
  296.     call    OUTCMD
  297.     mvi    a,TXEN+DTR+RXEN+ER+RTS    ;enable receive, transmit, DTR, RTS
  298.     call    OUTCMD
  299.     ret
  300.  
  301. ; Dummy routine
  302.  
  303. DUMMY:    ret
  304.  
  305. ; Issue signon message
  306.  
  307. SYSVER:    mvi    c,ILP
  308.     call    MEX
  309.     db    'Version ',VERSION/10+'0','.',VERSION MOD 10+'0'
  310.     db    ' for SSM IO5 board',CR,LF,0
  311.     mvi    c,ILP
  312.     call    MEX
  313.     db    'Base address ',0
  314.     lda    BASEVAL        ;print base port number
  315.     call    PRTHEX
  316.     mvi    c,ILP
  317.     call    MEX
  318.     db    ', serial port ',0
  319.     mvi    c,CONOUT
  320.     lda    PORTVAL        ;print serial port (A or B)
  321.     mov    e,a
  322.     call    MEX
  323.     mvi    c,ILP        ;show data port as even or odd
  324.     call    MEX
  325.     db    ', data port is ',0
  326.     lda    DATAVAL
  327.     lxi    d,EVEN        ;print even/odd
  328.     ora    a        ;is it even ?
  329.     jz    SYSVR1        ;yes
  330.     lxi    d,ODD        ;else odd
  331. SYSVR1:    mvi    c,PRINT
  332.     call    MEX
  333.     mvi    c,ILP
  334.     call    MEX
  335.     db    ', ',0
  336.     lda    TPULSE
  337.     lxi    d,PLSMSG    ;print pulse/touch
  338.     cpi    'P'        ;is it pulse ?
  339.     jz    SYSVR2        ;yes
  340.     lxi    d,TCHMSG    ;else touch
  341. SYSVR2:    mvi    c,PRINT
  342.     call    MEX
  343.     mvi    c,ILP
  344.     call    MEX
  345.     db    ' dialing',0
  346.     ret
  347.  
  348. ; Send break to remote
  349.  
  350. PBREAK:    mvi    a,TXEN+DTR+RXEN+SBRK+ER+RTS    ;set break
  351.     call    OUTCMD
  352.     mvi    b,3                ;delay 300 milliseconds
  353.     mvi    c,TIMER
  354.     call    MEX
  355.     mvi    a,TXEN+DTR+RXEN+ER+RTS        ;resuming normal service ...
  356.     call    OUTCMD
  357.     ret
  358.  
  359. ; Handle SET command
  360.  
  361. SETCMD:    mvi    c,SBLANK    ;any arguments?
  362.     call    MEX
  363.     jc    STSHOW        ;if not, go print out values
  364.     mvi    c,LOOKUP
  365.     lxi    d,CMDTBL    ;parse command
  366.     call    MEX
  367.     jc    SETERR        ;can't find it
  368.     pchl            ;else go there
  369. SETERR:    mvi    c,PRINT
  370.     lxi    d,SETEMS    ;print error
  371.     call    MEX
  372.     ret
  373.  
  374. SETEMS:    db    'SET command error',CR,LF,CR,LF,'$'
  375.  
  376. CMDTBL:    db    '?'+80h            ; "set ?"
  377.     dw    STHELP
  378.     db    'BAS','E'+80h        ; "set base"
  379.     dw    STBASE
  380.     db    'DAT','A'+80h        ; "set data"
  381.     dw    STDATA
  382.     db    'DIA','L'+80h        ; "set dial"
  383.     dw    STDIAL
  384.     db    'POR','T'+80h        ; "set port"
  385.     dw    STPORT
  386.     db    0
  387.  
  388. ; SET <no-args>: print current statistics
  389.  
  390. STSHOW:    lxi    h,SHOTBL    ;get table of SHOW subroutines
  391. STSHLP:    mov    e,m        ;get table address
  392.     inx    h
  393.     mov    d,m
  394.     inx    h
  395.     mov    a,d        ;end of table?
  396.     ora    e
  397.     rz            ;exit if so
  398.     push    h        ;save table pointer
  399.     xchg            ;adrs to HL
  400.     call    GOHL        ;do it
  401.     mvi    c,CHEKCC    ;check for console abort
  402.     call    MEX
  403.     pop    h        ;it's done
  404.     jnz    STSHLP        ;continue if no abort
  405.     call    CRLF
  406.     ret
  407.  
  408. GOHL:    pchl
  409.  
  410. ; table of SHOW subroutines
  411.  
  412. SHOTBL:    dw    SHOWBA
  413.     dw    SHOWPO
  414.     dw    SHOWDT
  415.     dw    SHOWDL
  416.     dw    0
  417.  
  418. ; SET ?  processor
  419.  
  420. STHELP:    mvi    c,PRINT
  421.     lxi    d,HLPMSG
  422.     call    MEX
  423.     ret
  424.  
  425. ; The help message
  426.  
  427. HLPMSG:    db    CR,LF,'SET command options:'
  428.     db    CR,LF,'  SET BASE <hex #>      ... set new base port (00,10 ... F0)'
  429.     db    CR,LF,'  SET DATA <0|1>        ... set data port address (0=even,1=odd)'
  430.     db    CR,LF,'  SET DIAL <P|T>        ... set Pulse or Touch dialing'
  431.     db    CR,LF,'  SET PORT <A|B>        ... set serial port id'
  432.     db    CR,LF
  433. CRLFMS:    db    CR,LF,'$'
  434.  
  435. ; SET BASE command processor
  436.  
  437. STBASE:    mvi    c,SBLANK    ;skip blanks
  438.     call    MEX
  439.     jc    SETERR        ;nothing else
  440.     lxi    h,0        ;use HL to build port #
  441. STBAS1:    push    h        ;save across MEX
  442.     mvi    c,GNC        ;get char from input, cy=1 if none
  443.     call    MEX
  444.     pop    h        ;restore
  445.     jc    STBAS2
  446.     call    HEXCON        ;convert to hex nybble in A
  447.     jc    SETERR        ;not hex
  448.     dad    h        ;shift L left by 4 bits
  449.     dad    h
  450.     dad    h
  451.     dad    h
  452.     ora    l        ;or with new nybble
  453.     mov    l,a        ;back to L
  454.     mov    a,h        ;anything in H yet ?
  455.     ora    a
  456.     jnz    SETERR        ;yes - too big
  457.     jmp    STBAS1        ;else go round again
  458. STBAS2:    mov    a,l        ;reg L contains base port #
  459.     ani    0fh        ;check boundary alignment
  460.     jnz    SETERR        ;no good
  461.     mov    a,l        ;ok - save for display
  462.     sta    BASEVAL
  463.     call    FIXIO        ;fix up in/out with BASEVAL,PORTVAL,DATAVAL
  464. SHOWBA:    mvi    c,ILP
  465.     call    MEX
  466.     db    'Base address set to ',0
  467.     lda    BASEVAL
  468.     call    PRTHEX
  469.     call    CRLF
  470.     ret
  471.  
  472. ; SET DATA processor
  473.  
  474. STDATA:    mvi    c,SBLANK    ;skip blanks
  475.     call    MEX
  476.     jc    SETERR        ;nothing else
  477.     mvi    c,EVALA        ;get numeric from input
  478.     call    MEX
  479.     mov    a,h
  480.     ora    a        ;> 256 ?
  481.     jnz    SETERR        ;yes, error
  482.     mov    a,l
  483.     cpi    2        ;check it
  484.     jnc    SETERR        ;invalid
  485.     sta    DATAVAL        ;store it
  486.     call    FIXIO        ;fix up in/out with BASEVAL,PORTVAL,DATAVAL
  487. SHOWDT:    mvi    c,ILP
  488.     call    MEX
  489.     db    'Data port set to ',0
  490.     lda    DATAVAL        ;get data setting
  491.     lxi    d,EVEN        ;assume even
  492.     ora    a        ;is it ?
  493.     jz    SHOWT2        ;yes
  494.     lxi    d,ODD        ;else odd
  495. SHOWT2:    mvi    c,PRINT
  496.     call    MEX
  497.     call    CRLF
  498.     ret
  499.  
  500. ; SET DIAL processor
  501.  
  502. STDIAL:    mvi    c,SBLANK    ;skip blanks
  503.     call    MEX
  504.     jc    SETERR        ;nothing else
  505.     lxi    d,DIALTB    ;parse cmd
  506.     mvi    c,LOOKUP
  507.     call    MEX
  508.     jc    SETERR
  509.     mov    a,l        ;get upper case character
  510.     sta    TPULSE        ;store it for MXO-SMxx
  511. SHOWDL:    mvi    c,ILP        ;display status
  512.     call    MEX
  513.     db    'Dialing type set to ',0
  514.     lda    TPULSE        ;get pulse/touch setting
  515.     lxi    d,PLSMSG    ;assume pulse
  516.     cpi    'P'        ;is it ?
  517.     jz    SHOWD2        ;yes
  518.     lxi    d,TCHMSG    ;else touch
  519. SHOWD2:    mvi    c,PRINT
  520.     call    MEX
  521.     call    CRLF
  522.     ret
  523.  
  524. ; Dial table - saves us worrying about upper/lower case
  525.  
  526. DIALTB:    db    'P'+80H        ;pulse dial
  527.     db    'P',0
  528.     db    'T'+80H        ;touch dial
  529.     db    'T',0
  530.     db    0
  531.  
  532. ; SET PORT processor
  533.  
  534. STPORT:    mvi    c,SBLANK    ;skip blanks
  535.     call    MEX
  536.     jc    SETERR        ;nothing else
  537.     lxi    d,PORTTB    ;parse cmd
  538.     mvi    c,LOOKUP
  539.     call    MEX
  540.     jc    SETERR
  541.     mov    a,l        ;get upper case character
  542.     sta    PORTVAL        ;a-ok, save it
  543.     call    FIXIO        ;fix up in/out with BASEVAL,PORTVAL,DATAVAL
  544. SHOWPO:    mvi    c,ILP        ;display status
  545.     call    MEX
  546.     db    'Port set to ',0
  547.     mvi    c,CONOUT
  548.     lda    PORTVAL
  549.     mov    e,a
  550.     call    MEX        ;display it
  551.     call    CRLF
  552.     ret
  553.  
  554. ; Port table - saves us worrying about upper/lower case
  555.  
  556. PORTTB:    db    'A'+80H
  557.     db    'A',0
  558.     db    'B'+80H
  559.     db    'B',0
  560.     db    0
  561.  
  562. ;..........    subroutines used by the above routines    ..........
  563.  
  564. ; Convert ascii char in A to hex nybble
  565.  
  566. HEXCON:    cpi    '0'        ;< '0' ?
  567.     rc            ;error - return with carry set
  568.     cpi    '9'+1        ;<= '9' ?
  569.     jc    HEXNUM        ;yes - must be 0-9
  570.     cpi    'A'        ;< 'A' ?
  571.     rc            ;error
  572.     cpi    'F'+1        ;<= 'F' ?
  573.     jc    HEXALF        ;yes - convert to hex nybble
  574.     cpi    'a'        ;< 'a' ?
  575.     rc            ;error
  576.     cpi    'f'+1        ;<= 'f' ?
  577.     jnc    HEXERR        ;no - error
  578.     sui    'a'-'A'        ;convert lower case a-f to upper
  579. HEXALF:    stc
  580.     adi    9        ;convert upper case A-F to 3ah-3fh
  581. HEXNUM:    ani    0fh        ;clear high-order nybble
  582.     ret
  583. HEXERR:    stc
  584.     ret
  585.  
  586. ; Print contents of A as hex, followed by 'h'
  587.  
  588. PRTHEX:    push    psw        ;save A
  589.     rrc            ;right justify one hex digit
  590.     rrc
  591.     rrc
  592.     rrc
  593.     call    PRTNYB        ;print first hex digit
  594.     pop    psw
  595.     call    PRTNYB        ;print second hex digit
  596.     mvi    c,CONOUT
  597.     mvi    e,'h'
  598.     call    MEX        ;print trailing 'h'
  599.     ret
  600.  
  601. ; Print hex nybble
  602.  
  603. PRTNYB:    ani    0fh        ;print one hex digit
  604.     adi    90h        ;trust me, this works
  605.     daa
  606.     aci    40h
  607.     daa            ;now ascii
  608.     mvi    c,CONOUT    ;print it
  609.     mov    e,a
  610.     call    MEX
  611.     ret
  612.  
  613. ; Do cr, lf
  614.  
  615. CRLF:    mvi    c,PRINT
  616.     lxi    d,CRLFMS
  617.     call    MEX
  618.     ret
  619.  
  620. ; Update in & out instructions with new BASEVAL, PORTVAL, DATAVAL
  621.  
  622. FIXIO:    lda    PORTVAL        ;get port id
  623.     sui    'A'        ; make it 0 or 1
  624.     add    a        ;  then 0 or 2 (offset to 1st reg for A or B)
  625.     mov    b,a        ;   in reg b
  626.     lda    BASEVAL        ;get base address
  627.     ora    b
  628.     mov    b,a        ;b = address of even port
  629.     lda    DATAVAL        ;get data port offset
  630.     ora    b        ;a = address of data port
  631.     sta    DA1+1
  632.     sta    DA2+1
  633.     xri    01h        ;now a = address of status port
  634.     sta    ST1+1
  635.     sta    ST2+1
  636.     jmp    INITMD        ;go reinitialise ports & return
  637.  
  638. ; Miscellaneous messages
  639.  
  640. EVEN:    db    'even address','$'
  641. ODD:    db    'odd address','$'
  642. PLSMSG:    db    'pulse','$'
  643. TCHMSG:    db    'touch','$'
  644.  
  645. ; Terminal-dependent control sequences
  646.  
  647. TCLEOS:    db    17H,'$'        ;clear to end-of-screen
  648. TCLSCR:    db    18H,'$'        ;clear screen
  649.  
  650. ;.....
  651. ;
  652. ; Note:    This overlay must terminate prior to 0B00H (with Smartmodem overlay)
  653. ;                         0D00H (without Smartmodem overlay)
  654. ;.....
  655.  
  656.     END
  657.