home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols100 / vol170 / comm725.asm < prev    next >
Encoding:
Assembly Source File  |  1994-07-13  |  50.0 KB  |  1,728 lines

  1. ; title    'cp/m-80 communication program version 7.25'
  2.  
  3. VERS    EQU    7$25    ;version number..
  4. MONTH    EQU    11    ;..month..
  5. DAY    EQU    26    ;..day..
  6. YEAR    EQU    83    ;..and year.
  7.  
  8. ;comm7 provides extensive communications capabilities using the established
  9. ;christensen 'xmodem' protocol.  additionally, integrated file manipulation
  10. ;routines ('utl' and 'sap') allow disk housekeeping functions to be performed
  11. ;efficiently without leaving the program.  a full single-screen main menu
  12. ;plus sub-menus provide summaries of commands and options available to the
  13. ;operator.  lasm.com or linkasm.com is required to assembly comm7.  operating
  14. ;procedures are detailed in comm7.doc.
  15.  
  16. ;s-100 bus features are emphasized.  primarily, u.s. robotics s-100 (smart
  17. ;modem), pmmi mm-103, and hayes mm-100 plug-in boards are handled.
  18. ;external (rs-232c) ported modems can be used if applicable code and equates
  19. ;are fittingly altered.  clock/calendar s-100 boards from compupro (ss1) and
  20. ;compu/time (cw) are provided for.
  21.  
  22. ;comm7 is dedicated to public domain software (pds) contributions made
  23. ;by rich berg, david boruff, ben bronson, ward christensen, bob clyne,
  24. ;richard conn, bill earnest, bob fischer, bob fisher, ron fowler, richard
  25. ;greenlaw, irv hoff, dave jaffe, paul kelley, bruce kendall, bob kuhman,
  26. ;jim mills, keith petersen, bob plouffe, bruce ratoff, kelly smith, paul
  27. ;traina, hal walchli, and mark zeiger.  comm7 is updated as changes are
  28. ;indicated to maintain a friendly, end-user interface and a consistency of
  29. ;form compatible with changing microcomputer equipment environment.  (the
  30. ;listing style is unique and should remain a characteristic of comm7.)
  31.  
  32. ; latest changes 
  33.  
  34. ;11/26/83  maximum allowed cpu clock rate increased to 25.5 mhz.  code added
  35. ;to manage u.s. robotics s-100 modem board.  operation is similar (though
  36. ;not identical) to that of mm-100 and mm-103.  baudrate must be set while
  37. ;off-line and can't change from originate to answer mode.  program comes
  38. ;up in 1200 baud default mode.  tnx to paul traina, mark edwards, walter
  39. ;blady, and jim mills for assistance in learning some required code fragments.
  40. ;also tnx to irv hoff for 'mci/sprint' type alternate dialing approach.  and
  41. ;for their help, special tnx to the great guys (bob fulton and jim butler) at
  42. ;u.s. robotics in chicago.  set crt attribute code equates to refer to memory
  43. ;hopefully permitting future use of 'comm7ins' to change from one crt to
  44. ;another.  (725)  fg
  45.  
  46. ;copyright to program has been maintained for one reason -- we can get very
  47. ;(legally) annoyed if somebody tries to sell these fruits of our labor for a
  48. ;profit.  you may make copies for yourself and your friends, and you can even
  49. ;sell it for disk cost plus postage.  we encourage this to get the program to
  50. ;people who need it, to keep them from reinventing it.  we would appreciate
  51. ;you keeping our names on it.  (oh, come on...it's not that much trouble.)
  52. ;if we give up money-making on the thing, it's hardly fair for someone
  53. ;else to mop up.  (but on the other hand, who said "living is fair"?)
  54.  
  55. ;        frank gaude'            paul traina
  56. ;        los altos hills, calif.        saratoga, calif.
  57.  
  58. ; comm7 is copyright (c) 1980, 1983 by mark zeiger, paul traina, and frank
  59. ; gaude' and released to public domain for non-commerical use.  monetary gain
  60. ; is not permitted under any circumstance by individual, partnership, or
  61. ; corporation without written permission of the authors.
  62.  
  63. ; assemble using 'lasm.com' or 'linkasm.com'.  comm725.asm, comm725a, b, c,
  64. ; and d.asm must be on same drive.  (edit each assembly subfile independently,
  65. ; as required.)
  66.  
  67. ; enter -> lasm comm725.aaz b:  (source on 'a' drive, hex goes on 'a', no prn
  68. ;                    file, and symbol table on drive b: for use by
  69. ;                    sid.com.  'lasm comm725' produces prn, all 
  70. ;                    files on default drive, no symbol table.  see
  71. ;                    lasm.doc for complete details.)
  72.  
  73. ;          load comm725        (produces com file.)
  74.  
  75. ; starting definitions
  76.  
  77. TRUE      EQU    0FFH        ;define true..
  78. FALSE      EQU    0        ;..and false.
  79.  
  80. ; set modem port address and type
  81.  
  82. PORT      EQU    070H        ;modem port base address (use 70h or c0h)
  83.  
  84. US100      EQU    TRUE        ;true for u.s. robotics s-100, else false.
  85. DL$TYPE      EQU    'T'        ;touch-tone (t) or pulse (p) dial
  86. ALT$DIAL  EQU    TRUE        ;true if 'mci/sprint' type dialing permitted
  87. PMMI      EQU    FALSE        ;true if using a pmmi, false if not.
  88. MM100      EQU    FALSE        ;true if using a mm-100, false if not.
  89. EXTERNAL  EQU    FALSE        ;true if external modem, else false.
  90.  
  91. ; set utilities
  92.  
  93. SOFTKEY      EQU    TRUE        ;true for soft dual-key auto-text output
  94. UTL      EQU    TRUE        ;true if 'utl' disk file manipulator (disk7)
  95. VUE      EQU    FALSE        ;true if 'vue' instead of 'utl'.  must be
  96. DUMB      EQU      TRUE        ;true if not smart line-editor transfers
  97.  
  98. ; rtc clock port (if using s-100 hardware time/date circuit)
  99.  
  100. RTC      EQU    FALSE        ;true if using clock/calendar circuit
  101. CW      EQU    FALSE        ;true if compu/time cw board
  102. SS1      EQU    FALSE        ;true if compupro/godbout ss1 board
  103. TIME$ONLY EQU    FALSE        ;true if 'time' without 'day/date' at cmd line
  104. CLKBASE      EQU    54H        ;base port of clock board (if rtc true)
  105.  
  106. ; system equates
  107.  
  108. CPM$BASE  EQU    000H        ;cp/m system entry address
  109. TPA      EQU    100H        ;cp/m transient program area base
  110. DBUFSIZ      EQU    16        ;file s/r buffer size in kbytes (k=1024)
  111. MAXDR      EQU    'C'        ;maximum drive in system: 'a', 'b', 'c', etc.
  112. RING      EQU    32        ;printer ring-buffer and..
  113. CCP      EQU    8        ;..cp/m 'ccp/zcpr' size in 256-byte pages.
  114. ERRLIM      EQU    10        ;number of re-tries on send/receive..
  115.                 ;..error before auto-quitting.
  116. ERRCRC      EQU    6        ;number of tries (at 10 seconds each)..
  117.                 ;..for crc before switching to checksum.
  118. LPS      EQU    24-2        ;lines-per-screen 'vue' pagination
  119. NPL      EQU    5        ; 'dir' display filenames-per-line
  120. RBUF      EQU    40        ;buffer at auto-colon-file ram-to-disk save
  121.                 ; (set to 128 if using 'mci/sprint' circuits)
  122. GET      EQU    0FFH        ;get user area e-reg value
  123.  
  124. ; set system cpu clock frequency to nearest tenth megahertz x 10.
  125. ; 4 mhz = 40, 3.7 mhz = 37, up to 25.5 mhz = 255 (max).
  126.  
  127. MHZ      EQU    40        ;cpu speed * ten in megahertz
  128.  
  129. ; crt terminal selection
  130.  
  131. ADM21      EQU    FALSE         ;true for lsi adm-21
  132. ADM31      EQU    FALSE        ;true for lsi adm-31
  133. ADM42      EQU    FALSE        ;true for lsi adm-42
  134. ADM5      EQU    FALSE        ;true for lsi adm-5
  135. SOROC      EQU    FALSE        ;true for soroc 120
  136. TELEVIDEO EQU    TRUE        ;true for tvi910/912/920/925/950 or 970
  137. TELE25TH  EQU    TRUE        ;true if tvi has 25th line (925/950/970)
  138. VIEWPOINT EQU    FALSE        ;true for adds viewpoint
  139. VISUAL      EQU    FALSE        ;true for visual 200
  140. ZENITH      EQU    FALSE        ;true for zenith h19/z19 terminals
  141.  
  142. ; waiting limit for remote computer carrier (cd/cts/tone)
  143.  
  144. WAIT$CD      EQU    '25'        ;seconds to wait for remote computer..
  145.                 ;..carrier tone after auto-dial function.
  146.                 ;used by u.s. robotics (99 max value).  up
  147.                 ;to 60 seconds required for int'l calls.
  148.  
  149. WAITCTS      EQU    125        ;seconds x 5, 255 max. (used by pmmi and mm100)
  150.  
  151. ; crt terminal equates
  152. ; ((add values as required and known.  if half-intensity (dim) not available
  153. ; for your terminal, you may prefer to use dummy character instead of reverse
  154. ; video.))
  155.  
  156.      IF    TELEVIDEO OR ADM21
  157. CLS    EQU    1AH        ; '^z' = clear screen/home cursor
  158. CLS2    EQU    1AH        ;send again to fill memory space pervided
  159.      ENDIF            ;televideo or adm21
  160.  
  161.      IF    ADM31
  162. CLS    EQU    1BH        ; <esc> '*' = clear screen
  163. CLS2    EQU    2AH
  164.      ENDIF            ;adm31
  165.  
  166.      IF    TELEVIDEO OR ADM21 OR ADM31
  167. ETEOP    EQU    'Y'        ; <esc> 'y' = erase-to-end-of-page
  168. BDIM    EQU    ')'        ;begin and..
  169. EDIM    EQU    '('        ;..end half-intensity.
  170.      ENDIF            ;televideo or adm21 or adm31
  171.  
  172.      IF    ADM42
  173. CLS    EQU    1BH        ; <esc> 'e' = clear screen
  174. CLS2    EQU    45H
  175. ETEOP    EQU    'Y'        ; <esc> 'y' = erase to end of page
  176. BDIM    EQU    00H        ;dummy
  177. EDIM    EQU    00H        ;dummy
  178.      ENDIF            ;adm42
  179.  
  180.      IF    ADM5
  181. CLS    EQU    1AH        ; '^z' = clear
  182. CLS2    EQU    1AH
  183. ETEOP    EQU    'Y'        ; <esc> 'y' = erase to end of page
  184. BDIM    EQU    00H        ;dummy
  185. EDIM    EQU    00H        ;dummy
  186.      ENDIF            ;adm5
  187.  
  188.      IF SOROC
  189. CLS    EQU    1BH        ;clear = <esc> '*'
  190. CLS2    EQU    2AH
  191. ETEOP    EQU    'Y'        ; <esc> 'y' = erase to end of page
  192. BDIM    EQU    00H        ;dummy
  193. EDIM    EQU    00H        ;dummy
  194.      ENDIF            ;soroc
  195.  
  196.      IF    VIEWPOINT    ; (handled in custom way in various routines)
  197. CLS    EQU    0CH        ; '^l' = clear screen
  198. CLS2    EQU    0CH
  199. ETEOP    EQU    'Kº        ╗ <esc> 'kº = erase to end of page
  200. BDIM    EQU    'N'-40H
  201. EDIM    EQU    'O'-40H
  202.      ENDIF            ;viewpoint
  203.  
  204.      IF    VISUAL
  205. CLS    EQU    1BH        ;clear = <esc> 'v'
  206. CLS2    EQU    76H
  207. ETEOP    EQU    'y'        ; <esc> 'y' = erase to end of page
  208. BDIM    EQU    00H        ;dummy
  209. EDIM    EQU    00H        ;dummy
  210.      ENDIF            ;visual
  211.  
  212.      IF    ZENITH
  213. CLS    EQU    451BH        ; <esc> 'e' = clear screen/home cursor 
  214. ETEOP    EQU    'J'        ; <esc> 'j' = erase-to-end-of-page
  215. BDIM    EQU    'p'        ;begin and..
  216. EDIM    EQU    'q'        ;..end half-intensity.
  217.      ENDIF            ;zenith
  218.  
  219. ; modem sensitive equates (set base port address above)
  220.  
  221. ; u.s. robotics s-100 (uses 8251a usart)
  222.  
  223.      IF    US100
  224. SPORT      EQU    PORT+1        ;status/command/mode and..
  225. DPORT      EQU    PORT        ;..data port.
  226. CPORT2    EQU    SPORT        ;dummy 2nd control port
  227. TBMT$B    EQU    1        ;modem send bit (tbmt)..
  228. TBMT$R    EQU    1        ;..send ready..
  229. DAV$B    EQU    2        ;..receive bit (dav) and..
  230. DAV$R    EQU    2        ;..receive ready.
  231. CTS    EQU    80H        ;clear-to-send mask (status bit 7)
  232. BRK    EQU    08H        ;set break (command bit 3)
  233. FE    EQU    020H        ;framing..
  234. OE    EQU    010H        ;..overrun and..
  235. PE    EQU    008H        ;..parity error. (all status bits)
  236. ERRCDM    EQU    FE+OE+PE    ;mask for all error codes
  237. NOPARM    EQU    0CFH        ;reset to no parity (mode bits 4 & 5)
  238. ODDPARM    EQU    010H        ;set odd and.. (mode bit 4)
  239. EVNPARM    EQU    030H        ;..even parity. (mode bits 4 & 5)
  240.  
  241.  
  242. ; modem usart (mode) control bit equates
  243.  
  244. M5DATA    EQU    0000$0000B    ;5 data bits
  245. M6DATA    EQU    0000$0100B    ;6 data bits
  246. M7DATA    EQU    0000$1000B    ;7 data bits
  247. M8DATA    EQU    0000$1100B    ;8 data bits
  248. MEPAR    EQU    0011$0000B    ;even or..
  249. MOPAR    EQU    0001$0000B    ;..odd parity.
  250. MNPAR    EQU    0000$0000B    ;no parity
  251. M1STOP    EQU    0100$0000B    ;one or..
  252. M2STOP    EQU    1100$0000B    ;..two stop bits.
  253.      ENDIF            ;us100
  254.  
  255. ; hayes mm-100
  256.  
  257.      IF    MM100
  258. DPORT    EQU    PORT        ;data port
  259. SPORT    EQU    PORT+1        ;status port
  260. CPORT2    EQU    PORT+2        ;control port #2
  261. TPORT    EQU    PORT+3        ;timer port
  262. DAV$B    EQU    00000001B    ;data available (mask)
  263. DAV$R    EQU    00000001B    ;data available (test)
  264. TBMT$B    EQU    00000010B    ;xmit buffer empty (mask)
  265. TBMT$R    EQU    00000010B    ;xmit buffer empty (test)
  266. CTS    EQU    01000000B    ;clear to send (carrier detect)
  267. FE    EQU    00001000B    ;framing..
  268. OE    EQU    00010000B    ;..overrun and..
  269. PE    EQU    00000100B    ;..parity error.
  270. TMPUL    EQU    00100000B    ;timer end-up
  271. ERRCDM    EQU    PE+FE+OE    ;mask to detect all errors
  272. BRK    EQU    00001000B    ;set break
  273. NOPARM    EQU    11111110B    ;mask to remove parity attributes
  274. ODDPARM    EQU    00000000B    ;set odd parity attributes
  275. EVNPARM    EQU    00000001B    ;set even parity attributes
  276.  
  277. OFFHOOK    EQU    10000111B    ;bring modem off hook
  278. ONHOOK    EQU    00000101B    ;bring modem on hook (hangup)
  279.  
  280. ; modem uart control bit equates
  281.  
  282. M5DATA    EQU    00000000B    ; 5..
  283. M6DATA    EQU    00000010B    ;..6..
  284. M7DATA    EQU    00000100B    ;..7..
  285. M8DATA    EQU    00000110B    ;..and 8 data bits.
  286. MEPAR    EQU    00000001B    ;even parity
  287. MOPAR    EQU    00000000B    ;odd parity
  288. MNPAR    EQU    00010000B    ;no parity
  289. M1STOP    EQU    00000000B    ;one stop bit
  290. M2STOP    EQU    00001000B    ;two stop bits
  291.      ENDIF            ;mm100
  292.  
  293. ; pmmi mm-103
  294.  
  295.      IF    PMMI
  296. SPORT      EQU    PORT        ;status (control) and..
  297. DPORT      EQU    PORT+1        ;..data port.
  298. BPORT    EQU    PORT+2        ;baudrate and status port
  299. CPORT2    EQU    PORT+3        ;control port #2
  300. TBMT$B    EQU    1        ;modem send bit (tbmt)..
  301. TBMT$R    EQU    1        ;..send ready..
  302. DAV$B    EQU    2        ;..receive bit (dav) and..
  303. DAV$R    EQU    2        ;..receive ready.
  304. CTS    EQU    4        ;clear-to-send mask
  305. BRK    EQU    0FBH        ;mask to set break
  306. PE    EQU    008H        ;parity..
  307. FE    EQU    020H        ;..framing and..
  308. OE    EQU    010H        ;..overrun error.
  309. ODDPARM    EQU    0CFH        ;set odd parity..
  310. EVNPARM    EQU    020H        ;set even parity
  311. ERRCDM    EQU    FE+OE+PE    ;mask for all error codes
  312.  
  313. ; dialing routine equates
  314.  
  315. BRKMASK    EQU    0        ;tele line on-hook (break during dialing)
  316. CLEAR    EQU    3FH        ;idle mode
  317. DTMSK    EQU    1        ;dial tone mask
  318. MAKEM    EQU    1        ;tele line make (off-hook)
  319. TMPUL    EQU    80H        ;timer pulses mask bit
  320.  
  321. ; modem uart control bit equates -- set for originate mode
  322.  
  323. M5DATA    EQU    00000001B    ; 5..
  324. M6DATA    EQU    00000101B    ;..6..
  325. M7DATA    EQU    00001001B    ;..7 and..
  326. M8DATA    EQU    00001101B    ;..8 data bits.
  327. MEPAR    EQU    00100001B    ;even and..
  328. MOPAR    EQU    00000001B    ;..odd parity.
  329. MNPAR    EQU    00010001B    ;no parity
  330. M1STOP    EQU    00000001B    ;one or..
  331. M2STOP    EQU    01000001B    ;..two stop bits.
  332.      ENDIF            ;pmmi
  333.  
  334. ; external modem equates
  335.  
  336.      IF    EXTERNAL
  337. PORT    EQU    ??H        ;serial base (rs-232c) port
  338. DPORT    EQU    PORT        ;data port
  339. SPORT    EQU    PORT+1        ;status port
  340. DAV$B    EQU    00000001B    ;data available (mask)
  341. DAV$R    EQU    00000001B    ;data available (test)
  342. TBMT$B    EQU    00000010B    ;xmit buffer empty (mask)
  343. TBMT$R    EQU    00000010B    ;xmit buffer empty (test)
  344.      ENDIF            ;external
  345.  
  346. ; ascii    definitions
  347.  
  348. SOH    EQU    1        ; ^a, start of header.
  349. EOT    EQU    4        ; ^d, end of text.
  350. ACK    EQU    6        ; ^f, acknowledge.
  351. BELL    EQU    7        ; ^g, bell character.
  352. BS    EQU    8        ; ^h, back-space.
  353. HT    EQU    9        ; ^i, tab character.
  354. LF    EQU    10        ; ^j, linefeed.
  355. CR    EQU    13        ; ^m, cursor return.
  356. NAK    EQU    21        ; ^u, negative acknowledge.
  357. ESC    EQU    27        ; ^[, escape character.
  358. CRC    EQU    'C'        ;  c, crc request character.
  359. BDNMCH    EQU    'U'        ;  u, bad name match.
  360. OKNMCH    EQU    ACK        ; ^f, okay name match.
  361.  
  362. ; control equates
  363.  
  364. LEADIN    EQU    ESC        ;crt screen control character
  365. CAN    EQU    'X'-40H        ; ^x = cancel dial/send/receive/view-file
  366. EOFCHAR    EQU    'Z'-40H        ; ^z = end of ascii cp/m file
  367. XOFF    EQU    'S'-40H        ; ^s = xoff character
  368. XON    EQU    'Q'-40H        ; ^q = xon character
  369. INTCHR    EQU    '['-40H        ; ^[ = enter terminal command mode (cmd)
  370.  
  371. ; assembly origin (load address) and program beginning
  372.  
  373. SOURCE    ORG    CPM$BASE+TPA
  374.     JMP    START
  375.  
  376. ; storage is here for quick com file patching by a monitor without
  377. ; re-assembling program.  comm7ins uses this area for installing
  378. ; (changing) on-the-fly.
  379.  
  380. BAKUPBYTE DB    TRUE        ;true=make .bak file
  381. XPRFLG      DB    TRUE        ;false=print menu 1st time thru
  382. SAVCCP      DB    TRUE        ;true=do not overwrite ccp (or ring-buffer)
  383. CMDCHR      DB    INTCHR        ;set intercept (lead-in) character
  384. BELLFLG      DB    TRUE        ;true=beep for printer/file-save in term mode
  385. MCLS      DB    CLS
  386. MCLS2      DB    CLS2
  387. MLEADIN      DB    LEADIN
  388. METEOP      DB    ETEOP
  389. MBDIM      DB    BDIM
  390. MEDIM      DB    EDIM
  391. DIAL$TP      DB    DL$TYPE        ;touch-tone (t) or pulse (p) dialing
  392. TOUCH$T      DB    ALT$DIAL    ;permits 'mci/sprint' type dialing
  393.  
  394. ; baudrate index register -- 0=110, 1=300, 2=450, 3=600, 4=710
  395. ; and 5=1200 baud
  396.  
  397. MSPEED      DB    1        ;initial and new baudrate index register
  398.  
  399.        IF    PMMI
  400. PULSERATE DB    150        ; 125=20pps dialing, 250=10pps.
  401. ORIGMOD      DB    1DH        ;originate mode
  402. ANSWMOD      DB    1EH        ;answer mode
  403.            ENDIF        ;pmmi
  404.  
  405.        IF    MM100
  406. ORIGMOD      DB    87H        ;originate mode
  407. ANSWMOD      DB    83H        ;answer mode
  408.        ENDIF        ;mm100
  409.  
  410. ; modem sensitive routines
  411.  
  412. OUTSTAT    IN     SPORT        ;in (from) modem control port
  413.     ANI    TBMT$B        ;bit to test for send ready
  414.     CPI    TBMT$R ! RET    ;send bit value when ready
  415. INSTAT    IN     SPORT
  416.     ANI    DAV$B        ;bit to test for receive ready
  417.     CPI    DAV$R  ! RET    ;receive bit value when ready
  418. INCHAR    IN     DPORT  ! RET    ;in (from) and..
  419. OUTCHAR    OUT    DPORT  ! RET    ;..out (thru) modem data port.
  420.  
  421.      IF    PMMI OR MM100 OR US100
  422. INCTRL    IN     SPORT  ! RET    ;in and..
  423. OUTCTRL    OUT    SPORT  ! RET    ;..out modem control port.
  424. OUTCTR2    OUT    CPORT2 ! RET    ;out modem control port #2
  425.      ENDIF            ;pmmi or mm100 or us100
  426.  
  427.      IF    PMMI
  428. INBAUD    IN     BPORT  ! RET    ;in and..
  429. OUTBAUD    OUT    BPORT  ! RET    ;..out baudrate port.
  430.      ENDIF            ;pmmi
  431.  
  432.      IF    MM100
  433. OUTTIME    OUT    TPORT  ! RET    ;output to timer port
  434.      ENDIF            ;mm100
  435.  
  436. ; the 'softkey' simplifies sending of frequently used command
  437. ; lines or short messages to a remote line-editor or cp/m ccp.
  438. ; stored text is issued by pressing the 'cmdchar' (presently
  439. ; set to the 'esc' character) followed by a number from 0 to 9.
  440. ; the db's below indicate the stings set for automatic trans-
  441. ; mission.  when in terminal mode, entering 'esc 1' outputs:
  442. ;
  443. ;                   dir *.* $u0ad <return>
  444. ;
  445. ; this is an often manually typed entry to display the directory of
  446. ; each remote drive.  'esc 3' outputs the 'xmodem r ' string.  set
  447. ; 'softkey' equate true if this feature is desired.
  448. ;
  449. ; for compatibility with comm7 install program (comm7ins), each string
  450. ; should be exactly 32 characters long -- pad out unused bytes with 0s.
  451.  
  452.      IF    SOFTKEY
  453. SOFTMSG    DB    CR,ESC,ETEOP,' -- Softkey Stored '    ;header of..
  454.     DB    'Strings --',CR,LF            ;..local..
  455.     DB    '      <cmd> 1,2,3...9,0',CR,LF,LF    ;..display.
  456. SKONE    DB    'DIR *.* $U0AD',CR,0            ;esc '1'
  457.     DB    '                ',CR
  458. SKTWO    DB    '*.* $U0AD',CR,0            ;esc '2'
  459.     DB    '                    ',CR
  460. SKTHREE    DB    'XMODEM R ',0                ;esc '3'
  461.     DB    '                     ',CR
  462. SKFOUR    DB    'XMODEM S ',0                ;esc '4'
  463.     DB    '                     ',CR
  464. SKFIVE    DB    'USER',CR,0                ;esc '5'
  465.     DB    '                         ',CR
  466. SKSIX    DB    'WHATSNEW',CR,0                ;esc '6'
  467.     DB    '                     ',CR
  468. SKSEVEN    DB    'Frank;Gaude''',cr,0            ;esc '7'
  469.     DB    '                 ',CR
  470. SKEIGHT    DB    'Frank Gaude''',CR,0            ;esc '8'
  471.     DB    '                 ',CR
  472. SKNINE    DB    'Los Altos Hills, CA',CR,0        ;esc '9'    
  473.     DB    '          ',CR
  474. SKZERO    DB    'See you down the lines...',CR,0    ;esc '0'
  475.     DB    '   ',CR,'@'
  476.      ENDIF                        ;softkey
  477.  
  478. ; mainline beginning
  479.  
  480. START    LXI    H,0        ;save..
  481.     DAD    SP        ;..cp/m return..
  482.     SHLD    STACK        ;..address.
  483.     LXI    SP,STACK     ;start local stack
  484.     CALL    INITCRC        ;generate tables for fast 'crc' calculations
  485.     CALL    INITADR        ;establish bios/print-buffer addresses
  486.     CALL    PROCOPT        ;process primary/secondary options
  487.     LDA    XPRFLG        ;show menu 1st time thru..
  488.     ORA    A        ;..if..
  489.     JZ    MENU        ;..xprt mode set false.
  490.  
  491.      IF    VIEWPOINT
  492.     CALL    ILPRT        ;set half-intensity..
  493.     DB    ESC,'0A',0    ;..attribute.  (just for joe wright)
  494.      ENDIF            ;viewpoint
  495.  
  496.     CALL    CAPTION        ;show program title/header
  497.     CALL    CRLF
  498.  
  499. ; react to cp/m and comm7 command line entries
  500.  
  501. RESTART    LXI    SP,STACK    ;start a fresh stack at restart
  502.     CALL    CLR$L        ;remove noise characters from line
  503.     LDA    OPTION         ;react to main (primary) option
  504.  
  505.      IF    PMMI OR MM100 OR US100
  506.     CPI    'C'        ;call (dial) function?
  507.     JZ    DLFONE        ;yes, go for it.
  508.     CPI    'D'        ;disconnect?
  509.     JZ    DISCON1        ;yes, say disconnected and go to menu.
  510.      ENDIF            ;pmmi or mm100 or us100
  511.  
  512.     CPI    'M'         ;menu asked for?
  513.     JZ    MENU2        ;yes, go menu.
  514.     CALL    INITMOD        ;set modem parameters and 'setbaud'
  515.     CALL    MOVEFCB           ;put filename at fcb, if there's one.
  516.     LDA    OPTION           ;now process main (primary) option
  517.     CPI    'T'        ;terminal mode?
  518.     JZ    DSKSAVE        ;yes
  519.     CPI    'E'           ;echo (resemble host computer) mode?
  520.     JZ    TERM$ECHO    ;yes
  521.     CPI    'S'        ;send a file?
  522.     JZ    SENDFIL        ;yes
  523.     CPI    'R'        ;receive a file?
  524.     JZ    RCVFIL        ;yes
  525.     JMP    MENU        ;no valid option spec'd, go menu.
  526.  
  527. ; initialize console i/o and printer ring-buffer addresses -- save initial
  528. ; drive/user area for use in returning to cp/m -- initialize modem
  529.  
  530. INITADR    LHLD    CPM$BASE+1    ;entry to bios jmp table
  531.     LXI    D,3
  532.     DAD    D
  533.     SHLD    VSTAT+1        ;store const..
  534.     DAD    D
  535.     SHLD    VKEYIN+1    ;..conin and..
  536.     LXI    D,36
  537.     DAD    D
  538.     SHLD    LISTST+1    ;..list stat.
  539.     LDA    BDOS+2        ;get 'bdos' base page and..
  540.     SUI    CCP        ;..substract 'ccp' length in pages.
  541.     STA    BUFEND+1    ;store as ring-buffer end..
  542.     SUI    RING        ; (end - ring --> buffer begin)
  543.     STA    BUFBEG+1    ;..and beginning address.  put also..
  544.     STA    BUFRIN+1    ;..as 'in' and..
  545.     STA    BUFROUT+1    ;..'out' pointers.
  546.     MVI    E,GET        ;get current user..
  547.     CALL    GET$USR        ;..and..
  548.     STA    O$USR        ;..save for exit to cp/m.
  549.  
  550.      IF    US100
  551. INITUS    XRA    A        ;clear..
  552.     CALL    OUTCTRL        ;..command register.
  553.     CALL    OUTCTRL
  554.     CALL    OUTCTRL
  555. INITA   MVI    A,5        ;default transfer time at 1200 baud
  556.     STA    MSPEED
  557.     MVI    A,40H        ;reset 8251a usart in modem
  558.     CALL    OUTCTRL
  559. INITB    MVI    A,4EH        ; 1/16 clock rate, 8 data, no parity, 1 stop.
  560.     STA    UARTCTLB    ; (mode byte) (4fh for 300 baud)
  561.     CALL    OUTCTRL
  562. INITC    MVI    A,37H        ;dtr hi/rts on (hi-speed), xmit/rec enabled..
  563.     STA    MODCTLB        ;..reset error flags, no break.  (command byte)
  564.     CALL    OUTCTRL
  565.     RET
  566.      ENDIF            ;us100
  567.  
  568.      IF    MM100
  569.     MVI    A,23        ;set initial uart control block
  570.     STA    UARTCTLB
  571.     LDA    ORIGMOD        ;set originate mode
  572.     STA    MODCTLB
  573.     RET
  574.      ENDIF            ;mm100
  575.  
  576.      IF    PMMI
  577.     MVI    A,1EH        ;set initial uart control block..
  578.     STA    UARTCTLB    ;..as asnwer mode.
  579.     RET
  580.      ENDIF            ;pmmi
  581.  
  582. ; set requested baudrate -- initialize external modem, as required.  set
  583. ; operating mode to last requested determined by 'procopt'.  routine
  584. ; retains current mode and baudrate until explicitly changed at command
  585. ; line or with <cmd> 'b' in terminal mode.
  586.  
  587. INITMOD                ; (external rs-232c goes here, as required)
  588. SETBAUD 
  589.      IF    (NOT PMMI) AND (NOT MM100) AND (NOT US100)
  590.     RET
  591.      ENDIF            ;not pmmi/mm100/us100
  592.  
  593.      IF    MM100
  594.     LDA    UARTCTLB
  595.     CALL    OUTCTRL
  596.      ENDIF            ;mm100
  597.  
  598.      IF    PMMI OR MM100 OR US100
  599.     LDA    ANSWFLG        ; (don't go off-hook if mode not specifed)
  600.     ORA    A
  601.     JZ    FIXBAUD        ;if already 'off-hook' and if..
  602.     LDA    ORIGFLG        ;..neither mode specified, current baudrate..
  603.     ORA    A        ;..is retained even if declared (t.450 -->..
  604.     RNZ            ;..last rate declared.  use to.xxx to change.)
  605.      ENDIF            ;pmmi or mm100 or us100
  606.  
  607.      IF    PMMI OR MM100
  608. FIXBAUD    CALL    GETBAUD        ;baudrate divisor returned in a-reg
  609.     CALL    SETMSPD        ;index to print rate in c-reg; a-reg, divisor.
  610.      ENDIF            ;pmmi or mm100
  611.  
  612.      IF    US100
  613. FIXBAUD RET
  614. ;    LDA    MODCTLB        ;get current modem command byte
  615. ;    ANI    1111$1101B    ;set 'dtr' low (logical on-hook) to allow..
  616. ;    CALL    OUTCTRL        ;..baudrate/mode change while on-line (0fdh).
  617. ;    CALL    GETBAUD        ;get rate and set 'mspeed' time-to-send index
  618. ;    CALL    INCTRL        ;see if on-line and..
  619. ;    ANI    CTS        ;..if..
  620. ;    ORA    A        ;..so..
  621. ;    JZ    SETMODE        ;..output..
  622. ;    CALL    ON$PLUS        ;..escape string, delay fore and aft.
  623. ;SETMODE    LDA    ANSWFLG        ;see if answer mode requested, else..
  624. ;    LXI    H,ATA
  625. ;    ORA    A
  626. ;    JZ    SMODE2
  627. ;    LDA    ORIGFLG
  628. ;    LXI    H,ATD        ;..it is maybe originate..
  629. ;    ORA    A
  630. ;    JNZ    REINIT        ;..or none.
  631. ;SMODE2    CALL    SM$STR
  632. ;REINIT    JMP    INITA        ; (rets to caller)
  633.      ENDIF            ;us100
  634.  
  635.      IF    PMMI
  636.     CALL    OUTBAUD        ;set modem baud divisor
  637.     CPI    52        ; >300 baud?
  638.     MVI    A,5FH        ;dtr (filter for >300 baud)
  639.     JC    GT300        ;yes, greater than.
  640.     MVI    A,7FH        ;dtr (filter for 300 baud and less)
  641. GT300    STA    MODCTLB        ;store above filter value
  642.     CALL    OUTCTR2        ;set modem filter (go off-hook)
  643.     MVI    B,1        ;wait a bit after we said go off-hook
  644.     CALL    TIMER
  645.     LDA    UARTCTLB    ;put last requested mode.. 
  646.     CALL    OUTCTRL        ;..to modem.
  647.      ENDIF            ;pmmi
  648.  
  649.      IF    MM100
  650.     MOV    A,C        ;get baudrate (0=110, 1=300)
  651.     ANI    1        ;keep only the first bit
  652.     MOV    B,C        ;put it in b
  653.     LDA    ORIGMOD        ;get originate mode parameters
  654.     ANI    11111110B    ;keep all but baud rate
  655.     ORA    B        ;set in new rate (0=110/1=300)
  656.     STA    ORIGMOD        ;save new baud rate
  657.     LDA    ANSWMOD        ;get answer mode parameters
  658.     ANI    11111110B    ;keep all but baud rate
  659.     ORA    B        ;set in new rate
  660.     STA    ANSWMOD
  661.     LDA    MODCTLB        ;get uart control
  662.     ANI    11111110B    ;keep all but baud rate
  663.     ORA    B        ;set in new rate
  664.     STA    MODCTLB
  665.     CALL    OUTCTR2        ;set new baudrate
  666.      ENDIF            ;mm100
  667.  
  668.      IF    PMMI OR MM100
  669.     MOV    A,C        ;get index to print..
  670.     STA    MSPEED        ;..baudrate in 'openok'.
  671.     XRA    A        ;ret to caller with flags..
  672.     RET            ;..set.
  673.      ENDIF            ;pmmi or mm100
  674.  
  675. ; determine if rate-change is necessary
  676.  
  677.      IF    PMMI OR MM100
  678. GETBAUD    LDA    FCB+9        ;get 1st digit of baudrate from cmdline
  679.     CPI    ' '        ;if 'blank', return with..
  680.     LDA    BAUDRATE    ;..current rate.
  681.     RZ
  682.      ENDIF            ;pmmi or mm100
  683.  
  684. ; sm/usr baudrate determination routine
  685.  
  686.      IF    US100
  687. US$SET    CALL    CRONLY
  688.     CALL    CTEOP
  689.     LXI    D,BAUDBUF
  690.     CALL    ILPRT
  691.     DB    'Enter baudrate (300, 600, 1200): ',0
  692.     CALL    INBUF
  693.     LXI    D,BAUDBUF+2
  694.         CALL    ILCOMP        ;compare for match with characters..
  695.         DB    '300',0     ;..here and..
  696.         JNC    OK300
  697.         CALL    ILCOMP
  698.         DB    '600',0        ;..here and..
  699.         JNC    OK600
  700.         CALL    ILCOMP
  701.     DB    '1200',0    ;..here. (cp/m truncates digits over 3)
  702.         JNC    OK1200
  703.         CALL    ILPRT        ;no match, tell operator.
  704.         DB    '++ Invalid baudrate ++',CR,LF,BELL,0
  705.         JMP    US$SET        ;loop 'till good entry
  706.  
  707. OK300    MVI    A,1        ; 'mspeed' baud value into a-reg..
  708.     LHLD    BD300        ;..and 300 baud parameters in hl-pair.
  709.     JMP    LOADBD        ;now load them
  710.  
  711. OK600    MVI    A,3
  712.     LHLD    BD600
  713.     JMP    LOADBD
  714.  
  715. OK1200    MVI    A,5
  716.     LHLD    BD1200
  717.     JMP    LOADBD
  718.  
  719. LOADBD    STA    INITA+1        ;change time-to-send index to match baudrate
  720.     MOV    A,H        ;get baudrate byte and..
  721.     STA    INITB+1        ;..store in.. (mode)
  722.     MOV    A,L        ;..'initus'.
  723.     STA    INITC+1        ; (command)
  724.     CALL    INITA        ;initialize to new rate..
  725.     JMP    MENU        ;..then back to command line.
  726.  
  727. ; table of sm/usr baudrate parameters -- uart and modem control
  728.  
  729. BD300    DW    04F37H        ; 300..
  730. BD600    DW    04E27H        ;..600 and.. (pmmi fsk compatible)
  731. BD1200    DW    04E37H        ;..1200 baud.
  732.  
  733. BAUDBUF    DB    10,0
  734.     DS    10
  735.      ENDIF            ;us100
  736.  
  737. ; convert ascii baudrate to binary modem divisor -- store divisor in
  738. ; 'baudrate' register
  739.  
  740.      IF    PMMI OR MM100
  741.     LXI    D,FCB+9
  742.     LXI    H,0
  743. DECLP    LDAX    D        ;get ascii digit
  744.     INX    D
  745.     CPI    ' '
  746.     JZ    DECLP
  747.     CPI    '0'        ;validate digit here..
  748.     JC    BADRATE    
  749.     CPI    '9'+1        ;..and again here then..
  750.     JNC    BADRATE
  751.     SUI    '0'        ;..make digit binary.
  752.     MOV    B,H        ;set-up to multiply previous..
  753.     MOV    C,L        ;..value by ten.
  754.     DAD    H        ; x2
  755.     DAD    H        ; x2
  756.     DAD    B        ; +1
  757.     DAD    H        ; x2 = 10.
  758.     ADD    L
  759.     MOV    L,A
  760.     JNZ    DIGNC
  761.     INR    H
  762. DIGNC    MOV    A,E        ;see if past..
  763.     CPI    FCB+12        ;..last digit. ('e' is lsb of 'de')
  764.     JNZ    DECLP        ;loop till done
  765.     MOV    A,H
  766.     CMA            ;one's complement
  767.     MOV    D,A
  768.     MOV    A,L
  769.     CMA
  770.     MOV    E,A
  771.     INX    D        ;two's complement
  772.     LXI    H,15625        ; 250000/16
  773.     LXI    B,-1
  774. DIVLP    INX    B
  775.     DAD    D        ; ('dad' sets carry)
  776.     JC    DIVLP
  777.     MOV    A,B        ;assume valid divisor in c-reg..
  778.     ORA    A        ;..if b-reg is zero.
  779.     MOV    A,C        ;divisor into a-reg for output to modem
  780.     STA    BAUDRATE    ;retain as current rate
  781.     RZ            ;ret if <256, else error exit.
  782.  
  783. ; announce invalid baudrate entry
  784.  
  785. BADRATE    CALL    ERXIT
  786.     DB    '++ Invalid baudrate ++','@'
  787.  
  788. ; determine index for printing baudrate (divisor from 'getbaud' in a-reg)
  789.  
  790. SETMSPD    MVI    C,0        ; 0 --> 110 baud
  791.     CPI    100
  792.     RNC
  793.     INR    C        ; 1 --> 300 baud
  794.     CPI    40
  795.     RNC
  796.     INR    C
  797.     CPI    30
  798.     RNC
  799.     INR    C
  800.     CPI    24
  801.     RNC
  802.     INR    C        ; 4 --> 710 baud
  803.     RET
  804.      ENDIF            ;pmmi or mm100
  805.  
  806. ; change baudrate on-the-fly with <cmd> b in terminal mode
  807.  
  808.      IF    PMMI OR MM100 OR US100
  809. NEWBAUD    MVI    A,TRUE        ;don't print question on printer
  810.     STA    LISTFLG
  811.     CALL    ILPRT
  812.      ENDIF                ;pmmi or mm100 or us100
  813.                                  
  814.      IF    (NOT TELE25TH) AND (PMMI OR MM100 OR US100)
  815.     DB    CR,ESC,ETEOP     
  816.      ENDIF            ;(not tele25th) and (pmmi or mm100 or us100)
  817.  
  818.      IF    TELE25TH AND (PMMI OR MM100 OR US100)
  819.     DB    ESC,'g',ESC,'f'
  820.      ENDIF            ;tele25th and (pmmi or mm100 or us100)
  821.  
  822.      IF    US100
  823.     DB    'Enter baudrate (300/600/1200): ',0
  824.      ENDIF            ;us100
  825.  
  826.      IF    PMMI
  827.     DB    'Enter baudrate (110/300/450/600/710): ',0
  828.      ENDIF            ;pmmi
  829.  
  830.      IF    MM100
  831.     DB    'Enter baudrate (110/300): ',0
  832.      ENDIF            ;mm100
  833.  
  834.      IF    PMMI OR MM100 OR US100
  835.     LXI    H,FCB+9
  836.     MVI    M,' '        ;put a 'blank' in first position to..
  837. LOOP5    CALL    KEYIN        ;..signal using current baudrate.
  838.     CPI    CR        ; <return> enters baudrate
  839.     JNZ    LOOP6        ;not cursor return
  840.      ENDIF            ;pmmi or mm100 or us100
  841.  
  842.      IF    TELE25TH AND (PMMI OR MM100 OR US100)
  843.     CALL    ILPRT
  844.     DB    CR,ESC,'h',0    ;turn off 25th line
  845.      ENDIF            ;tele25th and (pmmi or mm100 or us100)
  846.  
  847.      IF    PMMI OR MM100 OR US100
  848.     LDA    LSTRETF        ;get printer status
  849.     CMA            ;flip it
  850.     STA    LISTFLG        ;turn printer back on (maybe)
  851.     CALL    CRLF
  852.     JMP    FIXBAUD        ;make baudrate
  853.  
  854. ; check and show keyboard entries
  855.  
  856. LOOP6    CPI    '0'        ;make sure it's..
  857.     JC    LOOP5        ;..a number, else..
  858.     CPI    '9'+1        ;..don't accept it.
  859.     JNC    LOOP5
  860.     MOV    M,A        ; 3 digits to memory (fcb9 to fcb11)
  861.     CALL    TYPE        ;echo character entered
  862.     INX    H
  863.     JMP    LOOP5        ;loop till <return> entered
  864.      ENDIF            ;pmmi or mm100 or us100
  865.  
  866. ; t e l e p h o n e   n u m b e r   t a b l e
  867.  
  868. ; dial from library of numbers entered into storage here before assembly-time.
  869. ; each db must be 'liblen' characters long for correct operation.  last db
  870. ; must end with 0 (null).  up to 26 numbers are allowed.  'r' as last
  871. ; character in line indicates an automatic ringback call, i.e., ring once,
  872. ; hang up, ring back and let ring until connection or 'timeout'.
  873.  
  874. ; alternate dial feature:  use '<' or '>' in front of telephone number for
  875. ; alternate dial through 'mci/sprint' type services.  for example,
  876. ; 'g al mehr servu......>408/238-9621' dials 'alt$dial2' set
  877. ; of digits, 408/238-9621 digits next.  x's represent service
  878. ; access number; y's, user charge code; and each comma is a 2-second delay
  879. ; as necessary for correct circuit opeation.  'altdial' stings can be of any
  880. ; reasonable length, terminated by '@'. characters '<' and '>' cannot be used
  881. ; other than as first byte of station to be dialed.
  882.  
  883.        IF    US100
  884. ALT$DIAL1 DB    'xxxxxxx,,,,,,yyyyyyyy,,','@'    ;accessed by '<' and..
  885. ALT$DIAL2 DB    'xxxxxxx,,,,,,yyyyyyyy,,','@'    ;..'>' character.
  886.        ENDIF                ;us100
  887.  
  888. NUMBLIB    DB    'A Portola Valley PMS*.....851-3453'
  889.     DB    'B Bob Nelson RCP/M....408/733-1364'
  890.     DB    'C Dave Morgan RCP/M*..503/641-7276'
  891.     DB    'D Hayward FORTH Tree......538-3580'
  892.     DB    'E Milpitas OxGate*....408/263-2588'
  893.     DB    'F Marin RCP/M RBBS........383-0473'
  894.     DB    'G Al Mehr SERVU.......408/238-9621'
  895.     DB    'H Thousand Oaks*......805/492-5472'
  896.     DB    'I Tim Gary ''C'' RCP/M......949-1476'
  897.     DB    'J Ed Svoboda*.........408/732-9190'
  898.     DB    'K Mountain View PicoNET*..965-4097'
  899.     DB    'L Paul Traina*........408/354-5934'
  900.     DB    'M Bruce Ratoff RIBBS..201/272-1874'
  901.     DB    'N TCBBS Dave Hardy*...313/846-6127'
  902.     DB    'O Ed Huang DataTech*......595-0541'
  903.     DB    'P       (*=24hr/R=ring back)      '
  904.     DB    'Q Keith Petersen*....313/759-6569R'
  905.     DB    'R LA RCP/M RBBS.......213/296-5927'
  906.     DB    'S CompuServe/Mtn View.....961-7242'
  907.     DB    'T Pasadena RBBS.......213/577-9947'
  908.     DB    'U UAHsv RCP/M RBBS...205/895-6749R'
  909.     DB    'V Pasadena CBBS*......213/799-1632'
  910.     DB    'W Kelly Smith.........805/527-9321'
  911.     DB    'X Chuck Forsberg*.....503/621-3193'
  912.     DB    'Y Ward/Randy CBBS*....312/545-8086'
  913.     DB    'Z Tim Linehan RCP/M*..206/357-7400',0    ;end
  914.  
  915. ; c a l
  916.  
  917. ; modem auto-dial routines
  918. ; options from main command line:
  919. ;    1. cal <return>
  920. ;    2. cal x
  921. ;    3. cal nnn-nnn-nnnn[r]
  922. ;
  923. ; options from the library prompt line:
  924. ;    1. x
  925. ;    2. nnn-nnn-nnnn[r]
  926. ;
  927. ; where:   x = a telephone library letter
  928. ;       n = a manually entered number to auto-dial
  929. ;        [r] = 'r' is optionally used for ring-back type of auto-dial
  930.  
  931. ; modem control masks and library equate
  932.  
  933. RBLMT    EQU    35        ; 7 sec to wait till no-ring-heard msg shows
  934. RBWAIT    EQU    50        ; 5 sec delay before re-dialing number
  935. LIBLEN    EQU    34        ;library entry length
  936.  
  937. ; smartmodem/usr control strings
  938.  
  939.      IF    US100
  940. ATTEN    DB    'ATV0S7='    ;get attention, terse, wait-time..
  941.     DW    WAIT$CD        ;..for remote tone (carrier) and..
  942. STYLE    DB    'D?','@'    ;..dial number (touch-tone or pulse).
  943. ATA    DB    'ATA',CR,'@'    ;change to answer and..
  944. ATD    DB    'ATD',CR,'@'    ;..to originate mode.
  945. PLUS    DB    '+++','@'    ;to ascii command mode while on-line, hang-up.
  946.      ENDIF            ;us100
  947.  
  948. ; dial phone number
  949.  
  950.      IF    PMMI OR MM100 OR US100
  951. DLFONE    XRA    A        ;zero the..
  952.     STA    CRFLAG        ;..continuous re-dial and..
  953.     STA    RBFLAG        ;..ringback flags..
  954.     LXI    H,0        ;..and..
  955.     SHLD    DIALCNT        ;..the dial-count register.
  956.     LXI    H,CMDBUF+1    ; # of chars in buffer..
  957.     MOV    A,M        ;..copied to determine move.
  958.     CPI    3+1        ; >3 chars typed before <return>?
  959.     JC    ENTNUM        ;no, go library, ask letter/numbers.
  960.     MOV    B,A        ; move count in b-reg for..
  961.     SUI    4        ;scratch the 'cal' header
  962.     MOV    M,A        ;store new count at cmdbuf+1
  963.     INX    H        ;at cmdbuf+2, 1st character of string.
  964.     XCHG            ;destination in de-pair
  965.     LXI    H,CMDBUF+6    ;point to # or letter to dial
  966.     CALL    MOVE        ; ..shifting down 4 characters.
  967.     JMP    DIALLP1        ;ck if library #, then dial.
  968.  
  969. ; set-up for local print at entnum2.  enters here if 'cal' and no telephone
  970. ; number or letter were typed.  displays phone number library and asks for
  971. ; entry.
  972.  
  973. ENTNUM    CALL    CLEAR$S
  974.     CALL    TO$DIM
  975.     CALL    ILPRT
  976.     DB    CR,LF,LF
  977.     DB    HT,HT,HT,'        M o d e m',CR,LF
  978.     DB    HT,HT,HT,'    T e l e p h o n e',CR,LF
  979.     DB    HT,HT,HT,'      L i b r a r y',CR,LF,LF,0
  980.     CALL    TO$FULL
  981.     MVI    C,13        ;number of lines to move.
  982.     LXI    H,NUMBLIB     ;address of source memory..
  983.     LXI    D,DBUF        ;..and target memory.
  984. ENTNUM1    MVI    B,LIBLEN    ;number of bytes..
  985.     CALL    MOVE        ;..to move to buffer.
  986.     MVI    A,' '        ;space (4 + (2 * 'liblen') = line length)
  987.     STAX    D        ; 1st
  988.     INX    D
  989.     STAX    D        ; 2nd
  990.     INX    D
  991.     STAX    D        ; 3rd
  992.     INX    D
  993.     STAX    D        ; 4th space
  994.     INX    D
  995.     MVI    B,LIBLEN
  996.     CALL    MOVE
  997.     MVI    A,CR        ;cr (cursor return)
  998.     STAX    D        ;store it
  999.     MVI    A,LF        ;lf (newline) 
  1000.     INX    D        ;bump pointer
  1001.     STAX    D        ;store lf
  1002.     INX    D        ;bump pointer
  1003.     DCR    C        ;bump # of lines to print
  1004.     JNZ    ENTNUM1
  1005. ENTNUM2    MVI    A,'@'        ;put terminator as last..
  1006.     STAX    D        ;..character in table.
  1007.     LXI    H,DBUF        ;point to library..
  1008.     CALL    TEXTOUT        ;..numbers to display locally.
  1009.     CALL    TO$DIM
  1010.     CALL    ILPRT
  1011.     DB    CR,LF,'Enter library letter or phone '
  1012.     DB    'number -- press <RETURN> to start dialing.',CR,LF
  1013.     DB    '^X aborts dialing routine: ',0
  1014.     CALL    TO$FULL
  1015.     LXI    D,CMDBUF
  1016.     CALL    INBUF
  1017.     CALL    CRLF
  1018.     CALL    CRLF
  1019. DIALLP1    LXI    H,CMDBUF+1    ; # of characters in buffer (auto-redial..
  1020.     MOV    A,M        ;..entry here.)
  1021.     ORA    A           ;null means <return> pressed so..
  1022.     JZ    MENU        ;..simply return to menu.
  1023.     INX    H         ;ltr or 1st typed number of # to dial
  1024.      ENDIF            ;pmmi or mm100 or us100
  1025.  
  1026. ; enter routine with hl-pair pointing to # to dial
  1027.  
  1028. DIAL10
  1029.      IF    PMMI OR MM100
  1030.     CALL    WTTONE        ;disconnect, reconnect, wait dial tone.
  1031.     JC    MENU        ;if no dial tone, go menu.
  1032.      ENDIF            ;pmmi or mm100
  1033.  
  1034.      IF    US100
  1035.     MVI    B,1        ; *** test wait routine ***
  1036.     CALL    TIMER
  1037.      ENDIF            ;us100
  1038.  
  1039.      IF    PMMI OR MM100 OR US100
  1040.     CALL    ILPRT        ;clear 'waiting...' line
  1041.     DB    CR,ESC,ETEOP,0
  1042.     MVI    B,'A'        ;first letter of alphabet
  1043.     MVI    E,0        ;counts number of letters to match
  1044.     MVI    C,26        ;number of letters in alphabet
  1045.     MOV    A,M        ;get char buffer
  1046. DIAL11    CMP    B        ;letter from library table?
  1047.     JZ    LIBSET
  1048.     INR    B        ;make next letter (a --> z)
  1049.     INR    E        ;count up
  1050.     DCR    C        ;count down
  1051.     JZ    DIALLPX        ;not a letter, go get typed numbers.
  1052.     JMP    DIAL11        ;loop
  1053.  
  1054. ; match between requested ltr and one in library
  1055. ; (e-reg contains decimal equivalent of ltr)
  1056.  
  1057. LIBSET    LXI    H,NUMBLIB    ;phone number library
  1058.     LXI    B,LIBLEN    ;length of library entry
  1059.     MOV    A,E        ;number of times to add 34 to hl-pair
  1060.     ORA    A        ;set flags
  1061.     JZ    DIAL13
  1062. DIAL12    MOV    A,M        ;get first char of selected lib entry
  1063.     ORA    A
  1064.     JZ    DIALLP2        ;send badlib msg
  1065.     DAD    B        ;increment hl-pair by 34
  1066.     DCR    E        ;countdown
  1067.     JNZ    DIAL12        ;not there yet, loop.
  1068. DIAL13    MVI    B,LIBLEN    ;number of characters to get from table
  1069.     LXI    D,CMDBUF+1    ;point to buffer
  1070.     XCHG            ;hl-pair points to cmdbuf+1 (exchange de/hl)
  1071.     MOV    M,B        ;store # of bytes in each library entry
  1072.     XCHG            ;restore regs
  1073.     INX    D        ;point to first char position in buffer
  1074.     CALL    MOVE        ;move table entry to buffer
  1075. DIALLPX CALL    ILPRT
  1076.     DB    CR,ESC,ETEOP,0    ;clear crt line on re-dial
  1077.      ENDIF            ;pmmi or mm100 or us100
  1078.  
  1079. ; get smartmodem/usr attention for dialing
  1080.  
  1081.      IF    US100
  1082.     LDA    DIAL$TP        ;touch-tone or pulse dial?
  1083.     STA    STYLE+1        ;put 't' or 'p' here
  1084.     LXI    H,ATTEN        ;point to string
  1085.     CALL    SM$STR
  1086. CLS$L    CALL    IN$SM
  1087.     JNC    CLS$L
  1088.      ENDIF            ;us100
  1089.  
  1090. ; full telephone number in 'cmdbuf' -- show # of dialing attempts at end
  1091.  
  1092.      IF    PMMI OR MM100 OR US100
  1093.     LXI    H,CMDBUF+1
  1094.     MOV    E,M        ; # of chars in buffer with pointer..
  1095.     INX    H        ;..to first chararacter to dial.
  1096. DIALLP2    MOV    A,M        ;get first # from buffer
  1097.  
  1098. ; routine to print 'badlib' message, abort if null encountered
  1099.  
  1100.     ORA    A        ;set flags
  1101.     PUSH    H        ;save hl-pair registers
  1102.     PUSH    PSW        ;save a and flags
  1103.     LXI    H,BADLIB    ;bad library number if null
  1104.     CZ    TEXTOUT
  1105.     POP    PSW        ;restore a-reg and flags
  1106.     POP    H        ;restore hl-pair
  1107.     JZ    BORTIT0        ;abort dialing
  1108.  
  1109. ; dial a digit -- check kbd for abort
  1110.  
  1111.     CALL    DIAL        ;dial it (type all letters & numbers dialed)
  1112.     CALL    STAT        ;keypress?
  1113.     CNZ    KEYIN        ;yes, go get it.
  1114.     CPI    CAN        ; ^x?
  1115.     JZ    BORTIT0        ;yes, abort.
  1116.     INX    H        ;bump pointer
  1117.     DCR    E        ;count dial-characters down
  1118.     JNZ    DIALLP2        ;not done, loop.
  1119.  
  1120. ; dialing completed
  1121.  
  1122.     CALL    TO$DIM
  1123.     CALL    ILPRT
  1124.     DB    ' (dial #',0
  1125.     LHLD    DIALCNT        ;update number of..
  1126.     INX    H    
  1127.     SHLD    DIALCNT        ;..dialings and display these..
  1128.     CALL    DECOUT        ;..connection attempts.
  1129.     CALL    ILPRT
  1130.     DB    ') ',0
  1131.     CALL    CTEOP
  1132.     CALL    TO$FULL
  1133.      ENDIF            ;pmmi or mm100 or us100
  1134.  
  1135.      IF    US100
  1136.     MVI    A,CR        ;enter command
  1137.     CALL    SM$TYPE
  1138. SM$DLP    CALL    IN$SM        ;clear modem line of 'ok' (0)
  1139.     JNC    SM$DLP
  1140.     JMP    SM$ANS        ;get response (connect/no carrier)
  1141.      ENDIF            ;us100
  1142.  
  1143.      IF    PMMI
  1144.     MVI    A,7FH        ;turn-on 'dtr'
  1145.     CALL    OUTCTR2
  1146.     MVI    B,1
  1147.     CALL    TIMER          ;wait for modem to turn-on 'dtr'
  1148.     MVI    A,5DH          ;no parity, 2 stop & 8 data bits + ..
  1149.     CALL    OUTCTRL        ;..disconnect on carrier loss after 17 secs.
  1150.      ENDIF            ;pmmi
  1151.  
  1152.      IF    MM100
  1153.     LDA    UARTCTLB    ;set uart word format
  1154.     CALL    OUTCTRL
  1155.     LDA    ORIGMOD        ;set modem mode
  1156.     STA    MODCTLB        ;and force it to originate mode
  1157.     CALL    OUTCTR2
  1158.      ENDIF            ;mm100
  1159.  
  1160.      IF    PMMI OR MM100
  1161.     MVI    D,CTS        ;clear to send mask
  1162.     MVI    C,WAITCTS     ;wait-time for 'cts'
  1163.     CALL    WAIT
  1164.      JNC    CONMADE          ; 'connection made' (cm) else..
  1165.     CALL    DISCONN          ;..go on-hook.
  1166.      ENDIF            ;pmmi or mm100
  1167.  
  1168.      IF    PMMI OR MM100 OR US100
  1169. DILAGN    LDA    CRFLAG          ;continuous re-dial (cr) flag
  1170.     ORA    A
  1171.     JNZ    DILAGN0
  1172.     CALL    ILPRT
  1173.     DB    CR,'No answer after normal time-out.  Re-dial?  '
  1174.     DB    'Y>es, N>o, or C>ontinuous: ',BELL,0
  1175.     CALL    RESPOND        ;get response
  1176.     CALL    CRONLY        ;overwrite with new line to be dialed
  1177.     CPI    'N'        ;re-dial?
  1178.     JZ    MENU        ;no, go menu.
  1179.     CPI    'Y'
  1180.     JZ    DILAGN0        ;yes, re-dial.
  1181.     CPI    'C'        ;continuous re-dial?
  1182.     JNZ    DILAGN        ;invalid response, ask again.
  1183.     MVI    A,TRUE        ;set continuous re-dial flag..
  1184.     STA    CRFLAG        ;..true.
  1185. DILAGN0    MVI    B,50        ; 5-second wait for modem reset else busy..
  1186.     CALL    TIMER        ;..signal may be sensed as dial tone.
  1187.     LDA    RBFLAG        ;ringback type of dial? (# of chars to dial)
  1188.     ORA    A
  1189.     JZ    DIALLP1        ;no, re-dial a normal number..
  1190.     STA    CMDBUF+1    ;..else restore full # including 'r'.
  1191.     JMP    DIALLP1        ;re-dial entry point at cmdbuf+2
  1192.  
  1193. BADLIB    DB    CR,LF,'++ Faulty dialing ++',CR,LF,'@'
  1194.  
  1195. ; auto dialer
  1196.  
  1197. DIAL    CALL    TYPE        ;print all characters, dashes, etc.
  1198.     CPI    'R'        ;ringback character?
  1199.     JNZ    DIAL1        ;if not, jump.
  1200.     PUSH    PSW        ;save accumulator & flags..
  1201.     MOV    A,E        ;put # of char left into a-reg
  1202.     CPI    1        ;is this the last character?
  1203.     JZ    RINGBK        ;yes, must be ringback char so ringback.
  1204.     POP    PSW        ;..and restore.
  1205. DIAL1      ENDIF            ;pmmi or mm100 or us100
  1206.  
  1207.      IF    US100
  1208.          MOV    B,A
  1209.     CALL    ALT$DL        ;see if 'mci/sprint' type call
  1210.     MOV    A,B        ;ascii character retained in b-reg
  1211.     CPI    ','        ; 2-second delay requested?
  1212.     JZ    SM$TYPE        ;branch, if yes.  returns to caller.
  1213.      ENDIF            ;us100
  1214.  
  1215.      IF    PMMI OR MM100 OR US100
  1216.     CPI    '0'        ;byte must be at least 0..
  1217.     RC
  1218.     CPI    '9'+1        ;..but not more than 9 to be dialed.
  1219.     RNC
  1220.     ANI    0FH        ;make ascii into binary for dialing
  1221.     JNZ    DIALS        ;convert a zero into..
  1222.     MVI    A,10        ;..10 pulses.
  1223. DIALS    MOV    C,A        ; # of pulses to dial in a/c-regs
  1224.      ENDIF            ;pmmi or mm100 or us100
  1225.  
  1226.      IF    US100
  1227.     MOV    A,B        ;put ascii digit to dial in a-reg
  1228.     JMP    SM$TYPE        ;send digit and return to caller
  1229.      ENDIF            ;us100
  1230.  
  1231.      IF    PMMI
  1232.     LDA    PULSERATE    ;contains value for dial speed
  1233.     CALL    OUTBAUD
  1234. DIALC    CALL    INBAUD        ;is timer done?
  1235.     ANI    TMPUL
  1236.     JNZ    DIALC        ;no, so loop
  1237. DIALB    CALL    INBAUD        ;wait one more time...
  1238.     ANI    TMPUL
  1239.     JZ    DIALB
  1240. MAKEP    MVI    A,MAKEM        ;pulse phone off hook for a bit
  1241.     CALL    OUTCTRL
  1242. TIMEM    CALL    INBAUD        ;wait n ms
  1243.     ANI    TMPUL
  1244.     JNZ    TIMEM
  1245.     MVI    A,BRKMASK    ;pulse phone on hook for a bit
  1246.     CALL    OUTCTRL
  1247. TIMEB    CALL    INBAUD        ;wait n ms
  1248.     ANI    TMPUL
  1249.     JZ    TIMEB
  1250.     DCR    C        ;end of pulses?
  1251.     JNZ    MAKEP        ;no, go pulse phone some more
  1252.     MVI    A,MAKEM        ;yes, make sure phone is still off hook
  1253.     CALL    OUTCTRL
  1254.      ENDIF            ;pmmi
  1255.  
  1256.      IF    MM100
  1257. MAKEP    MVI    A,OFFHOOK    ;spend 50ms off hook
  1258.     CALL    OUTCTR2
  1259.     CALL    OUTTIME        ;start 50ms timer
  1260. TIMEM    CALL    INCTRL        ;time up?
  1261.     ANI    TMPUL
  1262.     JZ    TIMEM
  1263.     MVI    A,ONHOOK    ;now spend 50ms on hook
  1264.     CALL    OUTCTR2
  1265.     CALL    OUTTIME        ;start timer
  1266. TIMEB    CALL    INCTRL        ;time up?
  1267.     ANI    TMPUL
  1268.     JZ    TIMEB
  1269.     DCR    C
  1270.     JNZ    MAKEP
  1271.     MVI    A,OFFHOOK    ;phone off hook while we wait for next digit
  1272.     CALL    OUTCTR2
  1273.      ENDIF            ;mm100
  1274.  
  1275.      IF    PMMI OR MM100
  1276.     MVI    B,2        ; 200 milliseconds between..
  1277.     JMP    TIMER        ;..each dialed digit.
  1278.      ENDIF            ;pmmi or mm100
  1279.  
  1280. ; ring once -- hang up -- redial
  1281.  
  1282.      IF    PMMI OR MM100 OR US100
  1283. RINGBK    POP    PSW          ;balance stack
  1284.     CALL    ILPRT
  1285.     DB    ESC,ETEOP,0    ;clear console line
  1286.     LDA    CMDBUF+1      ;get # of char in buffer
  1287.     STA    RBFLAG        ;store # including the 'r'
  1288.     DCR    A           ;subtract 1 to avoid 'r' char
  1289.     STA    CMDBUF+1      ;store new value for next ring
  1290.      ENDIF            ;pmmi or mm100 or us100
  1291.  
  1292.      IF    US100
  1293.     MVI    A,CR        ;enter dial-number command
  1294.     CALL    SM$TYPE
  1295.     MVI    B,80        ;wait for..
  1296.     CALL    TIMER        ;..one ring.
  1297.     MVI    A,CR        ;abort..
  1298.     CALL    SM$TYPE        ;..dial routine, then..
  1299.     MVI    B,25        ;..wait more..
  1300.     CALL    TIMER        ;..before..
  1301.     JMP    DIALLPX        ;..redialing.
  1302.      ENDIF            ;us100
  1303.  
  1304.      IF    PMMI
  1305.     MVI    D,DTMSK          ;load tone detect mask
  1306.     MVI    C,RBLMT          ;set timer for rblmt # of seconds
  1307.     CALL    WAIT
  1308.     JC    RBTIME          ;jump if no tone detected
  1309.     MVI    B,25          ;wait 2.5 sec
  1310.     CALL    TIMER
  1311.     CALL    INBAUD        ;get dial tone status
  1312.     ANA    D        ;active low
  1313.     JNZ    RNGBK1
  1314.     JMP    DILAGN          ;yes, must be busy now.
  1315.      ENDIF            ;pmmi
  1316.  
  1317.      IF    MM100
  1318.     MVI    B,25        ;wait 2.5 seconds to get dial tone
  1319.     CALL    TIMER
  1320.     JMP    DILAGN        ;dial number again
  1321.      ENDIF            ;mm100
  1322.  
  1323. ; hangup -- re-dial -- listen for dial tone
  1324.  
  1325.      IF    PMMI OR MM100
  1326. RBTIME    CALL    CRONLY        ;just a cursor return
  1327. RNGBK1    CALL    HANGUP         ;hang up the phone
  1328.     MVI    B,RBWAIT     ;wait x sec before re-dialing
  1329.     CALL    TIMER
  1330.     CALL    WTTONE         ;go off-hook, listen for dialtone.
  1331.     JNC    DIALLPX         ;dial number and wait till..
  1332.     JMP    MENU         ;..time-out or connection.
  1333.      ENDIF            ;pmmi or mm100
  1334.  
  1335. ; modem go on-hook
  1336.  
  1337.      IF    PMMI
  1338. HANGUP    MVI    A,CLEAR        ;idle
  1339.     CALL    OUTCTR2
  1340.     XRA    A
  1341.     CALL    OUTCTRL        ;clear dtr/etc.
  1342.     RET
  1343.      ENDIF            ;pmmi
  1344.  
  1345.      IF    MM100
  1346. HANGUP    XRA    A        ;turn off carrier, go on-hook.
  1347.     CALL    OUTCTR2
  1348.     RET
  1349.      ENDIF            ;mm100
  1350.  
  1351. ; smartmodem/u.s. robotics special routines
  1352.  
  1353. ; get sm/usr response to dialing (connect, no carrier, or error) -- abort
  1354. ; call with ^x from keyboard
  1355.  
  1356.      IF    US100
  1357. SM$ANS    CALL    INSTAT
  1358.     JZ    SM$ANS2        ;loop if no character ready, but 1st..
  1359.     CALL    STAT        ;..see if abort requested.
  1360.     JZ    SM$ANS
  1361.     CALL    KEYIN
  1362.     CPI    CAN        ;cancel?  (^x)
  1363.     JNZ    SM$ANS        ;branch if not, to loop beginning.
  1364.     MVI    A,CR        ;exit from..
  1365.     CALL    SM$TYPE        ;..dialing..
  1366.     JMP    BORT$IT        ;..disconnect, then to cmd line.
  1367.  
  1368. SM$ANS2    CALL    INCHAR
  1369.     ANI    7FH
  1370.     CPI    '1'        ;connected?
  1371. ;    JZ    PRETERM        ; *** test line ***
  1372.     jz    conmade        ;get options from operator (cmd line)
  1373.     CPI    '4'        ;error occurred?
  1374.     JZ    SM$ANS4        ;if no, abort.
  1375.     CPI    '3'        ;no carrier?
  1376.     JNZ    SM$ANS
  1377. SM$ANS3    CALL    IN$SM        ;strip remaining characters and..
  1378.     JNC    SM$ANS3
  1379.     JMP    DILAGN        ;..redial.
  1380.  
  1381. SM$ANS4    CALL    NO$DT        ;show trouble and..
  1382.     JMP    BORT$IT        ;..return to command line.
  1383.  
  1384. PRETERM CALL    ILPRT
  1385.     DB    CR,LF,LF,'In Terminal Mode',CR,LF,LF,BELL,0
  1386.     JMP    TERM
  1387.  
  1388. ; get character from line (return with carry set at time-out)
  1389.  
  1390. IN$SM    LXI    B,312*MHZ    ;set for 300 millisec time-out loop
  1391. IN$SMLP    CALL    INSTAT
  1392.     JZ    INCHAR        ;get character (rets to caller)
  1393.     DCX    B
  1394.         MOV    A,B
  1395.     ORA    C
  1396.     JNZ    IN$SMLP        ;loop till count-down to zero
  1397.     STC            ;if time-out, return with..
  1398.     RET            ;..carry set.
  1399.  
  1400. ; string out to sm/usr modem
  1401.  
  1402. SM$STR    MOV    A,M
  1403.     CPI    '@'
  1404.     RZ            ;return to caller at string terminator
  1405.     CALL    SM$TYPE        ;send to modem
  1406.     INX    H
  1407.     JMP    SM$STR        ;loop until done
  1408.  
  1409. ; character out to sm/usr modem
  1410.  
  1411. SM$TYPE    PUSH    PSW        ;save character and..
  1412. SM$LP    CALL    OUTSTAT        ;see if ready for next character
  1413.     JNZ    SM$LP        ;loop 'till ready
  1414.     POP    PSW        ;..restore
  1415.     CALL    OUTCHAR        ;send to modem but..
  1416.     MVI    B,1         ;..send..
  1417.     JMP    TIMER        ;..slowly (for drama at the console).
  1418.  
  1419. ; sm/usr disconnect
  1420.  
  1421. DISCONN    XRA    A        ;store a disconnected..
  1422.     STA    LINEFLG        ;..condition.
  1423.     CALL    ILPRT
  1424.     DB    CR,ESC,ETEOP    ;clear line and to-end-of-page
  1425.     DB    'Stand by... ',0    ;fall-thru to go on-hook command
  1426.  
  1427. ; send on-hook escape command with delay fore and wait for response aft
  1428.  
  1429. ON$PLUS    MVI    B,12
  1430.     CALL    TIMER
  1431.     LXI    H,PLUS        ;send escape string..
  1432.     CALL    SM$STR        ;..to modem.
  1433.     MVI    B,12
  1434.     JMP    TIMER
  1435.  
  1436. ; esc$2    call    instat        ;wait for response
  1437. ;     jnz    esc$2
  1438. ;        call    inchar
  1439. ;      ani    7fh
  1440. ;    cpi    '3'        ;disconnected?
  1441. ;    jz    esc$3
  1442. ;    cpi    'N'        ;disconnected?
  1443. ;    jnz    esc$2
  1444. ;esc$3    call    in$sm        ;bucket 'cr' and anything else on-line
  1445. ;    jnc    esc$3
  1446. ;    ret
  1447.  
  1448. ; alternate dialing using 'mci', 'sprint', etc.  only used with touch-tone
  1449. ; dialing and smart modems.
  1450.  
  1451. ALT$DL    LDA    TOUCH$T        ;return if..
  1452.     ORA    A        ;..alternate 'mci/sprint' type
  1453.     RZ            ;..dialing not indicated.
  1454.     MOV    A,B        ;get byte from 'dial'
  1455.     CPI    '<'
  1456.     JNZ    ALT$DL2
  1457.     PUSH    H
  1458.     LXI    H,ALT$DIAL1
  1459.     JMP    ALT$DL3
  1460.  
  1461. ALT$DL2    CPI    '>'
  1462.     RNZ
  1463.     PUSH    H
  1464.     LXI    H,ALT$DIAL2
  1465. ALT$DL3    MOV    A,M
  1466.     CPI    '@'
  1467.     JZ    ALT$DL4
  1468.     MOV    B,A
  1469.     CALL    SM$TYPE
  1470.     INX    H
  1471.     CALL    STAT
  1472.     JZ    ALT$DL3
  1473.     CALL    KEYIN
  1474.     CPI    CAN
  1475.     JZ    DISCONN
  1476.     JMP    ALT$DL3
  1477.  
  1478. ALT$DL4    MVI    A,' '        ;space between alternate and station
  1479.     CALL    TYPE
  1480.     POP    H
  1481.     RET
  1482.      ENDIF            ;us100
  1483.  
  1484. ; time-out routine.  called with mask in d-reg for input at
  1485. ; relative port 2 and # of seconds * 5 in c-reg.  checks kbd
  1486. ; for abort.
  1487.  
  1488.      IF    PMMI OR MM100
  1489. WAIT    MVI    B,2        ;makes interval..
  1490.     CALL    TIMER          ;..200 milliseconds.
  1491.      ENDIF            ;pmmi or mm100
  1492.  
  1493.      IF    PMMI
  1494.     CALL    INBAUD         ;modem status port
  1495.     ANA    D        ;mask status bit
  1496.     RZ            ;return active 'lo'
  1497.      ENDIF            ;pmmi
  1498.  
  1499.      IF    MM100
  1500.     CALL    INCTRL        ;modem status port
  1501.     ANA    D
  1502.     RNZ            ;return active 'hi'
  1503.      ENDIF            ;mm100
  1504.  
  1505.      IF    PMMI OR MM100
  1506.     PUSH    D        ;save mask
  1507.     CALL    STAT          ;keypress?
  1508.     CNZ    KEYIN          ;yes, get character.
  1509.     CPI    CAN        ; ^x?
  1510.     JZ    BORTIT0        ;yes, disconnect, jmp to menu.
  1511.     POP    D        ;get mask back
  1512.     DCR    C        ;count-down (100 = 20 sec)
  1513.     JNZ    WAIT
  1514.     CALL    DISCONN          ;go on-hook
  1515.     STC            ;set carry to indicate either dial tone..
  1516.     RET            ;..not detected or 'cts' not received.
  1517.      ENDIF            ;pmmi or mm100
  1518.  
  1519. ; disconnect and start anew
  1520.  
  1521.      IF    PMMI OR MM100 OR US100
  1522. BORTIT0 CALL    CRLF        ;a 'crlf' followed by..
  1523. BORT$IT    CALL    DISCONN     ;..disconnect, reset option..
  1524.     JMP    MENU        ;..table, and show prompt.
  1525.      ENDIF            ;pmmi or mm100 or us100
  1526.  
  1527. ; disconnect then wait for dial tone
  1528.  
  1529.      IF    PMMI OR MM100
  1530. WTTONE    CALL    DISCONN        ;go on-hook
  1531.     CALL    CRONLY
  1532.     CALL    CTEOP
  1533.     CALL    TO$DIM
  1534.     CALL    ILPRT
  1535.     DB    '           Waiting for dial tone  ',CR,0
  1536.     CALL    TO$FULL
  1537.      ENDIF            ;pmmi or mm100
  1538.  
  1539.      IF    PMMI
  1540.     MVI    A,MAKEM        ;make 'make' (off-hook)
  1541.     CALL    OUTCTRL
  1542.     MVI    D,DTMSK        ;dial tone mask
  1543.     MVI    C,25        ; 25 = 5 second wait, wait for dial tone
  1544.     CALL    WAIT        ;delay -- 'wait' returns with no carry if tone
  1545.     RNC            ;if dial tone within 5 seconds..
  1546.      ENDIF            ;pmmi
  1547.  
  1548.      IF    PMMI OR US100
  1549. NO$DT    CALL    ILPRT        ;..else show msg and return to menu.
  1550.     DB    CR,LF,LF
  1551.     DB    '++ NO DIAL TONE -- line/hardware problem ++'
  1552.     DB    CR,LF,LF,BELL,0
  1553.     STC            ;set carry true
  1554.     RET
  1555.      ENDIF            ;pmmi or us100
  1556.  
  1557.      IF    MM100
  1558.     MVI    A,OFFHOOK    ;bring modem off-hook
  1559.     CALL    OUTCTR2
  1560.     MVI    B,10        ;wait some more
  1561.     CALL    TIMER
  1562.     XRA    A        ;clear carry
  1563.     RET
  1564.      ENDIF            ;mm100
  1565.  
  1566. ; modem disconnect routine
  1567.  
  1568.      IF    PMMI OR MM100
  1569. DISCONN XRA    A        ;store a disconnected..
  1570.     STA    LINEFLG        ;..condition here.
  1571.     CALL    OUTCTR2        ;clear dtr, esd, etc., and..
  1572.      ENDIF            ;pmmi or mm100
  1573.  
  1574.      IF    PMMI
  1575.     CALL    OUTCTRL
  1576.      ENDIF             ;pmmi
  1577.                                  
  1578.      IF    PMMI OR MM100    
  1579.     CALL    OUTCTRL        ;..hang-up (go on-hook).
  1580.     MVI    B,8        ;wait for modem to disconnect
  1581.     JMP    TIMER        ;ret to caller
  1582.      ENDIF            ;pmmi or mm100
  1583.  
  1584. ; telephone-connection-made announcement
  1585.  
  1586.      IF    PMMI OR MM100 OR US100
  1587. CONMADE    CALL    TO$FULL
  1588.     CALL    CTEOP
  1589.     CALL    ILPRT
  1590.     DB    CR,LF
  1591.     DB    'Connection established -- '
  1592.      ENDIF            ;pmmi or mm100 or us100
  1593.  
  1594.      IF    PMMI OR MM100
  1595.     DB    'select options (e.g., TO.300 fn.ft): ',0
  1596.      ENDIF            ;pmmi or mm100
  1597.  
  1598.      IF    US100
  1599.     DB    'select E or T [fn.ft]: ',0
  1600.      ENDIF            ;us100
  1601.  
  1602.      IF    PMMI OR MM100 OR US100
  1603.     MVI    A,TRUE        ;indicate line..
  1604.     STA    LINEFLG        ;..is connected.
  1605. CMLP    CALL    STAT        ;check for keypress
  1606.     JNZ    GETCMD        ;key pressed, go get options.
  1607.     MVI    A,BELL        ;ring bell until..
  1608.     CALL    TYPE        ;..a key pressed.
  1609.     MVI    B,1        ;delay for console..
  1610.     CALL    TIMER        ;..to process bell.
  1611.     JMP    CMLP        ;loop 'til keypress
  1612.      ENDIF            ;pmmi or mm100 or us100
  1613.  
  1614. ; d i r
  1615.  
  1616. ; display drive directory & reset disk system
  1617.  
  1618. DIR    CALL    RESET        ;reset system for disk changes
  1619.     CALL    DIRLIST        ;show directory and space remaining
  1620.  
  1621. ; m e n u   (command mode)
  1622.  
  1623. MENU    LXI    H,RESTRN    ;restore record numbers, etc,..
  1624.     LXI    D,RECDNOB    ;..for new file transfer.
  1625.     MVI    B,RECDNOE-RECDNOB
  1626.     CALL    MOVE
  1627.     LXI    H,RESTROPT    ;restore secondary option table
  1628.     LXI    D,OPTBL
  1629.     MVI    B,OPTBE-OPTBL
  1630.     CALL    MOVE
  1631.     XRA    A
  1632.     STA    MFFLG1        ; reset mfname (multi-filename) routine..
  1633.     STA    ABORTFLG    ;clear abort flag
  1634.     CMA            ; ..and batch mode to recover..
  1635.     STA    FSTFLG        ; ..from an abort.
  1636. MENU1    LDA    XPRFLG        ;test if menu should be shown
  1637.     ORA    A
  1638.     JNZ    XPRT        ;don't show menu
  1639. MENU2    CALL    CAPTION        ;show program title (header)
  1640.     CALL    TO$DIM
  1641.     CALL    ILPRTQ
  1642.     DB    '                                    -- M E N U --',CR,LF,LF
  1643.     DB    '                        C o m m a n d   M o d e',CR,LF,0
  1644.     CALL    TO$FULL
  1645.     CALL    ILPRTQ
  1646.     DB    '------- File Operations --------     ---------- Modem Contro'
  1647.     DB    'l ---------',CR,LF,0
  1648.     CALL    TO$DIM
  1649.     CALL    ILPRTQ
  1650.     DB    'DIR - Directory [d: *.ft]             CAL - Dial telephone n'
  1651.     DB    'umber    ',CR,LF
  1652.     DB    'WRT - Write save-file buffer          SEL - Select transmiss'
  1653.     DB    'ion format    ',CR,LF
  1654.     DB    'DEL - Delete save-file buffer         DSC - Disconnect telep'
  1655.     DB    'hone line    ',CR,LF
  1656.  
  1657.      IF    UTL
  1658.     DB    'UTL - Utility file manipulation       '
  1659.      ENDIF            ;utl
  1660.  
  1661.      IF    VUE
  1662.     DB    'VUE - View text file                  '
  1663.      ENDIF            ;vue
  1664.  
  1665.      IF    US100
  1666.     DB    'SET - Set baudrate (off-line)'
  1667.      ENDIF            ;us100
  1668.  
  1669.     DB    CR,LF
  1670.     DB    'SAP - Sort and Pack Directory        ',CR,LF
  1671.     DB    'ERA - Erase files (ERA fn.ft)',0
  1672.     CALL    TO$FULL
  1673.     CALL    ILPRTQ
  1674.     DB    '        --------- Miscellaneous ---------',CR,LF,0
  1675.     CALL    TO$DIM
  1676.     CALL    ILPRTQ
  1677.     DB    '                                      M - Menu     CPM - Exi'
  1678.     DB    't to CP/M',CR,LF,0
  1679.     CALL    TO$FULL
  1680.     CALL    ILPRTQ
  1681.     DB    ' ------- Primary Options -------',CR,LF,0
  1682.     CALL    TO$DIM
  1683.     CALL    ILPRTQ
  1684.     DB    '  T - Terminal Mode (T fn.ft)        ',0
  1685.     CALL    TO$FULL
  1686.     CALL    ILPRTQ
  1687.     DB    '------- Secondary Options -------',CR,LF,0
  1688.     CALL    TO$DIM
  1689.     CALL    ILPRTQ
  1690.     DB    '  E - Echo Mode (host computer)       B - Batch Transfer    '
  1691.     DB    'Q - Quiet',CR,LF
  1692.     DB    '  S - Send CP/M file (ST fn.ft)       D - Disconnect        '
  1693.     DB    'V - View',CR,LF
  1694.     DB    '  R - Receive file (RT fn.ft)         E - Exit to CP/M when '
  1695.     DB    'completed',CR,LF,LF,0
  1696.     CALL    TO$FULL
  1697.     CALL    ILPRTQ
  1698.     DB    '--- T e r m i n a l   M o d e ------------------------------'
  1699.     DB    '------------------',CR,LF,0
  1700.     CALL    TO$DIM
  1701.     CALL    ILPRTQ
  1702.     DB    'R - Review stored strings   S - Save-file (fn.ft) toggle   '
  1703.     DB    'T - Transfer file',CR,LF
  1704.     DB    'E - Exit to Command Mode  ',0
  1705.     LDA    CMDCHR        ;get command character and.. 
  1706.      CALL    SHOWCTL        ;..print it.                        
  1707.      CALL    ILPRTQ                                              
  1708.     DB    ' - Send lead-in character     '            
  1709.     DB    'D - Disconnect line',CR,LF                                  
  1710.     DB    'n - Send string (0 to 9)   '
  1711.  
  1712.      IF    PMMI OR MM100
  1713.     DB    'B - Baudrate change on-the-fly  '
  1714.      ENDIF            ;pmmi or mm100
  1715.  
  1716.     DB    ' P - Printer toggle',CR,LF
  1717.     DB    '                (terminal mode command lead-in character =',0
  1718.     LDA    CMDCHR        ;get command character and..
  1719.     CALL    SHOWCTL        ;..print it.
  1720.     CALL    ILPRTQ
  1721.     DB    ')',CR,LF,LF,0
  1722.     CALL    TO$FULL
  1723.     JMP    C$LINE        ;go show command line
  1724.  
  1725.     LINK    COMM725A    ;chains to 'comm725a.asm' using lasm.com
  1726.  
  1727.  
  1728.