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

  1.     Title    'MEX overlay for the PMMI version 2.2'
  2. ;
  3. ; Ignore the Title error message if using ASM.
  4. ;
  5. REV    equ    22        ; overlay revision number
  6. LVL    equ    'c'        ; overlay level ( as in Revision 2.2a )
  7. ;
  8. ; MEX PMMI OVERLAY VERSION 1.0: written 04/27/84            by Ron Fowler
  9. ;
  10. ;  "   "      "       "    2.0: generally rewritten 9/18/84 by Fred M. Spinner
  11. ;  "   "      "       '    2.1: rewritten 09/27/84 by Bill Norris
  12. ;  "   "      "       "    2.2:     "     10/30/84 by Bill Norris
  13. ;
  14. ;
  15. ; Version 2.2 notes:        Added 'SET EXTRA' command.  This is a toggle
  16. ;                  that allows you to see on the console when
  17. ;                  certain overlay functions are invoked.
  18. ;                Corrected a minor bug in the clear screen and
  19. ;                  clear to end of screen functions.
  20. ;                Added 15 to SET PPS command.
  21. ;                Added SET ONLINE ( SET OFFHOOK synonym )
  22. ;                OFF-HOOK and ON-HOOK have been changed from
  23. ;                  scattered in-line calls to subroutines.
  24. ;                Renamed SET FIDGET to SET ICD (intercall delay)
  25. ;                Renamed SET IDG    to SET IDD (interdigit delay)
  26. ;                The default PMMI base port was changed to 80h
  27. ;                  in version 2.1 due to conflicts with several
  28. ;                  disk controller boards.  If your PMMI is not
  29. ;                  addressed at this port, just use the SET BASE
  30. ;                  command (and CLONE) if you don't want to edit
  31. ;                  and re-assemble this file.
  32. ;                Speeded up keyboard abort (^X and ^C). ^S also
  33. ;                  accepted here (during dialing of a number).
  34. ;                Phone number '#' is replaced at dial time from
  35. ;                  the keyboard.
  36. ;
  37. ;
  38. ; Version 2.1 notes:        Unifies scattered PMMI I/O; allows modification
  39. ;                  of the PMMI base port with SET BASE command.
  40. ;                No PMMI I/O is done in-line.  It is all done
  41. ;                  using subroutine calls.  This should make all
  42. ;                  modifications simpler (including future
  43. ;                  changes to support MEX 2.x).
  44. ;                Base port address is printed in signon message.
  45. ;                SET FIDGET added (delay between calls).
  46. ;                BASE/FIDGET changes are preserved through CLONEs.
  47. ;                Uses BDOS 6 to force BUSY instead of using hard
  48. ;                coded keyboard I/O for the CTRLX function. (See
  49. ;                description in Version 2.0 notes below).
  50. ;
  51. ;
  52. ; Version 2.0 9/18/84:  Numerous bugs repaired.  The offhook command
  53. ; now actually takes the modem off hook.  The DTR bytes were swapped
  54. ; in 1.1 so that baud rates over 300 would barf.  This has been repaired
  55. ; The SET MODE command is no longer available.  Use SET ORIG, ORG, or
  56. ; ORIGINATE and SET ANS or ANSWER to switch modes.  The actual routine
  57. ; to switch modes has been re-written from scratch, also.  Overlay version
  58. ; message more verbose (better looking, also) now.  If your know your  
  59. ; keyboard (terminal)'s Status and Data Port and also know the value
  60. ; (bit) to check for for keyboard input, you can also implement the CTRLX
  61. ; feature which is handy to have if you know a number is busy and you
  62. ; want to call the next, etc. without further delays.  The keyboard info
  63. ; goes under KSTAT, KPORT, KBIT, and KVAL which mean Keyboard/Terminal status 
  64. ; port, Keyboard data port, AND bit to status input, and value to check for
  65. ; after status is ANDed, respectively.   Set CTRLX to YES if you have
  66. ; this information and want to use this feature, or set it to NO to use
  67. ; the standard MEX keyboard trap.
  68. ;
  69. ;                Fred M. Spinner
  70. ;
  71. ;
  72. ; (V1.1) 05/17/84 (Jim Byram) : Small bugs repaired.  Answer-mode
  73. ; bit (ANBIT) and originate-mode bit (ORBIT) were reversed; fixed
  74. ; SET MODE help message.
  75. ;
  76. ; This is a MEX overlay file for the PMMI modem.  You can use it as
  77. ; a model for designing your own modem overlay (or you can use any
  78. ; existing MDM7 overlay, if available).
  79. ;
  80. ; If you use this as a template for writing your own overlay, and
  81. ; distribute it to others, please pare down these comments as much
  82. ; as possible (to keep the overlays small). I'll maintain this file
  83. ; with as many notes and references as possible, but this will hope-
  84. ; fully be the only "big" overlay.
  85. ;
  86. ; There are advantages to recoding your overlay to conform to the
  87. ; techniques presented here: MEX 2.0 will likely have a much simpler
  88. ; overlay structure; if you stick to the label names and coding
  89. ; suggestions used here, you'll easily be able to follow the overlay
  90. ; upgrade instructions when MEX 2.0 hits the streets. Also, you can
  91. ; make use of the MEX service processor to write a very versatile
  92. ; SET command (as done here).
  93. ;
  94. ; Note that all overlays may freely use memory up to 0CFFH.  If your
  95. ; overlay must work with the MEX Smartmodem overlay (MXO-SMxx.ASM),
  96. ; the physical modem overlay should terminate by 0AFFH.
  97. ;
  98. ; For purposes of example, this is a "full-featured" MEX overlay.  In
  99. ; practice, your overlay may be much simpler (all that is really re-
  100. ; quired is the modem I/O code; fancy stuff like the SET command, and
  101. ; even the disconnect routine, may be left open.  You will need DIAL
  102. ; code, though, unless your modem doesn't support autodialing).
  103. ;
  104. ;------------------------------------------------------------
  105. ;
  106. ; Misc equates
  107. ;
  108. NO    equ    0
  109. YES    equ    0FFh
  110. TPA    equ    100h
  111. CR    equ    13
  112. LF    equ    10
  113. BS    equ    8
  114. TAB    equ    9
  115. ESC    equ    27
  116. CTRLX    equ    YES        ;YES, if use ^X for fake "BUSY"
  117. CONTX    equ    'X'-40h
  118.  
  119.  
  120. ;
  121. ; Equates used only by PMMI routines grouped together here.
  122. ;
  123. ;
  124. ; PMMI port definitions
  125. ;
  126. PORT    equ    080h        ;PMMI base port (data or status)
  127.                 ; PORT now also used by NITMOD.
  128.  
  129. MODCT1    equ    0        ;modem control port (added to base port).
  130. MODDAT    equ    MODCT1+1    ;modem data port      "
  131. BAUDRP    equ    MODCT1+2    ;modem baud rate port "
  132. MODCT2    equ    MODCT1+3    ;modem status port    "
  133. ;
  134. ; PMMI bit definitions
  135. ;
  136. MDRCVB    equ    02h        ;modem receive bit (DAV)
  137. MDRCVR    equ    02h        ;modem receive ready
  138. MDSNDB    equ    01h        ;modem send bit
  139. MDSNDR    equ    01h        ;modem send ready bit
  140. ;
  141. CTSMSK    equ    4        ;mask for CTS bit
  142. BRKMSK    equ    0FBh        ;mask to set break
  143. PARMSK    equ    0CFh        ;mask to remove parity bits
  144. OPARIT    equ    00h        ;odd-parity bits
  145. EPARIT    equ    20h        ;even-parity bits
  146. NPARIT    equ    10h        ;no-parity bits
  147. MODEMK    equ    0FCh        ;mode mask
  148. ANMODE    equ    1Eh        ;answer mode
  149. ANBIT    equ    2        ;answer-mode bit
  150. ORIGMD    equ    1Dh        ;originate mode
  151. ORBIT    equ    1        ;originate-mode bit
  152. WTCTS    equ    150        ;number of seconds (x5) to wait for the
  153.                 ;computer to answer after PMMI auto-dial
  154.                 ;100=20 sec, 150=30 sec, 255=51 sec.
  155.                 ;any number 0-255 acceptable
  156. ;
  157. ;    
  158. ; Modem control command words
  159. ;
  160. BRKMASK    equ    0        ;tele line on hook (break while dialing)
  161. CLEAR    equ    3Fh        ;idle mode
  162. DTMSK    equ    1        ;dial tone mask
  163. MAKEM    equ    1        ;tele line make (off hook)
  164. RBLMT    equ    35        ;7 seconds to wait til no-ring-heard msg
  165. RBWAIT    equ    50        ;5 second delay before redialing PMMI
  166. SMRWT    equ    15        ;1.5 sec delay before redialing HAYES
  167. TMPUL    equ    80h        ;timer pulses mask bit
  168. TRATE    equ    250        ;value for 0.1 second
  169. ;
  170. ;
  171. ; MEX service processor stuff ... MEX supports an overlay service
  172. ; processor, located at 0D00H (and maintained at this address from
  173. ; version to version).  If your overlay needs to call BDOS for any
  174. ; reason, it should call MEX instead; function calls below about
  175. ; 240 are simply passed on to the BDOS (console and list I/O calls
  176. ; are specially handled to allow modem port queueing, which is why
  177. ; you should call MEX instead of BDOS).  MEX uses function calls
  178. ; above about 244 for special overlay services (described below).
  179. ;
  180. ; Some sophisticated overlays may need to do file I/O; if so, use
  181. ; the PARSFN MEX call with a pointer to the FCB in DE to parse out
  182. ; the name.  This FCB should support a spare byte immediately pre-
  183. ; ceeding the actual FCB (to contain user # information).  If you've
  184. ; used MEX-10 for input instead of BDOS-10 (or you're parsing part
  185. ; of a SET command line that's already been input), then MEX will
  186. ; take care of DU specs, and set up the FCB accordingly.  There-
  187. ; after all file I/O calls done through the MEX service processor
  188. ; will handle drive and user with no further effort necessary on
  189. ; the part of the programmer.
  190. ;
  191. MEX    equ    0D00h        ;address of the service processor
  192. INMDM    equ    255        ;get char from port to A, CY=no more in 100 ms
  193. TIMER    equ    254        ;delay 100ms * reg B
  194. TMDINP    equ    253        ;B=# secs to wait for char, cy=no char
  195. CHEKCC    equ    252        ;check for ^C from KBD, Z=present
  196. SNDRDY    equ    251        ;test for modem-send ready
  197. RCVRDY    equ    250        ;test for modem-receive ready
  198. SNDCHR    equ    249        ;send a character to the modem (after sndrdy)
  199. RCVCHR    equ    248        ;recv a char from modem (after rcvrdy)
  200. LOOKUP    equ    247        ;table search: see CMDTBL comments for info
  201. PARSFN    equ    246        ;parse filename from input stream
  202. BDPARS    equ    245        ;parse baud-rate from input stream
  203. SBLANK    equ    244        ;scan input stream to next non-blank
  204. EVALA    equ    243        ;evaluate numeric from input stream
  205. LKAHED    equ    242        ;get nxt char w/o removing from input
  206. GNC    equ    241        ;get char from input, cy=1 if none
  207. ILP    equ    240        ;inline print
  208. DECOUT    equ    239        ;decimal output
  209. PRBAUD    equ    238        ;print baud rate
  210. ;
  211. ;
  212. CONOUT    equ    2        ;simulated BDOS function 2: console char out
  213. PRINT    equ    9        ;simulated BDOS function 9: print string
  214. INBUF    equ    10        ;input buffer, same structure as BDOS 10
  215. ;
  216.     org    TPA        ;we begin
  217. ;
  218. ;
  219.     ds    3        ;MEX has a JMP START here
  220. ;
  221. ; The following variables are located at the beginning of the program
  222. ; to facilitate modification without the need of re-assembly. They will
  223. ; be moved in MEX 2.0.
  224. ;
  225. PMODEM:    db    YES        ;yes=PMMI modem \ / These 2 locations are not
  226. SMODEM:    db    NO        ;yes=Smartmodem / \ referenced by MEX
  227. TPULSE:    db    'T'        ;T=touch, P=pulse (not referenced by MEX)
  228. CLOCK:    db    55        ;clock speed x .1, up to 25.5 mhz.
  229. MSPEED:    db    1        ;sets display time for sending a file
  230.                 ;0=110    1=300  2=450  3=600  4=710
  231.                 ;5=1200 6=2400 7=4800 8=9600 9=19200
  232. BYTDLY:    db    5        ;default time to send character in
  233.                 ;terminal mode file transfer (0-9)
  234.                 ;0=0 delay, 1=10 ms, 5=50 ms, 9=90 ms
  235. CRDLY:    db    5        ;end-of-line delay after CRLF in terminal
  236.                 ;mode file transfer for slow BBS systems
  237.                 ;0=0 delay, 1=100 ms, 5=500 ms, 9=900 ms
  238. COLUMS:    db    5        ;number of directory columns
  239. SETFL:    db    YES        ;yes=user-defined SET command
  240. SCRTST:    db    NO        ;yes=if home cursor and clear screen
  241.                 ;routine at CLRSCRN
  242.     db    0        ;was once ACKNAK, now spare
  243. BAKFLG:    db    NO        ;yes=make .BAK file
  244. CRCDFL:    db    YES        ;yes=default to CRC checking
  245.                 ;no=default to Checksum checking
  246. TOGCRC:    db    YES        ;yes=allow toggling of Checksum to CRC
  247. CVTBS:    db    NO        ;yes=convert backspace to rub
  248. TOGLBK:    db    YES        ;yes=allow toggling of bksp to rub
  249. ADDLF:    db    NO        ;no=no LF after CR to send file in
  250.                 ;terminal mode (added by remote echo)
  251. TOGLF:    db    YES        ;yes=allow toggling of LF after CR
  252. TRNLOG:    db    YES        ;yes=allow transmission of logon
  253.                 ;write logon sequence at location LOGON
  254. SAVCCP:    db    YES        ;yes=do not overwrite CCP
  255. LOCNXT:    db    NO        ;yes=local cmd if EXTCHR precedes
  256.                 ;no=not local cmd if EXTCHR precedes
  257. TOGLOC:    db    YES        ;yes=allow toggling of LOCNXTCHR
  258. LSTTST:    db    YES        ;yes=allow toggling of printer on/off
  259.                 ;in terminal mode. Set to no if using
  260.                 ;the printer port for the modem
  261. XOFTST:    db    NO        ;yes=allow testing of XOFF from remote
  262.                 ;while sending a file in terminal mode
  263. XONWT:    db    NO        ;yes=wait for XON after sending CR while
  264.                 ;transmitting a file in terminal mode    
  265. TOGXOF:    db    YES        ;yes=allow toggling of XOFF testing
  266. IGNCTL:    db    NO        ;yes=do not send control characters
  267.                 ;above CTL-M to CRT in terminal mode
  268.                 ;no=send any incoming CTL-char to CRT
  269. EXTRA1:    db    0        ;for future expansion
  270. EXTRA2:    db    0        ;for future expansion
  271. BRKCHR:    db    '@'-40h        ;^@ = Send a 300 ms. break tone
  272. NOCONN:    db    'N'-40h        ;^N = Disconnect from phone line
  273. LOGCHR:    db    'L'-40h        ;^L = Send logon
  274. LSTCHR:    db    'P'-40h        ;^P = Toggle printer
  275. UNSVCH:    db    'R'-40h        ;^R = Close input text buffer
  276. TRNCHR:    db    'T'-40h        ;^T = Transmit file to remote
  277. SAVCHR:    db    'Y'-40h        ;^Y = Open input text buffer
  278. EXTCHR:    db    '^'-40h        ;^^ = Send next character
  279. PRATE:    db    167        ;125=20pps dialing, 250=10pps
  280.     db    0        ;not used
  281. ;
  282. ; Low-level modem I/O routines: this will be replaced with
  283. ; a jump table in MEX 2.0 (you can insert jumps here to longer
  284. ; routines if you'd like ... I'd recommend NOT putting part of
  285. ; a routine in this area, then jumping to the rest of the routine
  286. ; in the non-fixed area; that will complicate the 2.0 conversion)
  287.  
  288. INCTL1:    jmp    iCTL1        ;in modem control port
  289.     db    0,0,0,0,0,0,0
  290.  
  291. OTDATA:    jmp    oDATA
  292.     db    0,0,0,0,0,0,0
  293.  
  294. INPORT:    jmp    iDATA
  295.     db    0,0,0,0,0,0,0
  296.  
  297.  
  298. ; Bit-test routines.  These will be merged with the above
  299. ; routines in MEX 2.0 to provide a more reasonable format
  300. ;
  301. MASKR:    ani MDRCVB        ;bit to test for receive ready
  302.     ret
  303. TESTR:    cpi MDRCVR        ;value of receive bit when ready
  304.     ret
  305. MASKS:    ani MDSNDB        ;bit to test for send ready
  306.     ret
  307. TESTS:    cpi MDSNDR        ;value of send bit when ready
  308.     ret
  309.  
  310. ;
  311. ; Unused area: was once used for special PMMI functions,
  312. ; Now used only to retain compatibility with MDM overlays.
  313. ; You may use this area for any miscellaneous storage you'd
  314. ; like but the length of the area *must* be 12 bytes.
  315. ;
  316.     ds    12
  317. ;
  318. ; Special modem function jump table: if your overlay cannot handle
  319. ; some of these, change the jump to "DS 3", so the code present in
  320. ; MEX will be retained.  Thus, if your modem can't dial, change the
  321. ; JMP PDIAL at DIALV to DS 3, and MEX will print a "not-implemented"
  322. ; diagnostic for any commands that require dialing.
  323. ;
  324. ; DIALV  dials the digit in A. See the comments at PDIAL for specs.
  325. ;
  326. ; DISCV  disconnects the modem
  327. ;
  328. ; GOODBV is called just before MEX exits to CP/M.  If your overlay
  329. ;        requires some exit cleanup, do it here.
  330. ;
  331. ; INMODV is called when MEX starts up; use INMODV to initialize the modem.
  332. ;
  333. ; NEWBDV is used for phone-number baud rates and is called with a baud-rate
  334. ;        code in the A register, value as follows:
  335. ;
  336. ;     A=0:   110 baud       A=1:   300 baud      A=2:   450 baud
  337. ;     A=3:   600 baud       A=4:   710 baud      A=5:  1200 baud
  338. ;     A=6:  2400 baud       A=7:  4800 baud      A=8: 19200 baud
  339. ;
  340. ;        If your overlay supports the passed baud rate, it should store the
  341. ;     value passed in A at MSPEED (107H), and set the requested rate. If
  342. ;     the value passed is not supported, you should simply return (with-
  343. ;     out modifying MSPEED) -or- optionally request a baud-rate from the
  344. ;     user interactively.
  345. ;
  346. ; NOPARV is called at the end of each file transfer; your overlay may simply
  347. ;     return here, or you may want to restore parity if you set no-parity
  348. ;     in the following vector (this is the case with the PMMI overlay).
  349. ;     
  350. ; PARITV is called at the start of each file transfer; your overlay may simply
  351. ;     return here, or you may want to enable parity detection (this is the
  352. ;     case with the PMMI overlay).
  353. ;
  354. ; SETUPV is the user-defined command ... to use this routine to build your own
  355. ;     MEX command, set the variable SETFL (117H) non-zero, and add your SET
  356. ;     code.  You can use the routine presented in the PMMI overlay as a 
  357. ;     guide for parsing, table lookup, etc.
  358. ;
  359. ; SPMENU is provided only for MDM compatibility, and is not used by MEX 1.0 for
  360. ;     any purpose (it will be gone in MEX 2).
  361. ;
  362. ; VERSNV is called immediately after MEX prints its sign-on message at cold
  363. ;     startup -- use this to identify your overlay in the sign-on message
  364. ;     (include overlay version number in the line).
  365. ; BREAKV is provided for sending a BREAK (<ESC>-B in terminal mode).  If your
  366. ;     modem doesn't support BREAK, or you don't care to code a BREAK rou-
  367. ;     tine, you may simply execute a RET instruction.
  368. ;
  369. LOGON:    ds    2        ;needed for MDM compat, not ref'd by MEX
  370. DIALV:    jmp    PDIAL        ;dial digit in A (see info at PDIAL)
  371. DISCV:    jmp    PDISC        ;disconnect the modem
  372. GOODBV:    jmp    DUMMY        ;called before exit to CP/M
  373. INMODV:    jmp    NITMOD        ;initialization. Called at cold-start
  374. NEWBDV:    jmp    PBAUD        ;set baud rate
  375. NOPARV:    jmp    NOPAR        ;set modem for no-parity
  376. PARITV:    jmp    PARITY        ;set modem parity
  377. SETUPV:    jmp    SETCMD        ;SET cmd: jump to a RET if you don't write SET
  378. SPMENV:    ds    3        ;not used with MEX
  379. VERSNV:    jmp    SYSVER        ;Overlay's voice in the sign-on message
  380. BREAKV:    jmp    PBREAK        ;send a break
  381. ;
  382. ; The following jump vector provides the overlay with access to special
  383. ; routines in the main program (retained and supported in the main pro-
  384. ; gram for MDM overlay compatibility). These should not be modified by
  385. ; the overlay.
  386. ;
  387. ; Note that for MEX 2.0 compatibility, you should not try to use these
  388. ; routines, since this table will go away with MEX 2.0 (use the MEX
  389. ; service call processor instead).
  390. ;
  391. ILPRTV:    ds    3        ;replace with MEX function 9
  392. INBUFV:    ds    3        ;replace with MEX function 10
  393. ILCMPV:    ds    3        ;replace with table lookup funct. 247
  394. INMDMV:    ds    3        ;replace with MEX function 255
  395. NXSCRV:    ds    3        ;not supported by MEX (returns w/no action)
  396. TIMERV:    ds    3        ;replace with MEX function 254
  397. ;
  398. ;
  399. ; Clear/screen and clear/end-of-screen. Each routine must use the
  400. ; full 9 bytes alloted (may be padded with nulls).
  401. ;
  402. ; These routines (and other screen routines that MEX 2.0 will sup-
  403. ; port) will be accessed through a jump table in 2.0, and will be
  404. ; located in an area that won't tie the screen functions to the
  405. ; modem overlay (as the MDM format does).
  406. ;
  407.  
  408. CLREOS:    lxi    h,SCRTST
  409.     lxi    d,EOSMSG
  410.     jmp    PRMAYBE
  411.  
  412.  
  413. CLS:    lxi    h,SCRTST
  414.     lxi    d,CLSMSG
  415.     jmp    PRMAYBE
  416.  
  417. ;
  418. ;------------------------------------------------------------
  419. ;
  420. ;    *** END OF FIXED FORMAT AREA ***
  421. ;
  422. ;------------------------------------------------------------
  423. ;
  424.  
  425. ; Data area
  426. ERRFLG:    db    0        ;connection error code
  427. UCTLB:    db    ORIGMD        ;uart-control byte image
  428. BAUDSV:    db    52        ;current baud rate (dflt 300)
  429. MODCTB:    db    07FH        ;modem control byte
  430. INTERD:    db    2        ;inter-digit delay in 100's of ms
  431. PRXTRA:    db    YES        ; Diagnostic prints upon function usage
  432. WTNUM:    db    WTCTS        ;
  433. OFFHK:    db    0        ;
  434.                 ;
  435. BPTAB:    db    '0123456789ABCDEF', 80h
  436. NITBYT:    db    PORT        ; Should be the PMMI base port.  Original port
  437.                 ; is C0 hex.  Recommended alternate is 80 hex.
  438. DIALFLG: db    0        ;
  439. ABOBYT:    db    0        ;
  440. TEMP:    dw    0        ;
  441.  
  442.  
  443. PRMAYBE: mov    a,m
  444.     ora    a
  445.     rz
  446. PRMBOK:    mvi    c,PRINT
  447.     jmp    MEX
  448.  
  449. iCTL1:    mvi    a,MODCT1
  450.     jmp    BPIN
  451. iCTL2:    mvi    a,MODCT2
  452.     jmp    BPIN
  453. iDATA:    mvi    a,MODDAT    ;in modem data port
  454.     jmp    BPIN
  455. iBDRP:    mvi    a,BAUDRP
  456.     jmp    BPIN
  457.  
  458. oCTL1:    push    psw
  459.     mvi    a,MODCT1
  460.     jmp    BPOUT
  461. oCTL2:    push    psw
  462.     mvi    a,MODCT2
  463.     jmp    BPOUT
  464. oDATA:    push    psw        ;out modem data port
  465.     mvi    a,MODDAT
  466.     jmp    BPOUT
  467. oBDRP:    push    psw
  468.     mvi    a,BAUDRP
  469.     jmp    BPOUT
  470.  
  471. BPIN:    push    b
  472.     mov    b,a
  473.     lda    NITBYT
  474.     add    b
  475.     sta    BPINX+1
  476. BPINX:    in    $-$
  477.     pop    b
  478.     ret
  479.  
  480. BPOUT:    push    b
  481.     mov    b,a
  482.     lda    NITBYT
  483.     add    b
  484.     sta    BPOUTX+1
  485.     pop    b
  486.     pop    psw
  487. BPOUTX:    out    $-$
  488.     ret
  489.  
  490.  
  491. ; Modem initialization.  This overlay doesn't do any initialization.
  492. ; (if we did, we'd disconnect a call already in progress).
  493.  
  494. NITMOD:    lda    NITBYT        ; Convert hex byte to ascii nibble.
  495.     rar
  496.     rar
  497.     rar
  498.     rar
  499.     ani    0Fh
  500.     mvi    d,0
  501.     mov    e,a
  502.     lxi    h,BPTAB
  503.     dad    d
  504.     mov    a,m
  505.     sta    BPMSG        ; Store base port in sign-on message.
  506.     mvi    a,LVL
  507.     sta    LEVEL
  508.     ret
  509.  
  510.  
  511. ; PMMI send-break routine
  512. PBREAK:    lda    MODCTB        ;get the last modem control byte
  513.     ani    BRKMSK        ;set the transmit break bit low
  514.     call    oCTL2        ;send it to the modem
  515.     mvi    b,2
  516.     call    TIMERV        ;send a space tone for 200 ms.
  517.     lda    MODCTB        ;get the last modem control byte
  518.     call    oCTL2        ;restore to normal
  519.     lxi    h,PRXTRA
  520.     lxi    d,BRKMSG
  521.     jmp    PRMAYBE
  522.  
  523. BRKMSG:    db    '.break. $'
  524.  
  525.  
  526. ;  Setup PMMI for odd/even parity.
  527. PARITY:    lda    UCTLB        ;send what's in the image byte
  528.     jmp    oCTL1
  529.  
  530.  
  531. ; set no-parity
  532. NOPAR:    lda    UCTLB        ;get uart/modem control byte
  533.     ani    PARMSK        ;reset parity bits
  534.     ori    NPARIT        ;add no-parity bits
  535.     jmp    oCTL1
  536.  
  537.  
  538. ; disconnect the modem
  539. PDISC:    call    HUKONN        ; Hang up
  540.     call    oCTL2        ; clear DAV, ESD, etc
  541.     push    b        ;
  542.     lxi    h,PRXTRA    ;
  543.     lxi    d,DSC1MSG    ;
  544.     call    PRMAYBE        ;
  545.     mvi    b,20        ;wait for PMMI to disconnect (2 sec) %%* 1 to 2
  546.     mvi    c,TIMER        ;0.1 second per timer interval
  547.     call    MEX        ;
  548.     lxi    h,PRXTRA    ;
  549.     lxi    d,DSC2MSG    ;
  550.     call    PRMAYBE        ;
  551.     pop    b        ;
  552.     ret            ;
  553.  
  554. DSC1MSG: db    '.di$'
  555. DSC2MSG: db    'sc. $'
  556.  
  557. ; exit routine
  558. DUMMY:    ret            ;we don't need one
  559. ;
  560. ;
  561. ;------------------------------------------------------------
  562. ;
  563. ;        <PMMI DIALING ROUTINES BEGIN>
  564. ;
  565. ; This is the DIAL routine called by MEX to dial a digit. The digit
  566. ; to be dialed is passed in the A register.  Note that two special
  567. ; codes must be intercepted as non-digits: 254 (start dial sequence)
  568. ; and 255 (end-dial sequence).  Mex will always call DIAL with 254
  569. ; in the accumulator prior to dialing a number.  Mex will also call
  570. ; dial with 255 in A as an indication that dialing is complete. Thus,
  571. ; the overlay may use these values to "block" the number, holding it
  572. ; in a buffer until it is completely assembled (we don't do this with
  573. ; the PMMI, however; we just dial the digits as they come in).
  574. ;
  575. ; After the 254-start-dial sequence, MEX will call the overlay with
  576. ; digits, one-at-a-time.  MEX will make no assumptions about the dig-
  577. ; its, and will send each to the DIAL routine un-inspected (some modems,
  578. ; like the Smartmodem, allow special non-numeric characters in the
  579. ; phone number, and MEX may make no assumptions about these). This
  580. ; dialing routine validates digits, and ignores any except 0-9 and
  581. ; comma (uses comma to simulate Smartmodem delay).
  582. ;
  583. ; After receiving the end-dial sequence (255) the overlay must take
  584. ; whatever end-of-dial actions are necessary *including* waiting for
  585. ; carrier at the distant end.  The overlay should monitor the keyboard
  586. ; during this wait (using the MEX keystat service call), and return
  587. ; an exit code to MEX in the A register, as follows:
  588. ;
  589. ;    0 - Carrier detected, connection established
  590. ;    1 - Far end busy (only for modems that can detect this condition)
  591. ;    2 - No answer (or timed out waiting for modem response)
  592. ;    3 - Keyboard abort (^C only: all others should be ignored)
  593. ;    4 - Error reported by modem
  594. ;
  595. ; <No other codes should be returned after an end-dial sequence>
  596. ;
  597. ; The overlay should not loop forever in the carrier-wait routine, but
  598. ; instead use either the overlay timer vector, or the INMDMV (timed 100
  599. ; ms character wait) service call routine.
  600. ;
  601. ; The DIAL routine is free to use any of the registers, but must return
  602. ; the above code after an end-dial sequence
  603. ;
  604. ;
  605. PDIAL:    cpi    254        ;start-dial?
  606.     jz    STDIAL        ;
  607.     cpi    255        ;end-dial
  608.     jz    ENDIAL        ;
  609.                 ;
  610.     push    psw        ;
  611.     mvi    a,7        ;
  612.     sta    DIALFLG        ;
  613.     pop    psw        ;
  614.                 ;
  615. PDIAL1:    cpi    ','        ;smartmodem pause command
  616.     jnz    PDIAL2        ;if not pause, continue
  617.     mvi    b,10        ;delay 1 second
  618.     jmp    TIMOUT        ;
  619.  
  620.  
  621. PDIAL2:    cpi    '#'        ;
  622.     jnz    CKDIG        ;
  623.     mvi    a,BS        ;
  624.     call    PUT1C        ;
  625. PDIAL3:    call    GET1C        ;
  626.     jz    PDIAL3        ;
  627.     call    PUT1C        ;
  628.     jmp    PDIAL1        ;
  629.  
  630.  
  631. CKDIG:    cpi    '9'+1        ; digits are 0-9
  632.     rnc            ; too big...
  633.     sui    '0'        ;
  634.     rc            ; too small....
  635.     jnz    DIALIT        ; just right...
  636.     mvi    a,10        ; convert zero to 10 pulses
  637.  
  638. ; Send a digit to the modem.
  639. DIALIT:    mov    c,a        ; save the digit
  640.     lda    ERRFLG        ; before we try to dial...
  641.     ora    a        ; ...check dialtone error flag
  642.     rnz            ; ...if no DT, exit now
  643.     lda    PRATE        ; value for dial speed
  644.     call    oBDRP        ;
  645.     call    WAITLO        ; wait for timer lo
  646.     call    WAITHI        ; wait for timer hi
  647.  
  648.     call    GET1C        ;
  649. DIAL1:    cpi    3        ; ^C ?
  650.     jz    DIALX        ;
  651.     cpi    24        ; ^X ?
  652.     jz    DIALX        ;
  653.     cpi    19        ; ^S ?
  654.     jnz    DIGLP        ;
  655.  
  656. DIALP:    call    GET1C        ; Wait for a character
  657.     jz    DIALP        ;
  658.     cpi    19        ;
  659.     jmp    DIGLP        ;
  660.                 ;
  661. DIALX:    sta    ABOBYT        ;
  662.  
  663. DIGLP:    lda    ABOBYT        ;
  664.     ora    a        ;
  665.     jnz    DIGLP2        ;
  666.                 ;
  667.     call    HUKOFF        ; Go off-hook
  668.     call    WAITLO        ;
  669.     call    HUKONN        ;
  670.     call    WAITHI        ;
  671. DIGLP2:    dcr    c        ;
  672.     jnz    DIGLP        ; send rest of digit
  673.     lda    ABOBYT        ;
  674.     ora    a        ;
  675.     rnz            ;
  676.                 ;
  677.     call    HUKOFF        ;
  678.     lda    INTERD        ; get inter-digit delay
  679.     mov    b,a        ;
  680.     jmp    TIMOUT        ;
  681.  
  682.  
  683. ; Wait for  negative edge of timer pulse
  684. WAITLO:    call    iBDRP
  685.     ani    TMPUL
  686.     jnz    WAITLO
  687.     ret
  688.  
  689.  
  690. ; Wait for positive edge of timer pulse
  691. WAITHI:    call    iBDRP
  692.     ani    TMPUL
  693.     jz    WAITHI
  694.     ret
  695.  
  696.  
  697. ; Start-dial sequence: disconnect, wait for dial-tone
  698. STDIAL:    xra    a        ; reset error flag
  699.     sta    ERRFLG        ;
  700.     call    PDISC        ; on-hook
  701.     call    HUKOFF        ;
  702.     call    PROFFH        ; (possibly) print .off hook. message
  703.  
  704. ; Wait routine will return with carry set if unable to get dialtone.
  705.     mvi    d,DTMSK        ;dial tone mask
  706.     mvi    e,50        ;waits up to 10 sec. for dial tone
  707.     call    WAIT        ;wait for dial tone
  708.     rnc            ;if dial tone within 10 seconds
  709.  
  710.     sta    ERRFLG        ;(action on error deferred until 
  711.     call    PDISC        ;no tone, hang up
  712.     ret            ;   dialing is completed)
  713.  
  714.  
  715. ; End-dial sequence
  716. ENDIAL:    call    ENDIT        ;close out dialing
  717.     push    psw        ;
  718.     xra    a        ;
  719.     sta    DIALFLG        ;
  720.     sta    ABOBYT        ;
  721.     pop    psw        ;
  722.     ora    a        ;successfully connected?
  723.     rz            ;exit now if so
  724.     push    psw        ;nope, save the error code
  725.     call    PDISC        ;shut down the modem
  726.     pop    psw        ;
  727.     ret            ;
  728.  
  729.  
  730. ENDIT:    lda    ERRFLG        ;no-dialtone error from STDIAL?
  731.     ora    a
  732.     rnz            ;if so, return the error here
  733.     call    OFF        ;go off-hook
  734.     lda    UCTLB        ;get uart/modem control byte
  735.     call    oCTL1        ;send it
  736.     mvi    d,4        ;clear-to-send mask
  737.                 ;
  738.     lda    WTNUM        ;
  739.     mov    e,a        ;
  740.     call    WAIT        ;
  741.     rnc            ;return A=0 if good
  742.                 ;
  743.     cpi    'C'-40h        ;keyboard abort?
  744.     rz            ;if so return it
  745.                 ;
  746.     if    CTRLX        ;
  747.     cpi    1        ;Fake busy?
  748.     rz            ;Return if so
  749.     endif            ;CTRLX
  750.                 ;
  751.     mvi    a,2        ;nope, convert error to "no answer"
  752.     ret            ;
  753.  
  754. ;    <end of PMMI dialing routines>
  755. ;------------------------------------------------------------
  756.  
  757.  
  758. ;    Go Off-Hook
  759. OFF:    lda    BAUDSV        ;set current baud rate
  760.     call    oBDRP        ;
  761.     lda    MODCTB        ;Load current DTR
  762.     call    oCTL2        ;
  763.     call    HUKOFF        ;
  764.     lda    UCTLB        ;
  765.     call    oCTL1        ;
  766.     mvi    b,2        ;wait 200 ms    %%* changed from 1 to 2.
  767.     call    TIMOUT        ;    
  768.     lda    DIALFLG        ;
  769.     ora    a        ;
  770.     jz    PRONLN        ;
  771.     xra    a        ;
  772.     sta    DIALFLG        ;
  773. PRWAIT:    lxi    h,PRXTRA    ;
  774.     lxi    d,WAITMSG    ;
  775.     jmp    PRMAYBE        ;
  776.  
  777. PROFFH:    lxi    h,PRXTRA    ;
  778.     lxi    d,OFFHMSG    ;
  779.     jmp    PRMAYBE        ;
  780.  
  781. PRONLN:    lxi    h,PRXTRA    ;
  782.     lxi    d,ONLNMSG    ;
  783.     jmp    PRMAYBE        ;
  784.  
  785. OFFHMSG: db    '.off-h. $'    ; Force PMMI to on-line status.
  786. ONLNMSG: db    '.on-line. $'    ; Force PMMI to on-line status.
  787. WAITMSG: db    '.wait. $'    ; Force PMMI to   "      " and wait
  788.                 ;  for either a carrier or timeout.
  789.  
  790.  
  791. HUKOFF:    mvi    a,255        ; Go Off-Hook
  792.     sta    OFFHK        ;
  793.     mvi    a,MAKEM        ;
  794.     jmp    oCTL1        ;
  795.  
  796.  
  797. HUKONN:    xra    a        ; Go On-Hook
  798.     sta    OFFHK        ;
  799.     mvi    a,BRKMASK    ;
  800.     jmp    oCTL1        ;
  801.  
  802.  
  803.  
  804.  
  805. ; Time-out routine.  Must be called with mask in D reg. for input at
  806. ; relative port 2 and number of seconds (times 10) in E reg.
  807. WAIT:    mvi    b,2        ; 200 ms
  808.     call    TIMOUT        ; wait for timer to go high then low
  809.     call    iBDRP        ; pmmiaddr+2 (modem status port)
  810.     ana    d        ; (cts or dialtone mask)
  811.     rz            ; active low, so return on 0
  812.  
  813.     if    not CTRLX    ;
  814.     mvi    c,CHEKCC    ;not yet, check for console-abort
  815.     call    MEX        ;abort?
  816.     mvi    a,3        ;set error code 3 if abort active
  817.     stc            ;
  818.     rz            ;return if aborted
  819.     endif            ;not CTRLX
  820.  
  821.     if    CTRLX        ;
  822.     lda    ABOBYT        ;
  823.     ora     a        ;
  824.     jz    WAIT0        ;
  825.     push    psw        ;
  826.     xra    a        ;
  827.     sta    ABOBYT        ;
  828.     pop    psw        ;
  829.     jmp    WAIT1        ;
  830.  
  831. WAIT0:    call    GET1C        ;
  832.     jz    WAITOR        ;
  833.                 ;
  834. WAIT1:    cpi    CONTX        ;'^X?'
  835.     jnz    WAIT2        ;no, check for ^C
  836.     call    GET1C        ;Clear out garbage
  837.     mvi    a,1        ;yes, return fake error code
  838.     stc            ;
  839.     ret            ;
  840. WAIT2:    cpi    3        ;Duplicate MEX ^C trap
  841.     jnz    WAITOR        ;Not ^C, continue
  842.     call    GET1C        ;Clear out garbage
  843.     mvi    a,3        ;"ABORT" error
  844.     stc            ;Yes, pass error 
  845.     ret            ;code and return
  846.     endif            ;CTRLX
  847.  
  848.  
  849. WAITOR:    dcr    e        ;
  850.     jnz    WAIT        ; nope, downcount
  851.     inr    a        ; set error=4 (modem error); cy already set
  852.     ret            ;
  853.  
  854.  
  855. GET1C:    push    h
  856.     push    d
  857.     push    b
  858.     mvi    c,6
  859.     mvi    e,0FFh
  860.     call    5
  861.     pop    b
  862.     pop    d
  863.     pop    h
  864.     ani    7Fh
  865.     ret
  866.  
  867.  
  868. PUT1C:    push    h
  869.     push    d
  870.     push    b
  871.     mvi    c,6
  872.     mov    e,a
  873.     call    5
  874.     pop    b
  875.     pop    d
  876.     pop    h
  877.     ret
  878.  
  879.  
  880. ; Set baud-rate code in A (if supported by your modem overlay).  PMMI
  881. ; supports only five rates, which are validated here. NOTE: this routine
  882. ; (ie, the one vectored through NEWBDV) should update MSPEED with the
  883. ; passed code, but ONLY if that rate is supported by the hardware.
  884. PBAUD:    push    h        ;don't alter anybody
  885.     push    d
  886.     push    b
  887.     mov    e,a        ;code to DE
  888.     mvi    d,0
  889.     lxi    h,BAUDTB    ;offset into table
  890.     dad    d
  891.     mov    a,m        ;fetch code
  892.     ora    a        ;0? (means unsupported code)
  893.     stc            ;return error for STBAUD caller
  894.     jz    PBEXIT        ;exit if so
  895.     call    oBDRP        ;good rate, set it
  896.     sta    BAUDSV        ;save it
  897.     mov    a,e        ;get speed code back
  898.     sta    MSPEED        ;make it current
  899.     call    GETDTR        ;get correct DTR based on baud rate
  900.     sta    MODCTB        ;save the code
  901.     call    CARRCK        ;is a connection in progress?
  902.     jnz    PBEXIT        ;skip this if not
  903.     lda    MODCTB        ;yep, set up DTR
  904.     call    oCTL2
  905.  
  906. PBEXIT:    lxi    h,PRXTRA
  907.     lxi    d,BDSTMSG
  908.     call    PRMAYBE
  909.     pop    b        ;all done
  910.     pop    d
  911.     pop    h
  912.     ret
  913.  
  914. BDSTMSG: db    '.bd-rt. $'
  915.  
  916. ; table of baud rate divisors for supported rates
  917. BAUDTB:    db    142,052,035,026,022    ;110,300,450,610,710
  918.     db    0,0,0,0,0        ;1200,2400,4800,9600,19200
  919.  
  920.  
  921. ; Sign-on message
  922. SYSVER:    lxi    d,LINMSG
  923.     mvi    c,PRINT
  924.     call    MEX
  925.     lxi    d,SOMESG
  926.     mvi    c,PRINT
  927.     call    MEX
  928.     lxi    d,bpmess
  929.     mvi    c,PRINT
  930.     call    MEX
  931. CARRSH:    lxi    d,NOMESG        ;tell about carrier
  932.     call    CARRCK            ;check for it
  933.     mvi    c,PRINT
  934.     cz    CMSG
  935.     cnz    MEX
  936.     lxi    d,LINMSG
  937.     mvi    c,PRINT
  938.     call    MEX
  939.     lxi    d,GRBMSG
  940.     mvi    c,PRINT
  941.     call    MEX
  942.     ret
  943. CMSG:    push    psw
  944.     mvi    c,PRINT
  945.     lxi    d,CARMSG
  946.     call    MEX
  947.     pop    psw
  948.     ret
  949.  
  950.  
  951. SOMESG: db    '* PMMI overlay version - '  
  952.     db    REV/10+'0'
  953.     db    '.'
  954.     db    REV MOD 10+'0'
  955. LEVEL:    db    '   *',CR,LF,'$'
  956. BPMESS:    db    '* Base port = '
  957. BPMSG:    db    'x0 hex.          *'
  958. NLMSG:    db    cr,lf,'$'
  959.  
  960. NOMESG:    db    '* No carrier present.          *$'
  961. CARMSG:    db    '* Carrier IS present.          *$'
  962. LINMSG:    db    CR,LF,'********************************',CR,LF,'$'
  963. GRBMSG:    db    CR,LF,'$'
  964. ;
  965. ;
  966. ; get DTR port value based on baud rate
  967. ;
  968. GETDTR:    lda    BAUDSV
  969.     cpi    52        ;>300?
  970.     mvi    a,05Fh        ;set speed configuration (ARRRRRRGGGGHHHH.)
  971.     rc            ;done if so (Swapped in version 2.0)
  972.     mvi    a,07Fh        ;reset speed config bit (ARRRRRRGGGGGHHHH.)
  973.     ret
  974.  
  975.  
  976. ; check the PMMI for carrier-present (NZ=no)
  977. CARRCK:    call    iBDRP        ;get status byte
  978.     ani    CTSMSK
  979.     rnz
  980.     push    psw
  981.     mvi    a,255
  982.     sta    OFFHK
  983.     pop    psw
  984.     ret
  985.  
  986.  
  987. ; Newline on console
  988. CRLF:    mvi    a,CR
  989.     call    TYPE
  990.     mvi    a,LF        ;fall into TYPE
  991.  
  992.  
  993. ; type char in A on console
  994. TYPE:    push    h        ;save 'em
  995.     push    d
  996.     push    b
  997.     mov    e,a        ;align output character
  998.     mvi    c,CONOUT    ;print via MEX
  999.     call    MEX
  1000.     pop    b
  1001.     pop    d
  1002.     pop    h
  1003.     ret
  1004.  
  1005.  
  1006. ; strings to clear-to-end-of-screen, and clear-screen
  1007. ; Note: these are dummy strings, not intended to be displayed...
  1008. EOSMSG:    db    ' -clr eos- $'    ;clear to end-of-screen
  1009. CLSMSG:    db    ' -clr all- $'    ;clear whole screen
  1010.  
  1011.  
  1012. ;
  1013. ;------------------------------------------------------------
  1014. ;
  1015. ; The remainder of this overlay implements a very versatile
  1016. ; SET command -- if you prefer not to write a SET for your
  1017. ; modem, you may delete the code from here to the END statement.
  1018. ;
  1019. ;
  1020. ; Control is passed here after MEX parses a SET command.
  1021. ;
  1022. SETCMD:    mvi    c,SBLANK    ;any arguments?
  1023.     call    MEX
  1024.     jc    SETSHO        ;if not, go print out values
  1025.     lxi    d,CMDTBL    ;parse command
  1026.     call    TSRCH        ;from table
  1027.     push    h        ;any address on stack
  1028.     rnc            ;if we have one, execute it
  1029.     pop    h        ;nope, fix stack
  1030. SETERR:    lxi    d,SETEMS    ;print error
  1031.     mvi    c,PRINT
  1032.     call    MEX
  1033.     ret
  1034. ;
  1035. SETEMS:    db    CR,LF,'SET command error',CR,LF,'$'
  1036. ;
  1037. ; SET command table ... note that tables are constructed of command-
  1038. ; name (terminated by high bit=1) followed by word-data-value returned
  1039. ; in HL by MEX service processor LOOKUP.  Table must be terminated by
  1040. ; a binary zero.
  1041. ;
  1042. ; Note that LOOKUP attempts to find the next item in the input stream
  1043. ; in the table passed to it in HL ... if found, the table data item is
  1044. ; returned in HL; if not found, LOOKUP returns carry set.
  1045. ;
  1046. CMDTBL:    db    '?'+80h            ; "set ?"
  1047.     dw    STHELP            ;
  1048.     db    'BAU','D'+80h        ; "set baud"
  1049.     dw    STBAUD            ;
  1050.     db    'ID','D'+80h        ; "set id"
  1051.     dw    SETIDD            ;
  1052.     db    'ANSWE','R'+80h        ; "set answer"
  1053.     dw    STANSW            ;
  1054.     db    'AN','S'+80h        ; "set ans" (same as above)
  1055.     dw    STANSW            ;
  1056.     db    'ORIGINAT','E'+80h    ; "set originate"
  1057.     dw    STORIG            ;
  1058.     db    'ORI','G'+80h        ; "set orig" (same as above)
  1059.     dw    STORIG            ;
  1060.     db    'OR','G'+80h        ; "set org" (same as above)
  1061.     dw    STORIG            ;
  1062.     db    'OFFHOO','K'+80h    ; "set offhook"
  1063.     dw    OFF            ;
  1064.     db    'ONLIN','E'+80h        ; "set online" (same as offhook)
  1065.     dw    OFF            ;
  1066.     db    'ONHOO','K'+80h        ; "set onhook"
  1067.     dw    PDISC            ;
  1068.     db    'OFFLIN','E'+80h    ; "set offline" (same as onhook)
  1069.     dw    PDISC            ;
  1070.     db    'PP','S'+80h        ; "set pps"
  1071.     dw    SETPPS            ;
  1072.     db    'BAS','E'+80h        ; "set PMMI base port."
  1073.     dw    SETBP            ;
  1074.     db    'IC','D'+80h        ; "set delay between calls"
  1075.     dw    SETICD            ;
  1076.     db    'EXTR','A'+80h        ; "set extra print mode"
  1077.     dw    SETXTRA            ;
  1078.     db    'XYZZ','Y'+80h        ;
  1079.     dw    XYZZY            ;
  1080.                     ;
  1081.     db    0            ; <<=== table terminator
  1082. ;
  1083. ; SET <no-args>: print current statistics
  1084. ;
  1085. SETSHO:    call    SYSVER        ;show carrier present/not present
  1086.     lxi    h,SHOTBL    ;get table of SHOW subroutines
  1087. SETSLP:    mov    e,m        ;get table address
  1088.     inx    h
  1089.     mov    d,m
  1090.     inx    h
  1091.     mov    a,d        ;end of table?
  1092.     ora    e
  1093.     rz            ;exit if so
  1094.     push    h        ;save table pointer
  1095.     xchg            ;adrs to HL
  1096.     call    GOHL        ;do it
  1097.     call    CRLF        ;print newline
  1098.     mvi    c,CHEKCC    ;check for console abort
  1099.     call    MEX
  1100.     pop    h        ;it's done
  1101.     jnz    SETSLP        ;continue if no abort
  1102.     call    CRLF
  1103.     ret
  1104.  
  1105. GOHL:    pchl
  1106.  
  1107.  
  1108. ; table of SHOW subroutines
  1109. SHOTBL:    dw    BDSHOW
  1110.     dw    MDSHOW
  1111.     dw    SHOICD
  1112.     dw    SHOIDD
  1113.     dw    SHOPPS
  1114.     dw    SHOXTRA
  1115.     dw    CRLF
  1116.     dw    0        ;<<== table terminator
  1117.  
  1118. ;
  1119. ; SET ?  processor
  1120. ;
  1121. STHELP:    lxi    d,HLPMSG
  1122.     mvi    c,PRINT
  1123.     call    MEX
  1124.     ret
  1125. ;
  1126. ; The help message
  1127. ;
  1128. HLPMSG:    db    cr,lf,'SET command, for the PMMI S-100 modem (r.i.p.)'
  1129.     db    cr,lf
  1130.     db    cr,lf,'SET ANSWER <or> SET ANS     ... put PMMI in answer mode'
  1131.     db    cr,lf,'SET BASE <hex #>            ... set new PMMI base port'
  1132.     db    cr,lf,'SET BAUD <value>            ... set baud rate'
  1133.     db    cr,lf,'    BAUD values allowed are:    110, 300, 450, 600, and 710'
  1134.     db    cr,lf,'SET EXTRA <value>           ... OFF if <value> == 0, else ON'
  1135.     db    cr,lf,'    EXTRA function diagnostics displayed: BAUD RATE, BREAK,'
  1136.     db    cr,lf,'          DISCONNECT, OFF-HOOK, and WAIT (for answer tone)'
  1137.     db    cr,lf,'SET ICD <value>'
  1138.     db          '             ... intercall delay; 150 == 30 seconds'
  1139.     db    cr,lf,'SET IDD <value>             ... interdigit delay in 100''s msec'
  1140.     db    cr,lf,'SET OFFHOOK <or> SET ONLINE ... force PMMI online'
  1141.     db    cr,lf,'SET ONHOOK <or> SET OFFHOOK ... disconnect without message'
  1142.     db    cr,lf,'SET ORIGINATE <or> SET ORIG ... put PMMI in originate mode'
  1143.     db    cr,lf,'SET PPS <value>             ... may be 10, 15 or 20 pulses/sec.'
  1144.     db    cr,lf
  1145.     db    cr,lf, '$'
  1146.  
  1147.  
  1148. ; SET BAUD processor
  1149. STBAUD:    mvi    c,BDPARS    ;function code
  1150.     call    MEX        ;let MEX look up code
  1151.     jc    SETERR        ;invalid code
  1152.     call    PBAUD        ;no, try to set it
  1153.     jc    SETERR        ;not-supported code
  1154. BDSHOW:    call    ILPRT        ;display baud
  1155.     db    'Baud rate: ', tab, '   ', 0
  1156.     lda    MSPEED
  1157.     mvi    c,PRBAUD    ;use MEX routine
  1158.     call    MEX
  1159.     ret
  1160.  
  1161.  
  1162. ; SET MODE processor
  1163. MDSHOW:    call    ILPRT        ;show mode
  1164.     db    'Mode:', tab, tab, '   ', 0
  1165.     lda    UCTLB        ;get UART B image
  1166.     ani    ORBIT        ;orig?
  1167.     jz    MDORIG
  1168.     call    ILPRT
  1169.     db    'Originate', 0
  1170.     ret
  1171.  
  1172. MDORIG:    call    ILPRT
  1173.     db    'Answer', 0
  1174.     ret
  1175.  
  1176. STORIG: mvi    l,ORBIT 
  1177.     jmp    CHGAO
  1178.  
  1179. STANSW: mvi    l,ANBIT
  1180. CHGAO:    lda    UCTLB
  1181.     ani    MODEMK
  1182.     ora    l
  1183.     sta    UCTLB
  1184.     call    OHKBYT
  1185.     jnz    MDSHOW
  1186.     call    oCTL1
  1187.     call    OFF
  1188.     jmp    MDSHOW
  1189.  
  1190. OHKBYT:    lda    OFFHK
  1191.     cma
  1192.     ora    a
  1193.     ret
  1194.  
  1195. ;
  1196. ; SET PPS command processor
  1197. ;
  1198. SETPPS:    lxi    d,PPSTBL    ;get value
  1199.     call    TSRCH
  1200.     jc    SETERR        ;not found in table? error out
  1201.     mov    a,l        ;yep, set it
  1202.     sta    PRATE
  1203. SHOPPS:    call    ILPRT
  1204.     db    'PPS rate: ', tab, '   ', 0
  1205.     lda    PRATE        ;display PPS
  1206.     cpi    250
  1207.     jnz    SHO2
  1208.     call    ILPRT
  1209.     db    '10', 0
  1210.     ret
  1211. SHO2:    cpi    125
  1212.     jnz    SHO3
  1213.     call    ILPRT
  1214.     db    '20',0
  1215.     ret
  1216. SHO3:    call    ILPRT
  1217.     db    '15',0
  1218.     ret
  1219.  
  1220.  
  1221. PPSTBL:    db    '1','0'+80H    ;"set pps 10"
  1222.     dw    250
  1223.     db    '1','5'+80h    ;"set pps 15"
  1224.     dw    167
  1225.     db    '2','0'+80H    ;"set pps 20"
  1226.     dw    125
  1227.     db    0        ;<<=== table terminator
  1228. ;
  1229. ; SET IDIG command processor
  1230. ;
  1231. SETIDD:    mvi    c,EVALA
  1232.     call    MEX        ;get numeric
  1233.     mov    a,h        ;validate
  1234.     ora    a
  1235.     jnz    SETERR
  1236.     mov    a,l
  1237.     sta    INTERD        ;set new rate
  1238. SHOIDD:    call    ILPRT
  1239.     db    'Inter-digit delay: ', 0
  1240.     lda    INTERD        ;get value
  1241.     mov    l,a        ;move delay to HL
  1242.     mvi    h,0
  1243.     mvi    c,DECOUT    ;print it
  1244.     call    MEX
  1245.     call    ILPRT
  1246.     db    '00 ms',0
  1247.     ret
  1248.  
  1249.  
  1250. ; Set BASE PORT command processor.
  1251. SETBP:    mvi    c,SBLANK
  1252.     call    MEX
  1253.     mvi    c,GNC        ;get char from input, cy=1 if none
  1254.     call    MEX
  1255.     call    UPPER
  1256.     mov    l,a        ; Character to test is in L.
  1257.     shld    TEMP
  1258.  
  1259.     lxi    b,BPTAB-1
  1260.     lxi    d,10h
  1261.     lxi    h,-10h
  1262.  
  1263. SETLP:    inx    b        ; Advance to next allowable character.
  1264.     dad    d        ; Add 10 hex to base port address.
  1265.     ldax    b        ;
  1266.     ora    a        ;
  1267.     jm    SETNG        ; Jump if character typed not in allowable set.
  1268.     push    h        ;
  1269.     lhld    TEMP        ;
  1270.     cmp    l        ; Valid port requested?
  1271.     shld    TEMP        ;
  1272.     pop    h        ; Restore new base port.
  1273.     jnz    SETLP        ; No match, try again.
  1274.     sta    BPMSG        ; Patch sign-on message with Port # (ascii).
  1275.     mov    a,l        ;
  1276.     sta    NITBYT        ; Save base port (hex) for I/O and for CLONING.
  1277.     ret
  1278.  
  1279.  
  1280. BPNOGO:    db    7, '  ****  Invalid port  ****', cr, lf, '$'
  1281. SETNG:    lxi    d,BPNOGO
  1282.     mvi    c,PRINT
  1283.     jmp    MEX
  1284.  
  1285.  
  1286. SETICD:    mvi    c,EVALA
  1287.     call    MEX        ;get numeric
  1288.     mov    a,h        ;validate
  1289.     ora    a
  1290.     jnz    SETERR
  1291.     mov    a,l
  1292.     sta    WTNUM        ;set new rate
  1293. SHOICD:    call    ILPRT
  1294.     db    'Inter-call delay:  ', 0
  1295.     lda    WTNUM        ;get value
  1296.     mov    l,a        ;move delay to HL
  1297.     mvi    h,0
  1298.     mvi    c,DECOUT    ;print it
  1299.     call    MEX
  1300.     call    ILPRT
  1301.     db    ' ticks. (150 ticks=30 seconds)', 0
  1302.     ret
  1303.  
  1304. SETXTRA: mvi    c,EVALA
  1305.     call    MEX
  1306.     mov    a,h
  1307.     ora    a
  1308.     jnz    SETERR
  1309.     mov    a,l
  1310.     sta    PRXTRA
  1311. SHOXTRA: call    ILPRT
  1312.     db    'Extra print mode:  ',0
  1313.     lda    PRXTRA
  1314.     ora    a
  1315.     lxi    d,ONNMSG
  1316.     jnz    SHOXT2
  1317.     lxi    d,OFFMSG
  1318. SHOXT2:    jmp    PRMBOK
  1319.  
  1320. ONNMSG:    db    'ON$'
  1321. OFFMSG:    db    'OFF$'
  1322.  
  1323.  
  1324. ; Compare next input-stream item in table @DE; CY=1
  1325. ; if not found, else HL=matched data item
  1326. TSRCH:    mvi    c,LOOKUP    ;get function code
  1327.     jmp    MEX        ;pass to MEX processor
  1328.  
  1329.  
  1330. XYZZY:    call ILPRT
  1331.     db    'Nothing happens...', 0
  1332.     ret
  1333.  
  1334.  
  1335. ; Print in-line message
  1336. ILPRT:    mvi    c,ILP        ;get function code
  1337.     jmp    MEX        ;go do it
  1338.  
  1339.  
  1340. TIMOUT:    mvi    c,TIMER        ;
  1341.     jmp    MEX        ;
  1342.  
  1343.  
  1344. UPPER:    cpi    'a'
  1345.     rc
  1346.     cpi    'z'+1
  1347.     rnc
  1348.     sui    'a'-'A'
  1349.     ret
  1350.  
  1351.  
  1352. ;------------------------------------------------------------
  1353. ;
  1354. ; End of PMMI MEX modem overlay
  1355. ;
  1356. ;------------------------------------------------------------
  1357.  
  1358.  
  1359.     end
  1360.