home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / mex / mxo-i510.asm < prev    next >
Assembly Source File  |  1994-07-13  |  21KB  |  816 lines

  1.     TITLE    'Interrupt-driven MEX overlay for SSM IO5  v1.0'
  2.  
  3. ; MXO-I510.ASM -- SSM IO5 overlay for MEX     86/11/22
  4.  
  5. VERSION    equ    10        ;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. ;        SET RST        selects restart vector to use
  20. ;    Other SET commands supported:
  21. ;        SET DIAL    select pulse/touch dialing
  22.  
  23.  
  24. ; TO USE: First edit this file filling in answers for your own equipment,
  25. ;    then assemble with ASM.COM or equivalent assembler.  Finally,
  26. ;    depending on the version of Mex, create an executable module:
  27. ;
  28. ;    For MEX (v1.1x), use MLOAD (v2.3 or later) to overlay the base
  29. ;    .COM file:
  30. ;        A>MLOAD MEX.COM=MEX114.COM,[MXO-SMxx,]MXO-I5xx
  31. ;            where MXO-SMxx is an optional modem overlay.
  32. ;
  33. ;    For MEXPLUS (v1.2 or greater), use MLOAD to create an overlay
  34. ;    file (.OVR), boot MEXPLUS, and use its builtin LOAD command to
  35. ;    install the overlay:
  36. ;        A>MLOAD MXO-MMxx.OVR=MXO-I5xx.HEX
  37. ;        A>MEXPLUS
  38. ;        [MEX] A0>>LOAD MXO-I5XX.OVR
  39. ;
  40. ; =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =   =
  41. ;
  42. ; 86.11.22 - v1.0: created first version, based on    - Roger Burrows
  43. ;           MXO-S511.ASM
  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    'B'        ;Default serial port (A or B)
  60. DEFDATA    equ    0        ;Default data port (0=even, 1=odd)
  61. DEFRST    equ    7        ;Default restart code (1 thru 7)
  62.  
  63. ; End of information to change
  64.  
  65. DEFSTAT    equ    1-DEFDATA    ;Default status port
  66.  
  67. DATA    equ    DEFBASE+(DEFPORT-'A')*2+DEFDATA    ;8251 data port
  68.  
  69. STATUS    equ    DEFBASE+(DEFPORT-'A')*2+DEFSTAT    ;8251 status port
  70. TXRDY    equ    01H        ;  Transmitter Empty
  71. MDSNDB    equ    TXRDY        ;    Bit to test for Send
  72. MDSNDR    equ    TXRDY        ;    & value when ready
  73. RXRDY    equ    02H        ;  Receiver Ready
  74. MDRCVB    equ    RXRDY        ;    Bit to test for Receive
  75. MDRCVR    equ    RXRDY        ;    & value when ready
  76.  
  77. COMMAND    equ    STATUS        ;8251 command port
  78. TXEN    equ    01H        ;  Transmit Enable
  79. DTR    equ    02H        ;  Data Terminal Ready
  80. RXEN    equ    04H        ;  Receive Enable
  81. SBRK    equ    08H        ;  Send Break
  82. ER    equ    10H        ;  Error Reset
  83. RTS    equ    20H        ;  Request To Send
  84. IR    equ    40H        ;  Internal Reset
  85. STDCMD    equ    TXEN+DTR+RXEN+RTS ;standard command combination
  86. STDMODE    equ    4EH        ;Standard Mode Value (see 8251 spec):
  87.                 ;  bits: 8 data, 1 stop, no parity
  88.                 ;  baud rate factor = 16x
  89.  
  90. ; MEX service processor
  91.  
  92. MEX    equ    0D00h        ;address of the service processor
  93. INMDM    equ    255        ;get char from port to A, CY=no more in 100 ms
  94. TIMER    equ    254        ;delay 100ms * reg B
  95. TMDINP    equ    253        ;B=# secs to wait for char, cy=no char
  96. CHEKCC    equ    252        ;check for ^C from KBD, Z=present
  97. SNDRDY    equ    251        ;test for modem-send ready
  98. RCVRDY    equ    250        ;test for modem-receive ready
  99. SNDCHR    equ    249        ;send a character to the modem (after sndrdy)
  100. RCVCHR    equ    248        ;recv a char from modem (after rcvrdy)
  101. LOOKUP    equ    247        ;table search: see CMDTBL comments for info
  102. PARSFN    equ    246        ;parse filename from input stream
  103. BDPARS    equ    245        ;parse baud-rate from input stream
  104. SBLANK    equ    244        ;scan input stream to next non-blank
  105. EVALA    equ    243        ;evaluate numeric from input stream
  106. LKAHED    equ    242        ;get nxt char w/o removing from input
  107. GNC    equ    241        ;get char from input, cy=1 if none
  108. ILP    equ    240        ;inline print
  109. DECOUT    equ    239        ;decimal output
  110. PRBAUD    equ    238        ;print baud rate
  111.  
  112. CONOUT    equ    2        ;simulated BDOS function 2: console char out
  113. PRINT    equ    9        ;simulated BDOS function 9: print string
  114. INBUF    equ    10        ;input buffer, same structure as BDOS 10
  115.  
  116.  
  117.     org    100h        ;we begin
  118.  
  119.     ds    3        ;for the "JMP START" instruction
  120. PMODEM:    db    NO        ;yes=PMMI modem \ / These 2 locations are not
  121. SMODEM:    db    NO        ;yes=Smartmodem / \ referenced by MEX
  122. TPULSE:    db    'T'        ;T=touch, P=pulse (referenced by MXO-SMxx)
  123. CLOCK:    db    40        ;clock speed x .1, up to 25.5 mhz.
  124. MSPEED:    db    5        ;sets display time for sending a file
  125.                 ;0=110    1=300  2=450  3=600  4=710
  126.                 ;5=1200 6=2400 7=4800 8=9600 9=19200
  127. BYTDLY:    db    5        ;default time to send character in
  128.                 ;terminal mode file transfer (0-9)
  129.                 ;0=0 delay, 1=10 ms, 5=50 ms, 9=90 ms
  130. CRDLY:    db    5        ;end-of-line delay after CRLF in terminal
  131.                 ;mode file transfer for slow BBS systems
  132.                 ;0=0 delay, 1=100 ms, 5=500 ms, 9=900 ms
  133. COLUMS:    db    5        ;number of directory columns
  134. SETFL:    db    YES        ;yes=user-defined SET command
  135. SCRTST:    db    YES        ;yes=if home cursor and clear screen
  136.                 ;routine at CLRSCRN
  137.     db    0        ;was once ACKNAK, now spare
  138. BAKFLG:    db    NO        ;yes=make .BAK file
  139. CRCDFL:    db    YES        ;yes=default to CRC checking
  140.                 ;no=default to Checksum checking
  141. TOGCRC:    db    YES        ;yes=allow toggling of Checksum to CRC
  142. CVTBS:    db    NO        ;yes=convert backspace to rub
  143. TOGLBK:    db    YES        ;yes=allow toggling of bksp to rub
  144. ADDLF:    db    NO        ;no=no LF after CR to send file in
  145.                 ;terminal mode (added by remote echo)
  146. TOGLF:    db    YES        ;yes=allow toggling of LF after CR
  147. TRNLOG:    db    YES        ;yes=allow transmission of logon
  148.                 ;write logon sequence at location LOGON
  149. SAVCCP:    db    YES        ;yes=do not overwrite CCP
  150. LOCNXT:    db    NO        ;yes=local cmd if EXTCHR precedes
  151.                 ;no=not local cmd if EXTCHR precedes
  152. TOGLOC:    db    YES        ;yes=allow toggling of LOCNXTCHR
  153. LSTTST:    db    YES        ;yes=allow toggling of printer on/off
  154.                 ;in terminal mode. Set to no if using
  155.                 ;the printer port for the modem
  156. XOFTST:    db    NO        ;yes=allow testing of XOFF from remote
  157.                 ;while sending a file in terminal mode
  158. XONWT:    db    NO        ;yes=wait for XON after sending CR while
  159.                 ;transmitting a file in terminal mode    
  160. TOGXOF:    db    YES        ;yes=allow toggling of XOFF testing
  161. IGNCTL:    db    NO        ;yes=do not send control characters
  162.                 ;above CTL-M to CRT in terminal mode
  163.                 ;no=send any incoming CTL-char to CRT
  164. EXTRA1:    db    0        ;for future expansion
  165. EXTRA2:    db    0        ;for future expansion
  166. BRKCHR:    db    '@'-40h        ;^@ = Send a 300 ms. break tone
  167. NOCONN:    db    'N'-40h        ;^N = Disconnect from phone line
  168. LOGCHR:    db    'L'-40h        ;^L = Send logon
  169. LSTCHR:    db    'P'-40h        ;^P = Toggle printer
  170. UNSVCH:    db    'R'-40h        ;^R = Close input text buffer
  171. TRNCHR:    db    'T'-40h        ;^T = Transmit file to remote
  172. SAVCHR:    db    'Y'-40h        ;^Y = Open input text buffer
  173. EXTCHR:    db    '^'-40h        ;^^ = Send next character
  174.     ds    2        ;used for PMMI (not referenced by MEX)
  175.  
  176. INSTAT:            ;in modem status port
  177.     jmp    STATIN        ;(can't fit code into 10 bytes)
  178.  
  179. ; Default values for BASE, PORT, DATA, RST (here to save space)
  180.  
  181.     db    'DFT'        ;eyecatcher
  182. BASEVAL:db    DEFBASE
  183. PORTVAL:db    DEFPORT
  184. DATAVAL:db    DEFDATA
  185. RSTVAL:    db    DEFRST
  186.  
  187.  
  188. OTDATA:    di        ;out modem data port
  189. DA1:    out    DATA
  190.     mvi    a,STDCMD    ;have to turn TXEN back on
  191.     call    OUTCMD        ; to transmit data 
  192.     ei
  193.     ret
  194.  
  195. INDATA:            ;in modem data port
  196.     jmp    DATAIN        ;(can't fit code into 10 bytes)
  197.  
  198. ; Buffer pointers & overrun counter (here to save space)
  199.  
  200.     db    'BU'        ;eyecatcher
  201. INTPTR:    dw    BUFFER        ;next spot where interrupt routine stores data
  202. MEXPTR:    dw    BUFFER        ;next spot where mex gets data from
  203. OVERUN:    db    0        ;number of buffer overruns
  204.  
  205.  
  206. MASKR:    ani    MDRCVB        ;bit to test for receive ready
  207.     ret
  208. TESTR:    cpi    MDRCVR        ;value of receive bit when ready
  209.     ret
  210. MASKS:    ani    MDSNDB        ;bit to test for send ready
  211.     ret
  212. TESTS:    cpi    MDSNDR        ;value of send bit when ready
  213.     ret
  214.  
  215. DCDTST:    jmp    DCDVEC        ;data carrier detect (MEXPLUS)
  216. RNGDET:    jmp    RNGVEC        ;ring detect (MEXPLUS)
  217.     db    0,0,0,0,0    ;reserved
  218. SMDISC:    ds    3        ;smartmodem disconnect (MEXPLUS)
  219.  
  220. DIALV:    ds    3        ;dial digit in A
  221. DISCV:    jmp    PDISC        ;disconnect modem (with DTR)
  222. GOODBV:    jmp    GOODBY        ;call just before exit to CP/M
  223. INMODV:    jmp    INITMD        ;called on entry from CP/M
  224. NEWBDV:    jmp    DUMMY        ;set new baud rate
  225. NOPARV:    jmp    DUMMY        ;set modem for no parity
  226. PARITV:    jmp    DUMMY        ;set modem for parity
  227. SETUPV:    jmp    SETCMD        ;process SET cmd
  228.     ds    3        ;reserved, not used by MEX
  229. VERSNV:    jmp    SYSVER        ;sign-on message from overlay
  230. BREAKV:    jmp    PBREAK        ;send a break
  231.  
  232. ; Do not change the following six lines
  233. ; (jump vectors, not supported in MEX 2.0)
  234.  
  235.     ds    3        ;replace with MEX function 9
  236.     ds    3        ;replace with MEX function 10
  237.     ds    3        ;replace with MEX function 247
  238.     ds    3        ;replace with MEX function 255
  239.     ds    3        ;not supported by MEX
  240.     ds    3        ;replace with MEX function 254
  241.  
  242. ; Routines to clear screen & clear to end of screen.  If using
  243. ; these routines, set SCRTST to YES at 010AH (above).
  244.  
  245. CLREOS:    mvi    c,PRINT
  246.     lxi    d,TCLEOS
  247.     call    MEX
  248.     ret
  249.  
  250. CLS:    mvi    c,PRINT
  251.     lxi    d,TCLSCR
  252.     call    MEX
  253.     ret
  254.  
  255. ; End of fixed area ... from here to 1FFH is reserved (MEXPLUS)
  256.  
  257.     org    200H
  258.  
  259. ;..........    start of free-format user routines    ..........
  260.  
  261. ; Return data carrier detect status (MEXPLUS)
  262.  
  263. DCDVEC:                ;not supported - no DCD on 8251s
  264.                 ;(drops through into RNGVEC)
  265.  
  266. ; Return ring indicator status (MEXPLUS)
  267.  
  268. RNGVEC:    mvi    a,254        ;not supported - no RI on 8251s
  269. DUMMY:    ret
  270.  
  271. ; Get input status by combining hardware & buffer status
  272.  
  273. STATIN:    push    h        ;save regs
  274. ST1:    in    STATUS
  275.     ani    255-MDRCVR    ;turn off real input status
  276.     mov    h,a        ;and save across s/rtn call
  277.     call    COMPTR        ;compare pointers
  278.     mov    a,h        ;restore status
  279.     pop    h        ; & regs
  280.     rz            ;equal, return any o/p status
  281.     ori    MDRCVR        ;else set i/p waiting
  282.     ret
  283.  
  284. ; Get input data (from buffer)
  285.  
  286. DATAIN:
  287.     call    COMPTR        ;buffer empty ?
  288.     mvi    a,BELL        ;yes - return with a bell (mex shouldn't
  289.     rz            ;    be calling us anyway)
  290.     push    h        ;save regs
  291.     push    d
  292.     lhld    MEXPTR        ;get data ptr
  293.     mov    d,m        ;get the byte
  294.     call    INCPTR        ;up the pointer
  295.     shld    MEXPTR        ; & save
  296.     mov    a,d        ;put byte where mex wants it
  297.     pop    d        ;restore regs
  298.     pop    h
  299.     ret
  300.  
  301. ;*************** keep the next few routines together ***************
  302.  
  303. ; Send break to remote
  304.  
  305. PBREAK:    call    FLUSH        ;flush buffer first
  306.     mvi    a,STDCMD+SBRK    ;set break
  307.     jmp    ODO        ;go output, delay, then output
  308.  
  309. ; Disconnect modem
  310.  
  311. PDISC:    call    FLUSH        ;flush buffer first
  312.     mvi    a,STDCMD-DTR    ;turn off DTR
  313.  
  314. ; Output A to command port, Delay 300 millisecs, then Output normal command
  315.  
  316. ODO:    call    OUTCMD
  317.     mvi    b,3        ;delay 300 milliseconds
  318.     mvi    c,TIMER
  319.     call    MEX
  320.  
  321. ; Output command to resume normal status
  322.  
  323. NORMST:    mvi    a,STDCMD    ;resuming normal service ...
  324.  
  325. ; Output to command port
  326.  
  327. OUTCMD:                ;output to command port
  328. CO1:    out    COMMAND
  329.  
  330. ; Dummy routine
  331.  
  332.     ret
  333.  
  334. ;*************** end of 'drop-through' routines ***************
  335.  
  336. ; Enter from CP/M
  337.  
  338. INITMD:    call    FIXRST        ;set up restart vector
  339.     call    FIXIO        ;fix up port references
  340.     ret
  341.  
  342. ; Exit to CP/M
  343.  
  344. GOODBY:    di            ;disable interrupts
  345.     xra    a        ;turn off everything (DTR, RTS etc)
  346.     jmp    OUTCMD        ;which returns
  347.  
  348. ; Issue signon message
  349.  
  350. SYSVER:    mvi    c,ILP
  351.     call    MEX
  352.     db    'Version ',VERSION/10+'0','.',VERSION MOD 10+'0'
  353.     db    ' for SSM IO5 board at base address ',0
  354.     lda    BASEVAL        ;print base port number
  355.     call    PRTHEX
  356.     call    CRLF
  357.     mvi    c,ILP
  358.     call    MEX
  359.     db    'Serial port ',0
  360.     mvi    c,CONOUT
  361.     lda    PORTVAL        ;print serial port (A or B)
  362.     mov    e,a
  363.     call    MEX
  364.     mvi    c,ILP        ;show data port as even or odd
  365.     call    MEX
  366.     db    ', data port is ',0
  367.     lda    DATAVAL
  368.     lxi    d,EVEN        ;print even/odd
  369.     ora    a        ;is it even ?
  370.     jz    SYSVR1        ;yes
  371.     lxi    d,ODD        ;else odd
  372. SYSVR1:    mvi    c,PRINT
  373.     call    MEX
  374.     mvi    c,ILP
  375.     call    MEX
  376.     db    ', restart code ',0
  377.     lhld    RSTVAL        ;print restart code
  378.     mvi    h,0
  379.     mvi    c,DECOUT
  380.     call    MEX
  381.     mvi    c,ILP
  382.     call    MEX
  383.     db    ', ',0
  384.     lda    TPULSE
  385.     lxi    d,PLSMSG    ;print pulse/touch
  386.     cpi    'P'        ;is it pulse ?
  387.     jz    SYSVR2        ;yes
  388.     lxi    d,TCHMSG    ;else touch
  389. SYSVR2:    mvi    c,PRINT
  390.     call    MEX
  391.     mvi    c,ILP
  392.     call    MEX
  393.     db    ' dialing',0
  394.     ret
  395.  
  396. ; Handle SET command
  397.  
  398. SETCMD:    mvi    c,SBLANK    ;any arguments?
  399.     call    MEX
  400.     jc    STSHOW        ;if not, go print out values
  401.     mvi    c,LOOKUP
  402.     lxi    d,CMDTBL    ;parse command
  403.     call    MEX
  404.     jc    SETERR        ;can't find it
  405.     pchl            ;else go there
  406. SETERR:    mvi    c,PRINT
  407.     lxi    d,SETEMS    ;print error
  408.     jmp    MEX        ;which returns
  409.  
  410. SETEMS:    db    'SET command error',CR,LF,CR,LF,'$'
  411.  
  412. CMDTBL:    db    '?'+80h        ; "set ?"
  413.     dw    STHELP
  414.     db    'BAS','E'+80h    ; "set base"
  415.     dw    STBASE
  416.     db    'DAT','A'+80h    ; "set data"
  417.     dw    STDATA
  418.     db    'DIA','L'+80h    ; "set dial"
  419.     dw    STDIAL
  420.     db    'RS','T'+80h    ; "set rst"
  421.     dw    STRST
  422.     db    'POR','T'+80h    ; "set port"
  423.     dw    STPORT
  424.     db    0
  425.  
  426. ; SET <no-args>: print current statistics
  427.  
  428. STSHOW:    lxi    h,SHOTBL    ;get table of SHOW subroutines
  429. STSHLP:    mov    e,m        ;get table address
  430.     inx    h
  431.     mov    d,m
  432.     inx    h
  433.     mov    a,d        ;end of table?
  434.     ora    e
  435.     rz            ;exit if so
  436.     push    h        ;save table pointer
  437.     xchg            ;adrs to HL
  438.     call    GOHL        ;do it
  439.     mvi    c,CHEKCC    ;check for console abort
  440.     call    MEX
  441.     pop    h        ;it's done
  442.     jnz    STSHLP        ;continue if no abort
  443.  
  444. ; Enter here to do cr+lf
  445.  
  446. CRLF:    mvi    c,PRINT
  447.     lxi    d,CRLFMS
  448.     jmp    MEX        ;which returns
  449.  
  450. GOHL:    pchl
  451.  
  452. ; table of SHOW subroutines
  453.  
  454. SHOTBL:    dw    SHOWBA
  455.     dw    SHOWPO
  456.     dw    SHOWDT
  457.     dw    SHOWRS
  458.     dw    SHOWDL
  459.     dw    0
  460.  
  461. ; SET ?  processor
  462.  
  463. STHELP:    mvi    c,PRINT
  464.     lxi    d,HLPMSG
  465.     jmp    MEX        ;which returns
  466.  
  467. ; The help message
  468.  
  469. HLPMSG:    db    CR,LF,'SET command options:'
  470.     db    CR,LF,'  SET BASE <hex #>    ... set new base port (00,10 ... F0)'
  471.     db    CR,LF,'  SET DATA <0|1>      ... set data port address (0=even,1=odd)'
  472.     db    CR,LF,'  SET DIAL <P|T>      ... set Pulse or Touch dialing'
  473.     db    CR,LF,'  SET PORT <A|B>      ... set serial port id'
  474.     db    CR,LF,'  SET RST  <dec #>    ... set restart code (1 thru 7)'
  475.     db    CR,LF
  476. CRLFMS:    db    CR,LF,'$'
  477.  
  478. ; SET BASE command processor
  479.  
  480. STBASE:    mvi    c,SBLANK    ;skip blanks
  481.     call    MEX
  482.     jc    SETERR        ;nothing else
  483.     lxi    h,0        ;use HL to build port #
  484. STBAS1:    push    h        ;save across MEX
  485.     mvi    c,GNC        ;get char from input, cy=1 if none
  486.     call    MEX
  487.     pop    h        ;restore
  488.     jc    STBAS2
  489.     call    HEXCON        ;convert to hex nybble in A
  490.     jc    SETERR        ;not hex
  491.     dad    h        ;shift L left by 4 bits
  492.     dad    h
  493.     dad    h
  494.     dad    h
  495.     ora    l        ;or with new nybble
  496.     mov    l,a        ;back to L
  497.     mov    a,h        ;anything in H yet ?
  498.     ora    a
  499.     jnz    SETERR        ;yes - too big
  500.     jmp    STBAS1        ;else go round again
  501. STBAS2:    mov    a,l        ;reg L contains base port #
  502.     ani    0fh        ;check boundary alignment
  503.     jnz    SETERR        ;no good
  504.     mov    a,l        ;ok - save for display
  505.     sta    BASEVAL
  506.     call    FIXIO        ;fix up in/out with BASEVAL,PORTVAL,DATAVAL
  507. SHOWBA:    mvi    c,ILP
  508.     call    MEX
  509.     db    'Base address set to ',0
  510.     lda    BASEVAL
  511.     call    PRTHEX
  512.     jmp    CRLF        ;which returns
  513.  
  514. ; SET DATA processor
  515.  
  516. STDATA:    mvi    c,SBLANK    ;skip blanks
  517.     call    MEX
  518.     jc    SETERR        ;nothing else
  519.     mvi    c,EVALA        ;get numeric from input
  520.     call    MEX
  521.     mov    a,h
  522.     ora    a        ;> 256 ?
  523.     jnz    SETERR        ;yes, error
  524.     mov    a,l
  525.     cpi    2        ;check it
  526.     jnc    SETERR        ;invalid
  527.     sta    DATAVAL        ;store it
  528.     call    FIXIO        ;fix up in/out with BASEVAL,PORTVAL,DATAVAL
  529. SHOWDT:    mvi    c,ILP
  530.     call    MEX
  531.     db    'Data port set to ',0
  532.     lda    DATAVAL        ;get data setting
  533.     lxi    d,EVEN        ;assume even
  534.     ora    a        ;is it ?
  535.     jz    SHOWT2        ;yes
  536.     lxi    d,ODD        ;else odd
  537. SHOWT2:    mvi    c,PRINT
  538.     call    MEX
  539.     jmp    CRLF        ;which returns
  540.  
  541. ; SET DIAL processor
  542.  
  543. STDIAL:    mvi    c,SBLANK    ;skip blanks
  544.     call    MEX
  545.     jc    SETERR        ;nothing else
  546.     lxi    d,DIALTB    ;parse cmd
  547.     mvi    c,LOOKUP
  548.     call    MEX
  549.     jc    SETERR
  550.     mov    a,l        ;get upper case character
  551.     sta    TPULSE        ;store it for MXO-SMxx
  552. SHOWDL:    mvi    c,ILP        ;display status
  553.     call    MEX
  554.     db    'Dialing type set to ',0
  555.     lda    TPULSE        ;get pulse/touch setting
  556.     lxi    d,PLSMSG    ;assume pulse
  557.     cpi    'P'        ;is it ?
  558.     jz    SHOWD2        ;yes
  559.     lxi    d,TCHMSG    ;else touch
  560. SHOWD2:    mvi    c,PRINT
  561.     call    MEX
  562.     jmp    CRLF        ;which returns
  563.  
  564. ; Dial table - saves us worrying about upper/lower case
  565.  
  566. DIALTB:    db    'P'+80H        ;pulse dial
  567.     db    'P',0
  568.     db    'T'+80H        ;touch dial
  569.     db    'T',0
  570.     db    0
  571.  
  572. ; SET PORT processor
  573.  
  574. STPORT:    mvi    c,SBLANK    ;skip blanks
  575.     call    MEX
  576.     jc    SETERR        ;nothing else
  577.     lxi    d,PORTTB    ;parse cmd
  578.     mvi    c,LOOKUP
  579.     call    MEX
  580.     jc    SETERR
  581.     mov    a,l        ;get upper case character
  582.     sta    PORTVAL        ;a-ok, save it
  583.     call    FIXIO        ;fix up in/out with BASEVAL,PORTVAL,DATAVAL
  584. SHOWPO:    mvi    c,ILP        ;display status
  585.     call    MEX
  586.     db    'Port set to ',0
  587.     mvi    c,CONOUT
  588.     lda    PORTVAL
  589.     mov    e,a
  590.     call    MEX        ;display it
  591.     jmp    CRLF        ;which returns
  592.  
  593. ; SET RST processor
  594.  
  595. STRST:    mvi    c,SBLANK    ;skip blanks
  596.     call    MEX
  597.     jc    SETERR        ;nothing else
  598.     mvi    c,EVALA        ;get numeric from input
  599.     call    MEX
  600.     mov    a,h
  601.     ora    a        ;> 256 ?
  602.     jnz    SETERR        ;yes, error
  603.     mov    a,l
  604.     ora    a        ;zero isn't allowed
  605.     jz    SETERR
  606.     cpi    8        ;max of 7
  607.     jnc    SETERR        ;invalid
  608.     sta    RSTVAL        ;store it
  609.     call    FIXRST        ;fix up RST vector
  610. SHOWRS:    mvi    c,ILP
  611.     call    MEX
  612.     db    'Restart code set to ',0
  613.     lhld    RSTVAL        ;get value in hl
  614.     mvi    h,0
  615.     mvi    c,DECOUT
  616.     call    MEX
  617.     jmp    CRLF        ;which returns
  618.  
  619. ; Port table - saves us worrying about upper/lower case
  620.  
  621. PORTTB:    db    'A'+80H
  622.     db    'A',0
  623.     db    'B'+80H
  624.     db    'B',0
  625.     db    0
  626.  
  627. ;..........    subroutines used by the above routines    ..........
  628.  
  629. ; Convert ascii char in A to hex nybble
  630.  
  631. HEXCON:    cpi    '0'        ;< '0' ?
  632.     rc            ;error - return with carry set
  633.     cpi    '9'+1        ;<= '9' ?
  634.     jc    HEXNUM        ;yes - must be 0-9
  635.     cpi    'A'        ;< 'A' ?
  636.     rc            ;error
  637.     cpi    'F'+1        ;<= 'F' ?
  638.     jc    HEXALF        ;yes - convert to hex nybble
  639.     cpi    'a'        ;< 'a' ?
  640.     rc            ;error
  641.     cpi    'f'+1        ;<= 'f' ?
  642.     jnc    HEXERR        ;no - error
  643.     sui    'a'-'A'        ;convert lower case a-f to upper
  644. HEXALF:    stc
  645.     adi    9        ;convert upper case A-F to 3ah-3fh
  646. HEXNUM:    ani    0fh        ;clear high-order nybble
  647.     ret
  648. HEXERR:    stc
  649.     ret
  650.  
  651. ; Print contents of A as hex, followed by 'h'
  652.  
  653. PRTHEX:    push    psw        ;save A
  654.     rrc            ;right justify one hex digit
  655.     rrc
  656.     rrc
  657.     rrc
  658.     call    PRTNYB        ;print first hex digit
  659.     pop    psw
  660.     call    PRTNYB        ;print second hex digit
  661.     mvi    c,CONOUT
  662.     mvi    e,'h'
  663.     jmp    MEX        ;print trailing 'h' & return
  664.  
  665. ; Print hex nybble
  666.  
  667. PRTNYB:    ani    0fh        ;print one hex digit
  668.     adi    90h        ;trust me, this works
  669.     daa
  670.     aci    40h
  671.     daa            ;now ascii
  672.     mvi    c,CONOUT    ;print it
  673.     mov    e,a
  674.     jmp    MEX        ;which returns
  675.  
  676. ; Update in & out instructions with new BASEVAL, PORTVAL, DATAVAL
  677.  
  678. FIXIO:    lda    PORTVAL        ;get port id
  679.     sui    'A'        ; make it 0 or 1
  680.     add    a        ;  then 0 or 2 (offset to 1st reg for A or B)
  681.     mov    b,a        ;   in reg b
  682.     lda    BASEVAL        ;get base address
  683.     ora    b
  684.     mov    b,a        ;b = address of even port
  685.     lda    DATAVAL        ;get data port offset
  686.     ora    b        ;a = address of data port
  687.     sta    DA1+1
  688.     sta    DA2+1
  689.     xri    01h        ;now a = address of status/command port
  690.     sta    ST1+1
  691.     sta    ST2+1
  692.     sta    CO1+1
  693.             ;now go reinitialise ports
  694.     mvi    b,3        ;send 3 nulls
  695.     xra    a        ; to force to command state
  696. FIXIO2:    call    OUTCMD
  697.     dcr    b
  698.     jnz    FIXIO2
  699.     mvi    a,IR        ;reset to mode level
  700.     call    OUTCMD
  701.     mvi    a,STDMODE     ;set standard mode
  702.     call    OUTCMD
  703.     mvi    a,STDCMD+ER    ;clear errors
  704.     call    OUTCMD
  705.     jmp    NORMST        ;which returns
  706.  
  707. ; Initialise restart vector & interrupts
  708.  
  709. FIXRST:    di            ;safety first
  710.     lxi    d,INTRPT    ;de->interrupt routine
  711.     lhld    RSTVAL        ;hl = restart code
  712.     mvi    h,0
  713.     dad    h
  714.     dad    h
  715.     dad    h        ;* 8 = address of restart vector
  716.     mvi    a,JMP        ;set up vector
  717.     mov    m,a
  718.     inx    h        ;hl->a(interrupt routine)
  719.     xchg            ;hl->interrupt rtn, de->a(interrupt rtn)
  720.     mov    a,l
  721.     stax    d        ;store address
  722.     inx    d
  723.     mov    a,h
  724.     stax    d
  725.     ei            ;ok, interrupt away
  726.     ret
  727.  
  728. ; Compare buffer pointers
  729. ;    return with    z flag set => pointers equal
  730.  
  731. COMPTR:    push    h        ;save regs
  732.     push    d
  733.     lhld    INTPTR
  734.     xchg            ;de->next place for input data
  735.     lhld    MEXPTR        ;hl->next char for mex
  736.     mov    a,h
  737.     cmp    d        ;high-order bytes the same ?
  738.     jnz    COMPTX        ;no - definitely not equal
  739.     mov    a,l        ;yes - it all depends on the low-order
  740.     cmp    e
  741. COMPTX:    pop    d        ;restore regs
  742.     pop    h
  743.     ret            ;with z/nz set
  744.  
  745. ; Increment buffer pointer
  746. ;    enter with    pointer in hl
  747. ;    return with    hl pointing to next byte of buffer (wrapped if nec)
  748.  
  749. INCPTR:    inx    h        ;increment
  750.     mov    a,h
  751.     cpi    HIGH BUFEND    ;reached end of buffer ?
  752.     rnz            ;no, return
  753.     mov    a,l        ;maybe
  754.     cpi    LOW BUFEND    ;really end ?
  755.     rnz            ;no, return
  756.     lxi    h,BUFFER    ;yes - time to wrap instead
  757.     ret
  758.  
  759. ; Flush buffer
  760.  
  761. FLUSH:    lhld    INTPTR        ;set MEXPTR equal to INTPTR
  762.     shld    MEXPTR
  763.     ret
  764.  
  765. ; Miscellaneous messages
  766.  
  767. EVEN:    db    'even address','$'
  768. ODD:    db    'odd address','$'
  769. PLSMSG:    db    'pulse','$'
  770. TCHMSG:    db    'touch','$'
  771.  
  772. ; Terminal-dependent control sequences
  773.  
  774. TCLEOS:    db    17H,'$'        ;clear to end-of-screen
  775. TCLSCR:    db    18H,'$'        ;clear screen
  776.  
  777. ;..........    interrupt-related items    ..........
  778.  
  779. ; Interrupt handler
  780.  
  781. INTRPT:    push    psw        ;minimum status save to start with
  782. ST2:    in    STATUS        ;get status
  783.     ani    RXRDY        ;receive data ?
  784.     jnz    INTRCV        ;yes,  go get it
  785.     mvi    a,STDCMD-TXEN    ;else we got a useless TXRDY interrupt
  786.     call    OUTCMD        ; so turn off TXEN
  787.     jmp    INTXIT        ;  & exit
  788. INTRCV:    push    h        ;save more status
  789. DA2:    in    DATA
  790.     lhld    INTPTR        ;where we want to store data
  791.     mov    m,a        ;store it
  792.     call    INCPTR        ;up to next
  793.     shld    INTPTR
  794.     call    COMPTR        ;caught up to MEXPTR ?
  795.     jnz    INTOK        ;no
  796.     lxi    h,OVERUN    ;oops - overrun
  797.     inr    m
  798. INTOK:    pop    h        ;restore status
  799. INTXIT:    pop    psw
  800.     ei            ;enable interrupts again
  801.     ret
  802.  
  803. ; Circular buffer for interrupt routine
  804.  
  805. BUFFER    equ    $        ;at 1200 baud, 100h bytes fills in 2 secs
  806. BUFEND    equ    0b00h        ;don't club Smartmodem overlay
  807. BUFSIZ    equ    BUFEND-BUFFER    ;for interest
  808.  
  809. ;.....
  810. ;
  811. ; Note:    This overlay must terminate prior to 0B00H (with Smartmodem overlay)
  812. ;                         0D00H (without Smartmodem overlay)
  813. ;.....
  814.  
  815.     END
  816.