home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / TERMS / IMP245S.LBR / IMP245.AZM / IMP245.ASM
Assembly Source File  |  1991-09-01  |  182KB  |  7,829 lines

  1.  
  2. VERSION    EQU    245    ; IMP (05/22/87)  -    CP/M-80 MODEM PROGRAM
  3. ;
  4. ;-----------------------------------------------------------------------
  5. ;  o  05/22/87  Added BREAK tone routine, added BRKCHR:, J$BREAK and
  6. ;        SENDBRK: routines in each overlay, added a JZ SBREAK
  7. ;        to the main program if ESC-BRKCHR is typed, added the
  8. ;        STPCHR: and SBREAK: routines to the main program and
  9. ;        changed the DONETD: and BYEBYE: routines in main pgm.
  10. ;  o  02/07/87  Changed routine for sending batch header, constructs
  11. ;        the header BEFORE looking for a 'C' from remote, also
  12. ;        uses conventional "GTACK" routine, saving bytes.
  13. ;  o  02/04/87  Increased some "RECV" times for PC Pursuit satelite
  14. ;        networks, added a few manual abort calls, rewrote the
  15. ;        'JZ  CKCAN'  to  'CALL  CKCAN'.
  16. ;  o  01/12/87  Added 'TIG' option to toggle IGNORCTL on/off.  (For
  17. ;        David Cortesi).
  18. ;  o        Now shows file name being received or sent.
  19. ;-----------------------------------------------------------------------
  20.     ASEG        ; Needed for M80, disregard error if using MAC
  21. ;
  22. ;
  23. ;     NOTE:  This program is written in Intel 8080 code.
  24. ;         It assembles with ASM, LASM, MAC or M80 and
  25. ;         will operate on 8080/8085 or Z80 computers.
  26. ;
  27. ;        COPYRIGHTED 1985,1987 BY IRVIN M. HOFF
  28. ;
  29. ; THIS TELEPHONE MODEM PROGRAM USES THE CHRISTENSEN PROTOCOL.  IT HAS
  30. ; BOTH 'CRC' AND CHECKSUM CAPABILITY FOR ERROR-DETECTION. IT SUPPORTS
  31. ; DIALING AND AUTO-REDIALING FOR 2400 BPS MODEMS USING THE HAYES PRO-
  32. ; TOCOL, AS WELL AS THE RACAL-VADIC 2400V, WITH ITS SUPERIOR PROGRESS
  33. ; REPORTING RESULT CODES.
  34. ;
  35. ;***********************************************************************
  36. ;
  37. ;       THIS PROGRAM IS COPYRIGHTED. IT MAY BE DISTRIBUTED 
  38. ;          WITH NO PREVIOUS WRITTEN PERMISSION WITH THE 
  39. ;          UNDERSTANDING THA╘ NO FINANCIAL GAIN WILL RESULT 
  40. ;          FROM SUCH TRANSACTION.
  41. ;
  42. ;***********************************************************************
  43. ;
  44. ;   GENERAL INTEREST:  When transferring files modem-to-modem, the batch
  45. ;   mode is extremely useful.  It allows automatic transmission of nu-
  46. ;   merous files while the operator at the receiving end does virtually
  47. ;   nothing.  It can be used for single files or with wildcards.  With
  48. ;   normal single program transfer, the receiving end switches from CRC
  49. ;   to checksum in one minute and times out completely in 120 seconds.
  50. ;   (In batch mode it times out in 3 minutes for receive.)  This offers
  51. ;   ample opportunity to transfer programs between individuals.
  52. ;
  53. ;      I2NM-1.ASM can be used to change the telephone overlay numbers
  54. ;         and/or set the alternate dialing system code (also used toè;         change SAVSIZ, mentioned below.)  It can also be used for
  55. ;         intially setting (or changing) any of the function key as-
  56. ;         signments.
  57. ;
  58. ;      I2LIB.COM  can be used to very easily and very quickly change
  59. ;         any of the telephone overlay numbers.
  60. ;
  61. ;      I2FUNC.COM can be used to quickly and easily change any of the
  62. ;         10 function key assignments (or the function key intercept
  63. ;         character itself, which is currently the '^' character.
  64. ;
  65. ;    Significant address changes now used:
  66. ;
  67. ;       0BFFH  -  SAVSIZ  20 = 4k file transfer buffer size
  68. ;                 40 = 8k file transfer buffer size
  69. ;                 80 = 16k file transfer buffer size
  70. ;       0C00H  -  NUMBLIB (start of telephone number library)
  71. ;
  72. ;***********************************************************************
  73. ;
  74. ;    In past years many people have contributed ideas for modem pro-
  75. ;    grams that I have adapted for use in the IMP2 series.  The list
  76. ;    below includes as many of those as I can recall.
  77. ;
  78. ;         Ward Christensen, Jim Mills, Mark Zeigler, Keith Petersen,
  79. ;         Paul Kelly, Bruce Ratoff, John Mahr, Rich Berg, Bob Clyne,
  80. ;         Bill Earnest, Paul Hansknecht, Ron Fowler, Fred Viles, Bob
  81. ;         Plouffe, Ben Bronson, Sigi Kluger, Frank Gaude' and likely
  82. ;         others.
  83. ;                    - Irv Hoff W6FFC
  84. ;
  85. ;***********************************************************************
  86. ;
  87. ; 05/22/87  Improved the GOODBYE routine, added BREAK routine, needs
  88. ;   v245    IMP245 to use it.            - Irv Hoff
  89. ;    
  90. ; 09/22/86  Eliminated converting a '/' to '_' in batch mode.  If send-
  91. ;   v245    ing a file that already exists in batch mode, KMD22 sends an
  92. ;        EOT which in turns displays a "File exists..." line in IMP
  93. ;        and then aborts.  Now accepts "CALL" in addition to "CAL" in
  94. ;        dial mode.            - Irv Hoff
  95. ;  
  96. ; 10/01/85  Fixed SMRESUL5 so autodial works normally with the Anchor
  97. ;   v244    modems.  Fixed DONETD to call J$DSCONT if using modems with
  98. ;        no DTR for disconnect.  (Set byte 011EH to other than 00 in
  99. ;        that case.)  SPDMSG now goes 0-36 ms for delay between char-
  100. ;        acters when sending ASCII files in terminal mode instead of
  101. ;        only 0-9 ms (needed by Osborne OS-1, etc.)  File length now
  102. ;        stored at end of header in hex rather than ASCII, saved 53
  103. ;        bytes.  Batch receive shows file name, length in records and
  104. ;        'k' and time to receive.  (Same feature added to KMD07 - no
  105. ;        longer shows file length at all, with earlier versions of
  106. ;        KMD.)  Fixed STDRV to permit using area 1, which it had pre-
  107. ;        viously ignored - although it allowed selecting all other
  108. ;        user areas.            - Irv Hoff
  109. ;
  110. ; 09/07/85  Found the one of the flags was not being reset after a batch
  111. ;   v243    file was received.  This would prevent subsequent files from
  112. ;        being received if the initial 'C' was garbled.  (This goes
  113. ;        clear back to when CRC was added to MODEM7 in October 1981,
  114. ;        that flag was never reset for batch receive.)  Also removed
  115. ;        a  "CALL  DSCONCT"  which slowed disconneting with ESC-N
  116. ;        or DSC.            - Irv Hoff
  117. ;
  118. ; 08/27/85  The YAM receive routine did not properly handle filenames
  119. ;   v242    with 8 characters and no extent.  Our system of storing file
  120. ;        length turned them into read-only files to which you could
  121. ;        not write.  Other minor changes.
  122. ;                    - Irv Hoff
  123. ;
  124. ; 08/20/85  Added YAM batch mode.  Use the command: TBM to select MODEM7
  125. ;   v241    batch mode if preferred.  Uses some routines adapted from
  126. ;        work done by Dennis Vallianos.
  127. ;                    - Irv Hoff
  128. ;
  129. ; 07/17/85  First version of IMP2, adapted from MDM740.  Supports 2400
  130. ;   v240    bps modems using auto-stepdown Racal-Vadic 2400V protocol or
  131. ;        Hayes 2400 protocol.  Companion overlays start with I2, such
  132. ;        as I2DP-1.ASM for the 8251 with CTC implemented into this
  133. ;        version.  These overlays only work with IMP2.
  134. ;                    - Irv Hoff
  135. ;
  136. ;***********************************************************************
  137. ;
  138. ; 05/07/84  Numerous small bugs fixed that have apparently been present
  139. ;  MDM740   since MODEM7 days.    Copyright notice added when the program
  140. ;        is brought up, to be legal.  Auto-linking added which gives
  141. ;        the ability to automatically redial a sequential list up to
  142. ;        32 numbers.  Two options:
  143. ;
  144. ;            B>>COMMAND:  A,F,4,G,Z
  145. ;                          or
  146. ;            B>>COMMAND:  A/F/4/G/Z
  147. ;
  148. ;        The '/' beeps just once when connected and then jumps auto-
  149. ;        matically to the terminal mode to catch any signon messages
  150. ;        from IBM or Unix systems, etc.  The first option beeps con-
  151. ;        tinuously until the operator hits any key.    This places the
  152. ;        program in the terminal mode.  These two options combine to
  153. ;        make MDM740 one of the most useful modem programs currently
  154. ;        available for dialing busy numbers.
  155. ;                    - Irv Hoff
  156. ;
  157. ; 01/01/83  First version.  Can be assembled with ASM.COM.  (Previously
  158. ;  MDM700   it was necessary to have the MODEM7.LIB file and use MAC.COM
  159. ;        to assemble the program.)  Selected MDM700 as a new program
  160. ;        to allow me to make changes that I felt might be beneficial.
  161. ;        This would not hinder others from updating existing programs
  162. ;        to their own satisfaction.    The name was also selected so it
  163. ;        would fit on databanks limiting file names to 6 characters.
  164. ;                    - Irv Hoff
  165. ;
  166. ;***********************************************************************
  167. ;
  168. ;
  169. YES    EQU    0FFH    ; Use in DB options, MVI  A,YES (8 bit values)
  170. NO    EQU    0    ;  "   "  "    "      "   "  "     "  "     "
  171. TRUE    EQU    0FFFFH    ; Use in all EQUs for conditionals (16 bits)
  172. FALSE    EQU    0    ;  "   "  "   "    "  "    "         "     "
  173. ;
  174. ;
  175. ; Values shown are for a 8251A I/O
  176. ;
  177. PORT    EQU    28H    ; Your base port (data or status)
  178. MDCTL1    EQU    PORT+1    ; Modem control port
  179. MDDATP    EQU    PORT    ; Modem data port
  180. MDRCV    EQU    02H    ; Modem receive ready
  181. MDSND    EQU    01H    ; Modem send ready bit
  182. MDTXE    EQU    05H    ; Modem send buffer empty, holding buffer empty
  183. ;
  184. BDPORTR    EQU    20H    ; CTC port for receive baudrate
  185. BDPORTS    EQU    1AH    ; CTC port for transmit baudrate
  186. ;
  187. MDMODE    EQU    82H    ; Insures 8251A I/O is out of mode with DTR high
  188. MDRSET    EQU    42H    ; Resets USART for additional commands
  189. MDSET1    EQU    4EH    ; 1 stop bit, no parity, 8 bits, x16
  190. MDSET2    EQU    0CEH    ; 2 stop bits, no parity, 8 bits, x16
  191. MDCOM    EQU    17H    ; Reset error flags, RCV, DTR, TX ready
  192. ;
  193. ;
  194. ;-----------------------------------------------------------------------
  195. ;
  196. ;
  197. BUFSIZ    EQU    16    ; Buffer size in Kbytes for ASCII capture to disk
  198.             ; (16k is one file extent)
  199. XFRSIZ    EQU    16    ; File transfer buffer in Kbytes.  Do not make
  200.             ; Any larger than BUFSIZ.  16k works fine on
  201.             ;   all but very slowest floppy systems
  202. STOPBIT    EQU    FALSE    ; Yes, if using 2 stop bits, no if using 1
  203. ;
  204. BDNMCH    EQU    75H    ; Bad name match
  205. ERRLIM    EQU    10    ; Maximum allowable consecutive errors
  206. ERRCRC    EQU    6    ; CRC tries, then switches to CHECKSUM
  207. LIBLEN    EQU    34    ; Length of each phone library entry
  208. RUB    EQU    7FH    ; Rub
  209. STRSPD    EQU    3CH    ; MSPEED location in low ram
  210. CRC    EQU    'C'    ; Requests 'CRC' instead of 'CKSUM'
  211. KSND    EQU    'K'    ; Requests 1k blocks
  212. ESC    EQU    '['-40H    ; ^[ = Escape
  213. SOH    EQU    'A'-40H    ; ^A = Start of header
  214. STX    EQU    'B'-40H    ; ^B = Start of text (for 1k blocks)
  215. EOT    EQU    'D'-40H    ; ^D = End of text
  216. ACK    EQU    'F'-40H    ; ^F = Acknowledge
  217. OKNMCH    EQU    'F'-40H    ; ^F = Ok name match
  218. BELL    EQU    'G'-40H    ; ^G = Bell character
  219. BKSP    EQU    'H'-40H    ; ^H = Backspace
  220. LF    EQU    'J'-40H    ; ^J = Linefeed
  221. NEXTRY    EQU    'K'-40H    ; ^K = Try next phone number, abort this try
  222. CR    EQU    'M'-40H    ; ^M = Carriage return
  223. XON    EQU    'Q'-40H    ; ^Q = XON character
  224. XOFF    EQU    'S'-40H    ; ^S = XOFF character
  225. NAK    EQU    'U'-40H    ; ^U = Not acknowledge
  226. CANCEL    EQU    'X'-40H    ; ^X = Cancel send or receive
  227. CLEARSC    EQU    'Z'-40H    ; ^Z = Clears screen, command mode
  228. EOFCHAR    EQU    'Z'-40H    ; ^Z = End of file
  229. ;
  230. ;
  231. ;-----------------------------------------------------------------------
  232. ;
  233. ;
  234.     ORG    0100H
  235. ;
  236. ;
  237.     JMP    START        ; Skip the data area below
  238. ;
  239. ;
  240. ; These routines and equates are at the beginning of the program so
  241. ; they can be patched by a monitor or overlay file without re-assembling
  242. ; the program.
  243. ;
  244. MSPEED:     DB    6    ; 0=110 1=300 2=450 3=600 4=710 5=1200        103H
  245.             ; 6=2400 7=4800 8=9600 9=19200 default
  246. HS2400:     DB    YES    ; Yes=2400 bps highest speed            104H
  247. HS1200:     DB    NO    ; Yes=1200 bps highest speed            105H
  248. RACAL:     DB    NO    ; Yes=Racal-Vadic 1200V or 2400V or 2400PA    106H
  249. PROMODM: DB    NO    ; Yes=Prometheus ProModem 1200 bps        107H
  250. RESVD1:     DB    NO    ; Reserved for special modems            108H
  251. RESVD2:     DB    NO    ; Reserved for special modems            109H
  252. ;
  253. ;
  254. CLEAR:     DB    1AH    ; Clear screen character (ESC not needed)    10AH
  255. CLOCK:     DB    37    ; Clock speed in MHz x10, 25.5 MHz max.     10BH
  256.             ; 20=2 MHh, 37=3.68 MHz, 40=4 MHz, etc.
  257. BYTDLY:     DB    2    ; 0=0 delay  1=10ms  5=50 ms - 9=90 ms        10CH
  258.             ;   default time to send character in ter-
  259.             ;   minal mode file transfer for slow BBS
  260. CRDLY:     DB    2    ; 0=0 delay 1=100 ms 5=500 ms - 9=900 ms    10DH
  261.             ;   default time for extra wait after CRLF
  262.             ;   in terminal mode file transfer
  263. NOFCOL:     DB    5    ; Number of directory columns shown        10EH
  264. TCHPUL:     DB    'T'    ; T=tone, P=Pulse ('AT' protocol only)        10FH
  265. ;.....
  266. ;
  267. ;
  268. ADDLFD:     DB    NO    ; Yes=add LF after CR to send file in terminal    110H
  269.             ;   mode (normally added by remote echo)
  270. CONVRUB: DB    YES    ; Yes=convert rub to backspace            111H
  271. CRCDFLT: DB    YES    ; Yes=default to CRC checking            112H
  272. IGNRCTL: DB    NO    ; Yes=CTL-chars above ^M not displayed        113H
  273. ;.....
  274. ;
  275. ;
  276. EXTCHR:     DB    '['-40H    ; ESC = preceeds local control character    114H
  277. EXITCHR: DB    'E'    ; Exit character                115H
  278. FILESND: DB    'F'    ; Send file when in terminal mode        116H
  279. NOCONCT: DB    'N'    ; Disconnect from phone line            117H
  280. LOGCHR:     DB    'L'    ; Send logon                    118H
  281. LSTCHR:     DB    'P'    ; Toggle printer                119H
  282. UNSAVCH: DB    'R'    ; Close input text buffer            11AH
  283. SAVECHR: DB    'Y'    ; Open input text buffer            11BH
  284. CLEARS:     DB    'Z'    ; Clears screen, terminal mode            11CH
  285. BRKCHR:     DB    'Q'    ; Send a break tone                11DH
  286. NODTR:     DB    0    ; For future development            11EH
  287. ;.....
  288. ;
  289. ;
  290. ; Handles in/out ports for data and status
  291. ;
  292. I$MDCTL1: IN    MDCTL1        ;                    11FH
  293.       RET            ; IN modem control port         121H
  294.       DB    0,0,0,0,0,0,0    ; Spares if needed            122H
  295. ;
  296. I$MDTXE:  IN    MDCTL1        ; (Needed for SIO or DART register 1    129H
  297.       RET            ;                    12BH
  298.       DB    0,0,0,0,0,0,0    ;                    12CH
  299. ;
  300. I$MDDATP: MVI    A,MDCOM        ;                    133H
  301.       OUT    MDCTL1        ;                    135H
  302.       IN    MDDATP        ;                    147H
  303.       RET            ;                    139H
  304.       DB    0,0,0        ; Spares if needed            13AH
  305. ;
  306. O$MDDATP: OUT    MDDATP        ;                    13DH
  307.       RET            ; OUT modem data port            13FH
  308.       DB    0,0,0,0,0,0,0    ; Spares if needed            140H
  309. ;
  310. A$MDRCV:  ANI    MDRCV        ;                    147H
  311.       RET            ;                    149H
  312. ;
  313. C$MDRCV:  CPI    MDRCV        ;                    14AH
  314.       RET            ;                    14CH
  315. ;
  316. A$MDSND:  ANI    MDSND        ;                    14DH
  317.       RET            ;                    14FH
  318. ;
  319. C$MDSND:  CPI    MDSND        ;                    150H
  320.       RET            ;                    152H
  321. ;
  322. A$MDTXE:  ANI    MDTXE        ;                    153H
  323.       RET            ;                    155H
  324. ;
  325. C$MDTXE:  CPI    MDTXE        ;                    156H
  326.       RET            ;                    158H
  327. ;.....
  328. ;
  329. ;
  330. ; Special exit vector, used by some computers to reset interrupt vectors
  331. ;
  332. J$EXITVEC:RET            ;                    159H
  333.       DB    0,0        ;                    15AH
  334. ;.....
  335. ;
  336. ;
  337. ; Jump vectors needed by each overlay
  338. ;
  339. J$GOODBYE:JMP    GOODBYE        ; Disconnects modem by dropping DTR    15CH
  340. J$INITMOD:JMP    INITMOD        ; Initializes modem, autosets baudrate    15FH
  341. J$STUPR:  JMP    STUPR        ; SET routine to change baudrate    162H
  342. J$SYSVR:  JMP    SYSVR        ; Signon message            165H
  343. ;.....
  344. ;
  345. ;
  346. ; "AT" command strings, can be replaced in individual overlay if needed
  347. ;
  348. J$STRNGA: JMP    STRNGA        ; 1200 bps "AT" string            168H
  349. J$STRNG1: JMP    STRNG1        ; 2400 bps "AT" string            16BH
  350. ;
  351. ;
  352. ; Next fourteen lines should not be changed by user overlay as these go
  353. ; to specific locations in the main program, not in the overlay.
  354. ;
  355. ;
  356. J$CMDSPL: JMP    CMDSPL        ; Allows entry of baudrate on CMD line    16EH
  357. J$CRLF:      JMP    CRLF        ; Turns up one new line on display    171H
  358. J$DIAL:      JMP    DIAL1        ; Start of dialing routine        174H
  359. J$DSCONT: JMP    DSCONT        ; Terminates modem use            177H
  360. J$GOLST:  JMP    GOLST        ; Printer routine, needed by Apple //e    17AH
  361. J$ILPRT:  JMP    ILPRT        ; Prints an inline string, 0 to end    17DH
  362. J$INBUF:  JMP    INBUF        ; Stores a keybd string for comparison    180H
  363. J$INLNCP: JMP    INLNCP        ; Inline "compare strings" routine    183H
  364. J$INMDM:  JMP    INMDM        ; Max .1 sec wait for modem character    186H
  365. J$RCVRSP: JMP    RCVRSP        ; For 3801 I/O use (TV-803)        189H
  366. J$SNDCHR: JMP    SNDCHR        ; Sends a character to the modem    18CH
  367. J$SNDSTR: JMP    SNDSTR        ; Sends a string to the modem, $ to end 18FH
  368. J$TIMER:  JMP    TIMER        ; .1 second timer (amount in 'B' reg.)    192H
  369. J$BREAK:  JMP    SENDBRK        ; Break routine                195H
  370. J$NEW2:      DB    0,0,0        ; For future needs            198H
  371. ;.....
  372. ;
  373. ;
  374. ; For 2400 bps auto-stepdown units
  375. ;
  376. MANUAL:      DB    0        ; For manual selection flag        19BH
  377. J$300:      JMP    OK300        ; Sets baudrate to 300 baud        19CH
  378. J$1200:      JMP    OK1200        ; Sets baudrate to 1200 bps        19FH
  379. J$2400:      JMP    OK2400        ; Sets baudrate to 2400 bps        1A2H
  380. ;.....
  381. ;
  382. ;
  383. LOGPTR:      DW    LOGON        ; Pointer to display LOGON message    1A5H
  384. ;
  385. SYSVR:      CALL    J$ILPRT        ; Display the following line        1A7H
  386.       DB    'Version for Datapoint 1560 modem port 28H' ;        1AAH
  387.       DB    CR,LF,0
  388.       RET
  389. ;.....
  390. ;
  391. ;
  392. ;-----------------------------------------------------------------------
  393. ;
  394. ; NOTE:  You can change the SYSVER message to be longer or shorter.  The
  395. ;     end of your last routine should terminate by 0400H (601 bytes
  396. ;     available after start of SYSVER).
  397. ;
  398. ;-----------------------------------------------------------------------
  399. ;
  400. ; You can put in a message at this location which can be called up with
  401. ; (special character-L).  You can put in several lines.  End with a 0.
  402. ;
  403. ;
  404. LOGON:    DB    '              - Irv Hoff (W6FFC) '
  405.     DB    'Los Altos Hills, CA 94022',CR,LF,0
  406. ;
  407. ;=======================================================================
  408. ;
  409. ; This routine sends a 300 ms break tone to the modem
  410. ;
  411. SENDBRK:
  412.     MVI    A,3FH        ; DTR normal, send break tone
  413.     JMP    GOODBYE+2
  414. ;.....
  415. ;
  416. ;
  417. ; This routine sets DTR low for 300 ms to disonnect the phone
  418. ;
  419. GOODBYE:
  420.     MVI    A,3DH        ; Send break, turn off DTR
  421.     OUT    MDCTL1        ; Send to status port
  422.     MVI    B,3        ; Delay 300 ms to hang up phone
  423.     CALL    J$TIMER
  424.     MVI    A,MDCOM        ; Normal send/receive with DTR
  425.     OUT    MDCTL1        ; Send to status port
  426.     RET
  427. ;.....
  428. ;
  429. ;
  430. ; Sets 8251 to 8 bits, DTR, RCV and TX ready
  431. ;
  432. INITMOD:
  433.     MVI    A,MDMODE    ; Insure 8251 is out of mode
  434.     OUT    MDCTL1
  435.     XTHL            ; Small delay to complete command
  436.     XTHL
  437.     MVI    A,MDRSET    ; Reset the 8251A for new command
  438.     OUT    MDCTL1
  439.     XTHL            ; Small delay to complete command
  440.     XTHL
  441.     MVI    A,MDSET1    ; Set stop pulse, no parity 8 bits, x16
  442.     OUT    MDCTL1
  443.     XTHL            ; Small delay to complete command
  444.     XTHL
  445.     MVI    A,MDCOM        ; Error reset, RCV, DTR, TX ready
  446.     OUT    MDCTL1
  447.     XTHL            ; Small delay to complete command
  448.     XTHL
  449. ;
  450.     LDA    MSPEED        ; Get the selected value
  451.     CPI    1        ; 300 bps
  452.     JZ    OK300
  453.     CPI    5        ; 1200 bps
  454.     JZ    OK1200
  455.     CPI    6        ; 2400 bps
  456.     JZ    OK2400
  457.     CPI    8        ; 9600 bps
  458.     JZ    OK9600
  459.     JMP    STUPR1        ; Else ask what is wanted
  460. ;.....
  461. ;
  462. ;
  463. STUPR:    CALL    J$CMDSPL    ; Gives us CMDBUF+6
  464.     JNC    STUPR2
  465. ;
  466. STUPR1:    CALL    J$ILPRT
  467.     DB    'Input Baud Rate (300, 1200, 2400, 9600): ',0
  468.     LXI    D,BAUDBUF    ; Point to new input buffer
  469.     CALL    J$INBUF
  470.     CALL    J$CRLF
  471.     LXI    D,BAUDBUF+2
  472. ;
  473. STUPR2:    CALL    J$INLNCP    ; Compare BAUDBUF+2 with chars. below
  474.     DB    '300',0
  475.     JNC    OK300        ; Go if got match
  476.     CALL    J$INLNCP
  477.     DB    '1200',0
  478.     JNC    OK1200
  479.     CALL    J$INLNCP
  480.     DB    '2400',0
  481.     JNC    OK2400
  482.     CALL    J$INLNCP
  483.     DB    '9600',0
  484.     JNC    OK9600
  485.     CALL    J$ILPRT        ; All matches failed, tell operator
  486.     DB    '++ Incorrect entry ++',CR,LF,BELL,CR,LF,0
  487.     JMP    STUPR1        ; Try again
  488. ;
  489. OK300:    MVI    A,1        ; MSPEED 300 baud value
  490.     MVI    B,BD300        ; Get 300 baud parameters in 'HL'
  491.     JMP    LOADBD        ; Go load them
  492. ;
  493. OK1200:    MVI    A,5
  494.     MVI    B,BD1200
  495.     JMP    LOADBD
  496. ;
  497. OK2400:    XRA    A
  498.     STA    MANUAL        ; Reset to maximum auto-speed
  499.     MVI    A,6
  500.     MVI    B,BD2400
  501.     JMP    LOADBD
  502. ;
  503. OK9600:    MVI    A,8
  504.     MVI    B,BD9600
  505. ;
  506. LOADBD:    STA    MSPEED        ; Change time-to-send to match baudrate
  507.     MVI    A,47H        ; CTC command word
  508.     OUT    BDPORTR        ; Give to both Tx and Rx sections
  509.     OUT    BDPORTS
  510.     MOV    A,B        ; Get baudrate byte
  511.     OUT    BDPORTR        ; Give to both Tx and Rx sections
  512.     OUT    BDPORTS
  513.     RET
  514. ;.....
  515. ;
  516. ;
  517. ; Table of baudrate parameters
  518. ;
  519. BD300    EQU    20H        ; 9600/300  converted to hex value
  520. BD1200    EQU    08H        ; 9600/1200
  521. BD2400    EQU    04H        ; 9600/2400
  522. BD9600    EQU    01H        ; 9600/9600
  523. ;
  524. BAUDBUF:DB    10,0,0,0,0,0
  525.     DB    0,0,0,0,0,0
  526. ;
  527. ;                   end
  528. ;=======================================================================
  529. ;
  530. ;         RACAL-VADIC/HAYES DIALING ROUTINES
  531. ;
  532. ;=======================================================================
  533. ;
  534. ;
  535.     ORG    400H
  536. ;
  537. ;
  538. ; Dialing routine
  539. ;
  540. DIAL1:    XRA    A
  541.     STA    AUTODIR        ; Zero the direct to terminal mode flag
  542.     STA    AUTOFL        ; Zero the auto-linking flag
  543.     STA    CRFLAG        ; Zero the continuous dial flag
  544.     LXI    H,0
  545.     SHLD    DIALCT        ; Zero the dial count
  546.     LXI    H,CMDBUF+1    ; Point to the number of characters in..
  547.     MOV    A,M        ; The buffer, then get the number
  548.     CPI    3+1        ; Anything typed after 'CAL'?
  549.     JC    DIAL2        ; If not, go through library routine
  550. ;
  551. ;
  552. ; If there were only 3 characters, then "CAL<RET>" was typed -- the user
  553. ; obviously expecting to get a phone number (or letter) from the library
  554. ; file.  If 4 or more, a number (or letter) was typed in from the menu
  555. ; command line, so move the characters down 4 to compensate.  Needed for
  556. ; auto-redialing of menu command line entries.
  557. ;
  558.     MOV    C,A        ; Put into the 'C' reg.
  559.     MVI    B,0        ; Will move original number down 4
  560.     SUI    4        ; Eliminate the 'CAL' portion
  561.     MOV    M,A        ; Store new count at CMDBUF+1
  562.     INX    H        ; CMDBUF+2 (first character of string)
  563.     XCHG            ; 'DE' now has CMDBUF+2
  564.     LXI    H,CMDBUF+6    ; Point to number (or letter) to dial
  565.     CALL    MOVER        ; Move the group down 4 places
  566.     JMP    DIAL4        ; Check if library number, then dial
  567. ;...
  568. ;
  569. ;
  570. ; Comes here if no phone number was manually entered after 'CAL' and if
  571. ; no phone library code was entered.  Displays the phone number library
  572. ; then asks for an entry.
  573. ;
  574. DIAL2:    MVI    C,18        ; Number of lines to move
  575.     LXI    H,NUMBLIB    ; Start of phone number library
  576.     LXI    D,BUFFER    ; Buffer add. to store them temporarily
  577.     CALL    NEWLINE        ; Start with CR/LF
  578.     STAX    D        ; +LF
  579.     INX    D        ; And bump it
  580. ;
  581. DIAL3:    MVI    B,LIBLEN    ; Number of bytes to move
  582.     CALL    MOVE        ; Move to buffer
  583.     CALL    SPACES        ; 2 entries + 3 spaces = 71 characters
  584.     PUSH    H        ; Save source address
  585.     PUSH    D        ; Save destination address
  586.     LXI    D,(17*LIBLEN)    ; Get offset of 17 times entry length
  587.     DAD    D        ; Add it to source address
  588.     POP    D        ; Restore destination address
  589.     MVI    B,LIBLEN    ; Get length of library entry
  590.     CALL    MOVE        ; Move another entry
  591.     POP    H        ; Restore source address
  592.     CALL    NEWLINE
  593.     DCR    C        ; One less line to print
  594.     JNZ    DIAL3        ; If not zero, print another
  595.     MVI    A,'$'        ; BDOS print routine terminate character
  596.     STAX    D        ; Store in buffer
  597.     CALL    CLRTST
  598.     MVI    C,PRINT
  599.     LXI    D,BUFFER    ; Print the library on the CRT
  600.     CALL    BDOS
  601.     CALL    J$ILPRT        ; Ask which one is wanted
  602.     DB    CR,LF,'Enter library code or phone number,',CR,LF
  603.     DB    'Hit RET to abort this function now or',CR,LF
  604.     DB    'CTL-X quits while dialing or ringing: ',0
  605.     LXI    D,CMDBUF
  606.     CALL    J$INBUF
  607. ;
  608. ;
  609. ; You now have either a library code or a manually entered phone num-
  610. ; ber.    These either came from the menu command line or from the library
  611. ; command line.  Next we see if a code, if so, get the corresponding
  612. ; line with phone number from the library.  If a number greater than
  613. ; one digit, we ignore the library look-up.  (Ringback numbers must end
  614. ; with letter 'R'.)
  615. ;
  616. DIAL4:    LXI    H,CMDBUF+1    ; Number of characters in buffer
  617.     MOV    A,M
  618.     ORA    A        ; Null means CR was typed
  619.     JZ    DIALEXIT    ; Abort dialing, return to menu
  620.     STA    NUMBER
  621.     LDA    CMDBUF+3    ; See if at least two characters entered
  622.     CPI    '/'        ; Slash for linking, direct to terminal..
  623.     CZ    AUTO        ; Mode on answer
  624.     CPI    ','        ; Comma used for linking
  625.     CZ    AUTO1        ; If yes, set it up for auto-linking
  626. ;
  627. ;
  628. ; Wait until now to initialize the modem in case they only wanted to see
  629. ; a number in the library.
  630. ;
  631.     CALL    SMIN1        ; Initialize the modem
  632. ;
  633. ;
  634. ; Check to see how many characters were typed.    If more than one, then
  635. ; it was a hand-entered phone number, so exit.
  636. ;
  637. DIAL5:    XRA    A
  638.     STA    ANSWFL        ; Clear the answer flag, just in case
  639.     LDA    AUTOFL        ; Auto-link flag set?
  640.     ORA    A
  641.     JNZ    AUTO2        ; If yes exit
  642.     LDA    NUMBER        ; Number of characters in buffer
  643.     STA    CMDBUF+1    ; Reset the character count, if needed
  644.     CPI    1+1        ; More than one character?
  645.     JNC    DIAL14        ; If more than one, hand-entered number
  646.     LXI    H,CMDBUF+2    ; First character in phone number line
  647. ;
  648. ;
  649. ; If just one character entered, see if a (A-Z) letter
  650. ;
  651. DIAL6:    MOV    A,M
  652.     MVI    B,'A'        ; First letter of alphabet
  653.     MVI    E,0        ; Counts number of letters to match
  654.     MVI    C,26        ; Number of letters in alphabet
  655. ;
  656. DIAL7:    CMP    B        ; Letter from table?
  657.     JZ    DIAL9        ; If yes, get phone number, else
  658.     INR    B        ; Make next letter (A-Z)
  659.     INR    E        ; Count up
  660.     DCR    C        ; Count down
  661.     JNZ    DIAL7        ; Try next one in (A-Z) table
  662. ;
  663. ;
  664. ; If not (A-Z) then should be (0-9)
  665. ;
  666.     MVI    B,'0'        ; First digit to check
  667.     MVI    E,26        ; Point past alpha codes
  668.     MVI    C,10        ; Number of digits in table
  669. ;
  670. DIAL8:    CMP    B        ; Number from table?
  671.     JZ    DIAL9        ; If yes, go dial, else
  672.     INR    B        ; Make next digit to compare
  673.     INR    E        ; Make next table line number
  674.     DCR    C        ; Count down - loop counter
  675.     JNZ    DIAL8        ; Loop
  676.     JMP    DIALBAD        ; Error if not a number or a letter
  677. ;
  678. ;
  679. ; Now have a match between the requested code and one in the library.
  680. ; E-reg. holds the library line number (1-36) that matches the requested
  681. ; code (A-Z or 0-9).
  682. ;
  683. DIAL9:    LXI    H,NUMBLIB    ; Phone number library
  684.     LXI    B,LIBLEN    ; Length of library entry
  685.     MOV    A,E        ; Number of times to library length to HL
  686.     ORA    A        ; Set flags
  687.     JZ    DIAL11
  688. ;
  689. DIAL10:    MOV    A,M        ; Get first char of selected lib entry
  690.     ORA    A        ; Set flags
  691.     JZ    DIALBAD        ; Send bad library msg and abort
  692.     DAD    B        ; Increment 'HL' by library length
  693.     DCR    E        ; Countdown
  694.     JNZ    DIAL10        ; Not there yet, loop
  695. ;
  696. ;
  697. ; Now have the line in the phone number library matching the requested
  698. ; letter so store that line starting at 'CMDBUF+1'
  699. ;
  700. DIAL11:    MVI    B,LIBLEN    ; Number of characters to get from table
  701.     LXI    D,CMDBUF+1    ; Point to buffer
  702.     XCHG            ; 'HL' points to CMDBUF+1
  703.     MOV    M,B        ; Length of each table entry
  704.     XCHG            ; Restore the registers
  705.     INX    D        ; Point to first char position in buffer
  706.     CALL    MOVE        ; Move the table entry to the buffer
  707. ;
  708. ;
  709. ; Now have the full line including phone number in 'CMDBUF' area.  Scan
  710. ; past the descriptive portion of library entry - terminate scan at the
  711. ; first '.'  This allows commas and numbers to be part of the text, such
  712. ; as:
  713. ;         'A=DataTech, Node 7..1-408-238-9621'
  714. ;
  715. DIAL12:    LXI    H,CMDBUF+1
  716.     MOV    E,M        ; Number of chars in buffer
  717.     INX    H        ; Point to 1st character in buffer
  718. ;
  719. DIAL13:    MOV    A,M        ; Get next character
  720.     CALL    TYPE        ; Show it
  721.     INX    H        ; Bump pointer
  722.     DCR    E        ; Decrement count
  723.     JZ    DIALEXIT    ; Exit if no '.' (bad library entry)
  724.     CPI    '.'        ; Dot?
  725.     JZ    DIAL15        ; Yes, go dial the phone
  726.     JMP    DIAL13        ; No, loop for next character
  727. ;.....
  728. ;
  729. ;
  730. ; There is a user entered phone number in 'CMDBUF' area
  731. ;
  732. DIAL14:    LXI    H,CMDBUF+1    ; Get the number of characters in buffer
  733.     MOV    A,M
  734.     MOV    E,M
  735.     INX    H        ; Point to 1st character to dial
  736. ;.....
  737. ;
  738. ;
  739. ; Loop to dial the phone number pointed to by 'HL', character count in
  740. ; the 'E' register.  First, set the modem to auto-dial mode.
  741. ;
  742. DIAL15:    PUSH    H
  743.     CALL    SMIN2        ; Put modem in dialing mode
  744.     POP    H
  745.  
  746. DIAL16:    MOV    A,M        ; Get first number from the buffer
  747.     ORA    A        ; Set flags
  748.     JZ    DIALBAD        ; Bad number if a null
  749. ;
  750. ;
  751. ; Dial a digit, check keyboard for abort
  752. ;
  753.     CALL    DIALA        ; Dial a digit, show on CRT
  754.     CALL    STAT        ; Key depressed?
  755.     JZ    DIAL18        ; If not, exit
  756.     CALL    KEYIN        ; See what it was
  757.     CPI    CANCEL        ; CTL-X to abort?
  758.     JZ    DIAL17        ; If yes, exit
  759.     MOV    B,A        ; Save the character momentarily
  760.     LDA    EXTCHR        ; Want to abort?
  761.     CMP    B
  762.     JNZ    DIAL18
  763. ;
  764. DIAL17:    MVI    B,CR        ; Terminate the dialing if needed
  765.     CALL    J$SNDCHR
  766.     JMP    DIALEXIT    ; Back to command mode
  767. ;
  768. DIAL18:    INX    H        ; Bump pointer
  769.     DCR    E        ; One less character to go
  770.     JNZ    DIAL16        ; If not done, send the next digit
  771.     MVI    B,CR        ; Modem needs a CR to enter the number
  772.     CALL    J$SNDCHR
  773.     CALL    CATCH        ; Catch the numbers the modem echoes
  774.     CALL    J$ILPRT
  775.     DB    ' - try #',0
  776.     LHLD    DIALCT        ; Increment the dial count
  777.     INX    H
  778.     SHLD    DIALCT
  779.     CALL    DECOUT        ; Show number of attempts so far
  780.     MVI    A,' '        ; Extra space to position cursor
  781.     CALL    TYPE
  782.     CALL    CATCH        ; Catch any output from the modem
  783.     JMP    SMRESULT    ; Number sent to modem, now get results
  784. ;
  785. ;
  786. ; Connection not made, see if a redial is desired
  787. ;
  788. DIALAGN:
  789.     LXI    SP,STACK    ; Reset the stack to normal just in case
  790.     XRA    A
  791.     STA    RINGFL        ; Reset the ring flag
  792.     LDA    CRFLAG        ; Continuous redial flag
  793.     ORA    A
  794.     JNZ    DIALAGN1    ; If already set, go dial again
  795.     CALL    J$ILPRT        ; See if we should keep trying
  796.     DB    CR,LF,CR,LF
  797.     DB    '     Redial? (C/Y/N): ',BELL,0
  798.     CALL    KBDCHR
  799.     PUSH    PSW        ; Save the answer
  800.     CALL    CRLF        ; Turn up a line
  801.     POP    PSW        ; Get the answer back
  802.     CPI    'Y'        ; Redial?
  803.     JZ    DIALAGN1    ; Yes, redial
  804.     CPI    'C'        ; Continuous redial?
  805.     JNZ    DIALEXIT1    ; None of these, quit
  806.     MVI    A,1
  807.     STA    CRFLAG        ; Continuous redial flag
  808. ;
  809. DIALAGN1:
  810.     CALL    CRLF        ; Start a new line
  811.     JMP    DIAL5        ; Redial entry point
  812. ;.....
  813. ;
  814. ;
  815. ; Connection has been made
  816. ;
  817. CONMADE:
  818.     CALL    J$ILPRT
  819.     DB    BELL,CR,LF,CR,LF,'     CONNECTED',0
  820.     LDA    AUTODIR        ; Going direct to terminal mode?
  821.     ORA    A
  822.     JNZ    RETRN
  823.     LDA    CRFLAG        ; Continuous redial or first time try?
  824.     ORA    A
  825.     JZ    RETRN        ; Go to terminal mode if first time
  826.     CALL    J$ILPRT
  827.     DB    ' - any key for terminal mode ',0
  828. ;
  829. CONMADE1:
  830.     MVI    E,10
  831. ;
  832. CONMADE2:
  833.     CALL    STAT        ; Keypress?
  834.     JZ    CONMADE3    ; Exit if no keys pressed
  835.     CALL    KEYIN
  836.     XRA    A
  837.     JMP    RETRN        ; Key pressed, go to terminal mode
  838. ;
  839. CONMADE3:
  840.     MVI    B,1        ; Wait 0.1 second
  841.     CALL    J$TIMER
  842.     DCR    E        ; One less loop to make
  843.     JNZ    CONMADE2    ; See if a keyboard character yet
  844.     MVI    A,BELL        ; Sound a bell
  845.     CALL    TYPE
  846.     JMP    CONMADE1    ; Reset the counter
  847. ;.....
  848. ;
  849. ;
  850. ; Automatic dialing routine, prints the number being dialed.
  851. ;
  852. DIALA:    CALL    TYPE        ; Print whatever character, dashes, etc.
  853.     MOV    B,A        ; Store the character for now
  854.     CALL    DIALAD        ; Check for alternate dialing like 'MCI'
  855.     MOV    A,B        ; Get the original character back
  856. ;
  857. DIALA1:    CPI    '*'        ; * is a valid dial digit
  858.     JZ    DIALA2
  859.     CPI    '#'        ; # is a valid dial digit
  860.     JZ    DIALA2
  861.     CPI    ','        ; Pause for all modems
  862.     JZ    DIALA2
  863.     CPI    'K'        ; K = Racal-Vadic dial tone wait
  864.     JZ    DIALA2
  865.     CPI    'T'        ; T = Tone dial request
  866.     JZ    DIALA2
  867.     CPI    'W'        ; W = Hayes or Robotics dial tone wait
  868.     JZ    DIALA2
  869.     CPI    '0'        ; Digits are (0-9)
  870.     RC            ; Exit if less than ASCII '0'
  871.     CPI    '9'+1
  872.     RNC            ; Exit if more than ASCII '9'
  873. ;
  874. ;
  875. ; Sends the digit to the modem.  Waits 100 ms. after each digit to in-
  876. ; sure it gets to the modem ok.
  877. ;
  878. DIALA2:    CALL    J$SNDCHR    ; Go send it
  879.     JMP    J$INMDM        ; Get the echo character and ignore
  880. ;.....
  881. ;
  882. ;
  883. ; Print bad library number message and abort if a null is encountered.
  884. ;
  885. DIALBAD:
  886.     CALL    J$ILPRT
  887.     DB    CR,LF,CR,LF,'++ Bad library number called ++',CR,LF,0
  888. ;
  889. DIALEXIT:
  890.     CALL    CRLF
  891. ;
  892. DIALEXIT1:
  893.     LXI    SP,STACK    ; Make sure the stack is normal again
  894.     CALL    SMIN4        ; Reset the modem
  895.     XRA    A
  896.     STA    CRFLAG        ; Reset the continuous redial flag
  897.     JMP    MENU
  898. ;.....
  899. ;
  900. ;
  901. ; Do any alternate dialing such as 'MCI' or 'SPRINT'
  902. ;
  903. DIALAD:    LDA    TCHPUL        ; Using touch tone dialing?
  904.     CPI    'T'
  905.     RNZ            ; If not, ignore
  906.     MOV    A,B        ; Get the character back
  907.     CPI    '<'        ; Alternate dialing system #1 (MCI?)
  908.     JNZ    DIALAD1        ; If not, exit
  909.     PUSH    H        ; Save the current values
  910.     LXI    H,ALTDL1    ; Alternate dialing area
  911.     JMP    DIALAD2
  912. ;
  913. DIALAD1:CPI    '>'        ; Alternate dialing system #2 (Sprint?)
  914.     RNZ            ; If neither, exit
  915.     PUSH    H        ; Save the current values
  916.     LXI    H,ALTDL2
  917. ;
  918. DIALAD2:MOV    A,M
  919.     CPI    '$'        ; Ready to terminate?
  920.     JZ    DIALAD3        ; If yes, exit
  921.     CALL    TYPE        ; Display the character
  922.     MOV    B,A        ; Need the char. in 'B' to send to modem
  923.     CALL    DIALA1        ; Send proper characters to the modem
  924.     INX    H        ; Next location
  925.     CALL    QUIT        ; Want to quit dialing?
  926.     JMP    DIALAD2        ; If not, handle the next character
  927. ;
  928. DIALAD3:MVI    A,' '
  929.     MOV    B,A        ; Clears 'B' from last digit sent
  930.     CALL    TYPE        ; Separate from the main number
  931.     POP    H        ; Restore the location
  932.     RET
  933. ;.....
  934. ;
  935. ;
  936. ; Disconnect the autodial modem from the phone line.  Sends 'I, CR' to
  937. ; the Racal-Vadic to return to IDLE mode
  938. ;
  939. ;
  940. DSCONT:    LDA    RACAL
  941.     ORA    A
  942.     JNZ    SMIN3        ; Reset modem to normal
  943. ;
  944.     MVI    B,15        ; 1 second pause
  945.     CALL    J$TIMER
  946.     LXI    H,STRNG5    ; Get into command mode
  947.     CALL    J$SNDSTR
  948.     MVI    B,15        ; Another 1 second pause
  949.     CALL    J$TIMER
  950.     JMP    SMIN3        ; Reset modem to normal
  951. ;.....
  952. ;
  953. ;
  954. ; Want to quit dialing?
  955. ;
  956. QUIT:    CALL    STAT        ; Keypress?
  957.     RZ            ; If not, do the next character
  958.     CALL    KEYIN        ; Yes, go get it
  959.     CPI    CANCEL        ; CTL-X?
  960.     JZ    QUIT1        ; Yes, quit dialing
  961.     MOV    B,A
  962.     LDA    EXTCHR
  963.     CMP    B
  964.     MOV    A,B        ; Get the character back again
  965.     JZ    QUIT1
  966.     CPI    NEXTRY        ; Special "dial next number" character
  967.     RNZ            ; None of these, proceed normally
  968.     MVI    B,CR
  969.     CALL    J$SNDCHR    ; Send to modem to stop dialing
  970.     MVI    B,10        ; Wait one second for new dial tone
  971.     CALL    J$TIMER        ; Let it abort any busy, dialing, etc.
  972.     POP    H
  973.     JMP    DIALAGN
  974. ;
  975. QUIT1:    POP    H        ; Reset stack for "CALL QUIT"
  976.     JMP    DIALEXIT    ; Terminate
  977. ;.....
  978. ;
  979. ;
  980. ; Insure the modem has completed its reply
  981. ;
  982. CATCH:    CALL    J$INMDM        ; Catch any output from the modem
  983.     JNC    CATCH        ; If you got one, see if any more
  984.     RET            ; Returns if no character in 100 ms.
  985. ;.....
  986. ;
  987. ;
  988. ; Clear the result buffer for slower 300 speed combined results
  989. ;
  990. EMPTY:    MVI    B,80
  991.     LXI    H,TBUF        ; TBUF area is not currently used
  992. ;
  993. EMPTY1:    MVI    M,' '
  994.     INX    H
  995.     DCR    B
  996.     JNZ    EMPTY1
  997.     RET
  998. ;.....
  999. ;
  1000. ;
  1001. ; Initializaton
  1002. ;
  1003. SMIN1:    LDA    MANUAL        ; Manually selected 'SET' speed?
  1004.     ORA    A
  1005.     JNZ    SMIN11        ; Exit if set for manual selection
  1006. ;
  1007.     LDA    HS2400        ; High speed 2400 bps?
  1008.     ORA    A
  1009.     CNZ    J$2400        ; If yes, set to 2400 bps
  1010. ;
  1011.     LDA    HS1200        ; High speed 1200 bps?
  1012.     ORA    A
  1013.     CNZ    J$1200        ; If yes, set to 1200 speed
  1014. ;
  1015. SMIN11:    CALL    RATE        ; Show current baudrate
  1016.     CALL    CRLF        ; Turn up an extra line
  1017. ;
  1018. SMIN12:    LXI    H,RTRNG1    ; Set to auto-answer
  1019.     LDA    RACAL        ; Using the Racal-Vadic protocol?
  1020.     ORA    A
  1021.     JNZ    J$SNDSTR    ; If yes, use RTRNG1
  1022. ;
  1023.     LHLD    J$STRNG1+1
  1024.     LDA    HS2400        ; High speed 2400 bps?
  1025.     ORA    A
  1026.     JNZ    J$SNDSTR    ; If yes, modify basic "AT" string
  1027. ;
  1028.     LHLD    J$STRNGA+1    ; Else must be "AT" protocol
  1029.     CALL    J$SNDSTR    ; Send basic "AT" string
  1030. ;
  1031.     LDA    PROMODM        ; Using a 1200 bps Prometheus ProModem?
  1032.     ORA    A
  1033.     RZ            ; If not, finished
  1034.     LXI    H,STRNGP    ; If yes, send special ProModem string
  1035.     JMP    J$SNDSTR
  1036. ;.....
  1037. ;
  1038. ;
  1039. SMIN2:    LXI    H,RTRNG2    ; Set to disable auto-answer
  1040.     LDA    RACAL
  1041.     ORA    A
  1042.     JNZ    J$SNDSTR
  1043. ;
  1044.     LDA    TCHPUL        ; Touch or pulse dialing for autodial?
  1045.     STA    STRNG2+3    ; Store
  1046.     LXI    H,STRNG2
  1047.     JMP    J$SNDSTR
  1048. ;.....
  1049. ;
  1050. ;
  1051. SMIN3:    LXI    H,RTRNG3
  1052.     LDA    RACAL
  1053.     ORA    A
  1054.     JNZ    J$SNDSTR
  1055. ;
  1056.     LXI    H,STRNG3
  1057.     CALL    J$SNDSTR
  1058. ;
  1059. SMIN4:    LXI    H,RTRNG3
  1060.     LDA    RACAL
  1061.     ORA    A
  1062.     JNZ    J$SNDSTR
  1063. ;
  1064.     MVI    B,10        ; Wait 1 second to go on hook
  1065.     CALL    J$TIMER
  1066.     LXI    H,STRNG4    ; Set to auto-answer OFF
  1067.     JMP    J$SNDSTR
  1068. ;.....
  1069. ;
  1070. ;
  1071. ; Racal-Vadic mode
  1072. ;
  1073. RTRNG1:    DB    'E'-40H,CR,'##','I',CR,'##','E'-40H,CR,'##'
  1074.     DB    'O23121111212',CR,'####','$'
  1075. RTRNG2:    DB    'D','#','$'
  1076. RTRNG3:    DB    '#','I',CR,'#','E'-40H,CR,'#'
  1077.     DB    'O23121111212',CR,'####','I',CR,'$'
  1078. ;...
  1079. ;
  1080. ;
  1081. ; 1200 "AT" mode, start out with this string for both 1200 and 2400 bps
  1082. ;
  1083. STRNGA:    DB    'ATE1Q0V0X1H0'
  1084.     DB    CR,'####','$'    ; Delay to let modem accept commands
  1085. ;
  1086. ;
  1087. ; Special mode for Prometheus
  1088. ;
  1089. STRNGP:    DB    'ATV2',CR,'###','$'
  1090. ;
  1091. ;
  1092. ; 2400 "AT" mode
  1093. ;
  1094. STRNG1:    DB    'ATM3'        ; Loud speaker on after dialing
  1095.     DB    'L1',CR,'####'    ; Hayes 2400 speaker volume
  1096.     DB    'ATE1Q0V0X4H0'    ; Extended result codes (0-10)
  1097.     DB    CR,'####','$'    ; Delay to let modem accept commands
  1098. STRNG2:    DB    'ATDT','#','$'    ; Dial via Tone mode
  1099. STRNG3:    DB    'ATH0',CR,'#','$'
  1100. STRNG4:    DB    'ATS0=0',CR,'#','$'
  1101. STRNG5:    DB    '+++','$'
  1102. ;.....
  1103. ;
  1104. ;
  1105. ; Send the string pointed to by 'HL' to both the CRT and the modem.
  1106. ;
  1107. SNDSTR:    CALL    QUIT        ; Want to quit now?
  1108.     MOV    A,M
  1109.     CPI    '$'
  1110.     RZ
  1111. ;
  1112.     CPI    '#'        ; Special character to catch chars.?
  1113.     JNZ    SEND1        ; If not, exit
  1114.     CALL    CATCH        ; Else catch any/all characters
  1115.     JMP    SEND2        ; Get next char. in string and continue
  1116. ;
  1117. SEND1:    MOV    B,A        ; SNDCHR needs character in 'B' reg.
  1118.     CALL    J$SNDCHR
  1119. ;
  1120. SEND2:    INX    H        ; Next character in the string
  1121.     JMP    SNDSTR
  1122. ;.....
  1123. ;
  1124. ;
  1125. ; Checks for answer from the Racal-Vadic and stores it in the buffer.
  1126. ; Has a 30-second timer included, in case the Racal times out without
  1127. ; sending a "failed call", our timer will.
  1128. ;
  1129. SMRESULT:
  1130.     CALL    EMPTY        ; Clear the buffer
  1131.     LXI    H,TBUF        ; Put the modem result answer here
  1132.     PUSH    H        ; Save it
  1133. ;
  1134. SMRESUL1:
  1135.     LXI    D,330        ; Time out 33 seconds after dialing
  1136. ;
  1137. SMRESUL2:
  1138.     CALL    RCVRDY        ; See if a character is ready
  1139.     JZ    SMRESUL4    ; If yes, go get it
  1140.     CALL    QUIT        ; Want to quit dialing?
  1141.     CALL    J$INMDM        ; Wait up to 0.1 second for an answer
  1142.     JNC    SMRESUL5    ; If a character, fine, skip delay count
  1143.     DCX    D        ; One less loop
  1144.     MOV    A,D        ; See if both are zero, yet
  1145.     ORA    E
  1146.     JNZ    SMRESUL2    ; Make next loop
  1147.     POP    H        ; Restore the stack to normal
  1148.     CALL    SMIN12        ; Reinitialize the modem
  1149.     JMP    FAILED        ; Timed out
  1150. ;
  1151. SMRESUL4:
  1152.     CALL    J$INMDM        ; Wait for the character and get it
  1153.     JC    SMRESUL6    ; If done now, exit
  1154. ;
  1155. SMRESUL5:
  1156.     ANI    7FH        ; Remove any parity
  1157.     CPI    '*'+1        ; Catches spaces, nulls, CR, LF, Bell..
  1158.     JC    SMRESUL4    ; Asterisk and lesser characters
  1159.     POP    H        ; Get the address in the buffer
  1160.     MOV    M,A        ; Store the character there
  1161.     INX    H        ; Get the next address
  1162.     PUSH    H        ; Save it for now
  1163.     JMP    SMRESUL4    ; Get the next character, if any
  1164. ;
  1165. ;
  1166. ; Find what comment the Racal sent
  1167. ;
  1168. SMRESUL6:
  1169.     POP    H        ; Reset the stack
  1170.     LXI    D,TBUF
  1171. ;
  1172.     LDA    RACAL        ; Using the Racal-Vadic protocol?
  1173.     ORA    A
  1174.     JNZ    SMRESUL7    ; If yes, jump to other section
  1175. ;
  1176. ;
  1177. ; Handle the Hayes 0-5 result codes
  1178. ;
  1179.     CALL    INLNCP
  1180.     DB    '1',0        ; Connect 300 baud
  1181.     JNC    ON$3X        ; See if '1' for 300 or '10' for 2400
  1182.     CALL    INLNCP
  1183.     DB    '3',0        ; No Carrier
  1184.     JNC    NO$CAR
  1185.     CALL    INLNCP
  1186.     DB    '5',0        ; Connect 1200 bps
  1187.     JNC    ON$1200
  1188. ;
  1189. ;
  1190. ; See if using a Prometheus 1200 ProModem
  1191. ;
  1192.     LDA    PROMODM        ; Using a Prometheus ProModem?
  1193.     ORA    A
  1194.     JNZ    PROMDM        ; If yes, exit
  1195. ;
  1196. ;
  1197. ; See if running 1200 bps
  1198. ;
  1199.     LDA    HS1200        ; High speed 1200 bps?
  1200.     ORA    A
  1201.     JNZ    FAILED        ; If yes, no other result codes coming
  1202. ;
  1203. ;
  1204. ; Keep going if running 2400 bps with AT protocol
  1205. ;
  1206.     CALL    INLNCP
  1207.     DB    '6',0        ; No dial tone
  1208.     JNC    NO$DT
  1209.     CALL    INLNCP
  1210.     DB    '7',0        ; Busy
  1211.     JNC    BUSY
  1212.     CALL    INLNCP
  1213.     DB    '8',0        ; No answer
  1214.     JNC    FAILED
  1215.     CALL    INLNCP
  1216.     DB    '10',0        ; Connect 2400 bps
  1217.     JNC    ON$2400
  1218.     JMP    FAILED        ; If anything else, an error
  1219. ;...
  1220. ;
  1221. ;
  1222. PROMDM:    CALL    INLNCP
  1223.     DB    '43',0
  1224.     JNC    NO$DT        ; No dial tone
  1225.     CALL    INLNCP
  1226.     DB    '60',0
  1227.     JNC    DIALING        ; Dialing...
  1228.     CALL    INLNCP
  1229.     DB    '61',0
  1230.     JNC    RINGING        ; Ringing...
  1231.     JMP    FAILED        ; Anything else, call failed
  1232. ;...
  1233. ;
  1234. ;
  1235. ; Handle the Racal results
  1236. ;
  1237. SMRESUL7:
  1238.     CALL    INLNCP
  1239.     DB    'B',0        ; Busy
  1240.     JNC    BUSY
  1241.     CALL    INLNCP
  1242.     DB    'H',0        ; HELLO:I'M READY
  1243.     JNC    SMIN2
  1244.     CALL    INLNCP
  1245.     DB    'D',0        ; Dialing...
  1246.     JNC    DIALING
  1247.     CALL    INLNCP
  1248.     DB    'R',0        ; Ringing...
  1249.     JNC    RINGING
  1250.     CALL    INLNCP
  1251.     DB    'A',0        ; Answer tone
  1252.     JNC    ANSWER
  1253.     CALL    INLNCP
  1254.     DB    '1',0        ; On line
  1255.     JNC    ON$300
  1256.     CALL    INLNCP
  1257.     DB    '2',0        ; On line
  1258.     JNC    ON$1200
  1259.     CALL    INLNCP
  1260.     DB    '3',0        ; On line
  1261.     JNC    ON$2400
  1262.     CALL    INLNCP
  1263.     DB    'L',0        ; On line
  1264.     JNC    ON$LINE
  1265.     CALL    INLNCP
  1266.     DB    'F',0        ; Failed call - no answer, abort
  1267.     JNC    FAILED
  1268.     CALL    INLNCP
  1269.     DB    'T',0        ; Timed out
  1270.     JNC    FAILED
  1271.     CALL    INLNCP
  1272.     DB    'E',0        ; No dial tone
  1273.     JNC    NO$DT
  1274.     JMP    FAILED        ; Anything else, call failed
  1275. ;.....
  1276. ;
  1277. ;
  1278. ANSWER:    CALL    J$ILPRT
  1279.     DB    'answer, ',0
  1280.     INR    A
  1281.     STA    ANSWFL        ; Show it did answer at least
  1282. ;
  1283. ;
  1284. ; At 300 bps, the modems come back almost simultaneously with ANSWER and
  1285. ; ONLINE, so we check the buffer to see if both answers are stored now.
  1286. ;
  1287.     LDA    TBUF+1        ; For 300 baud and terse mode
  1288.     CPI    'L'
  1289.     JZ    ON$LINE
  1290.     CPI    '1'
  1291.     JZ    ON$300
  1292.     CPI    '2'
  1293.     JZ    ON$1200
  1294.     CPI    '3'
  1295.     JZ    ON$2400
  1296.     LDA    TBUF+12        ; For 300 bps and verbose mode
  1297.     CPI    'L'
  1298.     JZ    ON$LINE
  1299.     JMP    SMRESULT
  1300. ;.....
  1301. ;
  1302. ;
  1303. BUSY:    CALL    J$ILPRT
  1304.     DB    'busy! ',0
  1305.     LDA    DIALWT
  1306.     MOV    B,A
  1307.     CALL    J$TIMER        ; Slight pause to let phone hang up
  1308.     JMP    DIALAGN
  1309. ;.....
  1310. ;
  1311. ;
  1312. DIALING:CALL    J$ILPRT
  1313.     DB    'dial, ',0
  1314.     JMP    SMRESULT
  1315. ;.....
  1316. ;
  1317. ;
  1318. ; Failed call is usually caused by continuous ringing with no answer.
  1319. ; The modem times out (can be set to either 30 seconds or 60 seconds.)
  1320. ;
  1321. FAILED:    CALL    J$ILPRT
  1322.     DB    'abort ',0
  1323.     LDA    DIALWT
  1324.     MOV    B,A
  1325.     CALL    J$TIMER        ; Slight pause to let phone hang up
  1326.     JMP    DIALAGN
  1327. ;.....
  1328. ;
  1329. ;
  1330. NO$CAR:    LDA    PROMODM        ; Using a 1200 bps Prometheus ProModem?
  1331.     ORA    A
  1332.     JZ    FAILED        ; If not, handle as a failed call
  1333.     LDA    RINGFL        ; Have we recorded any rings yet?
  1334.     ORA    A
  1335.     JZ    BUSY        ; If not, handle as a Busy signal
  1336.     JMP    FAILED        ; If yes, handle as a failed call
  1337. ;
  1338. ON$LINE:CALL    J$ILPRT
  1339.     DB    'on line',0
  1340.     JMP    CONMADE
  1341. ;.....
  1342. ;
  1343. ;
  1344. ON$300:    CALL    J$ILPRT
  1345.     DB    'on 300',0
  1346.     CALL    J$300
  1347.     JMP    CONMADE
  1348. ;.....
  1349. ;
  1350. ;
  1351. ON$1200:CALL    J$ILPRT
  1352.     DB    'on 1200',0
  1353.     CALL    J$1200
  1354.     JMP    CONMADE
  1355. ;.....
  1356. ;
  1357. ;
  1358. ON$2400:CALL    J$ILPRT
  1359.     DB    'on 2400',0
  1360.     CALL    J$2400
  1361.     JMP    CONMADE
  1362. ;.....
  1363. ;
  1364. ;
  1365. ON$3X:    LDA    TBUF+1        ; If 2nd char is 0 for 10, then 2400
  1366.     CPI    '0'
  1367.     JZ    ON$2400
  1368.     JMP    ON$300
  1369. ;.....
  1370. ;
  1371. ;
  1372. ; No dial tone can occur when using the alternate dialing option and a
  1373. ; dial tone is not detected after the pause 'K' or within 5 sec after
  1374. ; the start of the modem dialing routine
  1375. ;
  1376. NO$DT:    CALL    J$ILPRT
  1377.     DB    '- no dial tone',0
  1378.     JMP    DIALAGN
  1379. ;.....
  1380. ;
  1381. ;
  1382. RINGING:CALL    J$ILPRT
  1383.     DB    'ring, ',0
  1384.     MVI    A,1        ; Insure 'A' is not zero
  1385.     STA    RINGFL
  1386.     JMP    SMRESULT
  1387. ;.....
  1388. ;
  1389. ;
  1390. ; This is the auto-linking area.  Up to 32 numbers may be linked, each
  1391. ; should have a comma for a separator, such as:
  1392. ;
  1393. ;    B>>COMMAND: CAL A,F,3,A,G,A,H
  1394. ;
  1395. AUTO:    STA    AUTODIR        ; Direct to terminal mode on answer
  1396. ;
  1397. AUTO1:    MVI    A,0FFH        ; Set the flags to -1
  1398.     STA    AUTOFL        ; Set the auto-linking flag
  1399.     STA    CRFLAG        ; Set the continuous redial flag
  1400.     MVI    B,64        ; Maximum number of characters to move
  1401.     LXI    H,CMDBUF+1    ; Start with number in the string
  1402.     LXI    D,CMDBUF+65    ; Move to aft part of buffer
  1403.     JMP    MOVE        ; When finished return to caller
  1404. ;.....
  1405. ;
  1406. ;
  1407. ; Linking routine
  1408. ;
  1409. AUTO2:    LDA    AUTOFL        ; Increment the flag for each new try
  1410.     INR    A
  1411.     INR    A
  1412.     STA    AUTOFL
  1413.     MOV    C,A        ; Hold momentarily
  1414.     MVI    B,0
  1415.     LDA    CMDBUF+65    ; See how many characters typed
  1416.     CMP    C
  1417.     JNC    AUTO3
  1418.     MVI    A,1        ; Reset the flag to start over
  1419.     MOV    C,A
  1420.     STA    AUTOFL
  1421. ;
  1422. AUTO3:    LXI    H,CMDBUF+65
  1423.     DAD    B
  1424.     JMP    DIAL6        ; Go to work
  1425. ;.....
  1426. ;
  1427. ;
  1428. ANSWFL:    DB    0        ; Answer flag abort, no on line report
  1429. AUTODIR:DB    0        ; Direct to terminal mode on answer
  1430. AUTOFL:    DB    0        ; Auto-linking flag
  1431. NUMBER:    DB    0        ; Number of characters in CMDBUF
  1432. RINGFL:    DB    0        ; Only prints one 'ringing' msg
  1433. ;.....
  1434. ;
  1435. ;
  1436.     DS    50        ; Insures some spares will be available
  1437. ;
  1438. ;           (end of Racal-Vadic/Hayes dialing routine)
  1439. ;=======================================================================
  1440. ;
  1441.     ORG    (($+255+50)/256*256)-50    ; Even page for 'NUMLIB'
  1442. ;
  1443. ; Long distance alternate dialing such as MCI, SPRINT, etc.  Must end
  1444. ; with a '$', use as many commas (2 seconds delay, each) as needed to
  1445. ; let the alternate dialing code return with a new dial tone.  Fill in
  1446. ; any character (periods are fine) after the $ to keep number of columns
  1447. ; to 24, i.e.,    '1234567,,,,12345,,$.....'   --   the first group is the
  1448. ; MCI or SPRINT access number, the second group is the user number.  A
  1449. ; small delay is usually required after the billing number also.
  1450. ;
  1451. ALTDL1:    DB    'xxxxxxx,,,,,,xxxxxxxx,,$' ; Accessed by a < character
  1452. ALTDL2:    DB    'xxxxxxx,,,,,,xxxxxxxx,,$' ; Accessed by a > character
  1453. ;
  1454. ;=======================================================================
  1455. ;
  1456. DIALWT:    DB    5        ; tenth-seconds to wait for dial tone
  1457. SAVSIZ:    DB    XFRSIZ*8    ; Can easily change buffer size for file
  1458.                 ;   transfers with DDT for "NUMBLIB-1"
  1459.                 ;   address.  Normally 4k (32 records
  1460.                 ;   or 4k).
  1461. ;
  1462. ;=======================================================================
  1463. ;
  1464. ; Phone number library table for auto-dialing.    Each number must be as
  1465. ; long as"LIBLEN" (EQU at start of program).  Some areas require extra
  1466. ; characters such as:    1-313-846-7127.  Room is left for those.  Use
  1467. ; a (<) for alternate dialing system #1, and a (>) for alternate dialing
  1468. ; System #2.  Either would preceed the actual number, for example:
  1469. ;
  1470. ;    DB    'A=Alan Alda..........<123-456-7890'    ;'A'
  1471. ;
  1472. ; -    -     -     -      -    -     -     -      -    -     -     -
  1473. ;
  1474. ; NOTE: At least one dot (.) MUST precede the actual phone number
  1475. ;
  1476. ;        '----5---10---15---20---25---30--34'
  1477. NUMBLIB:DB    'A=Norman Beeler.....1-408-245-1420' ; 'A'
  1478.     DB    'B=Rich Berg.........1-618-359-4446' ; 'B'
  1479.     DB    'C=Robert Blacher....1-202-254-2008' ; 'C'
  1480.     DB    'D=Brian Callahan....1-718-625-5931' ; 'D'
  1481.     DB    'E=Bob Clyne.........1-313-759-6569' ; 'E'
  1482.     DB    'F=Bill Earnest......1-215-398-3937' ; 'F'
  1483.     DB    'G=Norm Gregory......1-206-325-1325' ; 'G'
  1484.     DB    'H=Irv Hoff................948-2166' ; 'H'
  1485.     DB    'I=Jeff King.........1-408-247-2853' ; 'I'
  1486.     DB    'J=Kim Levitt........1-213-653-6398' ; 'J'
  1487.     DB    'K=Tim Linehan.......1-206-357-7400' ; 'K'
  1488.     DB    'L=Jim Lopushinski...1-403-484-5981' ; 'L'
  1489.     DB    'M=Trevor Marshall...1-805-492-5472' ; 'M'
  1490.     DB    'N=Wayne Masters.....1-408-378-7474' ; 'N'
  1491.     DB    'O=Paul Matlin.......1-301-661-2175' ; 'O'
  1492.     DB    'P=Dave McCord ZCPR3.1-415-489-9005' ; 'P'
  1493.     DB    'Q=Byron McKay.......1-415-965-4097' ; 'Q'
  1494.     DB    'R=Dick Mead.........1-818-799-1632' ; 'R'
  1495.     DB    'S=Chuck Metz........1-408-354-5934' ; 'S'
  1496.     DB    'T=Al Mehr...........1-408-238-9621' ; 'T'
  1497.     DB    'U=Jud Newell........1-416-232-0442' ; 'U'
  1498.     DB    'V=George Peace......1-717-657-8699' ; 'V'
  1499.     DB    'W=John Riehl........1-713-488-5619' ; 'W'
  1500.     DB    'X=Gary Shaffstall...1-303-985-1108' ; 'X'
  1501.     DB    'Y=Murray Simsolo....1-516-825-8465' ; 'Y'
  1502.     DB    'Z=Larry Snyder......1-305-677-8086' ; 'Z'
  1503.     DB    '0=John Sojak........1-312-941-0049' ; '0'
  1504.     DB    '1=Alex Soya.........1-305-727-0331' ; '1'
  1505.     DB    '2=Ken Stritzel......1-312-983-5147' ; '2'
  1506.     DB    '3=Henry Trujilio....1-207-443-4657' ; '3'
  1507.     DB    '4=Bill Wood.........1-619-256-3914' ; '4'
  1508.     DB    '5=Tom Vande-Stouwe..1-516-567-8267' ; '5'
  1509.     DB    '6=Spare.............1-xxx-xxx-xxxx' ; '6'
  1510.     DB    '7=Spare.............1-xxx-xxx-xxxx' ; '7'
  1511.     DB    '8=Spare.............1-xxx-xxx-xxxx' ; '8'
  1512.     DB    '9=Spare.............1-xxx-xxx-xxxx' ; '9'
  1513.     DB    0        ; End
  1514. ;        '----5---10---15---20---25---30--34'
  1515. ;
  1516. ;-----------------------------------------------------------------------
  1517. ;
  1518. ; This is the storage area for the ten function keys.  The I2FUNC.COM
  1519. ; program dynamically allocates the storage for the keys.  Thus, no
  1520. ; function key is limited to so-and-so many characters.  Rather, the
  1521. ; total number of bytes in the function key library (including flags)
  1522. ; is 256.
  1523. ;
  1524. INTCPT:    DB    ESC        ; Intercept character (prefix)
  1525. ;
  1526. FNCTBL:    DB    0,'DIR ',CR,0
  1527.     DB    1,'DIR *.* $U0AD ',CR,0
  1528.     DB    2,'KMD R ',0
  1529.     DB    3,'KMD S ',0
  1530.     DB    4,'XMODEM R ',0
  1531.     DB    5,'XMODEM S ',0
  1532.     DB    6,'BYE ',CR,0
  1533.     DB    7,'RBBS ',CR,0
  1534.     DB    8,'(vacant)',0
  1535.     DB    9,'Nice chatting, see you again soon... ',CR,0
  1536. ;
  1537.     DS    256-($-FNCTBL)
  1538. ;
  1539. ;
  1540. ;
  1541. ;***********************************************************************
  1542. ;
  1543. ;
  1544. ; P - R - O - G - R - A - M    S - T - A - R - T - S      H - E - R - E
  1545. ;
  1546. ;
  1547. ;***********************************************************************
  1548. ;
  1549. ;
  1550. START:    LXI    H,0
  1551.     DAD    SP        ; Add the current stack pointer to 'HL'
  1552.     SHLD    STACK
  1553.     LXI    SP,STACK    ; Start local stack
  1554. ;
  1555. ;
  1556. ; The 'FIXCNT' calculations are done here and the values stored so the
  1557. ; overhead of doing the calculation is not incurred in the RECV routine
  1558. ; where it is desired to pick up a character from the modem data port as
  1559. ; quickly as possible.
  1560. ;
  1561.     LXI    H,480        ; Adjust to get 1 second time intervals
  1562.     CALL    FIXCNT
  1563.     SHLD    TIMVAL
  1564.     LXI    H,48        ; Should be 1/10 of above value
  1565.     CALL    FIXCNT
  1566.     SHLD    QUIKTIM
  1567. ;
  1568. ;
  1569. ; Now display the program name and version number and we are under way
  1570. ;
  1571.     CALL    CRCGN        ; Generate tables for fast 'CRC' check
  1572.     CALL    INITADR        ; Initialize addresses
  1573.     CALL    INTERCEPT    ; Establish the function key intercept
  1574.     CALL    SETSPD        ; Bring up DTR, set modem speed
  1575.     CALL    PROCOPT        ; Process any options
  1576.     LDA    OPTION        ; Any options on the command line?
  1577.     CPI    ' '+1
  1578.     JNC    RSTRT
  1579.     CALL    ILPRT
  1580.     DB    CR,LF,'IMP v',VERSION/100+'0'
  1581.     DB    VERSION    MOD    100/10+'0'
  1582.     DB    VERSION    MOD 10+'0'
  1583.     DB    ' modem pgm (type M for Menu)'
  1584.     DB    CR,LF,'Copyright (c) 1985, 1987 Irvin M. Hoff'
  1585.     DB    CR,LF,0
  1586.     CALL    J$SYSVR        ; Give configuration message
  1587.     CALL    RATE
  1588.     JMP    MENU
  1589. ;
  1590. ;
  1591. ; Comes here from menu once the options have been set
  1592. ;
  1593. RSTRT:    LXI    SP,STACK    ; Make sure we have a clean stack
  1594.     CALL    CKCHAR        ; Catch any garbage characters left
  1595. ;
  1596. RSTRT1:    LDA    OPTION        ; Get the option
  1597.     CPI    'C'        ; Call (dial) function?
  1598.     JZ    J$DIAL        ; Yes, go to it
  1599. ;
  1600. RSTRT2:    CALL    MOVEFCB
  1601.     XRA    A
  1602.     STA    GOTONE        ; Indicated a batch file was transferred
  1603.     STA    KFLG        ; Reset the flag (might have been used)
  1604.     LDA    OPTION        ; Get main option
  1605.     CPI    'D'        ; Disconnect?
  1606.     JZ    DONETD        ; Yes, disconnect then back to the menu
  1607.     CPI    'M'        ; Menu asked for?
  1608.     JZ    MENU2        ; Go display the menu
  1609.     CPI    'R'        ; Want to receive a file?
  1610.     JZ    RCVFL        ; Exit if yes
  1611.     CPI    'S'        ; Want to send a file?
  1612.     JZ    SNDFL        ; Exit if yes
  1613.     CPI    'T'        ; Want terminal mode?
  1614.     JNZ    RSTRT3        ; If not, exit
  1615.     XRA    A
  1616.     STA    ECHOFLG        ; Reset echo flag
  1617.     STA    LOCFLG        ; Reset local flag
  1618.     JMP    DSKSV        ; Exit if yes
  1619. ;
  1620. RSTRT3:    CPI    'E'        ; Want echo mode?
  1621.     JNZ    NOECHO        ; If not, exit
  1622.     STA    ECHOFLG        ; Set the echo flag
  1623.     XRA    A
  1624.     STA    LOCFLG        ; Reset local flag
  1625.     JMP    DSKSV
  1626. ;
  1627. NOECHO:    CPI    'L'        ; Want local echo mode?
  1628.     JNZ    NOLOCAL        ; If not, exit
  1629.     STA    LOCFLG        ; Set the local flag
  1630.     XRA    A
  1631.     STA    ECHOFLG        ; Reset echo flag
  1632.     JMP    DSKSV
  1633. ;
  1634. NOLOCAL:CALL    NTVLDMSG    ; Say not a valid option
  1635.     JMP    MENU        ; Then go back to the command mode
  1636. ;.....
  1637. ;
  1638. ;
  1639. INITADR:LHLD    0000H+1        ; BIOS warm reboot jump vector
  1640.     LXI    D,3
  1641.     DAD    D
  1642.     SHLD    VSTAT+1        ; BIOS console status jump vector
  1643.     DAD    D
  1644.     SHLD    VKEYIN+1    ; BIOS console keyboard jump vector
  1645.     DAD    D
  1646.     SHLD    VTYPE+1        ; BIOS console CRT jump vector
  1647.     LXI    D,33
  1648.     DAD    D
  1649.     SHLD    GOLIST+1    ; BIOS list device status jump vector
  1650.     CALL    GETUSER        ; Get current user number
  1651.     STA    OLDUSER        ; Save to restore upon exit
  1652.     JMP    GTMAX        ; Find maximum ram for printer use, done
  1653. ;.....
  1654. ;
  1655. ;
  1656. ; Get the function key intercept character and put in appropriate places
  1657. ;
  1658. INTERCEPT:
  1659.     LDA    INTCPT        ; Get the function key intercept char.
  1660.     ANI    07FH        ; Strip off any parity
  1661.     STA    GTCMD1+1    ; Store in the menu area
  1662.     CPI    ' '        ; Printing character?
  1663.     JNC    INTER1        ; If yes, exit
  1664. ;
  1665.     CPI    ESC        ; Using the ESC key?
  1666.     JZ    INTER2        ; If yes, special case
  1667.     ADI    40H        ; Change to printing character
  1668.     STA    MENU3+1
  1669.     MVI    A,'^'
  1670.     STA    MENU3        ; Store the "control-" character
  1671.     RET
  1672. ;...
  1673. ;
  1674. ;
  1675. INTER1:    STA    MENU3+1
  1676.     RET
  1677. ;...
  1678. ;
  1679. ;
  1680. INTER2:    MVI    A,'E'        ; Just show 'ESC' then rather than ^[
  1681.     STA    MENU3
  1682.     MVI    A,'S'
  1683.     STA    MENU3+1
  1684.     MVI    A,'C'
  1685.     STA    MENU3+2
  1686.     RET
  1687. ;.....
  1688. ;
  1689. ;
  1690. ; Process any options - put 0 in appropriate place in option table if
  1691. ; option is selected
  1692. ;
  1693. PROCOPT:LXI    D,FCB+1        ; Look at first char. on command line
  1694.     LDAX    D        ; Get the character
  1695.     STA    OPTION        ; Store it for primary option
  1696.     CPI    ' '        ; Exit if no options
  1697.     RZ
  1698. ;
  1699. OPTLP:    INX    D        ; See if an additional option
  1700.     LDAX    D        ; Get the character
  1701.     CPI    ' '        ; Was it a space?
  1702.     JZ    ENDOPT        ; If yes, options are finished
  1703.     LXI    H,OPTBL        ; Start of option table
  1704.     MVI    B,OPTBE-OPTBL    ; Number of entries in option table
  1705. ;
  1706. OPTCK:    CMP    M        ; See if character matches one in table
  1707.     JNZ    OPTNO        ; If not, keep looking
  1708.     MVI    M,0        ; If yes, reset the flag to zero
  1709.     JMP    OPTLP        ; Check on additional options on line
  1710. ;
  1711. OPTNO:    INX    H        ; Next location in option table
  1712.     DCR    B        ; One less to go
  1713.     JNZ    OPTCK        ; If not zero, keep checking the table
  1714.     CALL    NTVLDMSG    ; If none of those was a wrong entry
  1715.     POP    H        ; Preserve stack
  1716.     JMP    MENU        ; Jump out to the menu
  1717. ;
  1718. ENDOPT:    LDA    VSEEFLG        ; See if visual flag is set
  1719.     ORA    A
  1720.     JNZ    CKOPT
  1721.     STA    QFLG        ; Quiet mode for watching data items
  1722. ;
  1723. ;
  1724. ; Checked for supplementary options, now check the primary option
  1725. ;
  1726. CKOPT:    LDA    OPTION        ; Check on the primary option
  1727.     CPI    'C'        ; Going to autodial now?
  1728.     RZ
  1729.     CPI    'D'        ; Going to disconnect?
  1730.     RZ
  1731.     CPI    'E'        ; Return if echo option
  1732.     RZ
  1733.     CPI    'M'        ; Return if help option
  1734.     RZ
  1735.     CPI    'L'        ; Return if local echo option
  1736.     RZ
  1737.     CPI    'T'        ; Return if terminal mode
  1738.     RZ
  1739. ;
  1740.     MOV    B,A        ; Save the character
  1741.     LDA    NFILFLG        ; Saving memory for disk file?
  1742.     ORA    A
  1743.     JZ    CKOPT2        ; If not, continue
  1744.     POP    H        ; Reset the stack from 'CALL PROCOPT'
  1745.     JMP    MENU0        ; Go show the 'FILE OPEN' message
  1746. ;
  1747. CKOPT2:    MOV    A,B        ; Get the option back
  1748.     CPI    'S'
  1749.     JZ    CKFILE
  1750.     CPI    'R'
  1751.     JNZ    BDOPT        ; None of these, bad option
  1752. ;
  1753.     LDA    BATCHFLG    ; See if the batch mode flag is set
  1754.     ORA    A
  1755.     RZ            ; If yes, exit
  1756. ;
  1757. CKFILE:    LDA    FCB+17        ; 'S' and 'R' need a file name
  1758.     CPI    ' '
  1759.     RNZ            ; Exit if a file name is present
  1760.     MOV    A,B        ; Call 'R' without filename batch
  1761.     CPI    'R'
  1762.     JNZ    CKFILE1
  1763.     XRA    A
  1764.     STA    BATCHFLG    ; Show now in batch mode
  1765.     RET
  1766. ;...
  1767. ;
  1768. ;
  1769. CKFILE1:CALL    ILPRT
  1770.     DB    '++ Enter primary option plus file name ++'
  1771.     DB    CR,LF,BELL,0
  1772.     POP    H        ; Reset stack from 'CALL STFCB'
  1773.     JMP    MENU        ; Abort to command line
  1774. ;.....
  1775. ;
  1776. ;
  1777. BDOPT:    CALL    ILPRT
  1778.     DB    CR,LF,'++ Bad option ++',CR,LF,LF,0
  1779. ;.....
  1780. ;
  1781. ;
  1782. ; Check for any garbage characters on line - catch and ignore
  1783. ;
  1784. CKCHAR:    CALL    RCVRDY        ; Any characters ready to receive?
  1785.     RNZ            ; If not, return
  1786.     CALL    I$MDDATP    ; Otherwise get the character and ignore
  1787.     JMP    CKCHAR        ; Check for any additional characters
  1788. ;.....
  1789. ;
  1790. ;
  1791. ; Revised terminal routine allowing memory save.  First checks for bad
  1792. ; options, to prevent wiping out the disk with accidental memory save.
  1793. ;
  1794. DSKSV:    LDA    BATCHFLG    ; Batch flag set?
  1795.     ORA    A
  1796.     JNZ    DSKSV1        ; If not set, everything is normal
  1797.     MVI    A,'B'        ; If set, shouldn't be, so reset it
  1798.     STA    BATCHFLG
  1799.     JMP    NOTVLD        ; If set, error for 'E', 'L' or 'T'
  1800. ;
  1801. DSKSV1:    STA    XFLG        ; Will use the ASCII capture buffer size
  1802.     LDA    NFILFLG        ; Already saving for a file?
  1803.     ORA    A
  1804.     JZ    DSKSV2        ; Exit if not, and open a file
  1805.     CALL    BUFMS        ; Tell if buffer if on or off
  1806.     JMP    TERM
  1807. ;
  1808. DSKSV2:    LDA    FCB+1        ; First character of filename (if any)
  1809.     CPI    ' '        ; File specified?
  1810.     JNZ    GOODNM        ; Yes, good name
  1811.     XRA    A
  1812.     STA    NFILFLG        ; Show no file being saved
  1813.     STA    SAVEFLG        ; Reset the flag to zero
  1814.     JMP    TERM
  1815. ;...
  1816. ;
  1817. ;
  1818. GOODNM:    CALL    ERASF
  1819.     LXI    H,FCB3
  1820.     CALL    INITFCB
  1821.     LXI    H,FCB        ; Move the disk name into FCB3 area
  1822.     LXI    D,FCB3
  1823.     MVI    B,12
  1824.     CALL    MOVE
  1825.     LXI    D,FCB3        ; Now make a file from that name
  1826.     MVI    C,MAKE
  1827.     CALL    BDOS
  1828.     LXI    D,FCB3        ; Now open the file from FCB3
  1829.     MVI    C,OPEN
  1830.     CALL    BDOS
  1831.     LXI    H,BUFFER    ; Reset pointers to start of buffer
  1832.     SHLD    HLSAV
  1833.     MVI    A,1
  1834.     STA    NFILFLG        ; Show now saving to memory for disk file
  1835.     STA    SAVEFLG        ; Active the file at the same time
  1836.     CALL    BUFMS        ; Show buffer is open
  1837. ;
  1838. TERM:    CALL    GOLIST
  1839.     CALL    STAT        ; Keyboard have a character?
  1840.     JZ    TERML        ; If not, see if any incoming
  1841. ;
  1842.     CALL    KEYIN        ; Get character from keyboard
  1843.     MOV    B,A        ; Save for now to protect 'A' reg.
  1844.     CPI    RUB        ; Test for rub
  1845.     JNZ    NOTRUB        ; Exit if not
  1846.     LDA    CONVRUB        ; Convert rub to backspace?
  1847.     ORA    A
  1848.     JZ    NOTRUB        ; Exit if no conversion
  1849.     MVI    B,BKSP        ; Call it a backspace
  1850.     JMP    NTOG        ; Go send a backspace
  1851. ;
  1852. NOTRUB:    LDA    FNKFLG        ; Get function key active flag
  1853.     ORA    A
  1854.     JZ    CKEXAC        ; If not set yet, exit
  1855. ;
  1856.     XRA    A        ; First zero the flag
  1857.     STA    FNKFLG
  1858.     MOV    A,B        ; Get character
  1859.     CPI    '0'
  1860.     JC    CKEXAC        ; If less, not a function key
  1861.     CPI    '9'+1
  1862.     JNC    CKEXAC        ; If more, not a function key
  1863.     XRA    A
  1864.     STA    EXACFLG        ; Just in case both use same character
  1865.     MOV    A,B        ; Get the character back
  1866.     ANI    0FH        ; Make 0..9
  1867.     JMP    SNDFK
  1868. ;
  1869. CKEXAC:    LDA    EXACFLG        ; External flag set yet?
  1870.     ORA    A
  1871.     JZ    NTEXAFLG    ; If not, proceed normally
  1872. ;
  1873.     XRA    A        ; Reset the flag
  1874.     STA    EXACFLG
  1875.     MOV    A,B        ; Get the character back
  1876.     ANI    5FH        ; Make sure it is upper case
  1877.     MOV    B,A        ; Save for comparison
  1878.     CALL    EXITTST1    ; Want to exit to menu?
  1879. ;
  1880.     LDA    CLEARS        ; ESC-Z to clear screen, terminal mode
  1881.     CMP    B
  1882.     JZ    CLRCRT
  1883.     LDA    FILESND        ; Output text file to remote?
  1884.     CMP    B
  1885.     JZ    SNDFILE
  1886.     LDA    LOGCHR        ; Send logon?
  1887.     CMP    B
  1888.     JZ    SNDLOG
  1889.     LDA    LSTCHR        ; Get the printer control-character
  1890.     CMP    B        ; Did we just ask for printer control?
  1891.     JNZ    NOLST        ; If not, exit
  1892.     LDA    LISTFLG        ; Otherwise reset the printer toggle
  1893.     CMA
  1894.     STA    LISTFLG        ; And store
  1895.     CALL    CRLF
  1896.     CALL    CRLF
  1897.     CALL    LSTMS        ; Tell if printer is on or off now
  1898.     CALL    CRLF
  1899.     JMP    TERML        ; Back to the terminal mode again
  1900. ;...
  1901. ;
  1902. ;
  1903. NOLST:    LDA    BRKCHR        ; Want to send a break tone?
  1904.     CMP    B
  1905.     JZ    SBREAK
  1906.     LDA    NOCONCT        ; Want to disconnect from line?
  1907.     CMP    B
  1908.     JZ    DONETD        ; If yes go disconnect
  1909.     LDA    UNSAVCH        ; Close input buffer?
  1910.     CMP    B
  1911.     JZ    NOLST1        ; If yes, disable copy
  1912.     LDA    SAVECHR        ; Open input buffer?
  1913.     CMP    B
  1914.     JNZ    NTOG
  1915.     LDA    NFILFLG        ; Do not allow save if flag is set
  1916.     ORA    A
  1917.     JZ    TERML
  1918.     JMP    NOLST2
  1919. ;
  1920. NOLST1:    XRA    A        ; Stop copy into file
  1921. ;
  1922. NOLST2:    STA    SAVEFLG
  1923.     CALL    BUFMS
  1924.     JMP    TERM        ; Get next character
  1925. ;.....
  1926. ;
  1927. ;
  1928. NTEXAFLG:
  1929.     LDA    EXTCHR        ; Treat next character in special way?
  1930.     CMP    B        ; Check against this control character
  1931.     JNZ    NOF
  1932.     STA    EXACFLG        ; Set the flag
  1933. ;
  1934.     LDA    INTCPT        ; See if INTCPT is same as EXTCHR
  1935.     CMP    B        ; (If it is, is ok - it uses 0-9)
  1936.     JNZ    TERML        ; If not, all set with EXACFLG flag set
  1937.     STA    FNKFLG        ; If yes, set FNKFLG also
  1938.     JMP    TERML        ; Do not send, get next character
  1939. ;.....
  1940. ;
  1941. ;
  1942. NOF:    LDA    INTCPT        ; Check intercept character
  1943.     CMP    B
  1944.     JNZ    NTOG        ; If not send this character to modem
  1945.     STA    FNKFLG        ; Set the function flag
  1946.     JMP    TERML        ; Do not send the intercept character
  1947. ;.....
  1948. ;
  1949. ;
  1950. ; Clears the CRT screen with "ESC-Z"
  1951. ;
  1952. CLRCRT:    CALL    CLRTST
  1953.     JMP    TERML        ; Back to work
  1954. ;.....
  1955. ;
  1956. ;
  1957. ;***********************************************************************
  1958. ;
  1959. ;             SND A CP/M FILE
  1960. ;
  1961. ;***********************************************************************
  1962. ;
  1963. ;
  1964. SNDFL:    CALL    CKCHAR        ; Catch any garbage characters
  1965.     XRA    A        ; Indicate using send batch mode
  1966.     STA    SNDFLG
  1967.     LDA    BATCHFLG    ; Check if multiple file mode is set
  1968.     ORA    A
  1969.     JNZ    SNDFL4        ; If not using batch mode, exit
  1970. ;
  1971.     CALL    ILPRT
  1972.     DB    'Ready to send in batch mode',CR,LF,0
  1973. ;
  1974. SNDFL1:    LDA    FSTFLG        ; First time through?
  1975.     ORA    A
  1976.     JNZ    SNDFL2        ; If not, exit
  1977.     CALL    TNMBUF        ; Get and store batch file names
  1978.     LDA    FILECT        ; Get the number of files to send
  1979.     ORA    A
  1980.     JNZ    SNDFL2        ; Exit if something to send
  1981.     CALL    ILPRTQ
  1982.     DB    CR,LF,'++ Ask again, file not found ++',0
  1983. ;
  1984. SNDFL2:    CALL    SNDFN        ; Sends file name to receive
  1985.     JNC    SNDFL3        ; More files if carry is not set
  1986. ;
  1987.     MVI    A,'B'        ; Stop batch mode
  1988.     STA    BATCHFLG
  1989.     LDA    GOTONE        ; Was a file actually transferred?
  1990.     ORA    A
  1991.     JZ    ABORT        ; If not, don't say it was
  1992.     JMP    DONE
  1993. ;
  1994. SNDFL3:    CALL    CRLF        ; Extra line before file name
  1995.     CALL    SHOWFIL        ; Display the file name
  1996.     CALL    CRLF
  1997. ;
  1998. SNDFL4:    LDA    FCB+1
  1999.     CPI    ' '
  2000.     JZ    BLKFILE
  2001.     CALL    CNREC        ; Get number of records
  2002.     CALL    OPENFIL
  2003.     CALL    RDBLK1        ; Read some of the file into the buffer
  2004.     CALL    CKCHAR        ; Catch any garbage characters
  2005.     LDA    KKMD        ; See if operator typed "SK"
  2006.     ORA    A
  2007.     JNZ    SNDFL5        ; If not, exit
  2008.     INR    A        ; Else set the manual 1k flag
  2009.     STA    KFLG
  2010. ;
  2011. SNDFL5:    MVI    E,60        ; Wait up to 1 minute for a start signal
  2012.     CALL    WAITNAK
  2013.     CALL    SETFLG        ; Switch to 128 size if under 8 records
  2014. ;
  2015. SNDLP:    CALL    GTRATIO        ; Check the ACK ratio if using 1k blocks
  2016.     CALL    RDRECD        ; Read a record
  2017.     JC    SNDEOF        ; If finished, exit
  2018.     CALL    INCRNO        ; Increment the record number
  2019.     MVI    A,1
  2020.     STA    ERRCT        ; Reset the error count to normal
  2021. ;
  2022. SNDRPT:    CALL    CKABORT        ; Want to quit at this time?
  2023.     CALL    SNDHDR        ; Send a header group
  2024.     CALL    SNDREC        ; Send the record number
  2025.     CALL    SNDCHK        ; Send CRC or Checksum
  2026.     CALL    GTACK        ; Wait for an 'ACK' for this record
  2027.     JC    SNDRPT        ; Repeat same record if no 'ACK'
  2028. ;
  2029.     CALL    SETPTR        ; Successful record so increase pointers
  2030.     JMP    SNDLP        ; Send next record
  2031. ;.....
  2032. ;
  2033. ;
  2034. SNDEOF:    MVI    A,EOT        ; Send an End of Transmission character
  2035.     CALL    SEND
  2036.     LDA    CHKEOT        ; Did not get an 'ACK', try again
  2037.     INR    A
  2038.     STA    CHKEOT        ; Limit number of retries to 4
  2039.     CPI    4
  2040.     JNC    DONE        ; If four or more, assume he got one
  2041.     CALL    GTACK        ; Wait for an 'ACK' that it was received
  2042.     JC    SNDEOF        ; Try again, they didn't get it
  2043.     JMP    DONE        ; Else got a good ACK, so finished
  2044. ;.....
  2045. ;
  2046. ;
  2047. ;***********************************************************************
  2048. ;
  2049. ;               RECEIVE A CP/M FILE
  2050. ;
  2051. ;***********************************************************************
  2052. ;
  2053. ;
  2054. RCVFL:    LDA    XMODEM        ; "RX", insures receiving blocks of 128
  2055.     STA    KFLG        ; Set the 1k block flag similar
  2056.     LDA    CRCDFLT        ; Get mode requested by operator
  2057.     STA    CRCFLG        ; Store it, resets 1k blocks if needed
  2058.     ORA    A
  2059.     JNZ    RCVFL1        ; Skip next line if requesting CRC
  2060.     STA    KFLG        ; Can't have 1k blocks with checksum
  2061. ;
  2062. RCVFL1:    LDA    BATCHFLG    ; Check if multiple file mode
  2063.     ORA    A
  2064.     JNZ    RCVFL2        ; If not, exit
  2065.     MVI    A,1        ; Indicate using receive batch mode
  2066.     STA    SNDFLG        ; For next file transfer
  2067.     CALL    GETFN        ; Get the file name
  2068.     JNC    RCVFL3        ; Carry not set means more files yet
  2069. ;
  2070.     MVI    A,'B'        ; Stop batch
  2071.     STA    BATCHFLG    ; Mode option
  2072.     LDA    GOTONE        ; Indicates a batch file was transferred
  2073.     ORA    A
  2074.     JZ    ABORT        ; If not, don't indicate it was
  2075.     JMP    DONE
  2076. ;
  2077. RCVFL2:    LDA    FCB+1        ; Make sure file is named
  2078.     CPI    ' '
  2079.     JZ    BLKFILE
  2080.     JMP    RCVFL5
  2081. ;
  2082. RCVFL3:    LDA    KMDODE        ; Using Yam batch?
  2083.     ORA    A
  2084.     JZ    RCVFL4        ; Yes, skip showfil as already done
  2085.     CALL    SHOWFIL        ; Show the file name
  2086.     MVI    A,' '
  2087.     CALL    TYPE
  2088.     CALL    SNDPRG        ; Get progress and wait for quiet line
  2089. ;
  2090. RCVFL4:    CALL    CKCPM2
  2091.     LDA    KMDODE
  2092.     ORA    A
  2093.     JZ    RCVFL5        ; Skip CRLF if in Yam batch
  2094.     CALL    CRLF
  2095. ;
  2096. RCVFL5:    CALL    ERASF
  2097.     CALL    MAKEFIL
  2098.     CALL    WAITQ1
  2099.     LDA    BATCHFLG    ; Do not print message if in batch mode
  2100.     ORA    A
  2101.     JZ    RCVFL6        ; Exit if in batch mode
  2102.     CALL    FILNAM
  2103.     CALL    ILPRTQ
  2104.     DB    CR,LF,'File open, ready to receive',CR,LF,0
  2105. ;
  2106. RCVFL6:    LDA    CRCFLG
  2107.     ORA    A
  2108.     JZ    RCVFCHK        ; Exit if in checksum mode
  2109.     LDA    BATCHFLG    ; In batch mode?
  2110.     ORA    A
  2111.     JNZ    RCVFLC        ; Exit if not
  2112.     LDA    KMDODE        ; Yam batch?
  2113.     ORA    A
  2114.     JZ    RCVFL7        ; Yes, skip CRC message and KFLG
  2115. ;
  2116. RCVFLC:    CALL    ILPRTQ        ; Then say so
  2117.     DB    'CRC in effect',CR,LF,0
  2118. ;
  2119. RCVFL7:    MVI    A,CRC        ; Else request 128 size with CRC
  2120.     JMP    RCVLF8
  2121. ;
  2122. RCVFCHK:CALL    ILPRTQ        ; Else say 'CHECKSUM' mode
  2123.     DB    'Checksum in effect',CR,LF,0
  2124.     MVI    A,NAK
  2125. ;
  2126. RCVLF8:    PUSH    PSW
  2127.     CALL    ILPRT
  2128.     DB    'Waiting.....',0
  2129.     POP    PSW
  2130.     CALL    SEND
  2131.     LDA    KFLG        ; Requesting 1k blocks?
  2132.     ORA    A
  2133.     JZ    RCVLP
  2134.     MVI    A,KSND        ; 1k block request
  2135.     CALL    SEND
  2136. ;
  2137. ;
  2138. ; This is the acutal receive loop
  2139. ;
  2140. RCVLP:    CALL    RCVRECD
  2141.     JC    RCVEOT
  2142.     CALL    INCRNO
  2143.     CALL    REPORT        ; Show record received if not in quiet
  2144.     CALL    WRRECD
  2145.     CALL    SNDACK
  2146.     JMP    RCVLP        ; Loop for next incoming record
  2147. ;
  2148. ;
  2149. ; Got an EOT, erase an empty file, else write to disk and close the file
  2150. ;
  2151. RCVEOT:    LHLD    RECNO        ; Check for zero length file
  2152.     MOV    A,H        ; If no records, no file
  2153.     ORA    L
  2154.     JZ    ABORT        ; Abort and erase the zero-length file
  2155.     CALL    WRBLOCK
  2156.     CALL    CLOSFIL
  2157.     CALL    SNDACK
  2158.     JMP    DONE
  2159. ;.....
  2160. ;
  2161. ;
  2162. SNDACK:    MVI    A,ACK
  2163.     JMP    SEND
  2164. ;.....
  2165. ;
  2166. ;
  2167. ;===================== SEND FILE IN T-MODE =============================
  2168. ;
  2169. ;
  2170. ; Send file routine - called with (special character F) when in terminal
  2171. ; mode.  Sending may be cancelled by using CTL-X (cancel) key.
  2172. ;
  2173. SNDFILE:LXI    H,FCB4
  2174.     CALL    INITFCB        ; Initializes FCBs
  2175.     LXI    H,FCB+16
  2176.     CALL    INITFCB
  2177. ;
  2178. ;
  2179. ; Get name of file to send in "T" (terminal) mode
  2180. ;
  2181. GET:    CALL    ILPRT
  2182.     DB    CR,LF,'File name to send? (CR to abort): ',0
  2183.     LXI    D,CMDBUF
  2184.     CALL    INBUF
  2185.     LDA    CMDBUF+2    ; Was file entered?
  2186.     CPI    ' '
  2187.     JZ    RETRN        ; If not probably wanted to quit
  2188.     LXI    D,CMDBUF
  2189.     LXI    H,FCB4
  2190.     CALL    CMDLINE
  2191.     LXI    D,FCB4
  2192.     MVI    C,OPEN
  2193.     CALL    BDOS
  2194.     CPI    0FFH        ; Return with 0FFH means 'NO SUCH FILE'
  2195.     JZ    SNDMSG
  2196. ;
  2197. ;
  2198. ; Choice of normal speed or delays between characters / lines
  2199. ;
  2200.     CALL    ILPRT
  2201.     DB    'Want to include time delays? (Y/N): ',0
  2202.     CALL    KBDCHR
  2203.     CPI    'N'        ; If 'N' send normal speed
  2204.     JZ    DLYSAV
  2205.     XRA    A        ; Otherwise use character/line delays
  2206. ;
  2207. DLYSAV:    STA    DLYFLG        ; Store the decision
  2208.     CALL    CRLF
  2209.     LXI    D,CMDBUF+2    ; Make sure CMDBUF has been selected
  2210.     MVI    C,STDMA
  2211.     CALL    BDOS
  2212. ;
  2213. ;
  2214. ; Get 128-byte record
  2215. ;
  2216. READM:    LXI    D,FCB4
  2217.     MVI    C,READ
  2218.     CALL    BDOS
  2219.     ORA    A        ; Check for a good read
  2220.     JZ    READM1
  2221.     DCR    A        ; Check for end of file to send
  2222.     JZ    RETRNS
  2223.     CALL    ERXIT        ; Neither of those, was a read error
  2224.     DB    '++ DISK READ ERROR ++','$'
  2225. ;
  2226. ;
  2227. ; Successful read, so send the record
  2228. ;
  2229. READM1:    CALL    SND80C        ; Send one 128-char record
  2230.     CPI    EOFCHAR        ; End of file - omit if object
  2231.     JZ    RETRNS        ;   code is to be sent.
  2232.     CPI    CANCEL        ; Want to quit?
  2233.     JNZ    READM
  2234. ;
  2235. RETRN:    CALL    ILPRT
  2236.     DB    CR,LF,LF,'(in Terminal-mode now)',CR,LF,LF,0
  2237.     CALL    SNDNOW        ; Insures last character is finished
  2238.     CALL    CKCHAR        ; Catch any echo character on line
  2239.     JMP    TERM        ; Finished, back to Terminal-mode
  2240. ;.....
  2241. ;
  2242. ;
  2243. RETRNS:    CALL    ILPRT
  2244.     DB    CR,LF,'[Transfer completed]',0
  2245.     JMP    RETRN
  2246. ;.....
  2247. ;
  2248. ;
  2249. SNDMSG:    CALL    ILPRT
  2250.     DB    CR,LF,BELL,'++ FILE NAME ERROR ++ ',CR,LF,0
  2251.     JMP    GET
  2252. ;.....
  2253. ;
  2254. ;
  2255. ; Send one 128-byte record
  2256. ;
  2257. SND80C:    MVI    B,128        ; Will send a maximum of 128 character
  2258.     LXI    H,CMDBUF+2    ; They are in the CMDBUF area
  2259. ;
  2260. SNDCH1:    MOV    A,M        ; Get the character to send
  2261.     ANI    7FH        ; Strip off any high bits set
  2262.     CPI    EOFCHAR
  2263.     RZ
  2264.     CALL    MDOUT        ; Send the character to modem
  2265.     CALL    STAT        ; Want to terminate sending?
  2266.     ORA    A
  2267.     JZ    SKIP1
  2268.     CALL    KEYIN
  2269.     CPI    CANCEL
  2270.     RZ
  2271. ;
  2272. SKIP1:    INX    H
  2273.     DCR    B
  2274.     JNZ    SNDCH1
  2275.     RET
  2276. ;.....
  2277. ;
  2278. ;
  2279. ; Send the character to the output
  2280. ;
  2281. MDOUT:    PUSH    PSW        ; Save the character so can use 'A' reg.
  2282.     CPI    LF
  2283.     JNZ    MDOUTL
  2284.     LDA    ADDLFD        ; Going to send the line feed to modem?
  2285.     ORA    A
  2286.     JNZ    MDOUTL        ; If yes, go to normal routine
  2287.     POP    PSW        ; Get the character back (a line feed)
  2288.     CALL    TYPE        ; Show on CRT, do not send to modem
  2289.     RET
  2290. ;...
  2291. ;
  2292. ;
  2293. MDOUTL:    CALL    TXOFF        ; Check for Xoff
  2294.     LDA    DLYFLG        ; Going to include delays?
  2295.     ORA    A
  2296.     JNZ    MDOUTL2        ; If not, check normal flag
  2297. ;
  2298. MDOUTL1:CALL    SNDTXE        ; See if TxE output buffer is empty yet
  2299.     JNZ    MDOUTL1        ; If not, wait
  2300.     CALL    SPDCHR        ; When ready, kick in requested delay
  2301.     JMP    MDOUTL3        ; Go send the character
  2302. ;
  2303. MDOUTL2:CALL    SNDRDY        ; Wait until modem is ready to send
  2304.     JNZ    MDOUTL
  2305. ;
  2306. MDOUTL3:POP    PSW        ; Get the character back
  2307.     CALL    TYPE        ; Send character to CRT
  2308.     CALL    O$MDDATP    ; Send character to modem
  2309.     CPI    CR        ; Was it an end of line?
  2310.     RNZ            ; If yes, see if any delay is needed
  2311. ;
  2312. ;
  2313. ; Delay to allow slow BBS systems (most use BASIC) to enter the line.
  2314. ; Choice of 0-9 for 100 ms. each, maximum of 900 ms.
  2315. ;
  2316.     LDA    DLYFLG        ; Going to send a delay each line?
  2317.     ORA    A
  2318.     JZ    SPDLIN        ; If yes send the delay
  2319.     RET
  2320. ;.....
  2321. ;
  2322. ;
  2323. ; Add from 0 to 9 ms. delay between characters for slow bulletin board
  2324. ; systems (most use 'C' or 'MBASIC').
  2325. ;
  2326. SPDCHR:    LDA    BYTDLY        ; Get delay between characters (0-9)
  2327.     ORA    A
  2328.     RZ            ; Don't bother if set to zero
  2329.     PUSH    B
  2330.     ADD    A        ; Double the value for 1 ms. loops
  2331.     ADD    A        ; Double again for the 1 ms. loops
  2332.     MOV    B,A        ; Main number of loops
  2333.     CALL    SPEED
  2334.     POP    B        ; Restore the BC values
  2335.     RET
  2336. ;.....
  2337. ;
  2338. ;
  2339. ; Sends 0-900 ms between lines
  2340. ;
  2341. SPDLIN:    LDA    CRDLY        ; Get delay between lines (0-90)
  2342.     ORA    A
  2343.     RZ            ; Don't bother if set to zero
  2344.     PUSH    B
  2345.     ADD    A        ; Double the value for 1 ms. loops
  2346.     ADD    A        ; Double again for the 1 ms. loops
  2347.     MOV    C,A        ; Store
  2348.     MVI    D,100        ; 100 loops for 100 ms. each
  2349. ;
  2350. SPDLIN1:MOV    B,C        ; Get the original value again
  2351.     CALL    SPEED
  2352.     DCR    D        ; One less main loop to go
  2353.     JNZ    SPDLIN1        ; If not zero, keep delaying
  2354.     POP    B        ; Restore the BC values
  2355.     RET
  2356. ;...
  2357. ;
  2358. ;
  2359. ; For 1/2 ms delay
  2360. ;
  2361. SPEED:    LDA    CLOCK        ; Secondary number of loops
  2362. ;
  2363. SPEED1:    XCHG            ; Waste some time
  2364.     XCHG            ; Restore HL & DE, a little more time
  2365.     DCR    A        ; Decrement inner loop
  2366.     JNZ    SPEED1        ; If not zero, keep going
  2367.     DCR    B        ; Decrement outer loop
  2368.     JNZ    SPEED        ; If not zero, reset inner loop
  2369.     RET
  2370. ;.....
  2371. ;
  2372. ;
  2373. TXOFF:    CALL    RCVRDY
  2374.     RNZ
  2375.     CALL    I$MDDATP
  2376.     ANI    7FH
  2377.     CPI    XOFF
  2378.     CZ    WAITXON
  2379.     RET
  2380. ;.....
  2381. ;
  2382. ;
  2383. WAITXON:CALL    RCVRDY        ; Have a character? (like X-on)
  2384.     JNZ    WTXON1        ; If no character see if want to abort
  2385.     CALL    I$MDDATP
  2386.     ANI    7FH        ; Strip off any parity
  2387.     CPI    XON        ; See if character was X-on
  2388.     RZ            ; If yes, keep going
  2389. ;
  2390. WTXON1:    CALL    STAT        ; Test to see if requesting cancellation
  2391.     JZ    WAITXON        ; Nothing typed, wait for X-on
  2392.     CALL    KEYIN        ; Can abort if the X-on never comes
  2393.     CPI    CANCEL        ; CTL-X to abort?
  2394.     JNZ    WAITXON        ; If not, keep going
  2395.     RET
  2396. ;.....
  2397. ;
  2398. ;
  2399. ;=================== END OF FILE SEND IN T-MODE ========================
  2400. ;
  2401. ;
  2402. ;***********************************************************************
  2403. ;
  2404. ;               SUBROUTINES
  2405. ;
  2406. ;***********************************************************************
  2407. ;
  2408. ;
  2409. ; Show the file name as stored in the FCB but in CP/M format
  2410. ;
  2411. SHOWFIL:LDA    QFLG        ; Can type it if no 'QFLG'
  2412.     ORA    A
  2413.     RZ
  2414.     LXI    H,FCB+1
  2415.     XRA    A
  2416.     STA    FTYCNT
  2417.     MVI    C,11
  2418. ;
  2419. PRNAM:    CALL    FTYTST
  2420.     INX    H
  2421.     DCR    C
  2422.     JNZ    PRNAM
  2423.     RET
  2424. ;.....
  2425. ;
  2426. ;
  2427. ; Give report of received records as they occur
  2428. ;
  2429. REPORT:    LDA    QFLG
  2430.     ORA    A
  2431.     RZ
  2432.     LHLD    RECNO        ; Get record number
  2433.     CALL    ILPRT
  2434.     DB    CR,'Received # ',0
  2435.     CALL    DECOUT        ; Print record number in decimal
  2436.     CALL    ILPRT
  2437.     DB    ' ',0
  2438.     RET
  2439. ;.....
  2440. ;
  2441. ;
  2442. FTYTST:    LDA    FTYCNT
  2443.     INR    A
  2444.     STA    FTYCNT
  2445.     CPI    9        ; Are we at the file type?
  2446.     JZ    SPCTST        ; Go if so
  2447. ;
  2448. ENDSPT:    MOV    A,M
  2449.     CPI    ' '        ; Test for space
  2450.     CNZ    TYPE        ; Type if not
  2451.     RET
  2452. ;.....
  2453. ;
  2454. ;
  2455. ; See if enough records in file to use 1k protocol if requested
  2456. ;
  2457. SETFLG:    LHLD    RCNT
  2458.     MOV    A,H        ; Anything in the 'H' register?
  2459.     ORA    A
  2460.     RNZ
  2461.     MOV    A,L        ; Get number of records in 'L' register
  2462.     CPI    8        ; At least 8 yet?
  2463.     RNC            ; If 8 or more, keep going
  2464.     XRA    A        ; Reset the 'K' flag
  2465.     STA    KFLG
  2466.     RET
  2467. ;.....
  2468. ;
  2469. ;
  2470. SPCTST:    MOV    A,M
  2471.     CPI    ' '        ; Test for space in 1st file type byte
  2472.     RZ            ; Do not output period if space
  2473.     MVI    A,'.'
  2474.     CALL    TYPE
  2475.     JMP    ENDSPT        ; Output 1st file type byte
  2476. ;.....
  2477. ;
  2478. ;
  2479. ; Get sender's progress report if it is present and wait for line to get
  2480. ; quiet
  2481. ;
  2482. SNDPRG:    MVI    B,1        ; Wait up to 1 second
  2483.     CALL    RECV
  2484.     CALL    TYPE        ; Show the progress report from sender
  2485.     JNC    SNDPRG
  2486.     RET
  2487. ;.....
  2488. ;
  2489. ;
  2490. SNDFN:    LDA    KMDODE        ; Using Yam batch?
  2491.     ORA    A
  2492.     JZ    SNDKMD        ; If so, skip following routine
  2493. ;
  2494.     CALL    ILPRTQ
  2495.     DB    CR,LF,'Awaiting name NAK',0
  2496.     CALL    GTACK
  2497.     CC    SNDACK
  2498.     LXI    H,FILECT
  2499.     DCR    M
  2500.     JM    NOMRN
  2501.     LHLD    NBSAVE        ; Get file name..
  2502.     LXI    D,FCB        ; In FCB
  2503.     MVI    B,12
  2504.     CALL    MOVE
  2505.     SHLD    NBSAVE
  2506.     CALL    SNDNM        ; Send it
  2507.     ORA    A        ; Clear carry
  2508.     RET
  2509. ;.....
  2510. ;
  2511. ;
  2512. NOMRN:    MVI    A,EOT
  2513.     CALL    SEND
  2514.     STC
  2515.     RET
  2516. ;.....
  2517. ;
  2518. ;
  2519. ;-----------------------------------------------------------------------
  2520. ;               KMD send batch mode
  2521. ;
  2522. SNDKMD:    CALL    CATCH        ; Clear the decks for action
  2523.     XRA    A
  2524.     STA    ERRCT        ; Initialize the error counter
  2525.     MVI    A,1
  2526.     STA    CRCFLG        ; Make sure in CRC mode
  2527.     LDA    FILECT        ; Any files to send?
  2528.     ORA    A
  2529.     JZ    CCHECK        ; If not exit and wait for 'C'
  2530. ;
  2531.     LHLD    NBSAVE        ; Get current file name
  2532.     LXI    D,FCB        ; Move it into the FCB
  2533.     MVI    B,12
  2534.     CALL    MOVE
  2535.     SHLD    NBSAVE
  2536.     LHLD    RECPTR        ; Where to load the 0 block
  2537.     XCHG            ; Put into DE
  2538.     LXI    H,FCB+1
  2539.     MVI    B,8
  2540. ;
  2541. SKMD0:    MOV    A,M
  2542.     ANI    7FH        ; Strip any high bit set
  2543.     ORA    A
  2544.     JZ    SKMD5        ; Null pathname
  2545.     CPI    ' '
  2546.     JZ    SKMD2
  2547. ;
  2548. SKMD1:    CALL    LCASE        ; Put file name in lower case for UNIX
  2549.     STAX    D
  2550.     INX    H
  2551.     INX    D
  2552.     DCR    B
  2553.     JNZ    SKMD0
  2554.     JMP    SKMD3
  2555. ;
  2556. SKMD2:    INX    H        ; Skip over spaces is short name
  2557.     DCR    B
  2558.     JNZ    SKMD2
  2559. ;
  2560. SKMD3:    MOV    A,M
  2561.     CPI    ' '
  2562.     JZ    SKMD5        ; Missing file type field
  2563.     MVI    A,'.'        ; Send name-type seperator
  2564.     STAX    D
  2565.     INX    D
  2566.     MVI    B,3
  2567. ;
  2568. SKMD4:    MOV    A,M
  2569.     ANI    7FH        ; Strip any high bit set
  2570.     CPI    ' '
  2571.     JZ    SKMD5
  2572.     CALL    LCASE        ; Put extent in lower case for UNIX
  2573.     STAX    D
  2574.     INX    H
  2575.     INX    D
  2576.     DCR    B
  2577.     JNZ    SKMD4
  2578. ;
  2579. SKMD5:    XCHG            ; Get the address back to HL
  2580. ;
  2581. SKMD6:    MVI    M,0        ; Fill rest of block with zeroes
  2582.     INR    L
  2583.     JNZ    SKMD6
  2584. ;
  2585.     MVI    C,FILSIZ
  2586.     LXI    D,FCB
  2587.     CALL    BDOS
  2588.     LHLD    FCB+33
  2589.     SHLD    BUFSTR        ; Store the file length at end of block
  2590.     XRA    A
  2591.     STA    RCDCNT        ; Special header starts with 0
  2592. ;
  2593. ;
  2594. ; Wait for a 'C' from remote system
  2595. ;
  2596. CCHECK:    MVI    E,60
  2597. ;
  2598. CCHECK1:CALL    CKABORT
  2599.     MVI    B,1
  2600.     CALL    RECV
  2601.     JC    CCHECK2        ; No character, decrement counter
  2602.     CPI    CANCEL
  2603.     CZ    CKCAN        ; Check for cancel
  2604.     CPI    CRC
  2605.     JZ    SKMD7
  2606.     JMP    CCHECK1
  2607. ;
  2608. CCHECK2:DCR    E        ; One less loop to go
  2609.     JNZ    CCHECK
  2610.     JMP    ABORTX
  2611. ;
  2612. ;
  2613. ; Got a 'C' so either send the file or terminate batch, if no more files
  2614. ;
  2615. SKMD7:    LDA    FILECT        ; Any files to send?
  2616.     ORA    A
  2617.     JZ    KMDEND        ; If not, terminate batch send
  2618.     DCR    A        ; Else decrement count for this file
  2619.     STA    FILECT
  2620.     LXI    H,FILECT
  2621. ;
  2622. ;
  2623. ; Now send the 128-byte file name record
  2624. ;
  2625. SKMD8:    XRA    A
  2626.     STA    KFLG
  2627.     MVI    A,SOH        ; Send SOH
  2628.     CALL    SEND
  2629.     CALL    SNDHNM        ; Send header (record number, inverse)
  2630.     CALL    SNDREC        ; Send a 128 byte record
  2631.     CALL    SNDCRC        ; Send a two byte CRC
  2632.     CALL    GTACK        ; Get the ACK
  2633.     CPI    ACK        ; Was it an 'ACK'?
  2634.     JNZ    SKMD8        ; If not, send the header block again
  2635.     LDA    XMODEM        ; User want's 128 byte blocks?
  2636.     ORA    A
  2637.     JZ    SKMD9        ; Yes
  2638.     MVI    A,1
  2639.     STA    KFLG        ; Use 1k blocks in batch
  2640. ;
  2641. SKMD9:    XRA    A        ; Clear the carry flag
  2642.     STA    ERRCT        ; Start fresh for the main file
  2643.     RET
  2644. ;.....
  2645. ;
  2646. ;
  2647. KMDEND:    XRA    A
  2648.     LHLD    RECPTR
  2649.     MOV    M,A
  2650.     STA    RCDCNT
  2651.     STA    KFLG
  2652.     MVI    A,SOH
  2653.     CALL    SEND
  2654.     CALL    SNDHNM
  2655.     CALL    SNDREC
  2656.     CALL    SNDCRC
  2657.     STC
  2658.     RET
  2659. ;.....
  2660. ;
  2661. ;
  2662. ; Wait for line to get quiet and gobble characters
  2663. ;
  2664. WAITQ1:    MVI    B,1
  2665.     CALL    RECV
  2666.     JNC    WAITQ1
  2667.     RET
  2668. ;.....
  2669. ;
  2670. ;
  2671. ; Send the MODEM7 batch file name
  2672. ;
  2673. SNDNM:    PUSH    H
  2674. ;
  2675. SNDNM1:    MVI    D,11        ; Count characters in name
  2676.     MVI    C,0        ; Initialize checksum
  2677.     LXI    H,FCB+1        ; Address name
  2678. ;
  2679. NAMLPS:    MOV    A,M        ; Send name
  2680.     ANI    7FH        ; Strip high order bit so CP/M2
  2681.     CALL    SEND        ;   will not send R/O file designation.
  2682. ;
  2683. ACKLP:    PUSH    B        ; Save checksum
  2684.     MVI    B,5        ; Wait for receiver to acknowledge
  2685.     CALL    RECV        ;   getting the character
  2686.     POP    B
  2687.     JC    SCKSER
  2688.     CPI    ACK
  2689.     JNZ    ACKLP
  2690.     INX    H        ; Next character
  2691.     DCR    D
  2692.     JNZ    NAMLPS
  2693.     MVI    A,EOFCHAR    ; Tell receiver the end of name
  2694.     CALL    SEND
  2695.     MOV    D,C        ; Save checksum
  2696.     MVI    B,5        ; Wait up to 5 seconds
  2697.     CALL    RECV        ; Get checksum
  2698.     CMP    D
  2699.     JNZ    SCKSER        ; Exit if bad name
  2700.     MVI    A,OKNMCH    ; Good name-tell receiver
  2701.     CALL    SEND
  2702.     POP    H
  2703.     RET
  2704. ;.....
  2705. ;
  2706. ;
  2707. SCKSER:    MVI    A,BDNMCH    ; Bad name-tell receiver
  2708.     CALL    SEND
  2709.     CALL    ILPRT
  2710.     DB    CR,LF,'++ ERROR sending name  ++',CR,LF,0
  2711.     MVI    E,60        ; Do handshaking over (2 minutes maximum)
  2712.     CALL    WAITNAK        ; See what protocol the user has
  2713.     CALL    SNDACK
  2714.     JMP    SNDNM1
  2715. ;.....
  2716. ;
  2717. ;
  2718. GETFN:    LXI    H,FCB
  2719.     CALL    INITFCB1    ; Does not initialize drive
  2720.     LDA    KMDODE        ; Yam batch supported?
  2721.     ORA    A
  2722.     JZ    RCVKMD        ; Yes, go to alternate routine
  2723. ;
  2724.     CALL    ILPRTQ
  2725.     DB    CR,LF,'Awaiting file name',CR,LF,0
  2726.     CALL    HSNAK
  2727.     CALL    GETNM        ; Get the name
  2728.     CPI    EOT        ; If EOT, then no more files
  2729.     JZ    GETFN1
  2730.     ORA    A        ; Clear carry
  2731.     RET
  2732. ;
  2733. GETFN1:    STC            ; Set carry to show no more files
  2734.     RET
  2735. ;.....
  2736. ;
  2737. ;
  2738. ;-----------------------------------------------------------------------
  2739. ;             KMD receive batch mode
  2740. ;
  2741. RCVKMD:    XRA    A        ; Initialize the error counter
  2742.     STA    RCVTRY
  2743.     CALL    CATCH        ; Clear the decks for action
  2744. ;
  2745. RKMD1:    CALL    CKABORT        ; Check for user abort
  2746.     MVI    B,3        ; Wait up to 3 sec. for SOH from remote
  2747.     CALL    RECV
  2748.     JC    RKMD2        ; No character, decrement counter
  2749.     CPI    CANCEL        ; Was it a CTL-X for cancel?
  2750.     CZ    CKCAN        ; Abort if yes
  2751.     CPI    SOH        ; SOH is all we are interested in
  2752.     JZ    RKMD4
  2753.     JMP    RKMD1        ; Anything else, ignore
  2754. ;
  2755. RKMD2:    MVI    A,CRC        ; Send a 'C'
  2756.     CALL    SEND
  2757. ;
  2758. RKMD3:    LDA    RCVTRY        ; Increment the "try" counter
  2759.     INR    A
  2760.     STA    RCVTRY
  2761.     CPI    20        ; Tried 1 minute yet?
  2762.     JC    RKMD1
  2763.     JMP    ABORT        ; Quit and try to force him to quit
  2764. ;
  2765. RKMD4:    MVI    B,5        ; 5 seconds to get sector number
  2766.     CALL    RECV
  2767.     JC    KMDTOT        ; No character, exit
  2768.     MOV    D,A        ; Save sector number in D
  2769.     ORA    A
  2770.     JNZ    KMDHDR        ; Must be a 0 if sending batch header
  2771.     MVI    B,5        ; 5 seconds to get reciprocal
  2772.     CALL    RECV
  2773.     JC    KMDTOT        ; No character, exit
  2774.     CMA            ; Invert it and compare to sector #
  2775.     CMP    D
  2776.     JNZ    KMDCRC        ; Bad match
  2777.     LXI    H,0
  2778.     SHLD    CRCVAL        ; Clear CRC counter
  2779.     MVI    E,128
  2780.     LHLD    RECPTR        ; Get buffer address
  2781. ;
  2782. RKMD5:    MVI    B,5        ; 5 seconds to get 128 byte header block
  2783.     CALL    RECV
  2784.     JC    KMDTOT        ; No character, exit
  2785.     MOV    M,A        ; Store the character in the buffer
  2786.     INX    H        ; Next buffer address
  2787.     DCR    E        ; One less to go
  2788.     JNZ    RKMD5        ; If not, room for another character
  2789.     MVI    E,2
  2790. ;
  2791. RKMD6:    MVI    B,5
  2792.     CALL    RECV        ; Get CRC bytes
  2793.     JC    KMDTOT        ; No character, exit
  2794.     DCR    E        ; Done?
  2795.     JNZ    RKMD6        ; No
  2796.     CALL    CRCCHK        ; Compare CRC received against ours
  2797.     ORA    A        ; Ok?
  2798.     JNZ    KMDCRC        ; No
  2799.     CALL    SNDACK        ; Yes, acknowledge to remote
  2800. ;
  2801. ;
  2802. ; Decode pathname into CPM format
  2803. ;
  2804.     LXI    D,FCB+1        ; Where to put it
  2805.     LHLD    RECPTR        ; Where to get it
  2806.     MVI    B,8        ; Filename length
  2807. ;
  2808. RKMD7:    MOV    A,M        ; Get the character from the buffer
  2809.     ORA    A        ; Was it a zero?
  2810.     JZ    RKMD12        ; If yes, all done
  2811.     CPI    '.'        ; Was it a delimiter?
  2812.     JZ    RKMD9
  2813.     CPI    '_'        ; Unix can't handle this properly
  2814.     JNZ    RKMD8
  2815.     MVI    A,'/'        ; Change it to a slash
  2816. ;
  2817. RKMD8:    CALL    UCASE        ; Insure name is in upper case
  2818.     STAX    D        ; Store filename character in FCB
  2819.     INX    D        ; Increment pointers
  2820.     INX    H
  2821.     DCR    B        ; One less to go
  2822.     JNZ    RKMD7        ; If not 8, keep going
  2823. ;
  2824.     MOV    A,M        ; Get the character back
  2825.     ORA    A        ; We had 8, was there an extent?
  2826.     JZ    RKMD11        ; If zero, was all done
  2827.     JMP    RKMD10        ; Else must be a '.'
  2828. ;
  2829. RKMD9:    MVI    A,' '        ; Spaces to make up 8 spaces for name
  2830.     STAX    D        ; Store space character in FCB
  2831.     INX    D        ; Increment pointers
  2832.     DCR    B        ; One less to go
  2833.     JNZ    RKMD9        ; Keep going until in extent area
  2834. ;
  2835. RKMD10:    INX    H        ; Skip the '.' position
  2836.     MVI    B,3        ; Extent length
  2837.  
  2838. RKMD11:    MOV    A,M        ; Get the character from the buffer
  2839.     ORA    A        ; Was it a zero?
  2840.     JZ    RKMD12        ; If yes, all done
  2841.     CALL    UCASE        ; Insure extent is in upper case
  2842.     STAX    D        ; Store extent character
  2843.     INX    D        ; Increment pointers
  2844.     INX    H
  2845.     DCR    B        ; One less to go
  2846.     JNZ    RKMD11        ; Keep going until finished
  2847. ;
  2848. RKMD12:    LDA    FCB+1        ; See if there was any filename at all
  2849.     CPI    ' '
  2850.     STC
  2851.     RZ            ; No - end of batch
  2852. ;
  2853.     LDA    QFLG
  2854.     ORA    A
  2855.     RZ
  2856. ;
  2857.     CALL    ILPRTQ
  2858.     DB    CR,LF,'File name: ',0
  2859.     LHLD    RECPTR        ; Print filename
  2860. ;
  2861. RKMD13:    MOV    A,M
  2862.     ORA    A
  2863.     JZ    RKMD14        ; If zero, end of filename
  2864.     CALL    UCASE
  2865.     CALL    TYPE
  2866.     INX    H
  2867.     JMP    RKMD13
  2868. ;
  2869. RKMD14:    LHLD    BUFSTR        ; Get the file length, if provided
  2870.     MOV    A,H
  2871.     ORA    L
  2872.     JZ    RKMD15        ; If both zero, length not provided
  2873. ;
  2874.     SHLD    RCNT        ; Store the file length
  2875.     CALL    CRLF        ; Start a new line
  2876.     CALL    SNDTM
  2877. ;
  2878.     CALL    ILPRTQ
  2879.     DB    'k)',CR,LF,'Recv time: ',0
  2880.     LXI    H,KECTBL
  2881.     SHLD    RECTBL+1
  2882.     CALL    KTIM
  2883.     CALL    SNDTM1
  2884. ;
  2885. RKMD15:    CALL    CRLF        ; Finish the filename line
  2886.     XRA    A        ; Reset the carry flag
  2887.     STA    RCVTRY        ; Reset the error counter
  2888.     RET
  2889. ;.....
  2890. ;
  2891. ;
  2892. KMDCRC:    CALL    ILPRTQ
  2893.     DB    '++ CRC error ++',CR,LF,0
  2894.     JMP    KMDXFR
  2895. ;.....
  2896. ;
  2897. ;
  2898. KMDHDR:    CALL    ILPRTQ
  2899.     DB    '++ Wrong header type ++',CR,LF,0
  2900.     JMP    KMDXFR
  2901.  
  2902. ;.....
  2903. ;
  2904. ;
  2905. KMDTOT:    CALL    ILPRTQ
  2906.     DB    '++ Time out receiving filename ++',CR,LF,0
  2907. ;...
  2908. ;
  2909. ;
  2910. KMDXFR:    MVI    B,1        ; Make sure sender has stopped
  2911.     CALL    RECV
  2912.     JNC    KMDXFR        ; If not, wait until all sending stops
  2913.     MVI    A,NAK        ; Tell sender it was not successful
  2914.     CALL    SEND
  2915.     LDA    RCVTRY        ; Increment the error counter
  2916.     INR    A
  2917.     STA    RCVTRY
  2918.     CPI    33        ; Same as value in RKMD2
  2919.     JC    RKMD3        ; Send a NAK and tell him to try again
  2920.     JMP    ABORT        ; Else abort
  2921. ;.....
  2922. ;
  2923. ;          end of KMD get batch file name
  2924. ;-----------------------------------------------------------------------
  2925. ;            MODEM7 geta batch file name
  2926. ;
  2927. GETNM:    PUSH    H
  2928. ;
  2929. GETNM1:    MVI    A,0FFH
  2930.     STA    FLTRFLG
  2931.     MVI    C,0        ; Initialize checksum
  2932.     LXI    H,FCB+1
  2933. ;
  2934. NAMELPG:MVI    B,5
  2935.     CALL    RECV        ; Get the character
  2936.     PUSH    B
  2937.     PUSH    PSW
  2938. ;
  2939.     MVI    A,0FFH        ; Set the TIMFLG
  2940.     STA    TIMFLG
  2941. ;
  2942.     MVI    B,1
  2943.     CALL    RECV
  2944. ;
  2945.     XRA    A
  2946.     STA    TIMFLG
  2947. ;
  2948.     POP    PSW
  2949.     POP    B
  2950.     JNC    GETNM3
  2951.     CALL    ILPRTQ
  2952.     DB    'Time out receiving filename',CR,LF,0
  2953.     JMP    GCKSER
  2954. ;
  2955. GETNM3:    CPI    EOT        ; If EOT, then no more files
  2956.     JZ    GNRET
  2957.     CPI    EOFCHAR        ; Got end of name
  2958.     JZ    ENDNAME
  2959.     PUSH    PSW
  2960.     PUSH    B
  2961.     CALL    SNDACK
  2962.     POP    B
  2963.     POP    PSW
  2964.     MOV    M,A        ; Put name in FCB
  2965.     INX    H        ; Get next character
  2966.     MOV    A,L        ; Don not let noise cause overflow..
  2967.     CPI    7FH        ; Into the program area.
  2968.     JZ    GCKSER
  2969.     JMP    NAMELPG
  2970. ;
  2971. ENDNAME:XRA    A
  2972.     STA    FLTRFLG
  2973.     MOV    A,C        ; Send checksum
  2974.     MOV    D,C
  2975.     CALL    SEND
  2976. ;
  2977. NMLP1:    MVI    B,5        ; Wait up to 5 second to see if..
  2978.     CALL    RECV        ; The checksum is good
  2979.     CPI    OKNMCH        ; Yes if 'OKNMCH' sent
  2980.     JZ    GNRET
  2981.     CMP    D
  2982.     JZ    NMLP1        ; In case it is echo of send
  2983.     CPI    CR
  2984.     JZ    NMLP1
  2985.     CPI    LF
  2986.     JZ    NMLP1
  2987. ;
  2988. GCKSER:    LXI    H,FCB        ; Clear FCB (except drive) since it..
  2989.     CALL    INITFCB1    ; Might be damaged.
  2990.     CALL    ILPRTQ
  2991.     DB    CR,LF,'**  Checksum error  **',CR,LF,0
  2992.     XRA    A
  2993.     STA    FLTRFLG
  2994.     CALL    HSNAK        ; Do handshaking over
  2995.     JMP    GETNM1
  2996. ;
  2997. GNRET:    PUSH    PSW
  2998.     XRA    A
  2999.     STA    FLTRFLG
  3000.     POP    PSW
  3001.     POP    H
  3002.     RET
  3003. ;
  3004. HSNAK:    MVI    E,180        ; 3 minute wait for file name
  3005.     XRA    A
  3006.     STA    FLTRFLG
  3007. ;
  3008. HSNAK1:    CALL    CKABORT        ; Want to abort?
  3009.     MVI    A,NAK        ; Send 'NAK' until receiving 'ACK'
  3010.     CALL    SEND
  3011.     MVI    B,1        ; Wait up to 1 second for a character
  3012.     CALL    RECV
  3013.     CPI    ACK        ; 'ACK' is what we were waiting for
  3014.     RZ
  3015.     DCR    E
  3016.     JNZ    HSNAK1
  3017.     JMP    ABORT        ; Back to command line
  3018. ;.....
  3019. ;
  3020. ;
  3021. TNMBUF:    MVI    A,1        ; Call from 'SNDFL' only once.
  3022.     STA    FSTFLG
  3023.     XRA    A
  3024.     STA    FILECT
  3025.     CALL    SCAN
  3026.     LXI    H,NAMEBUF
  3027.     SHLD    NBSAVE        ; Save address of 1st name
  3028. ;
  3029. TNLP1:    CALL    TRTOBUF
  3030.     LXI    H,FCB
  3031.     LXI    D,FCBBUF
  3032.     CALL    CMDLINE        ; Parse name to CP/M format
  3033. ;
  3034. TNLP2:    CALL    MFNAM        ; Search for names (wildcard format)
  3035.     JC    NEXTNM
  3036.     MVI    C,FILSIZ
  3037.     LXI    D,FCB
  3038.     CALL    BDOS
  3039.     LHLD    FCB+33        ; Get number of records
  3040.     MOV    A,H
  3041.     ORA    L
  3042.     JZ    TNLP2        ; If no records, don't copy this file
  3043.     LDA    FCB+10        ; If CP/M 2 $sys file..
  3044.     ANI    80H        ; Do not send
  3045.     JNZ    TNLP2
  3046.     LHLD    NBSAVE        ; Get name
  3047.     LXI    D,FCB        ; Move it to FCB
  3048.     XCHG
  3049.     MVI    B,12
  3050.     CALL    MOVE
  3051.     XCHG
  3052.     SHLD    NBSAVE        ; Addressof next name
  3053.     LXI    H,FILECT    ; Count files found
  3054.     INR    M
  3055.     JMP    TNLP2
  3056. ;.....
  3057. ;
  3058. ;
  3059. NEXTNM:    LXI    H,NAMECT    ; Count names found
  3060.     DCR    M
  3061.     JNZ    TNLP1
  3062.     LXI    H,NAMEBUF    ; Save start of buffer
  3063.     SHLD    NBSAVE
  3064.  
  3065. ;~this limit is an antique.  allow up to FFh (256 files) by deleting
  3066. ; this routine
  3067. ;    LDA    FILECT
  3068. ;    CPI    64+1        ; No more than 64 transfers
  3069. ;    RC
  3070. ;    MVI    A,64        ; Only transfer first 64
  3071. ;    STA    FILECT
  3072.     RET
  3073. ;.....
  3074. ;
  3075. ;
  3076. ; Tells when buffer is opened/closed for memory save to write on disk
  3077. ;
  3078. BUFMS:    CALL    ILPRT
  3079.     DB    CR,LF,'** Memory buffer ',0
  3080.     LDA    SAVEFLG
  3081.     ORA    A
  3082.     JZ    BUFMS1
  3083.     CALL    ILPRT
  3084.     DB    'open **',CR,LF,LF,';',0
  3085.     RET
  3086. ;
  3087. BUFMS1:    CALL    ILPRT
  3088.     DB    'closed **',CR,LF,LF,0
  3089.     RET
  3090. ;
  3091. BUFMS2:    CALL    ILPRT
  3092.     DB    CR,LF,'** Memory buffer available **',CR,LF,0
  3093.     RET
  3094. ;.....
  3095. ;
  3096. ;
  3097. ; Checks to see if the modem has a character ready
  3098. ;
  3099. RCVRDY:    CALL    I$MDCTL1    ; Get the status register
  3100.     CALL    A$MDRCV        ; AND it with the receive ready flag
  3101.     JMP    C$MDRCV        ; Compare to see if it has a character
  3102. ;.....
  3103. ;
  3104. ;
  3105. ; Checks to see if the modem is ready to receive a character
  3106. ;
  3107. SNDRDY:    CALL    I$MDCTL1
  3108.     CALL    A$MDSND        ; Isolate the
  3109.     JMP    C$MDSND
  3110. ;.....
  3111. ;
  3112. ;
  3113. SNDNOW:    CALL    EXITTEST    ; See if want to quit now
  3114.     CALL    SNDRDY        ; Ready to send a character?
  3115.     JNZ    SNDNOW        ; If not ready wait some more
  3116.     RET            ; Exit if ready
  3117. ;.....
  3118. ;
  3119. ;
  3120. ; Checks to see if the modem TxE output buffer is empty
  3121. ;
  3122. SNDTXE:    CALL    I$MDTXE        ; Get the status register with TxE flag
  3123.     CALL    A$MDTXE        ; Isolate the TxE flag
  3124.     JMP    C$MDTXE        ; Compare to see if it is empty
  3125.  
  3126. ;.....
  3127. ;
  3128. ;
  3129. ; Send the log-on message when requested
  3130. ;
  3131. SNDLOG:    LHLD    LOGPTR        ; 'HL' points to start of logon message
  3132.     CALL    LOGLP
  3133.     JMP    TERML
  3134. ;...
  3135. ;
  3136. ;
  3137. LOGLP:    CALL    SNDNOW        ; Wait until modem is ready
  3138.     MOV    A,M        ; Get logon byte
  3139.     ORA    A        ; Last character in string is '0'
  3140.     RZ            ; Return if finished
  3141.     CALL    O$MDDATP    ; Otherwise send the character
  3142.     CALL    LOGLP1        ; Check for echo character and display it
  3143.     INX    H        ; Next location in message
  3144.     JMP    LOGLP        ; Get next character
  3145. ;.....
  3146. ;
  3147. ;
  3148. LOGLP1:    CALL    J$INMDM        ; Get the echo character
  3149.     RC            ; If no character don't try to print
  3150.     ANI    7FH        ; Strip off any parity
  3151.     JMP    TYPE        ; Display the character, then return
  3152. ;.....
  3153. ;
  3154. ;
  3155. ; Check for exit character
  3156. ;
  3157. EXITTEST:
  3158.     CALL    STAT        ; Anything on keyboard?
  3159.     RZ
  3160.     CALL    KEYIN        ; Get it, then
  3161.     MOV    B,A        ; Save to protect the 'A' reg.
  3162. ;
  3163. EXITTST1:
  3164.     LDA    EXITCHR        ; Exit character
  3165.     CMP    B        ; Asking to exit to menu?
  3166.     RNZ            ; If not, back to work
  3167.     POP    H        ; Clear the stack from 'CALL'
  3168.     CALL    CRLF
  3169.     JMP    MENU0
  3170. ;.....
  3171. ;
  3172. ;
  3173. LSTMS:    CALL    ILPRT
  3174.     DB    'Printer buffer is ',0
  3175.     LDA    LISTFLG        ; See if printer should be on or off
  3176.     ORA    A
  3177.     JZ    LSTMS1
  3178.     CALL    ILPRT
  3179.     DB    'ON',CR,LF,0
  3180.     RET
  3181. ;...
  3182. ;
  3183. ;
  3184. LSTMS1:    CALL    ILPRT
  3185.     DB    'OFF',CR,LF,0
  3186.     RET
  3187. ;.....
  3188. ;
  3189. ;
  3190. ; Special function key handler.  This routine is entered with the
  3191. ; function key number (0..9) in A.  The corresponding function key is
  3192. ; then transmitted.
  3193. ;
  3194. SNDFK:    PUSH    H        ; Save register
  3195.     LXI    H,FNCTBL    ; Point to function key codes
  3196.     DCR    A        ; Table is 1-0 rather than 0-9
  3197.     CPI    0FFH
  3198.     JNZ    SFK1
  3199.     MVI    A,9
  3200. ;
  3201. SFK1:    CMP    M        ; This the one?
  3202.     INX    H        ; Point to next byte
  3203.     JNZ    SFK1        ; Loop until found
  3204.     CALL    LOGLP        ; Send the character
  3205.     POP    H
  3206.     XRA    A        ; Reset the function flag
  3207.     STA    FNKFLG
  3208.     JMP    TERML
  3209. ;.....
  3210. ;
  3211. ;
  3212. ; Send keyboard character to modem, also to console if "E" or "L".  If
  3213. ; "E", include a LF after a CR, if either, include a LF if toggle is set.
  3214. ;
  3215. NTOG:    CALL    J$SNDCHR    ; Send char. in 'B' to modem
  3216.     LDA    LOCFLG        ; Using the local mode?
  3217.     ORA    A
  3218.     JNZ    LTYPE        ; If yes, show the character
  3219.     LDA    ECHOFLG        ; In echo mode?
  3220.     ORA    A
  3221.     JZ    TERML        ; If not, see if it was a 'CR'
  3222. ;
  3223. LTYPE:    MOV    A,B        ; Get the character back
  3224.     CALL    TYPE        ; Show on the local CRT
  3225.     CALL    CKSAV        ; To store local if buffer open
  3226.     CALL    CHKPRNT        ; Put on printer if running
  3227. ;
  3228. CHKCR:    MVI    A,CR
  3229.     CMP    B
  3230.     JNZ    TERML        ; If not CR, all done
  3231.     LDA    ECHOFLG        ; In echo mode now?
  3232.     ORA    A
  3233.     JNZ    CHKLF        ; If yes add a line feed
  3234.     LDA    ADDLFD        ; Going to add a line feed in 'L' mode?
  3235.     ORA    A
  3236.     JZ    TERM        ; If not, exit
  3237. ;
  3238. CHKLF:    MVI    B,LF
  3239.     JMP    NTOG        ; Send locally and to remote
  3240. ;.....
  3241. ;
  3242. ;
  3243. TERML:    CALL    RCVRDY        ; Character on the receive-ready line?
  3244.     JNZ    TERM        ; If not, exit
  3245.     CALL    I$MDDATP    ; Get the character
  3246.     ANI    7FH        ; Strip parity
  3247.     JZ    TERM        ; Don't bother with nulls
  3248.     CPI    RUB
  3249.     JZ    TERM        ; Don't bother with rubouts for fill
  3250.     MOV    B,A        ; Store temporarily
  3251.     LDA    IGNRCTL        ; Ignoring all but necessary CTL-chars?
  3252.     ORA    A
  3253.     JZ    GIVLF        ; If zero, display them all
  3254.     MOV    A,B
  3255.     CPI    ' '
  3256.     JNC    GIVLF        ; Display all printing characters
  3257.     CPI    'G'-40H        ; ^g for bell
  3258.     JC    TERM        ; Ignore ctl-characters less than ^g
  3259.     CPI    CR+1
  3260.     JNC    TERM        ; Ignore ctl-characters more than ^m
  3261. ;
  3262. GIVLF:    MOV    A,B        ; Get the character back
  3263.     CALL    TYPE        ; Show it on the CRT
  3264.     CALL    CKSAV        ; Saving for disk file?
  3265.     CALL    CHKPRNT        ; Printer running?
  3266.     LDA    ECHOFLG        ; Going to echo the character?
  3267.     ORA    A
  3268.     JZ    NOECH        ; If not, do not resend
  3269.     CALL    J$SNDCHR    ; Send char. in 'B' to modem
  3270. ;
  3271. NOECH:    MVI    A,CR
  3272.     CMP    B        ; Was it a 'CR' just now?
  3273.     JNZ    TERM        ; If not, all done so exit
  3274.     LDA    ECHOFLG        ; In the echo mode?
  3275.     ORA    A
  3276.     JZ    TERM
  3277.     CALL    SNDNOW        ; Modem ready for a character?
  3278.     MVI    B,LF
  3279.     JMP    GIVLF        ; Send lf
  3280. ;.....
  3281. ;
  3282. ;
  3283. ; See if putting character into memory for a disk file
  3284. ;
  3285. CKSAV:    LDA    SAVEFLG        ; Saving to disk?
  3286.     ORA    A
  3287.     RZ            ; If not, exit
  3288.     LHLD    HLSAV        ; Get last address
  3289.     MOV    M,B        ; Store this character
  3290.     INX    H        ; Increment for next character
  3291.     SHLD    HLSAV        ; Remember that location
  3292.     MVI    A,LF
  3293.     CMP    B        ; This character a line feed?
  3294.     JNZ    CKSAV1        ; Type ";" after each line feed..
  3295.     MVI    A,CR        ; Insure at left column with a lf
  3296.     CALL    TYPE
  3297.     CALL    TYPESCLN    ; Show a ';' on CRT
  3298. ;
  3299. CKSAV1:    MOV    A,H
  3300.     LXI    H,BUFTOP    ; Get the address at top of buffer
  3301.     CMP    H
  3302.     CZ    DCTLS        ; If different, buffer is not full
  3303.     RET
  3304. ;.....
  3305. ;
  3306. ;
  3307. ; Memory buffer is full, send a X-OFF (CTL-S, DC3), save any extra in-
  3308. ; coming characters, then dump to disk, reset buffer to include those
  3309. ; characters.
  3310. ;
  3311. DCTLS:    CALL    SNDNOW        ; Modem ready for a character?
  3312.     MVI    A,XOFF        ; Send a ctl-s to stop remote computer
  3313.     CALL    O$MDDATP
  3314.     CALL    CHKPRNT        ; Insure character gets to the printer
  3315.     LXI    H,BUFFDSK    ; Address of aux. buffer
  3316.     CALL    GTDSK        ; Put any extra chars. into aux. buffer
  3317.     PUSH    D        ; Save the number of aux. chars.
  3318.     MVI    A,1        ; Show we put something in the buffer..
  3319.     STA    WRFLG        ; To protect erasing an empty file
  3320.     LHLD    HLSAV        ; Find current end of buffer
  3321.     CALL    WRDSK1        ; Write the records
  3322.     POP    D        ; Get aux. char. count back
  3323.     LXI    H,BUFFER    ; Start again at bottom of buffer
  3324.     XRA    A        ; Set 'A' to zero
  3325.     CMP    D        ; See if any count in 'D'
  3326.     JZ    DCTLQ        ; If nothing, exit and continue
  3327.     LXI    B,BUFFDSK    ; Address of aux. buffer
  3328. ;
  3329. ;
  3330. ; Move the characters from the auxiliary buffer to the main buffer and
  3331. ; display
  3332. ;
  3333. DCTLS1:    LDAX    B        ; Get the character there
  3334.     MOV    M,A        ; Store in main buffer
  3335.     CALL    TYPE        ; Show on CRT
  3336.     PUSH    H
  3337.     PUSH    D
  3338.     PUSH    B
  3339.     PUSH    PSW
  3340.     MOV    B,A
  3341.     CALL    CHKPRNT
  3342.     POP    PSW        ; Get the character again
  3343.     POP    B
  3344.     POP    D
  3345.     POP    H
  3346.     CPI    LF
  3347.     CZ    TYPESCLN
  3348.     INX    H        ; Next buffer position
  3349.     INX    B        ; Next aux. buffer position
  3350.     DCR    D        ; One less to go
  3351.     JNZ    DCTLS1        ; If not zero, keep going
  3352.     MVI    B,0        ; Falls through to 'CHKPRNT' next
  3353. ;
  3354. DCTLQ:    SHLD    HLSAV        ; Next position to store in buffer
  3355.     CALL    SNDNOW
  3356.     MVI    A,XON        ; Allow remote input to continue
  3357.     JMP    O$MDDATP
  3358. ;.....
  3359. ;
  3360. ;
  3361. ; Gets any incoming characters after sending an XOFF and stores at HL.
  3362. ; Returns with number of characters stored in D-reg.
  3363. ;
  3364. GTDSK:    MVI    D,0        ; Character count in buffer
  3365.     MVI    E,128        ; Maximum for buffer length
  3366. ;
  3367. GTDSK1:    CALL    J$INMDM        ; Get any character
  3368.     RC            ; If none, finished
  3369.     CPI    ' '
  3370.     JNC    GTDSK2        ; If greater, handle normally
  3371.     CPI    CR+1        ; Ignore ctl-chars. > cr
  3372.     JNC    GTDSK1
  3373. ;
  3374. GTDSK2:    MOV    M,A        ; Store
  3375.     INX    H        ; Next buffer location to use
  3376.     INR    D        ; Increment character count
  3377.     DCR    E        ; Room for one less
  3378.     JNZ    GTDSK1        ; If room in buffer, keep going
  3379.     RET            ; If buffer is filled, exit
  3380. ;.....
  3381. ;
  3382. ;
  3383. ; See if printing the character, if yes, put into buffer
  3384. ;
  3385. CHKPRNT:LDA    LISTFLG        ; Printer in use?
  3386.     ORA    A
  3387.     RZ            ; Return if not
  3388.     LHLD    HLSAV1        ; Get input address
  3389.     MOV    M,B        ; Save this character there
  3390.     INX    H        ; Increment the buffer location
  3391.     SHLD    HLSAV1        ; Store for next character
  3392.     LDA    MAXRAM        ; See if at top of buffer yet
  3393.     CMP    H
  3394.     CZ    PCTLS        ; If different, buffer is not full
  3395.     RET
  3396. ;.....
  3397. ;
  3398. ;
  3399. ; Memory buffer is full, send a X-OFF (CTL-S, DC3), save any extra in-
  3400. ; coming characters, then dump to disk, reset buffer to include those
  3401. ; characters.
  3402. ;
  3403. PCTLS:    CALL    SNDNOW        ; Wait until modem is ready
  3404.     MVI    A,XOFF        ; Send a ctl-s to stop remote computer
  3405.     CALL    O$MDDATP
  3406.     LXI    H,BUFFPNT    ; Address of aux. buffer
  3407.     CALL    GTDSK        ; Put any extra chars. into aux. buffer
  3408.     MOV    A,D        ; Get the aux. buffer char. count
  3409.     STA    DSTORE        ; Save for later
  3410.     RET
  3411. ;.....
  3412. ;
  3413. ;
  3414. ; Output has now caught up to the input and both are at top of buffer
  3415. ;
  3416. PCTLS1:    LDA    DSTORE        ; Get the aux. buffer char. count
  3417.     MOV    D,A        ; Put into 'D' reg.
  3418.     XRA    A        ; Set 'A' to zero
  3419.     CMP    D        ; See if any count in 'D'
  3420.     LXI    H,PBUFF        ; Address at start of printer buffer
  3421.     JZ    PCTLQ        ; If nothing, exit and continue
  3422.     LXI    B,BUFFPNT    ; Address of aux. buffer
  3423. ;
  3424. ;
  3425. ; Move the characters from the auxiliary buffer to the main buffer and
  3426. ; display.
  3427. ;
  3428. PCTLS2:    LDAX    B        ; Get the character there
  3429.     MOV    M,A        ; Store in main buffer
  3430.     CALL    TYPE        ; Show on CRT
  3431.     PUSH    H
  3432.     PUSH    D
  3433.     PUSH    B
  3434.     PUSH    PSW
  3435.     MOV    B,A
  3436.     CALL    CKSAV
  3437.     POP    PSW
  3438.     POP    B
  3439.     POP    D
  3440.     POP    H
  3441.     CPI    LF
  3442.     CZ    TYPESCLN
  3443.     INX    H        ; Next buffer position
  3444.     INX    B        ; Next aux. buffer position
  3445.     DCR    D        ; One less to go
  3446.     JNZ    PCTLS2        ; If not zero, keep going
  3447. ;
  3448. PCTLQ:    SHLD    HLSAV1        ; Next position to store in buffer
  3449.     LXI    H,PBUFF        ; Start of buffer location
  3450.     SHLD    HLSAV2        ; Output to start of buffer
  3451.     CALL    SNDNOW        ; Wait until modem is ready
  3452.     MVI    A,XON        ; Send start character..
  3453.     JMP    O$MDDATP    ; To remote computer, back to work
  3454. ;.....
  3455. ;
  3456. ;
  3457. ; List the character on the printer if it is ready, then see if at the
  3458. ; top of the buffer.
  3459. ;
  3460. GOLIST:    CALL    $-$        ; Get the printer status - filled in..
  3461.     ORA    A        ; By 'INITADR' routine
  3462.     RZ            ; Return if printer not ready
  3463. ;
  3464. ;
  3465. ; Compare input and output pointers.  If at same address, nothing to
  3466. ; print.
  3467. ;
  3468.     CALL    CMP$I$O        ; If the same, nothing to print
  3469.     RZ
  3470. ;
  3471. ;
  3472. ; If not the same, print the character
  3473. ;
  3474.     PUSH    H        ; Save current buffer address
  3475.     MOV    E,M        ; Get the character to display
  3476.     MVI    C,LIST        ; List rutine
  3477.     CALL    BDOS
  3478.     POP    H        ; Restore current buffer address
  3479.     INX    H        ; Increment pointer for next position
  3480.     SHLD    HLSAV2        ; Store for next time through here
  3481. ;
  3482. ;
  3483. ; See if the output is at the end of the buffer now.  If yes, go put
  3484. ; the auxiliary characters into the start of the buffer.
  3485. ;
  3486.     LDA    MAXRAM        ; Check for end of buffer area
  3487.     CMP    H
  3488.     JZ    PCTLS1        ; If at end, restore aux. buffer
  3489. ;
  3490. ;
  3491. ; See if the output has caught up with the input - if so, reset the
  3492. ; pointers to the start of the buffer
  3493. ;
  3494.     CALL    CMP$I$O
  3495.     RNZ            ; If not, back to work
  3496.     LXI    H,PBUFF        ; If output caught input, reset both..
  3497.     SHLD    HLSAV1        ; To bottom of buffer to start over
  3498.     SHLD    HLSAV2
  3499.     RET
  3500. ;.....
  3501. ;
  3502. ;
  3503. ; Compare the input and output pointers to see if the same address
  3504. ;
  3505. CMP$I$O:LHLD    HLSAV1        ; Get input pointer address
  3506.     XCHG            ; Put in 'DE'
  3507.     LHLD    HLSAV2        ; Get output pointer address
  3508.     MOV    A,H
  3509.     CMP    D
  3510.     RNZ            ; Return if different
  3511.     MOV    A,L
  3512.     CMP    E
  3513.     RET
  3514. ;.....
  3515. ;
  3516. ;
  3517. GTMAX:    LDA    BDOS+2        ; 'MSP' of 'BDOS' address
  3518.     SBI    8        ; 'CCP' is 2k or 8 pages
  3519.     STA    MAXRAM        ; Save
  3520.     RET
  3521. ;.....
  3522. ;
  3523. ;
  3524. ; This subroutine will loop until the modem receives a character or 100
  3525. ; milliseconds.  It returns with a character in 'A' reg. but if no char-
  3526. ; acter was recieved it returns after a timeout with carry set.
  3527. ;
  3528. INMDM:    PUSH    H
  3529.     LXI    H,63        ; About 100 milliseconds
  3530.     CALL    FIXCNT
  3531.     MOV    B,H        ; Delay is in 'HL'
  3532.     MOV    C,L        ; Transfer to 'BC'
  3533.     POP    H        ; Get original value of 'HL' back
  3534. ;
  3535. INMDM1:    CALL    RCVRDY        ; See if there is a character ready
  3536.     JNZ    INMDM2        ; If no character, exit
  3537.     CALL    I$MDDATP    ; Get the character
  3538.     ANI    7FH        ; Strip off any parity
  3539.     RET            ; Return with character in 'A' reg.
  3540. ;
  3541. INMDM2:    DCX    B        ; Otherwise keep timing
  3542.     MOV    A,B
  3543.     ORA    C
  3544.     JNZ    INMDM1        ; Loop until timeout if needed
  3545.     STC            ; Shows a timeout occured
  3546.     RET
  3547. ;.....
  3548. ;
  3549. ;
  3550. ;=======================================================================
  3551. ;             WRITE BUFFER TO DISK
  3552. ;
  3553. ; Make sure this record is included in the count.
  3554. ;
  3555. WRDSK:    LHLD    HLSAV
  3556.     MVI    M,EOFCHAR    ; Ascii file, store end-of-file char.
  3557.     LXI    D,127
  3558.     DAD    D
  3559. ;
  3560. WRDSK1:    LXI    D,-(BUFFER)    ; Subtract the start of the buffer..
  3561.     DAD    D        ; By adding a minus number to buffer end
  3562.     MOV    A,L        ; Divide hl by 128..
  3563.     ORA    A
  3564.     RAL            ; To get the..
  3565.     MOV    L,H        ; Number of records
  3566.     MVI    H,0
  3567.     PUSH    PSW
  3568.     DAD    H
  3569.     POP    PSW
  3570.     MVI    A,0
  3571.     ADC    L
  3572.     MOV    L,A        ; Number of records in 'HL'
  3573. ;
  3574. ;
  3575. ; See if buffer is empty.  If yes, see if we need to erase an empty
  3576. ; file or have already written something.
  3577. ;
  3578.     LXI    D,BUFFER
  3579.     LDAX    D
  3580.     CPI    EOFCHAR        ; 'EOF' in first address means..
  3581.     JNZ    WRDSK2        ; Nothing in buffer to write
  3582.     LDA    WRFLG        ; First time by this way?
  3583.     ORA    A
  3584.     JZ    NOWRITE        ; If yes, show erasing file
  3585.     RET            ; Otherwise go close file
  3586. ;.....
  3587. ;
  3588. ;
  3589. ; Write to disk.  Start from BUFFER (in 'DE').    Number of records to
  3590. ; write in 'HL'.
  3591. ;
  3592. WRDSK2:    MVI    C,STDMA
  3593.     CALL    BDOSRT
  3594.     PUSH    D
  3595.     MVI    C,WRITE
  3596.     LXI    D,FCB3        ; Location of filename to write to
  3597.     CALL    BDOSRT
  3598.     POP    D
  3599.     ORA    A
  3600.     JNZ    WRERRSP        ; Error if disk is full ** special patch
  3601.     XCHG            ; Put the current address in 'HL'..
  3602.     PUSH    D        ; And number of records left in..
  3603.     LXI    D,128        ; For now
  3604.     DAD    D        ; Add for next record write, now in 'HL'
  3605.     POP    D        ; Restore number of records left
  3606.     XCHG            ; Records to 'HL' again, address to 'DE'
  3607.     DCX    H        ; One less record left
  3608.     MOV    A,H
  3609.     ORA    L        ; Done writing when 'H' and 'H' both zero
  3610.     JNZ    WRDSK2        ; Otherwise do another disk write
  3611.     RET
  3612. ;.....
  3613. ;
  3614. ;
  3615. ; Error while writing a record, show why it is aborting
  3616. ;
  3617. WRERR:    CALL    CLOSFIL        ; Close the current file
  3618.     MVI    C,CANCEL    ; Send cancel char. to sending station
  3619.     CALL    SEND        ; First cancel character
  3620.     CALL    SEND        ; Second cancel character
  3621.     CALL    SEND        ; Third, to help them cancel too
  3622. ;
  3623. WRERR1:    CALL    ERXIT        ; Also will reset stack
  3624.     DB    '++ DISK FULL, SAVING PARTIAL FILE ++','$'
  3625. ;.....
  3626. ;
  3627. ;
  3628. ; Patch to close FCB3 instead of FCB when in disk-capture mode.
  3629. ;
  3630. WRERRSP:CALL    WRFIL2        ; Close FCB3 file
  3631.     JMP    WRERR1        ; Go write 'DISK FULL' message and quit
  3632. ;.....
  3633. ;
  3634. ;
  3635. ; If no data to store on the disk, close the empty file and erase it
  3636. ;
  3637. NOWRITE:CALL    WRFIL2        ; Close the empty file
  3638.     CALL    NOASK        ; Erase the empty file
  3639.     CALL    ILPRT
  3640.     DB    CR,LF,'++ Nothing to save, erasing file ++'
  3641.     DB    CR,LF,BELL,0
  3642.     LDA    DONEFLG        ; Is the exit flag set?
  3643.     ORA    A
  3644.     JNZ    EXIT2        ; If yes, all done now
  3645.     MVI    A,1        ; Set the flag
  3646.     STA    ABORTFLG    ; Insures returning to command mode
  3647.     JMP    DONETA        ; Reset any flags, return to menu
  3648. ;.....
  3649. ;
  3650. ;
  3651. ; Show you are in memory-save for disk write
  3652. ;
  3653. TYPESCLN:
  3654.     MVI    A,';'
  3655.     JMP    TYPE        ; Show on CRT, return
  3656. ;.....
  3657. ;
  3658. ;
  3659. ; Save the registers, call BDOS then restore the registers
  3660. ;
  3661. BDOSRT:    PUSH    B
  3662.     PUSH    D
  3663.     PUSH    H
  3664.     CALL    BDOS
  3665.     POP    H
  3666.     POP    D
  3667.     POP    B
  3668.     RET
  3669. ;.....
  3670. ;
  3671. ;
  3672. INITFCB:MVI    M,0        ; Zeroes the drive to the 'A' drive
  3673. ;
  3674. INITFCB1:            ; Does not alter disk drive
  3675.     INX    H
  3676.     MVI    B,11        ; Spaces out filename area
  3677. ;
  3678. LOOP11:    MVI    M,' '
  3679.     INX    H
  3680.     DCR    B
  3681.     JNZ    LOOP11        ; Nulls out the data area with zeroes
  3682.     MVI    B,21
  3683. ;
  3684. LOOP21:    MVI    M,0
  3685.     INX    H
  3686.     DCR    B
  3687.     JNZ    LOOP21
  3688.     RET
  3689. ;.....
  3690. ;
  3691. ;
  3692. ; Scans CMDBUF counting names and putting delimiter (space) after last
  3693. ; name
  3694. ;
  3695. SCAN:    PUSH    H
  3696.     LXI    H,NAMECT
  3697.     MVI    M,0
  3698.     LXI    H,CMDBUF+1    ; Find end of cmd line..
  3699.     MOV    C,M        ; And put space there.
  3700.     MVI    B,0
  3701.     LXI    H,CMDBUF+2
  3702.     DAD    B
  3703.     MVI    M,' '
  3704.     LXI    H,CMDBUF+1
  3705.     MOV    B,M
  3706.     INR    B
  3707.     INR    B
  3708. ;
  3709. SCANL1:    INX    H
  3710.     DCR    B
  3711.     JZ    DNSCAN
  3712.     MOV    A,M
  3713.     CPI    ' '
  3714.     JNZ    SCANL1
  3715. ;
  3716. SCANL2:    INX    H        ; Eat extra spaces
  3717.     DCR    B
  3718.     JZ    DNSCAN
  3719.     MOV    A,M
  3720.     CPI    ' '
  3721.     JZ    SCANL2
  3722.     SHLD    BGNMS        ; Save start of names in cmdbuf
  3723.     INR    B
  3724.     DCX    H
  3725. ;
  3726. SCANL3:    INX    H
  3727.     DCR    B
  3728.     JZ    DNSCAN
  3729.     MOV    A,M
  3730.     CPI    ' '
  3731.     JNZ    SCANL3
  3732.     LDA    NAMECT        ; Counts names
  3733.     INR    A
  3734.     STA    NAMECT
  3735. ;
  3736. SCANL4:    INX    H        ; Eat spaces
  3737.     DCR    B
  3738.     JZ    DNSCAN
  3739.     MOV    A,M
  3740.     CPI    ' '
  3741.     JZ    SCANL4
  3742.     JMP    SCANL3
  3743. ;.....
  3744. ;
  3745. ;
  3746. DNSCAN:    MVI    M,' '        ; Space after last char
  3747.     POP    H
  3748.     RET
  3749. ;.....
  3750. ;
  3751. ;
  3752. ; Places next name in buffer so 'CMDLINE' may parse it
  3753. ;
  3754. TRTOBUF:LHLD    BGNMS
  3755.     MVI    B,0
  3756.     LXI    D,FCBBUF+2
  3757. ;
  3758. TBLP:    MOV    A,M
  3759.     CPI    ' '
  3760.     JZ    TRBFEND
  3761.     STAX    D
  3762.     INX    H
  3763.     INX    D
  3764.     INR    B        ; Count chars in name
  3765.     JMP    TBLP
  3766. ;.....
  3767. ;
  3768. ;
  3769. TRBFEND:INX    H
  3770.     MOV    A,M        ; Eat extra spaces
  3771.     CPI    ' '
  3772.     JZ    TRBFEND
  3773.     SHLD    BGNMS
  3774.     LXI    H,FCBBUF+1    ; Put # chars before name
  3775.     MOV    M,B
  3776.     RET
  3777. ;.....
  3778. ;
  3779. ;
  3780. CKCPM2:    MVI    C,CPMVER    ; Bdos 12 -- version number -- cp/m 2.2?
  3781.     CALL    BDOS
  3782.     ORA    A
  3783.     RZ
  3784.     MVI    C,STDMA
  3785.     LXI    D,TBUF
  3786.     CALL    BDOS
  3787.     MVI    C,SRCHF
  3788.     LXI    D,FCB
  3789.     CALL    BDOS
  3790.     CPI    0FFH
  3791.     RZ
  3792. ;
  3793.     CALL    GETADD
  3794.     LXI    D,9
  3795.     DAD    D        ; Point to R/O attribute byte
  3796.     MOV    A,M
  3797.     ANI    80H        ; Test most significant byte
  3798.     JNZ    MKCHG        ; If set, make change
  3799.     INX    H        ; Check system attribute byte
  3800.     MOV    A,M
  3801.     ANI    80H
  3802.     RZ            ; Not $SYS or $R/O attribute
  3803.     DCX    H
  3804. ;
  3805. MKCHG:    LXI    D,-8
  3806.     DAD    D        ; Point HL to filename + 1
  3807.     LXI    D,FCB+1        ; Move directory name to FCB..
  3808.     MVI    B,11        ; Without changing drive.
  3809.     CALL    MOVE
  3810.     LXI    H,FCB+9        ; R/O attribute
  3811.     MOV    A,M
  3812.     ANI    7FH        ; Strip R/O attribute
  3813.     MOV    M,A
  3814.     INX    H        ; System attribute
  3815.     MOV    A,M
  3816.     ANI    7FH
  3817.     MOV    M,A
  3818.     LXI    D,FCB
  3819.     MVI    C,30        ; Set new attributes in directory
  3820.     CALL    BDOS
  3821.     LXI    H,FCB        ; Change name to type "BAK"
  3822.     LXI    D,FCB2
  3823.     MVI    B,9        ; Move drive and name (not type)
  3824.     CALL    MOVE
  3825.     LXI    H,75H        ; Start of type in FCB2
  3826.     MVI    M,'B'
  3827.     INX    H
  3828.     MVI    M,'A'
  3829.     INX    H
  3830.     MVI    M,'K'
  3831.     LXI    D,FCB2
  3832.     MVI    C,ERASE        ; Erase any previous backups
  3833.     CALL    BDOS
  3834.     LXI    H,FCB2        ; FCB2 drive field should..
  3835.     MVI    M,0        ; 0 for rename.
  3836.     LXI    D,FCB
  3837.     MVI    C,23        ; Rename
  3838.     JMP    BDOS
  3839. ;.....
  3840. ;
  3841. ;
  3842. ;***********************************************************************
  3843. ;
  3844. ;        RECEIVE A RECORD FROM SENDING STATION
  3845. ;
  3846. ;***********************************************************************
  3847. ;
  3848. ; If CRC is in effect, there is a 10-second timeout to the first SOH.
  3849. ; It then tries six more times to let the sender know the system is
  3850. ; capable of receiving a 'CRC' check.  At the end of that time a NAK is
  3851. ; sent which tells the sender to use CHECKSUM checking instead of CRC.
  3852. ; This allows automatic compatability with systems implementing CRC -
  3853. ; (Cyclic Redundancy Checking).  The search for SOH will cycle through
  3854. ; one record interval and ignore noise or characters sent by the remote
  3855. ; for any purpose (such as progress reporting).  So extraneous characters
  3856. ; that are sometimes sent by remote-end protocol will be gobbled up until
  3857. ; the first SOH.  EOT is tested only as the first returned character af-
  3858. ; ter each sector.
  3859. ;
  3860. SRCHSOH    EQU    160        ; Number of times to loop search for SOH
  3861. ;
  3862. RCVRECD:MVI    A,1
  3863.     STA    ERRCT        ; Initialize the error count
  3864. ;
  3865. RCVSQ:    CALL    CKABORT        ; Want to quit now?
  3866.     MVI    B,10-1        ; 10 seconds allowed to receive 1st char.
  3867.     LXI    D,SRCHSOH    ; Initialize loop for up to 160 secs.
  3868.     CALL    RECV        ; Get the 1st character
  3869.     JC    RCVSTOT        ; Timeout error if not rcvd in 10 seconds
  3870.     MOV    C,A        ; Save the character for now
  3871.     CPI    EOT        ; See if end of transmission
  3872.     STC            ; Set carry
  3873.     RZ            ; Return with carry set
  3874. ;
  3875. SOHLUP:    MVI    A,0FFH
  3876.     STA    CHRFLG
  3877.     STA    TIMFLG
  3878.     MOV    A,E        ; Get search count-down value
  3879.     CPI    SRCHSOH        ; See if it is the 1st returned character
  3880.     MOV    A,C        ; Get the first character now
  3881.     JZ    NORECV        ; Skip RECV routine if 1st character
  3882.     MVI    B,1
  3883.     CALL    RECV
  3884.     MOV    B,A        ; Store the character again, for a bit
  3885.     JNC    TSTSOH
  3886. ;
  3887. NORECV:    MOV    B,A
  3888.     XRA    A        ; Else set the value that forces timeout
  3889.     STA    CHRFLG
  3890. ;
  3891. TSTSOH:    XRA    A
  3892.     STA    TIMFLG
  3893.     MOV    A,B        ; Get the character back
  3894. ;
  3895.     CPI    SOH        ; See if it is SOH
  3896.     JZ    RCVSOH        ; Got SOH, get rcd # and its complement
  3897.     CPI    STX        ; See if it is STX for 1k blocks
  3898.     JZ    RCVSTX        ; Got STR, get rec # and its complement
  3899.     CPI    CANCEL
  3900.     CZ    CKCAN        ; Check to see if 1st or 2nd one
  3901. ;
  3902.     MOV    A,D
  3903.     ORA    E        ; See if counted-down to zero
  3904.     DCX    D
  3905.     JNZ    SOHLUP        ; Go around again if not
  3906. ;
  3907.     LDA    CHRFLG        ; See if timeout needs to be forced
  3908.     ORA    A
  3909.     JZ    RCVSTOT        ; Go do timeout and count them
  3910. ;
  3911.     LDA    QFLG
  3912.     ORA    A
  3913.     JZ    RCVSR
  3914. ;
  3915.     CALL    CRLF
  3916.     MOV    A,B        ; Get the character back
  3917.     CALL    HEXO        ; And display it
  3918.     CALL    ILPRT
  3919.     DB    'H received not SOH - ',0
  3920. ;
  3921. RCVPRN:    CALL    SHOWERR        ; Display error count
  3922. ;
  3923. RCVSR:    CALL    WAITQ1        ; Clear any characters from the input
  3924.     CALL    CKABORT        ; Want to stop receiving now?
  3925.     LDA    FRSTIM        ; Get first time switch
  3926.     ORA    A        ; Has first 'SOH' been received?
  3927.     MVI    A,NAK        ; Put 'NAK' in 'A' reg.
  3928.     JNZ    RCVSR1        ; Yes, then send 'NAK'
  3929. ;
  3930.     LDA    CRCFLG        ; Get 'CRC' flag
  3931.     ORA    A        ; 'CRC' in effect?
  3932.     MVI    A,NAK        ; Put 'NAK' in 'A' reg.
  3933.     JZ    RCVSR1        ; No, send the 'NAK'
  3934. ;
  3935.     MVI    A,CRC        ; Else tell sender 'CRC' is in effect
  3936.     CALL    SEND
  3937.     LDA    KFLG        ; Capable of 1k blocks?
  3938.     ORA    A
  3939.     JZ    RCVSR1        ; If yes, start with 1k request
  3940.     MVI    A,KSND        ; Tell sender we can use 1k blocks
  3941. ;
  3942. RCVSR1:    CALL    SEND        ; The 'NAK' or 'CRC' request
  3943.     LDA    ERRCT        ; Abort if we have reached error limit
  3944.     INR    A
  3945.     STA    ERRCT        ; Store for next time
  3946.     CPI    ERRLIM        ; See if at limit yet
  3947.     JC    RCVSQ        ; If not, keep going
  3948.     JMP    ABORT
  3949. ;.....
  3950. ;
  3951. ;
  3952. ; Aborts with 1 CTL-X if first time flage is not set, two otherwise
  3953. ;
  3954. CKCAN:    LDA    FRSTIM        ; First time through?
  3955.     ORA    A
  3956.     JZ    CKCAN1        ; If first time, abort and close file
  3957.     MVI    B,2        ; Maximum of 2 seconds for extra CTL-X
  3958.     CALL    RECV
  3959.     RC            ; No additional character, ignore CTL-X
  3960.     CPI    CANCEL        ; If a 2nd CTL-X, wait for 3rd
  3961.     RNZ            ; If not CTL-X, ignore
  3962.     MVI    B,2        ; Maximum of 2 seconds for extra CTL-X
  3963.     CALL    RECV
  3964.     RC            ; No additional character, ignore CTL-X
  3965.     CPI    CANCEL        ; If a 3rd CTL-X, abort and close file
  3966.     RNZ            ; If not CTL-X, ignore
  3967. ;
  3968. CKCAN1:    POP    H        ; Reset stack for  CALL  CKCAN
  3969.     JMP    ABORT        ; Go abort
  3970. ;.....
  3971. ;
  3972. ;
  3973. ; Abort and cancel any partially received file
  3974. ;
  3975. RCVSABT:LXI    SP,STACK    ; Reset the stack just in case
  3976.     CALL    CLOSFIL        ; Close the partial file
  3977.     CALL    NOASK        ; Delete partial file
  3978.     CALL    ILPRT
  3979.     DB    CR,LF,LF
  3980.     DB    '++ RECEIVED FILE CANCELLED ++',CR,LF,BELL
  3981.     DB    '++ UNFINISHED FILE DELETED ++',CR,LF,0
  3982.     JMP    DONETA
  3983. ;.....
  3984. ;
  3985. ;
  3986. RCVSTOT:LDA    QFLG        ; Quiet flag in use?
  3987.     ORA    A
  3988.     JZ    RCVSCC        ; If yes, don't show message
  3989.     LDA    FRSTIM        ; If first time, do not show as error
  3990.     ORA    A
  3991.     JZ    RCVSCC
  3992.     CALL    ILPRT
  3993.     DB    '++ Timeout ',0
  3994.     CALL    SHOWERR
  3995. ;
  3996. RCVSCC:    CALL    RCVSCC2
  3997.     JMP    RCVSR
  3998. ;.....
  3999. ;
  4000. ;
  4001. ; Routine will switch from 'CRC' to Checksum if 'ERCNT' reaches 'ERRCRC'
  4002. ; and 'FIRSTIME' is false
  4003. ;
  4004. RCVSCC2:LDA    FRSTIM        ; First time flag set yet?
  4005.     ORA    A
  4006.     RNZ            ; If yes, already underway so exit
  4007. ;
  4008.     LDA    ERRCT
  4009.     CPI    ERRCRC        ; Up to enough errors to go to checksum?
  4010.     RNZ            ; If not, exit
  4011.     LDA    CRCFLG        ; See if checksum already in use
  4012.     ORA    A
  4013.     RZ            ; If yes, exit
  4014.     XRA    A        ; Else set flags for checksum
  4015.     STA    CRCFLG
  4016.     STA    CRCDFLT
  4017.     CALL    ILPRTQ
  4018.     DB    CR,LF,'** Switching to Checksum mode **',CR,BELL,LF,0
  4019.     RET
  4020. ;.....
  4021. ;
  4022. ;
  4023. ; Got STX - set the KFLG for 1k blocks
  4024. ;
  4025. RCVSTX:    STA    KFLG        ; Set flag for 1k blocks
  4026.     JMP    RCVS1
  4027. ;
  4028. ;
  4029. ; Got SOH - get block #, block # complemented
  4030. ;
  4031. RCVSOH:    XRA    A        ; Clear 1k block flag, will be using 128
  4032.     STA    KFLG
  4033. ;
  4034. RCVS1:    MVI    B,5        ; Timeout = 5 seconds
  4035.     MOV    A,B        ; Get something to store
  4036.     STA    FRSTIM        ; Indicate first 'SOH' received
  4037.     CALL    RECV        ; Get record
  4038.     JC    RCVSTOT        ; Got a timeout
  4039.     MOV    D,A        ; Save the record number for now
  4040.     MVI    B,5        ; Timeout = 5 seconds
  4041.     CALL    RECV        ; Get complemented record number
  4042.     JC    RCVSTOT        ; Got a timeout
  4043.     CMA            ; "Uncomplement" to get original value
  4044.     CMP    D        ; Compare with first bytee
  4045.     JZ    RCVDATA        ; If both the same, received ok
  4046. ;
  4047.     LDA    QFLG        ; See if in quiet mode
  4048.     ORA    A
  4049.     JZ    RCVSR        ; If yes just add up the error
  4050.     CALL    ILPRT        ; Else show bad header received
  4051.     DB    CR,LF,'++ Bad record # in header ',0
  4052.     JMP    RCVPRN
  4053. ;...
  4054. ;
  4055. ;
  4056. ; Got a good header, save the record number, inirialize cheksum and CRC
  4057. ;
  4058. RCVDATA:MOV    A,D        ; Get the record number again
  4059.     STA    RCVCNT        ; Save it
  4060.     MVI    A,1        ; Insures only data displayed visually
  4061.     STA    DATAFLG
  4062.     MVI    C,0        ; Clear the checksum value
  4063.     LXI    H,0        ; Clear the CRC value
  4064.     SHLD    CRCVAL
  4065. ;
  4066. ;
  4067. ; Copy either 128 or 1024 characters into the buffer starting at address
  4068. ; pointed to by RCVPTR.
  4069. ;
  4070.     LXI    D,128        ; For 128 character blocks
  4071.     LDA    KFLG        ; Using 1k blocks?
  4072.     ORA    A
  4073.     JZ    $+6        ; If not, skip next line
  4074.     LXI    D,1024        ; If using 1k blocks
  4075.     LHLD    RECPTR        ; Get buffer address
  4076. ;
  4077. RCVCHR:    MVI    B,5        ; Wait up to 5 seconds for a character
  4078.     CALL    RECV
  4079.     JC    RCVSTOT        ; Got a timeout
  4080.     MOV    M,A        ; Store the character in buffer
  4081.     INX    H        ; Next buffer address
  4082.     DCX    D        ; One less to go
  4083.     MOV    A,D        ; See if 'D' and 'E' are both zero
  4084.     ORA    E
  4085.     JNZ    RCVCHR        ; If not, room for another character
  4086.     XRA    A
  4087.     STA    DATAFLG
  4088.     LDA    CRCFLG        ; Sending CRC?
  4089.     ORA    A
  4090.     JNZ    RCVCR        ; If yes get the CRC bytes
  4091. ;
  4092. ;
  4093. ; Verify checksum
  4094. ;
  4095.     MOV    D,C        ; Otherwise put the checksum in 'D'
  4096.     MVI    B,5        ; Wait up to 5 seconds for an answer
  4097.     CALL    RECV        ; Get the checksum value
  4098.     JC    RCVSTOT        ; Exit if nothing
  4099.     CMP    D        ; Compare sender's checksum with ours
  4100.     JNZ    RCVCER        ; Show an error if not ok
  4101. ;
  4102. ;
  4103. ; Got a record, it's a duplicate if equal to the previous number, it's
  4104. ; OK if previous + 1 record
  4105. ;
  4106. CHKSNUM:LDA    RCVCNT        ; Get received record number
  4107.     MOV    B,A        ; Save it
  4108.     LDA    RCDCNT        ; Get previous record number
  4109.     CMP    B        ; Rrevious record repeated?
  4110.     JZ    RCVACK        ; If yes 'ACK' to catch up
  4111.     INR    A        ; Increment by 1 for 120 character block
  4112.     CMP    B        ; Match this one we just got?
  4113.     JNZ    ABORT        ; No match, stop the sender, exit
  4114.     RET            ; Else return with carry not set, was ok
  4115. ;.....
  4116. ;
  4117. ;
  4118. ; Get the CRC bytes
  4119. ;
  4120. RCVCR:    MVI    E,2        ; Number of 'CRC' bytes
  4121. ;
  4122. RCVCR2:    MVI    B,5        ; Wait up to 5 seconds for a character
  4123.     CALL    RECV
  4124.     JC    RCVSTOT
  4125.     DCR    E        ; Started out with 2 characters needed
  4126.     JNZ    RCVCR2        ; If not zero, need 1 more yet
  4127.     CALL    CRCCHK        ; Check incoming two against our two
  4128.     ORA    A
  4129.     JZ    CHKSNUM        ; If ok, exit
  4130. ;
  4131.     LDA    QFLG        ; Else show an error
  4132.     ORA    A
  4133.     JZ    RCVSR
  4134.     CALL    ILPRT
  4135.     DB    '++ CRC error ',0
  4136.     JMP    RCVPRN
  4137. ;.....
  4138. ;
  4139. ;
  4140. RCVCER:    LDA    QFLG
  4141.     ORA    A
  4142.     JZ    RCVSR
  4143.     CALL    ILPRT
  4144.     DB    '++ checksum error ',0
  4145.     JMP    RCVPRN
  4146. ;.....
  4147. ;
  4148. ;
  4149. RCVACK:    CALL    SNDACK
  4150.     JMP    RCVRECD
  4151. ;.....
  4152. ;
  4153. ;
  4154. ; Get the error count and display on CRT
  4155. ;
  4156. SHOWERR:PUSH    H
  4157.     LHLD    ERRCT
  4158.     MVI    H,0
  4159.     CALL    DECOUT
  4160.     POP    H
  4161.     CALL    ILPRT
  4162.     DB    ' ++',CR,LF,0
  4163.     LDA    ERRCT
  4164.     CPI    ERRLIM
  4165.     JNC    ABORT
  4166.     RET
  4167. ;.....
  4168. ;
  4169. ;
  4170. ; Send SOH (or STX), record number and complemented record number.  Put
  4171. ; the display after the first character to add any delay at that point.
  4172. ;
  4173. SNDHDR:    LDA    KFLG        ; Sending 1k blocks?
  4174.     ORA    A
  4175.     MVI    A,STX        ; If yes, send a 'STX' rather than 'SOH'
  4176.     JNZ    $+5
  4177.     MVI    A,SOH        ; Send 'SOH' character to the output
  4178.     CALL    SEND
  4179.     LDA    QFLG
  4180.     ORA    A
  4181.     JZ    SNDHNM
  4182.     CALL    ILPRT
  4183.     DB    CR,'Sending: # ',0
  4184.     PUSH    H        ; Store current address
  4185.     LHLD    RECNO        ; Get record number
  4186.     CALL    DECOUT        ; Print it in decimal
  4187.     CALL    ILPRT
  4188.     DB    ' ',0        ; Just spaces the cursor one extra
  4189.     POP    H        ; Restore current address
  4190. ;
  4191. SNDHNM:    LDA    RCDCNT        ; Send the current transmission number
  4192.     CALL    SEND
  4193.     LDA    RCDCNT
  4194.     CMA            ; Complement the transmission number
  4195.     JMP    SEND        ; Send this value to the output
  4196. ;.....
  4197. ;
  4198. ;
  4199. SNDREC:    MVI    A,1        ; Used for video display while sending
  4200.     STA    DATAFLG
  4201.     MVI    C,0
  4202.     LXI    H,0        ; New record, clear 'CHECKSUM' value
  4203.     SHLD    CRCVAL        ; New record, clear 'CRC' value
  4204.     LDA    KFLG        ; Sending 1k blocks?
  4205.     ORA    A
  4206.     LXI    D,1024        ; For 1k blocks
  4207.     JNZ    $+6        ; If yes, skip next line
  4208.     LXI    D,128        ; For 128 character blocks
  4209.     LHLD    RECPTR        ; Find buffer location for storage
  4210. ;
  4211. SENDC:    MOV    A,M        ; Get character from buffer
  4212.     CALL    SEND        ; Send to modem
  4213.     INX    H        ; Next character locatiuon
  4214.     DCX    D        ; One less to go
  4215.     MOV    A,E        ; Compare 'E' with 'D'
  4216.     ORA    D        ; Are both zero yet?
  4217.     JNZ    SENDC        ; If not, go do another
  4218.     XRA    A        ; Else finished
  4219.     STA    DATAFLG        ; Used for video display while sending
  4220.     RET
  4221. ;.....
  4222. ;
  4223. ;
  4224. ; Send the checksum or CRC bytes
  4225. ;
  4226. SNDCHK:    LDA    CRCFLG        ; Check if using CRC or checksum
  4227.     ORA    A
  4228.     JNZ    SNDCRC        ; Exit and send CRC bytes
  4229. ;...
  4230. ;
  4231. ;
  4232. ; Send the checksum
  4233. ;
  4234. SNDCKS:    MOV    A,C        ; Get the checksum value
  4235.     JMP    SEND        ; Send to modem
  4236. ;.....
  4237. ;
  4238. ;
  4239. ; Send the two CRC (Cyclic Redundancy Check) characters
  4240. ;
  4241. SNDCRC:    PUSH    H
  4242.     LHLD    CRCVAL        ; Get the two CRC bytes
  4243.     MOV    A,H
  4244.     CALL    SEND        ; Send the first
  4245.     MOV    A,L
  4246.     CALL    SEND        ; Send the second
  4247.     POP    H
  4248.     XRA    A        ; Reset the carry bit
  4249.     RET
  4250. ;.....
  4251. ;
  4252. ;
  4253. ; After a record has been sent, and accepted, move the pointers forward
  4254. ; 128 or 1024 characters for the next record.
  4255. ;
  4256. SETPTR:    LXI    D,128        ; For 128 character blocks
  4257.     LDA    KFLG        ; See if using 1k blocks
  4258.     ORA    A
  4259.     JZ    $+6        ; If not, skip next line
  4260.     LXI    D,1024        ; Else set for 1024 character blocks
  4261.     LHLD    RECPTR        ; Get the buffer pointer
  4262.     DAD    D        ; Increment for the record just sent
  4263.     SHLD    RECPTR        ; New buffer address for next block
  4264.     RET
  4265. ;.....
  4266. ;
  4267. ;
  4268. ; After a record is sent, a character is returned telling if it was re-
  4269. ; ceived properly or not.  An ACK allows the next record to be sent.  A
  4270. ; NAK causes the current record to be resent.  If no character (or any
  4271. ; character other than ACK or NAK) is received after a short wait (10
  4272. ; to 12 seconds), a timeout error message is shown and the record will
  4273. ; be resent.  The GTACK routine can gobble up a string of up to 191
  4274. ; characters while searching for an 'ACK' or a 'NAK'.
  4275. ;
  4276. GTACK:    MVI    E,192        ; Number of characters to gobble
  4277. ;
  4278. ACKLUP:    MVI    A,0FFH
  4279.     STA    CHRFLG        ; Set the character flag
  4280.     STA    TIMFLG        ; Set the time flag
  4281.     MVI    B,1
  4282.     CALL    RECV
  4283.     MOV    B,A        ; Save the character
  4284.     JNC    ACKTST
  4285.     XRA    A
  4286.     STA    CHRFLG        ; Reset the character flag, was none
  4287. ;
  4288. ACKTST:    XRA    A
  4289.     STA    TIMFLG        ; Reset the time flag
  4290.     MOV    A,B        ; Get the character back
  4291.     CPI    ACK
  4292.     RZ
  4293.     CPI    NAK
  4294.     JZ    GTACK1
  4295.     CPI    CANCEL        ; Was this a CTL-X to cancel?
  4296.     CZ    CKCAN        ; Check for abort
  4297.     DCR    E        ; One less to go
  4298.     JNZ    ACKLUP        ; Loop around again if not zero
  4299.     LDA    CHRFLG
  4300.     ORA    A
  4301.     JZ    GETATOT
  4302. ;
  4303. GTACK1:    LDA    QFLG
  4304.     ORA    A
  4305.     JZ    ACKER
  4306.     LDA    CHKEOT        ; Waiting for ACK after EOT?
  4307.     ORA    A
  4308.     JNZ    ACKER        ; If yes, ignore message
  4309.     CALL    ILPRT
  4310.     DB    '++ ',0
  4311.     MOV    A,B
  4312.     CPI    NAK
  4313.     JZ    GTACK3
  4314.     CALL    HEXO
  4315.     CALL    ILPRT
  4316.     DB    'H',0
  4317.     JMP    GTACK4
  4318. ;
  4319. GTACK3:    CALL    ILPRT
  4320.     DB    'NAK',0
  4321. ;
  4322. GTACK4:    CALL    ILPRT
  4323.     DB    ' received not ACK - ',0
  4324.     CALL    SHOWERR
  4325. ;
  4326. ACKER:    LDA    ERRCT
  4327.     INR    A
  4328.     STA    ERRCT
  4329.     CPI    ERRLIM+1    ; At error limit yet?
  4330.     RC            ; If not, return
  4331. ;
  4332. ACKMSG:    CALL    ERXIT
  4333.     DB    CR,LF,LF,'++ FILE TRANSFER ABORTED ++','$'
  4334. ;.....
  4335. ;
  4336. ;
  4337. ; Reached error limit
  4338. ;
  4339. GETATOT:CALL    ILPRT
  4340.     DB    CR,'++ TIMEOUT - no ACK - ',0
  4341.     CALL    SHOWERR        ; Display error count
  4342.     JMP    ACKER
  4343. ;.....
  4344. ;
  4345. ;
  4346. ; Check the total error count vs. records sent, switch from 1k to 128
  4347. ; character transmissions if higher than operator selected value.
  4348. ;
  4349. GTRATIO:LDA    KFLG        ; Using 1k blocks?
  4350.     ORA    A
  4351.     RZ            ; If not, skip this routine
  4352. ;
  4353.     LDA    ERRCT        ; See if we got any errors last record
  4354.     CPI    4+1        ; If under 4 consecutive errors, exit
  4355.     JNC    GTRATIO1    ; (ERRCT is set to 1 initially, below)
  4356.     LDA    ACCERR        ; See if up to minimum errors yet
  4357.     CPI    3        ; Had as many as three errors yet?
  4358.     RC            ; If not, don't get excited too quickly
  4359. ;
  4360.     LHLD    RECNO        ; Get current record number increment
  4361.     LXI    D,-8        ; Have not successfully sent this 1k yet
  4362.     DAD    D        ; Subtract the current increment, then
  4363.     XCHG            ; Put in DE for now
  4364.     LHLD    ACCERR        ; Number of non-'ACK' errors in HL
  4365.     XCHG            ; Back to normal
  4366.     CALL    DVHLDE        ; Get ratio in BC of records/hit
  4367.     LDA    MSPEED        ; Get current speed
  4368.     CPI    5        ; 1200 baud?
  4369.     MVI    A,71-1        ; For 1200 bps    (78 ms delay)
  4370.     JZ    $+5        ; If 1200, skip next line
  4371.     MVI    A,43-1        ; For 2400 bps    (78 ms delay)
  4372.     CMP    C        ; Compare with actual ratio
  4373.     RC            ; Return if less hits than allowed
  4374. ;
  4375. GTRATIO1:
  4376.     XRA    A        ; Else reset the system to 128
  4377.     STA    KFLG
  4378.     CALL    ILPRTQ
  4379.     DB    CR,LF,'Aborting 1k blocks, too many ACK errors',CR,LF,0
  4380.     RET
  4381. ;.....
  4382. ;
  4383. ;
  4384. CKABORT:LDA    QFLG
  4385.     ORA    A
  4386.     RZ
  4387.     CALL    STAT
  4388.     ORA    A
  4389.     RZ
  4390.     CALL    KEYIN
  4391.     CPI    CANCEL
  4392.     RNZ
  4393. ;
  4394. ;
  4395. ; Aborts send or receive routines and returns to command line
  4396. ;
  4397. ABORT:    LXI    SP,STACK
  4398. ;
  4399. ABORTL:    MVI    B,1        ; 1-second delay to clear input
  4400.     CALL    RECV
  4401.     JNC    ABORTL
  4402.     MVI    A,CANCEL    ; Show you are cancelling
  4403.     CALL    SEND        ; They may quit also with enough CTL-X
  4404.     CALL    SEND
  4405.     CALL    SEND
  4406. ;
  4407. ABORTW:    MVI    B,1        ; 1-second delay to clear input
  4408.     CALL    RECV
  4409.     JNC    ABORTW
  4410.     MVI    A,BKSP        ; Remove the three CTL-X's if needed
  4411.     CALL    SEND
  4412.     CALL    SEND
  4413.     CALL    SEND
  4414.     MVI    A,'B'        ; Clear the batch mode flag
  4415.     STA    BATCHFLG
  4416.     STA    ABORTFLG    ; Shows an abort was made
  4417.     XRA    A
  4418.     STA    NFILFLG        ; Stop copy into memory for disk file
  4419. ;
  4420. ABORTX:    LDA    OPTION        ; Receiving a file now?
  4421.     CPI    'R'
  4422.     JZ    RCVSABT        ; If yes, delete the unfinished file
  4423. ;
  4424.     CALL    ILPRT
  4425.     DB    CR,LF,LF,'++ FILE CANCELLED ++',CR,LF,BELL,0
  4426.     JMP    DONETA
  4427. ;.....
  4428. ;
  4429. ;
  4430. ; Increment the record count
  4431. ;
  4432. INCRNO:    PUSH    H
  4433.     PUSH    D
  4434.     LHLD    RCDCNT        ; Increment the transmission count
  4435.     INX    H
  4436.     SHLD    RCDCNT
  4437.     LXI    D,1        ; Increment by 1 for 128 char. blocks
  4438.     LDA    KFLG        ; Sending 1k blocks?
  4439.     ORA    A
  4440.     JZ    $+6        ; If not, skip next line
  4441.     LXI    D,8        ; If yes, increment count by 8
  4442.     LHLD    RECNO        ; Get record number
  4443.     DAD    D
  4444.     SHLD    RECNO        ; Store it
  4445.     POP    D
  4446.     POP    H
  4447.     RET
  4448. ;.....
  4449. ;
  4450. ;
  4451. ; First check for any wild cards and disallow, just to be safe.  Do not
  4452. ; want a group of files being accidently erased.
  4453. ;
  4454. ERASF:    LXI    H,FCB        ; File name is stored here
  4455.     MVI    B,11        ; Maximum of 11 chars for filename, ext.
  4456. ;
  4457. ERASF1:    INX    H        ; Next location in file name
  4458.     MOV    A,M        ; Get the character
  4459.     CPI    '?'        ; Check for any wild card characters
  4460.     JZ    ERRORW        ; Error if one is found
  4461.     DCR    B        ; Number of tries left
  4462.     JNZ    ERASF1        ; If not zero, keep checking
  4463. ;
  4464.     LDA    BATCHFLG    ; Batch mode?
  4465.     ORA    A
  4466.     JZ    NOASK        ; Exit if set (will be zero)
  4467. ;
  4468.     LXI    D,FCB
  4469.     MVI    C,SRCHF
  4470.     CALL    BDOS
  4471.     INR    A
  4472.     RZ            ; File erased ok, return
  4473.     CALL    ILPRT        ; Otherwise make sure it'S OK
  4474.     DB    'File exists - erase?  (Y/N): ',BELL,0
  4475.     CALL    KBDCHR
  4476.     PUSH    PSW        ; Save the answer for a moment
  4477.     CALL    CRLF        ; Turn up a line
  4478.     POP    PSW        ; Get the character back now
  4479.     CPI    'Y'
  4480.     JNZ    MENU        ; If not a 'Y' do not erase
  4481. ;
  4482. NOASK:    LXI    D,FCB        ; Else erase the file
  4483.     MVI    C,ERASE
  4484.     JMP    BDOS        ; Return from ERASF
  4485. ;.....
  4486. ;
  4487. ;
  4488. ERRORW:    POP    H        ; Restore stack from "call ERASF"
  4489.     CALL    ILPRT
  4490.     DB    '++ NO WILDCARDS ALLOWED FOR TEXT FILES ++'
  4491.     DB    CR,LF,BELL,0
  4492.     JMP    MENU
  4493. ;.....
  4494. ;
  4495. ;
  4496. BLKFILE:CALL    ILPRT        ; No file named for send or receive
  4497.     DB    '++ NO FILE SPECIFIED ++',CR,LF,BELL,0
  4498.     JMP    MENU
  4499. ;.....
  4500. ;
  4501. ;
  4502. MAKEFIL:LXI    D,FCB
  4503.     MVI    C,MAKE
  4504.     CALL    BDOS
  4505.     INR    A
  4506.     RNZ
  4507.     CALL    ERXIT
  4508.     DB    '++ ERROR -- Can''t open file ++',CR,LF
  4509.     DB    '++ Directory is perhaps full ++','$'
  4510. ;
  4511. CNREC:    MVI    C,FILSIZ    ; Compute file size function in cp/m 2.x
  4512.     LXI    D,FCB        ; Point to file control block
  4513.     CALL    BDOS
  4514.     LHLD    FCB+33        ; Get record count
  4515.     SHLD    RCNT        ; Store it
  4516.     LXI    H,0        ; Zero 'HL'
  4517.     SHLD    FCB+33        ; Reset random record in FCB
  4518.     RET
  4519. ;.....
  4520. ;
  4521. ;
  4522. OPENFIL:XRA    A
  4523.     STA    FCBEXT
  4524.     LXI    D,FCB
  4525.     MVI    C,OPEN
  4526.     CALL    BDOS
  4527.     INR    A
  4528.     JZ    OPENF1        ; Exit if no file
  4529.     LHLD    RCNT        ; See if anything in the file first
  4530.     MOV    A,H
  4531.     ORA    L
  4532.     JNZ    SNDTM        ; If yes send transfer time, etc.
  4533.     CALL    ERXIT
  4534.     DB    '++ File is zero-length ++','$'
  4535. ;
  4536. OPENF1:    CALL    ERXIT        ; File did not open
  4537.     DB    '++ FILE NOT FOUND ++','$'
  4538. ;.....
  4539. ;
  4540. ;
  4541. CLOSFIL:LXI    D,FCB        ; Get the file name
  4542.     MVI    C,CLOSE
  4543.     CALL    BDOS        ; Close the file
  4544.     INR    A
  4545.     RNZ
  4546.     JMP    ERXIT1        ; No file to close, exit
  4547. ;.....
  4548. ;
  4549. ;
  4550. ;-----------------------------------------------------------------------
  4551. ;        read a record, refill buffer if empty
  4552. ;
  4553. ; Update record read
  4554. ;
  4555. RDRECD:    LDA    RECNBF        ; Get number of records in buffer
  4556.     ORA    A
  4557.     JZ    RDBLOCK        ; If none, go get some
  4558.     LDA    KFLG        ; Using 1k blocks?
  4559.     ORA    A
  4560.     JZ    RDREC1        ; If not, exit
  4561. ;
  4562. ;
  4563. ; Using 1k blocks, switch to 128 if less than 8 records left
  4564. ;
  4565.     LDA    RECNBF        ; See how many records in buffer
  4566.     CPI    8
  4567.     JNC    RDREC2        ; If 8 or more stay in 1k blocks
  4568.     XRA    A        ; Else there are 1-7 records left
  4569.     STA    KFLG        ; Reset the 1k flag for 128
  4570. ;
  4571. RDREC1:    LDA    RECNBF        ; Decrement 'RECORDS IN BUFFER' count
  4572.     DCR    A
  4573.     STA    RECNBF
  4574.     RET
  4575. ;...
  4576. ;
  4577. ;
  4578. ; Using 1k blocks, get set to send another one
  4579. ;
  4580. RDREC2:    SUI    8        ; Subtract 1k worth
  4581.     STA    RECNBF
  4582.     RET
  4583. ;.....
  4584. ;
  4585. ;
  4586. ; Buffer empty so read in another block from the disk
  4587. ;
  4588. RDBLOCK:LDA    EOFLG
  4589.     CPI    1
  4590.     STC
  4591.     RZ
  4592. ;
  4593.     CALL    RDBLK1
  4594.     JMP    RDRECD
  4595. ;.....
  4596. ;
  4597. ;
  4598. ; Read up to 16k of the file from disk to buffer, ready to send
  4599. ;
  4600. RDBLK1:    MVI    C,0
  4601.     LXI    D,BUFFER
  4602. ;
  4603. RDRECLP:PUSH    B
  4604.     PUSH    D
  4605.     MVI    C,STDMA        ; Use the 'DE' address to store file
  4606.     CALL    BDOS
  4607. ;
  4608.     LXI    D,FCB
  4609.     MVI    C,READ        ; Read a record from the file and store
  4610.     CALL    BDOS
  4611. ;
  4612.     POP    D
  4613.     POP    B
  4614.     ORA    A        ; Read ok?
  4615.     JNZ    REOF        ; If not, error or end of file
  4616. ;
  4617.     LXI    H,128        ; Add length of one record
  4618.     DAD    D        ; To next buffer address
  4619.     XCHG            ; Buffer address for next record to DE
  4620.     INR    C        ; Increment records in buffer count
  4621.     CALL    DSKSIZ        ; See if buffer is full yet
  4622.     JNZ    RDRECLP        ; If not full, do another
  4623. ;...
  4624. ;
  4625. ;
  4626. ; Buffer full or received "End Of File (EOF)"
  4627. ;
  4628. RDBFULL:STA    RECNBF        ; Store the number records in buffer
  4629.     LXI    H,BUFFER    ; Start at beginning of buffer
  4630.     SHLD    RECPTR        ; Initialize buffer poninters
  4631.     MVI    C,STDMA        ; Reset file storage to default area
  4632.     LXI    D,TBUF
  4633.     JMP    BDOS        ; Have something to read, now
  4634. ;.....
  4635. ;
  4636. ;
  4637. REOF:    DCR    A        ; 'EOF' yet?
  4638.     JNZ    RDERR        ; If not, was an error
  4639.     MVI    A,1
  4640.     STA    EOFLG        ; Set EOF flag
  4641.     MOV    A,C
  4642.     JMP    RDBFULL
  4643. ;.....
  4644. ;
  4645. ;
  4646. RDERR:    CALL    ERXIT
  4647.     DB    '++ FILE READ ERROR ++','$'
  4648. ;
  4649. ;
  4650. ;
  4651. ;
  4652. ; If the 128 or 1024 byte record was received ok by RCVDATA and passed
  4653. ; the CRC (or checksum) test, then we aleady have the infomration in the
  4654. ; buffer and just move the RECPTR pointers 128 or 1024 bytes for the
  4655. ; next record's location.  If this puts us up to the limit of records,
  4656. ; we dump to disk and reset everything.
  4657. ;
  4658. WRRECD:    LHLD    RECPTR        ; Get buffer address
  4659.     LXI    D,128        ; 128 characters/record
  4660.     LDA    KFLG        ; Using 1k blocks?
  4661.     ORA    A
  4662.     JZ    $+6        ; If not skip next line
  4663.     LXI    D,1024        ; 1k characters/record
  4664.     DAD    D        ; To next buffer
  4665.     SHLD    RECPTR        ; Save buffer address
  4666.     LDA    KFLG        ; Using 1k blocks?
  4667.     ORA    A
  4668.     JZ    WRREC1        ; If not, exit
  4669.     LDA    RECNBF        ; Get number of records in buffer
  4670.     ADI    8        ; Increment it 8 records for 1k block
  4671.     JMP    WRREC2
  4672. ;
  4673. WRREC1:    LDA    RECNBF        ; Get number of records in buffer
  4674.     INR    A        ; Increment it for one 128 char. record
  4675. ;
  4676. WRREC2:    STA    RECNBF        ; Store the new value
  4677.     MOV    C,A        ; Store the record count for now
  4678.     CALL    DSKSIZ        ; Establish buffer size
  4679.     RNZ            ; Buffer not full, return
  4680. ;
  4681. ;
  4682. ; Write a block to disk
  4683. ;
  4684. WRBLOCK:LDA    RECNBF        ; Get the number of records in the buffer
  4685.     ORA    A
  4686.     RZ            ; If zero, don't try to move to disk
  4687.     MOV    C,A        ; Otherwise store in 'C' reg.
  4688.     LXI    D,BUFFER    ; Start of buffer to move to disk
  4689. ;
  4690. DSKWRT:    PUSH    B
  4691.     PUSH    D
  4692.     PUSH    H
  4693. ;
  4694.     MVI    C,STDMA
  4695.     CALL    BDOS
  4696. ;
  4697.     MVI    C,WRITE
  4698.     LXI    D,FCB
  4699.     CALL    BDOS
  4700. ;
  4701.     POP    H
  4702.     POP    D
  4703.     POP    B
  4704.     ORA    A
  4705.     JNZ    WRERR        ; Error if disk is full
  4706.     LXI    H,128        ; Add in another record
  4707.     DAD    D        ; Increment the current buffer address
  4708.     XCHG            ; Put in DE for new buffer address
  4709.     DCR    C        ; One less record left to move to disk
  4710.     JNZ    DSKWRT        ; If not finished, write another record
  4711.     XRA    A        ; Else all done, zero the pointers
  4712.     STA    RECNBF        ; Zero the 'RECORDS IN BUFFER' count
  4713.     LXI    H,BUFFER    ; Reset location to next buffer start
  4714.     SHLD    RECPTR        ; Now at start of buffer again
  4715.     RET
  4716. ;.....
  4717. ;
  4718. ;
  4719. ; Determine if the buffer size is for file transfer or for ASCII capture
  4720. ; to disk then compare with current record length
  4721. ;
  4722. DSKSIZ:    LDA    XFLG        ; See if transferring files now
  4723.     ORA    A
  4724.     MOV    A,C        ; Get the current record count
  4725.     JZ    DSKSIZ1        ; If yes, exit
  4726.     MOV    A,C
  4727.     CPI    BUFSIZ*8    ; Buffer size for ASCII capture to disk
  4728.     RET            ; Return with flag set for the compare
  4729. ;...
  4730. ;
  4731. ;
  4732. DSKSIZ1:LDA    SAVSIZ        ; Get the file transfer buffer size..
  4733.     CMP    C        ; From special storage area and compare
  4734.     RET            ; Return with flag set for the compare
  4735. ;.....
  4736. ;
  4737. ;
  4738. ; Timeout time is in B, in seconds.  Entry via 'RECVDG' deletes garbage
  4739. ; characters on the line.  For example, having just sent a record, cal-
  4740. ; ling RECVDG will delete any line noise induced characters LONG before
  4741. ; the ACK/NAK would be received.
  4742. ;
  4743. RECVDG:    CALL    CKCHAR        ; Catch any garbage characters
  4744. ;
  4745. RECV:    PUSH    D
  4746. ;
  4747. ;
  4748. ; Get back quickly to gobble 2nd character if TIMFLG is set by the GETNM
  4749. ; routine - or just step through quickly after the first wait for 'SOH'
  4750. ; in the 'SOHLUP' routine.
  4751. ;
  4752. MSEC:    PUSH    H
  4753.     LXI    H,TIMFLG
  4754.     MOV    E,M
  4755.     INR    E
  4756.     LHLD    QUIKTIM
  4757.     JZ    DOQUIK
  4758.     LHLD    TIMVAL
  4759. ;
  4760. DOQUIK:    XCHG
  4761.     POP    H
  4762. ;
  4763. MWTI:    CALL    RCVRDY
  4764.     JZ    MCHAR
  4765.     MOV    A,D
  4766.     ORA    E
  4767.     DCX    D
  4768.     JNZ    MWTI
  4769.     DCR    B
  4770.     JNZ    MSEC
  4771.     POP    D
  4772.     CALL    CKABORT
  4773.     STC
  4774.     RET
  4775. ;.....
  4776. ;
  4777. ;
  4778. ; Get the character from the modem, but filter out 'ACK' and '.' chars.
  4779. ; if recieving a file name.  ('FILTRFLG' is set by the 'GETNM' routine.)
  4780. ;
  4781. MCHAR:    CALL    I$MDDATP    ; Get the character that is waiting
  4782.     POP    D
  4783.     PUSH    PSW        ; Save the character for later use also
  4784.     CPI    ACK        ; See if it is 'ACK'
  4785.     JZ    ISACK
  4786.     CPI    '.'        ; See if it is a period
  4787.     JNZ    DOUPD        ; Neither, so update 'CRC'
  4788. ;
  4789. ISACK:    PUSH    H
  4790.     PUSH    D
  4791.     LXI    H,FLTRFLG    ; See if need to each 'ACK' or period
  4792.     MOV    E,M
  4793.     INR    E
  4794.     POP    D
  4795.     POP    H
  4796.     JZ    MWTI        ; Yes, so do it
  4797. ;
  4798. DOUPD:    CALL    CRCUPD        ; Calculate 'CRC'
  4799.     ADD    C
  4800.     MOV    C,A
  4801.     LDA    RSEEFLG
  4802.     ORA    A
  4803.     JZ    MONIN
  4804.     LDA    VSEEFLG
  4805.     ORA    A
  4806.     JNZ    NOMONIN
  4807.     LDA    DATAFLG
  4808.     ORA    A
  4809.     JZ    NOMONIN
  4810. ;
  4811. MONIN:    POP    PSW        ; Get the character again
  4812.     PUSH    PSW        ; Resave it for later use also
  4813.     CALL    SHOW        ; Show the character on the CRT
  4814. ;
  4815. NOMONIN:CALL    CKABORT
  4816.     POP    PSW        ; Get the character back once more
  4817.     ORA    A        ; Reset the carry flag
  4818.     RET            ; Return with the character and flag set
  4819. ;.....
  4820. ;
  4821. ;
  4822. ; Send a character to the modem
  4823. ;
  4824. SEND:    PUSH    PSW
  4825.     LDA    SSEEFLG
  4826.     ORA    A
  4827.     JZ    MONOUT
  4828.     LDA    VSEEFLG
  4829.     ORA    A
  4830.     JNZ    NOMONOT
  4831.     LDA    DATAFLG
  4832.     ORA    A
  4833.     JZ    NOMONOT
  4834. ;
  4835. MONOUT:    POP    PSW
  4836.     PUSH    PSW
  4837.     CALL    SHOW
  4838. ;
  4839. NOMONOT:POP    PSW
  4840.     PUSH    PSW
  4841.     CALL    CRCUPD        ; Update the 'CRC' calcuation
  4842.     ADD    C
  4843.     MOV    C,A
  4844. ;
  4845. SENDW:    CALL    SNDRDY        ; See if modem is ready for new char.
  4846.     JNZ    SENDW        ; If not, wait until modem is ready
  4847.     POP    PSW        ; Get the character back
  4848.     JMP    O$MDDATP    ; Send character to modem, done
  4849. ;.....
  4850. ;
  4851. ;
  4852. ; Waits for the first character received while waiting to send a file.
  4853. ; If a character is not received in one second, it loops again until a
  4854. ; char. is received or it times out.  The count is set for two minutes
  4855. ; before timeout.  This gives the receiving station ample time to name
  4856. ; a file, etc.
  4857. ;
  4858. WAITNAK:CALL    CKABORT
  4859.     MVI    B,1        ; Wait up to 1 second for a character
  4860.     CALL    RECV        ; Clear the buffer first then get char.
  4861.     JC    WAITN2        ; No character this time
  4862.     CPI    CANCEL        ; Want to quit?
  4863.     CZ    CKCAN        ; If yes, check for a trailing CTL-X
  4864. ;
  4865. WAITN1:    CPI    CRC        ; 'CRC' request?
  4866.     JZ    WAITK        ; Yes, see if there will be a trailing K
  4867.     CPI    KSND        ; Request for 1k blocks?
  4868.     JZ    WAIKST        ; Yes, go set the 1k flag
  4869.     CPI    NAK
  4870.     JZ    WAICKSM
  4871.     mov    b,a        ; Save the character for now
  4872.     lda    batchflg    ; In batch mode now?
  4873.     ora    a
  4874.     jnz    waitn2        ; if not, exit
  4875.     mov    a,b        ; Get the character back
  4876.     cpi    EOT        ; See if file exists on host
  4877.     jz    exists        ; Exit if batch file already exists
  4878. ;
  4879. WAITN2:    DCR    E
  4880.     JNZ    WAITNAK
  4881.     JMP    ABORT
  4882. ;...
  4883. ;
  4884. ;
  4885. WAITK:    MVI    B,1        ; Got a 'C', wait up to 1 second for 'K'
  4886.     CALL    RECV
  4887.     JC    WAITCRC        ; Didn't get anything, so not using 1k
  4888.     ANI    7FH
  4889.     CPI    '{'
  4890.     JZ    WAITK        ; Disregard noisy lines
  4891.     CPI    KSND        ; Requesting 1k?
  4892.     JZ    WAIKST        ; Exit if yes, otherwise set CRC
  4893.     JMP    WAITCRC
  4894. ;.....
  4895. ;
  4896. ;
  4897. WAICKSM:LDA    BATCHFLG    ; In batch mode?
  4898.     ORA    A
  4899.     JZ    WAICKSN        ; If yes, exit
  4900.     XRA    A
  4901.     STA    CRCFLG        ; Make sure in checksum mode
  4902.     STA    KFLG        ; Cancel any 1k block request
  4903.     CALL    ILPRTQ
  4904.     DB    'Got checksum request',CR,LF,0
  4905.     RET
  4906. ;...
  4907. ;
  4908. ;
  4909. WAICKSN:CALL    ILPRTQ
  4910.     DB    'Checksum not used for batch mode',CR,LF,0
  4911.     JMP    WAITNAK        ; Keep waiting for CRC value
  4912. ;.....
  4913. ;
  4914. ;
  4915. WAITCRC:LDA    KFLG
  4916.     ORA    A
  4917.     JNZ    WAIKST1
  4918.     CALL    ILPRTQ
  4919.     DB    'CRC request received',CR,LF,0
  4920.     MVI    A,1
  4921.     STA    CRCFLG        ; Make sure in 'CRC' mode then
  4922.     XRA    A
  4923.     STA    KFLG        ; Cancel any 1k blocks request
  4924.     RET
  4925. ;.....
  4926. ;
  4927. ;
  4928. ; If a 'K' was received set for 1k blocks, unless we typed a 'SX' to
  4929. ; force XMODEM protocol with 128 character blocks, intentionall.
  4930. ;
  4931. WAIKST:    LDA    XMODEM        ; Get the value of XMODEM flag
  4932.     ORA    A
  4933.     JZ    WAITCRC
  4934. ;
  4935. WAIKST1:STA    CRCFLG        ; Set the CRC flag
  4936.     STA    KFLG        ; Set the flag for 1k blocks
  4937.     CALL    ILPRTQ
  4938.     DB    '1k request received',CR,LF,0
  4939.     RET
  4940. ;.....
  4941. ;
  4942. ;
  4943. ; File exists we were trying to send via batch mode, so abort
  4944. ;
  4945. exists:    call    erxit
  4946.     db    CR,LF,'++ File exists on host, aborting transfer ++','$'
  4947. ;.....
  4948. ;
  4949. ;
  4950. ; Finished with the file transfer
  4951. ;
  4952. DONE:    LDA    BATCHFLG    ; In batch mode?
  4953.     ORA    A
  4954.     JNZ    DONET        ; Exit if not
  4955. ;
  4956.     LDA    QFLG
  4957.     ORA    A
  4958.     JZ    NMSTRNS
  4959.     MVI    B,12        ; Zero out FTRNM
  4960.     LXI    H,FTRNM
  4961.     MVI    A,0
  4962. ;
  4963. ZEROLP:    MOV    M,A
  4964.     INX    H
  4965.     DCR    B
  4966.     JNZ    ZEROLP
  4967.     MVI    B,12        ; Put file name in FTRNM
  4968.     LXI    H,FCB+1
  4969.     LXI    D,FTRNM
  4970. ;
  4971. LOADMSG:MVI    A,4        ; Start of file type?
  4972.     CMP    B
  4973.     JZ    PERIOD        ; Put in period if so
  4974.     MOV    A,M
  4975.     CPI    ' '        ; Don't put in space
  4976.     JZ    SKPSP
  4977.     STAX    D        ; Store in FTRNM
  4978.     INX    D
  4979. ;
  4980. SKPSP:    INX    H
  4981.     DCR    B
  4982.     MOV    A,B
  4983.     ORA    A        ; End of file name?
  4984.     JZ    FTRNM0        ; Display file name
  4985.     JMP    LOADMSG        ; Loop for another character
  4986. ;.....
  4987. ;
  4988. ;
  4989. PERIOD:    MOV    A,M
  4990.     CPI    ' '        ; Is file type empty?
  4991.     JZ    FTRNM0        ; Go if so
  4992.     MVI    A,'.'        ; Else put period in message
  4993.     STAX    D
  4994.     INX    D
  4995.     DCR    B
  4996.     JMP    LOADMSG
  4997. ;.....
  4998. ;
  4999. ;
  5000. FTRNM0:    CALL    ILPRT
  5001.     DB    CR,LF
  5002. ;
  5003. FTRNM:    DB    0,0,0,0,0,0,0
  5004.     DB    0,0,0,0,0,0
  5005.     CALL    ILPRT
  5006.     DB    ' Transferred',CR,LF,0
  5007. ;
  5008. NMSTRNS:LXI    H,FCB        ; Blank out file control blocks
  5009.     CALL    INITFCB1
  5010.     LXI    H,RESTSN    ; Restore record numbers
  5011.     LXI    D,RECNOB    ; For new file transfer
  5012.     MVI    B,RECNOE-RECNOB    ; Routine also done in menu
  5013.     CALL    MOVE
  5014.     CALL    SNDNOW        ; Insures last character is finished
  5015.     CALL    CKCHAR        ; Catch any echo characters on line
  5016.     MVI    A,1
  5017.     STA    GOTONE        ; Indicates a batch file was handled
  5018.     LDA    SNDFLG        ; Check batch flag
  5019.     ORA    A
  5020.     JNZ    RCVFL        ; Receiving batch, if set
  5021.     JMP    SNDFL1        ; Sending batch if not set
  5022. ;.....
  5023. ;
  5024. ;
  5025. DONET:    CALL    CKABORT        ; Slight delay for next message
  5026.     CALL    ILPRT
  5027.     DB    CR,LF,'[Transfer completed]',CR,LF,BELL,0
  5028. ;
  5029. DONETA:    LDA    XITFLG        ; Special 'Z' flag set?
  5030.     ORA    A
  5031.     JZ    BYEBYE        ; If yes, disconnect and reboot
  5032.     LDA    DISCFLG        ; Normal 'D' flag set?
  5033.     ORA    A
  5034.     JZ    DONETD        ; If yes, disconnect, get next command
  5035. ;
  5036. DONETB:    XRA    A
  5037.     STA    CRCFLG        ; Reset back to checksum
  5038.     STA    FRSTIM        ; Reset first-time 'SOH' flag
  5039.     STA    FSTFLG        ; Reset multi-file transmission
  5040.     STA    NFILFLG        ; Turn off the memory save for disk file
  5041.     STA    SAVEFLG        ; Stop memory save in term routine.
  5042.     LDA    VSEEFLG        ; View flag set?
  5043.     ORA    A
  5044.     JNZ    DONETC        ; If not, exit
  5045.     CMA
  5046.     STA    QFLG        ; VSEEFLG also sets the QFLG
  5047.     STA    VSEEFLG        ; Reset the flag
  5048. ;
  5049. DONETC:    LXI    H,QFLG        ; In quiet mode?
  5050.     MOV    A,M
  5051.     ORA    A
  5052.     MVI    M,'Q'        ; Reset the flag to normal
  5053.     JZ    MENU        ; If yes, go back to command line
  5054.     LDA    ABORTFLG    ; Come here from a timeout?
  5055.     ORA    A
  5056.     JNZ    MENU        ; If yes, go to command mode
  5057.     JMP    TERM        ; Otherwise return to terminal mode
  5058. ;.....
  5059. ;
  5060. ;
  5061. DONETD:    CALL    ILPRT
  5062.     DB    CR,LF,'  wait... ',0
  5063.     CALL    STPCHR        ; Try to stop any incoming characters
  5064.     LDA    NODTR        ; Able to disconnect by dropping DTR?
  5065.     ORA    A
  5066.     JNZ    DONETE        ; If not, exit
  5067.     CALL    J$GOODBYE    ; Disconect with ATH0 string
  5068.     JMP    DONETF
  5069. ;
  5070. DONETE:    CALL    J$DSCONT    ; Disconnect with ATH0 string    
  5071. ;
  5072. DONETF:    CALL    ILPRT
  5073.     DB    CR,'<< Disconnected >>',BELL,CR,LF,0
  5074.     JMP    MENU0        ; Back to command line
  5075. ;.....
  5076. ;
  5077. ;
  5078. ; Sends a break tone for 300 ms
  5079. ;
  5080. SBREAK:    LDA    J$BREAK
  5081.     CPI    0C3H        ; See if overlay has "J$BREAK" installed
  5082.     JNZ    TERM        ; If not, get next character/command
  5083.     CALL    STPCHR        ; Stop any incoming characters
  5084.     CALL    J$BREAK        ; Send the break tone
  5085. ;
  5086.     JMP    TERM        ; Get next character/command
  5087. ;.....
  5088. ;
  5089. ;
  5090. ; This routine stops any incoming characters if possible
  5091. ;
  5092. STPCHR:    CALL    J$INMDM        ; See if any incoming characters
  5093.     JC    STPCHR1        ; If no incoming, exit
  5094.     MVI    B,'S'-40H    ; X-off to stop host if possible
  5095.     CALL    J$SNDCHR    ; Send to host        
  5096.     MVI    B,1        ; Delay 100 ms to take effect
  5097.     CALL    J$TIMER
  5098.     JMP    STPCHR        ; See if characters have stopped now
  5099. ;
  5100. STPCHR1:RET            ; Done
  5101. ;.....
  5102. ;
  5103. ;
  5104. SHOW:    CPI    LF
  5105.     JZ    CTYPE
  5106.     CPI    CR
  5107.     JZ    CTYPE
  5108.     CPI    9
  5109.     JZ    CTYPE
  5110.     CPI    ' '
  5111.     JC    SEEHEX
  5112.     CPI    7FH
  5113.     JC    CTYPE
  5114. ;
  5115. SEEHEX:    PUSH    PSW
  5116.     MVI    A,'('
  5117.     CALL    CTYPE
  5118.     POP    PSW
  5119.     CALL    HEXO
  5120.     MVI    A,')'
  5121.     JMP    CTYPE
  5122. ;.....
  5123. ;
  5124. ;
  5125. CTYPE:    PUSH    B
  5126.     PUSH    D
  5127.     PUSH    H
  5128.     MOV    E,A
  5129.     MVI    C,WRCON
  5130.     CALL    BDOS
  5131.     POP    H
  5132.     POP    D
  5133.     POP    B
  5134.     RET
  5135. ;.....
  5136. ;
  5137. ;
  5138. CRLF:    PUSH    PSW
  5139.     MVI    A,CR
  5140.     CALL    TYPE
  5141.     MVI    A,LF
  5142.     CALL    TYPE
  5143.     POP    PSW
  5144.     RET
  5145. ;.....
  5146. ;
  5147. ;
  5148. STAT:    PUSH    B
  5149.     PUSH    D
  5150.     PUSH    H
  5151. ;
  5152. VSTAT:    CALL    $-$        ; BIOS constat address, filled in..
  5153.     POP    H        ; By 'INITADR' routine
  5154.     POP    D
  5155.     POP    B
  5156.     ORA    A
  5157.     RET
  5158. ;.....
  5159. ;
  5160. ;
  5161. KEYIN:    PUSH    B
  5162.     PUSH    D
  5163.     PUSH    H
  5164. ;
  5165. VKEYIN:    CALL    $-$        ; BIOS 'CONIN' address, filled in..
  5166.     POP    H        ; By 'INITADR' routine
  5167.     POP    D
  5168.     POP    B
  5169.     RET
  5170. ;.....
  5171. ;
  5172. ;
  5173. TYPE:    PUSH    PSW
  5174.     PUSH    B
  5175.     PUSH    D
  5176.     PUSH    H
  5177.     MOV    C,A
  5178. ;
  5179. VTYPE:    CALL    $-$        ; BIOS 'CONOUT' address, filled in..
  5180.     POP    H        ; By 'INITADR' routine
  5181.     POP    D
  5182.     POP    B
  5183.     POP    PSW
  5184.     RET
  5185. ;.....
  5186. ;
  5187. ;
  5188. ; Catch any extra keyboard characters coming through BDOS
  5189. ;
  5190. CKCON:    MVI    C,CONST        ; See if any characters waiting
  5191.     CALL    BDOS
  5192.     ORA    A
  5193.     RZ            ; If not, exit
  5194.     MVI    C,RDCON        ; Otherwise get the character
  5195.     CALL    BDOS
  5196.     XRA    A        ; Discard the character
  5197.     JMP    CKCON        ; See if any others
  5198. ;.....
  5199. ;
  5200. ;
  5201. ; Used in overlay area to permit saying "SET 2400", etc.
  5202. ;
  5203. CMDSPL:    LXI    D,CMDBUF+6
  5204.     LDAX    D
  5205.     CPI    '0'
  5206.     RET
  5207. ;.....
  5208. ;
  5209. ;
  5210. DECOUT:    PUSH    PSW
  5211.     PUSH    B
  5212.     PUSH    D
  5213.     PUSH    H
  5214.     LXI    B,-10
  5215.     LXI    D,-1
  5216. ;
  5217. DECOU1:    DAD    B
  5218.     INX    D
  5219.     JC    DECOU1
  5220.     LXI    B,10
  5221.     DAD    B
  5222.     XCHG
  5223.     MOV    A,H
  5224.     ORA    L
  5225.     CNZ    DECOUT
  5226.     MOV    A,E
  5227.     ADI    '0'
  5228.     CALL    CTYPE
  5229.     POP    H
  5230.     POP    D
  5231.     POP    B
  5232.     POP    PSW
  5233.     RET
  5234. ;.....
  5235. ;
  5236. ;
  5237. ; Displays error statement then resturns to command mode
  5238. ;
  5239. ERXIT:    POP    D
  5240.     CALL    PRTMSG
  5241.     MVI    A,BELL
  5242.     CALL    TYPE
  5243.     CALL    CRLF
  5244. ;
  5245. ERXIT1:    MVI    A,1
  5246.     STA    ABORTFLG    ; Shows an unintentional abort
  5247.     LDA    BATCHFLG    ; In batch mode?
  5248.     ORA    A
  5249.     JNZ    DONETB        ; If not, exit
  5250.     JMP    ABORT        ; Abort other computer
  5251. ;.....
  5252. ;
  5253. ;
  5254. ; Exits directly to CP/M, with no reboot unless you have selected pos-
  5255. ; sible overwriting of 'CCP'
  5256. ;
  5257. EXIT:    LDA    OLDUSER        ; Get original user number back
  5258.     MOV    E,A
  5259.     CALL    STUSER
  5260.     MVI    C,STDMA
  5261.     LXI    D,TBUF        ; Restore original buffer area
  5262.     CALL    BDOS
  5263.     LXI    B,1A00H        ; A little delay timer
  5264. ;
  5265. EXIT1:    DCX    B        ; One less loop to make
  5266.     MOV    A,B
  5267.     ORA    C
  5268.     JNZ    EXIT1        ; Loop again till both are zero
  5269.     CALL    CKCON        ; Catch any extra keyboard characters
  5270.     LDA    NFILFLG        ; Saving for a disk file?
  5271.     ORA    A
  5272.     STA    DONEFLG        ; Set the flag
  5273.     CNZ    WRFIL1        ; If yes, close the file
  5274.     LDA    MSPEED        ; Get the current modem speed
  5275.     STA    STRSPD        ; Store in case we come right back
  5276. ;
  5277. EXIT2:    CALL    J$EXITVEC    ; See if overlay needs to do anything
  5278.     XRA    A        ; Clear the 'A' reg. and all flags
  5279.     LHLD    STACK        ; Get the original stack pointer back
  5280.     SPHL            ; Set the stack pointer to that address
  5281.     RET
  5282. ;.....
  5283. ;
  5284. ;
  5285. ; Include the filename when transferring a file.  Check to see if from
  5286. ; an .ARC, .ARK or .LBR group first.
  5287. ;
  5288. FILNAM:    CALL    ILPRTQ
  5289.     DB    'File name: ',0
  5290.     LXI    H,93
  5291.     MVI    B,8        ; Maximum size of file name
  5292.     CALL    FILN1
  5293.     MOV    A,M        ; Get the next character
  5294.     CPI    32        ; Any file extent?
  5295.     RZ            ; If not, finished
  5296. ;
  5297.     MVI    A,46
  5298.     CALL    TYPE
  5299.     MVI    B,3        ; Maximum size of file extent
  5300. ;
  5301. FILN1:    MOV    A,M        ; Get FCB FILENAME/EXT character
  5302.     CPI    32        ; Skip any blanks
  5303.     CNZ    TYPE
  5304.     INX    H        ; Next FCB position
  5305.     DCR    B        ; One less to go
  5306.     JNZ    FILN1        ; If not done, get next one
  5307.     RET
  5308. ;.....
  5309. ;
  5310. ;
  5311. ; Adjusts loop counter for the selected clock speed.  Returns with delay
  5312. ; in 'HL'.
  5313. ;
  5314. FIXCNT:    LDA    CLOCK        ; Get the user's clock speed
  5315.     PUSH    D        ; Save the current 'DE' value
  5316.     PUSH    H
  5317.     POP    D        ; Get same value into 'DE' as in 'HL'
  5318. ;
  5319. CNTMUL:    DAD    D        ; Add 'DE' to 'HL'
  5320.     DCR    A        ; One less to go
  5321.     JNZ    CNTMUL
  5322.     POP    D        ; Restore current 'DE', delay in 'HL'
  5323.     RET
  5324. ;.....
  5325. ;
  5326. ;
  5327. ; Special routine to let overlays substitute their own printer routines.
  5328. ; Returns with GOLIST+1 and GOLIST+15 addresses.
  5329. ;
  5330. GOLST:    LXI    H,GOLIST+1
  5331.     LXI    D,GOLIST+15
  5332.     RET
  5333. ;.....
  5334. ;
  5335. ;
  5336. ; Prints a hex value in 'A' on the CRT
  5337. ;
  5338. HEXO:    PUSH    PSW
  5339.     RAR
  5340.     RAR
  5341.     RAR
  5342.     RAR
  5343.     CALL    NIBBL
  5344.     POP    PSW
  5345. ;
  5346. NIBBL:    ANI    0FH
  5347.     CPI    10
  5348.     JC    ISNUM
  5349.     ADI    7
  5350. ;
  5351. ISNUM:    ADI    '0'        ; Add in ASCII bias
  5352.     JMP    CTYPE
  5353. ;.....
  5354. ;
  5355. ;
  5356. ; Write a string of characters to the CRT
  5357. ;
  5358. ILPRT:    XTHL
  5359. ;
  5360. ILPRT1:    MOV    A,M        ; Get the character
  5361.     ORA    A        ; See if a "0" for end of string
  5362.     JZ    ILPRT2        ; If yes, all done
  5363.     CALL    CTYPE        ; Show on CRT
  5364.     INX    H        ; Get the next location in the string
  5365.     JMP    ILPRT1
  5366. ;
  5367. ILPRT2:    XTHL            ; Restore the address
  5368.     RET
  5369. ;.....
  5370. ;
  5371. ;
  5372. ; Write a string of characters unless in the Quiet mode
  5373. ;
  5374. ILPRTQ:    XTHL
  5375. ;
  5376. ILPRTQ1:MOV    A,M        ; Get the character
  5377.     ORA    A        ; See if a "0" for end of string
  5378.     JZ    ILPRTQ2        ; If yes, all done
  5379.     LDA    QFLG
  5380.     ORA    A
  5381.     MOV    A,M
  5382.     CNZ    CTYPE        ; Show on CRT if not in quiet mode
  5383.     INX    H        ; Get the next location in the string
  5384.     JMP    ILPRTQ1
  5385. ;
  5386. ILPRTQ2:XTHL            ; Restore the address
  5387.     RET
  5388. ;.....
  5389. ;
  5390. ;
  5391. MOVE128:MVI    B,128
  5392. ;
  5393. MOVE:    MOV    A,M
  5394.     STAX    D
  5395.     INX    H
  5396.     INX    D
  5397.     DCR    B
  5398.     JNZ    MOVE
  5399.     RET
  5400. ;.....
  5401. ;
  5402. ;
  5403. MOVEFCB:LXI    H,FCB+16
  5404.     LXI    D,FCB
  5405.     MVI    B,16
  5406.     CALL    MOVNAM
  5407.     XRA    A
  5408.     STA    FCBSNO
  5409.     STA    FCBEXT
  5410.     RET
  5411. ;.....
  5412. ;
  5413. ;
  5414. ; Prevents accidently including an "ESC" character in a file name
  5415. ;
  5416. MOVNAM:    MOV    A,M
  5417.     CPI    '['-40H        ; ESC character?
  5418.     JNZ    $+5        ; If yes, store normally
  5419.     MVI    A,' '
  5420.     STAX    D
  5421.     INX    D
  5422.     INX    H
  5423.     DCR    B
  5424.     JNZ    MOVNAM
  5425.     RET
  5426. ;.....
  5427. ;
  5428. ;
  5429. ; Initializes speed to that last used, if any, from 03CH MSPEED storage
  5430. ; and restores DTR.
  5431. ;
  5432. SETSPD:    LDA    STRSPD        ; Location of MSPEED from memory
  5433.     ORA    A        ; See if it has been used
  5434.     JZ    SETSP1        ; If not, use normal speed
  5435.     CPI    9+1        ; Takes us up to MSPEED = 19200 bps
  5436.     JNC    SETSP1        ; If more, was not a valid baudrate
  5437.     STA    MSPEED        ; Set former speed, then
  5438. ;
  5439. SETSP1:    JMP    J$INITMOD    ; Go set the speed, done
  5440. ;.....
  5441. ;
  5442. ;
  5443. ; Get a character from the keyboard, convert to upper-case if needed,
  5444. ; and show on CRT
  5445. ;
  5446. KBDCHR:    CALL    KEYIN        ; Get a keyboard character
  5447.     CALL    UCASE        ; Convert to upper case if needed
  5448.     CALL    TYPE        ; Show on CRT
  5449.     RET
  5450. ;.....
  5451. ;
  5452. ;
  5453. LCASE:    CPI    41H        ; Ignore if less than upper case 'A'
  5454.     RC
  5455.     CPI    5AH+1        ; Ignore if more than upper case 'Z'
  5456.     RNC
  5457.     ORI    20H        ; Change to lower case
  5458.     RET
  5459. ;.....
  5460. ;
  5461. ;
  5462. UCASE:    CPI    61H        ; Ignore if less than lower case 'a'
  5463.     RC
  5464.     CPI    7AH+1        ; Ignore if more than lower case 'z'
  5465.     RNC
  5466.     ANI    5FH        ; Else change lower ASCII to upper case
  5467.     RET
  5468. ;.....
  5469. ;
  5470. ;
  5471. ; Displays a string of chracters on the screen
  5472. ;
  5473. PRTMSG:    MVI    C,PRINT        ; Print the string
  5474.     JMP    BDOS
  5475. ;.....
  5476. ;
  5477. ;
  5478. ; Allows the TeleVideo 803 to use the RCVRDY routine for its special
  5479. ; receive-only status register.
  5480. ;
  5481. RCVRSP:    LXI    H,RCVRDY+1
  5482.     RET
  5483. ;.....
  5484. ;
  5485. ;
  5486. ; Displays the control-characters shown in the menu
  5487. ;
  5488. SHFTYPE:PUSH    PSW
  5489.     CALL    ILPRT
  5490.     DB    'ESC-',0
  5491.     POP    PSW
  5492.     CALL    TYPE        ; Show on the CRT
  5493.     JMP    ILPRT
  5494. ;.....
  5495. ;
  5496. ;
  5497. ; Sends the character in 'A' to the modem
  5498. ;
  5499. SNDCHR:    CALL    SNDNOW        ; Wait until modem is ready for char.
  5500.     MOV    A,B        ; Get the original character back
  5501.     JMP    O$MDDATP    ; Send the character to modem, return
  5502. ;.....
  5503. ;
  5504. ;
  5505. ; Initializes CP/M file control blocks AT 5CH and 6CH
  5506. ;
  5507. STFCB:    LXI    D,CMDBUF
  5508.     LXI    H,FCB
  5509.     JMP    CMDLINE
  5510. ;.....
  5511. ;
  5512. ;
  5513. ; Timer routine.  Waits 0.1 seconds for each unit in 'B' reg.
  5514. ;
  5515. TIMER:    PUSH    H
  5516. ;
  5517. TIMER1:    PUSH    B
  5518. ;
  5519. TIMER2:    CALL    J$INMDM        ; 100 ms. delay per loop
  5520.     JNC    TIMER2
  5521.     POP    B
  5522.     DCR    B
  5523.     JNZ    TIMER1
  5524.     POP    H
  5525.     RET
  5526. ;.....
  5527. ;
  5528. ;
  5529. ;=======================================================================
  5530. ;
  5531. ; Loads a command line addressed by 'DE' registers (max # characters in
  5532. ; line in 'DE', number of characters in line in DE+1, line starts in
  5533. ; DE+2) into FCB addressed by 'HL' registers.  The FCB should be at
  5534. ; least 33 bytes in length.  The command line buffer must have a maxi-
  5535. ; mum length at least one more than the greatest number of characters
  5536. ; that will be needed.
  5537.  
  5538. CMDLINE:PUSH    PSW
  5539.     PUSH    B
  5540.     PUSH    D
  5541.     PUSH    H
  5542.     CALL    INITIAL        ; Fills FCBs with blanks and nulls
  5543.     XCHG            ; Get start of command line in HL
  5544.     INX    H        ; Address # bytes in command line
  5545.     MOV    E,M        ; Load DE pair with # bytes
  5546.     MVI    D,0
  5547.     INX    H
  5548.     DAD    D        ; Point to byte after last character
  5549.     MVI    M,CR        ; In command line and store delimiter
  5550.     POP    H        ; Restore HL and DE
  5551.     POP    D
  5552.     PUSH    D
  5553.     PUSH    H
  5554.     INX    D        ; Address start of command
  5555.     INX    D
  5556.     CALL    DRIVE
  5557. ;
  5558.     MVI    C,8        ; Transfer first filename to FCB
  5559.     CALL    TRANS
  5560.     CPI    CR
  5561.     JZ    DONEL
  5562.     CPI    ' '        ; If space, then start of 2nd filename
  5563.     JZ    NAME1
  5564.     POP    H        ; Filetype starts after 8th byte
  5565.     PUSH    H
  5566.     LXI    B,9
  5567.     DAD    B
  5568.     MVI    C,3        ; Transfer type of first file
  5569.     CALL    TRANS
  5570.     CPI    CR
  5571.     JZ    DONEL
  5572. ;
  5573. NAME1:    LDAX    D        ; Eat multiple spaces between names
  5574.     CPI    ' '
  5575.     JNZ    NAME2
  5576.     INX    D
  5577.     JMP    NAME1
  5578. ;
  5579. NAME2:    POP    H        ; Second name starts in 16th byte
  5580.     PUSH    H        ; Point HL to this byte
  5581.     LXI    B,16
  5582.     DAD    B
  5583.     CALL    DRIVE
  5584.     MVI    C,8
  5585.     CALL    TRANS
  5586.     CPI    CR
  5587.     JZ    DONEL
  5588.     POP    H        ; Second file type starts in 25th byte
  5589.     PUSH    H
  5590.     LXI    B,25
  5591.     DAD    B
  5592.     MVI    C,3
  5593.     CALL    TRANS
  5594. ;
  5595. DONEL:    POP    H
  5596.     PUSH    H
  5597.     INX    H        ; Point to 1st char of 1st name in FCB
  5598.     CALL    SCANL        ; Check for * (ambiguous names)
  5599.     POP    H
  5600.     PUSH    H
  5601.     LXI    B,17        ; To 1st character of second name in FCB
  5602.     DAD    B
  5603.     CALL    SCANL
  5604.     POP    H
  5605.     POP    D
  5606.     POP    B
  5607.     POP    PSW
  5608.     RET
  5609. ;.....
  5610. ;
  5611. ;
  5612. ; Subroutines for CMDLINE section
  5613. ;
  5614. INITIAL:PUSH    H        ; Initializes FCB with 1 null for first
  5615.     PUSH    B        ; Drive with 11 blanks, 4 nulls, 1
  5616.     MVI    M,0        ; Null for second drive with 11 blanks
  5617.     INX    H        ; And 4 nulls
  5618.     MVI    B,11
  5619.     MVI    A,' '
  5620.     CALL    INITFILL
  5621.     MVI    B,5
  5622.     XRA    A
  5623.     CALL    INITFILL
  5624.     MVI    B,11
  5625.     MVI    A,' '
  5626.     CALL    INITFILL
  5627.     MVI    B,4
  5628.     XRA    A
  5629.     CALL    INITFILL
  5630.     POP    B
  5631.     POP    H
  5632.     RET
  5633. ;.....
  5634. ;
  5635. ;
  5636. INITFILL:
  5637.     MOV    M,A
  5638.     INX    H
  5639.     DCR    B
  5640.     JNZ    INITFILL
  5641.     RET
  5642. ;.....
  5643. ;
  5644. ;
  5645. DRIVE:    INX    D        ; Check 2nd byte of filename.  if it..
  5646.     LDAX    D        ; Is a ":", then drive was specified..
  5647.     DCX    D
  5648.     CPI    ':'
  5649.     JNZ    DEFDR        ; Else zero for default drive
  5650.     LDAX    D        ; ('INIT' put zero)
  5651.     ANI    5FH
  5652.     SUI    40H        ; Calculate drive (A=1, B=2,...)
  5653.     MOV    M,A        ; Place it in FCB
  5654.     INX    D        ; Address first byte in command line
  5655.     INX    D
  5656. ;
  5657. DEFDR:    INX    H        ; And name field in FCB
  5658.     RET
  5659. ;.....
  5660. ;
  5661. ;
  5662. TRANS:    LDAX    D        ; Transfer from command line to FCB
  5663.     INX    D        ; Up to number of chars specified
  5664.     CPI    CR        ; By 'C' reg.    Keep scanning field
  5665.     RZ            ; Without transfer until a delimiting
  5666.     CPI    '.'        ; Field char such as '.', blank, or
  5667.     RZ            ; CR (for end of commmand line).
  5668.     CPI    ' '
  5669.     RZ
  5670.     DCR    C
  5671.     JM    TRANS        ; Once C-reg is less than zero, keep
  5672.     MOV    M,A        ; Reading command line but do not
  5673.     INX    H        ; Transfer to FCB.
  5674.     JMP    TRANS
  5675. ;...
  5676. ;
  5677. ;
  5678. SCANL:    MVI    B,8        ; Scan file name addressed by HL
  5679. ;
  5680. TSTNAM:    MOV    A,M
  5681.     CPI    '*'        ; If '*' found, fill in rest of field
  5682.     JZ    FILL1        ; With '?' for ambiguous name.
  5683.     INX    H
  5684.     DCR    B
  5685.     JNZ    TSTNAM
  5686.     JMP    TSTTYP
  5687. ;...
  5688. ;
  5689. ;
  5690. FILL1:    CALL    FILL
  5691. ;
  5692. TSTTYP:    MVI    B,3        ; Scan and fill type field for name
  5693. ;
  5694. TSTTYPL:MOV    A,M
  5695.     CPI    '*'
  5696.     JZ    FILL2
  5697.     INX    H
  5698.     DCR    B
  5699.     JNZ    TSTTYPL
  5700.     RET
  5701. ;.....
  5702. ;
  5703. ;
  5704. FILL2:    CALL    FILL
  5705.     RET
  5706. ;.....
  5707. ;
  5708. ;
  5709. FILL:    MVI    M,'?'        ; Routine transfers '?'
  5710.     INX    H
  5711.     DCR    B
  5712.     JNZ    FILL
  5713.     RET
  5714.  
  5715. ;=======================================================================
  5716. ;
  5717. ; LISTS DIRECTORY AND GIVES FREE SPACE REMAINING ON THE REQUESTED DRIVE.
  5718. ;
  5719. ;
  5720. ; Disk system reset - currently bypassed, if you wish this feature, put
  5721. ;    JMP DRLST2 instead of JMP DRLST3 in the eighth line.  The
  5722. ;    current disk (plus the A: drive) will then reset each DIR re-
  5723. ;    quest.    You can also reset the disk with the LOG command when
  5724. ;    when inserting a different one.  This saves a reset each time
  5725. ;    DIR might be requested.
  5726. ;
  5727. DRLST:    CALL    GETDISK
  5728.     ADI    'A'        ; Change to ASCII
  5729.     STA    DRNAME        ; Show for drive name
  5730.     STA    ACTDRV        ; Show for space remaining on drive
  5731.     JMP    DRLST1
  5732.     MVI    C,RESET        ; 13 reset disk system (resetdk)
  5733.     CALL    BDOS
  5734. ;
  5735. ;
  5736. ; Directory list routine
  5737. ;
  5738. DRLST1:    LXI    D,CMDBUF    ; Put command line in FCB
  5739.     LXI    H,FCB
  5740.     CALL    CMDLINE
  5741.     LXI    H,FCB4
  5742.     CALL    INITFCB
  5743.     LDA    FCB2        ; Get drive number
  5744.     STA    FCB4
  5745.     LDA    FCB2+1
  5746.     CPI    ' '        ; If a space (blank) get all names
  5747.     PUSH    PSW
  5748.     CZ    QSTMARK
  5749.     POP    PSW
  5750.     CNZ    MOVNAME        ; Else move name into FCB
  5751.     CALL    DRIVEL
  5752.     MVI    C,STDMA
  5753.     LXI    D,TBUF
  5754.     CALL    BDOS
  5755.     LDA    NOFCOL        ; Number of columns into 'A' register
  5756.     STA    NAMECT        ; CRLF after 'NOFCOL' number of columns
  5757.     LXI    D,FCB4
  5758.     MVI    C,SRCHF        ; Do first search
  5759.     CALL    BDOS
  5760.     INR    A        ; 0FFH --> 0 if no file(s) found
  5761.     JNZ    DIRLOOP
  5762.     CALL    ILPRT
  5763.     DB    '++ FILE NOT FOUND ++',0
  5764.     JMP    STORAGE        ; Still show storage on default drive
  5765. ;
  5766. DIRLOOP:CALL    GETADD
  5767.     INX    H        ; Point to first letter of filename
  5768.     LXI    D,PRTNAME
  5769.     LXI    B,8
  5770.     CALL    MOVER
  5771.     INX    D
  5772.     LXI    B,3
  5773.     CALL    MOVER
  5774.     CALL    ILPRT
  5775. ;
  5776. PRTNAME:DB    '        ','.','   ',0 ; 8 spaces, period, 3 spaces
  5777. ;
  5778. NEXTSR:    LXI    D,FCB4
  5779.     MVI    C,SRCHN        ; Do next search
  5780.     CALL    BDOS
  5781.     INR    A        ; If 0FFH --> 0 directory read is done
  5782.     JZ    STORAGE
  5783.     PUSH    PSW
  5784.     PUSH    D
  5785.     PUSH    H
  5786.     LDA    NAMECT
  5787.     DCR    A
  5788.     STA    NAMECT        ; Name count updated
  5789.     ORA    A
  5790.     CZ    CRLF        ; Terminate line of file names
  5791.     JNZ    FENCE
  5792.     LDA    NOFCOL        ; Restart columns-per-line count
  5793.     STA    NAMECT
  5794.     JMP    NOFENCE        ; Fence not needed
  5795. ;
  5796. FENCE:    CALL    ILPRT
  5797.     DB    ' : ',0        ; Fence if not at end of line or
  5798. ;                ;   last filename
  5799. NOFENCE:POP    H
  5800.     POP    D
  5801.     POP    PSW
  5802.     JMP    DIRLOOP
  5803. ;.....
  5804. ;
  5805. ;
  5806. ; Determine storage remaining on default drive
  5807. ;
  5808. STORAGE:CALL    CKCPM3
  5809.     MVI    C,DSKPAR    ; Current disk parameter block
  5810.     CALL    BDOS
  5811.     INX    H
  5812.     INX    H
  5813.     MOV    A,M        ; Get block shift factor
  5814.     STA    BSHIFTF
  5815.     INX    H        ; Bump to block mask
  5816.     MOV    A,M        ; Get it
  5817.     STA    BMASK
  5818.     INX    H
  5819.     INX    H
  5820.     MOV    E,M        ; Get maximum block number
  5821.     INX    H
  5822.     MOV    D,M
  5823.     XCHG
  5824.     SHLD    BMAX        ; Put it away
  5825.     MVI    C,DSKALL    ; Address of CP/M allocation vector
  5826.     CALL    BDOS
  5827.     XCHG            ; Get its length
  5828.     LHLD    BMAX
  5829.     INX    H
  5830.     LXI    B,0        ; Initialize block count to zero
  5831. ;
  5832. GSPBYT:    PUSH    D        ; Save allocation address
  5833.     LDAX    D
  5834.     MVI    E,8        ; Set to process 8 blocks
  5835. ;
  5836. GSPLUP:    RAL            ; Test bit
  5837.     JC    NOTFRE
  5838.     INX    B
  5839. ;
  5840. NOTFRE:    MOV    D,A        ; Save bits
  5841.     DCX    H
  5842.     MOV    A,L
  5843.     ORA    H
  5844.     JZ    ENDALC        ; Quit if out of blocks
  5845.     MOV    A,D        ; Restore bits
  5846.     DCR    E        ; Count down 8 bits
  5847.     JNZ    GSPLUP        ; Do another bit
  5848.     POP    D        ; Next count of allocation vector
  5849.     INX    D
  5850.     JMP    GSPBYT        ; Process it
  5851. ;
  5852. ENDALC:    POP    D        ; Clear alloc vector pointer from stack
  5853.     MOV    L,C        ; Copy block to HL
  5854.     MOV    H,B
  5855.     LDA    BSHIFTF        ; Get block shift factor
  5856.     SUI    3        ; Convert from records to thousands (k)
  5857.     JZ    PRTFREE        ; Skip shifts if 1k blocks
  5858. ;
  5859. FREKLP:    DAD    H        ; Multiply blocks by 'k' per block
  5860.     DCR    A
  5861.     JNZ    FREKLP
  5862. ;
  5863. PRTFREE:CALL    DECOUT        ; (number of free 'k' bytes now in 'HL')
  5864.     LXI    D,FREEMSG
  5865.     JMP    PRTMSG
  5866. ;.....
  5867. ;
  5868. ;
  5869. ; Subroutines for 'DRLST' section
  5870. ;
  5871. QSTMARK:MVI    A,'?'        ; If blank in FCB, put in 11 ?'S
  5872.     MVI    B,11
  5873.     LXI    H,FCB4+1
  5874. ;
  5875. QSTLP:    MOV    M,A
  5876.     INX    H
  5877.     DCR    B
  5878.     JNZ    QSTLP
  5879.     RET
  5880. ;.....
  5881. ;
  5882. ;
  5883. MOVNAME:LXI    H,FCB2+1
  5884.     LXI    D,FCB4+1
  5885.     LXI    B,11
  5886.     CALL    MOVER
  5887.     RET
  5888. ;.....
  5889. ;
  5890. ;
  5891. GETADD:    DCR    A        ; Undo the INR above
  5892.     ADD    A        ; Times 32
  5893.     ADD    A
  5894.     ADD    A
  5895.     ADD    A
  5896.     ADD    A
  5897.     ADI    TBUF        ; Add buffer offset
  5898.     MOV    L,A
  5899.     MVI    H,0
  5900.     RET
  5901. ;.....
  5902. ;
  5903. ;
  5904. DRIVEL:    LDA    FCB4        ; Use default drive in DRNAME
  5905.     ORA    A
  5906.     JZ    PRNTHD
  5907.     PUSH    PSW
  5908.     DCR    A
  5909.     MOV    E,A
  5910.     MVI    C,SELDSK
  5911.     CALL    BDOS
  5912.     POP    PSW
  5913.     ADI    40H        ; Make 1=A, 2=B, etc.
  5914.     STA    DRNAME        ; Overwrite default stored below
  5915.     STA    ACTDRV
  5916. ;
  5917. PRNTHD:    CALL    ILPRT
  5918.     DB    'Drive '
  5919. ;
  5920. DRNAME:    DB    ' :',CR,LF,0
  5921.     RET
  5922. ;.....
  5923. ;
  5924. ;
  5925. ; Initialized storage
  5926. ;
  5927. FREEMSG:DB    'k bytes free on drive '
  5928. ACTDRV:    DB    ' :',CR,LF,'$'
  5929. ;
  5930. ;
  5931. ; Uninitialized storage
  5932. ;
  5933. BMAX:    DB    0,0        ; Highest block number on drive
  5934. BMASK:    DB    0        ; Rec/blk - 1
  5935. BSHIFTF:DB    0        ; # of shifts to multiply by rec/blk
  5936. ;.....
  5937. ;
  5938. ;
  5939. ; CALCULATES DISK SPACE REMAINING IF CP/M+
  5940. ;
  5941. CKCPM3:    CALL    CRLF
  5942.     MVI    C,CPMVER    ; Check version #
  5943.     CALL    BDOS
  5944.     MOV    A,L
  5945.     CPI    30H        ; Version 3.0?
  5946.     RC            ; Use normal method if not CP/M+
  5947.     POP    H        ; Remove "call CKCPM3" from stack
  5948.     MVI    C,CURDSK
  5949.     CALL    BDOS
  5950.     MOV    E,A
  5951.     MVI    C,46        ; CP/M+ compute free space call
  5952.     CALL    BDOS
  5953.     MVI    C,3        ; Answer is 3 bytes long (24 bits)
  5954. ;
  5955. FREE30:    LXI    H,TBUF+2    ; Answer is located here
  5956.     MVI    B,3        ; Convert to 'k' length
  5957.     ORA    A
  5958. ;
  5959. FREE31:    MOV    A,M
  5960.     RAR
  5961.     MOV    M,A
  5962.     DCX    H
  5963.     DCR    B
  5964.     JNZ    FREE31        ; Loop for 3 bytes
  5965.     DCR    C
  5966.     JNZ    FREE30        ; Shift 3 times
  5967.     LHLD    TBUF        ; Get result in 'k'
  5968.     JMP    PRTFREE        ; Display result
  5969. ;.....
  5970. ;
  5971. ;            end of directory routine
  5972. ;=======================================================================
  5973. ;
  5974. ; Duplicates 'READ BUFFER' routine same as CP/M function 10, but does
  5975. ; not use CTL-C (reason for the routine).  Does allow controls U, R and
  5976. ; H (BACKSPACE).  Outputs bell if the input is greater than the buffer.
  5977. ;
  5978. INBUF:    PUSH    PSW
  5979.     PUSH    H
  5980.     PUSH    B
  5981.     PUSH    D        ; 'DE' registers must be pushed last
  5982. ;
  5983. INBUFA:    CALL    CLEARBUF    ; Clear the buffer area
  5984.     POP    D        ; Get address of buffer on retries
  5985.     PUSH    D        ; Restore stack
  5986.     XRA    A
  5987.     INX    D        ; Address count field
  5988.     STAX    D        ; Initialize with a zero in count byte
  5989.     INX    D
  5990.     XCHG            ; Address first buffer byte with 'HL'
  5991. ;
  5992. INBUFB:    CALL    KEYIN        ; Waits for a charcter
  5993.     CALL    UCASE        ; Convert to upper case if needed
  5994.     CPI    CR        ; Is it <return> (enter command)?
  5995.     JZ    INBUFR        ; If so, then return
  5996.     CPI    'H'-40H        ; CTL-H backspaces over deleted char.
  5997.     JZ    DELETE
  5998.     CPI    7FH        ; Is it a delete?
  5999.     JZ    DELETE
  6000.     CPI    'U'-40H        ; Is it a CTL-U?
  6001.     JZ    INBUFO        ; Output #, CR, LF, and start over
  6002.     CPI    'R'-40H        ; CTL-R retypes line
  6003.     JZ    RETYPE
  6004.     CPI    CLEARSC        ; Want to clear CRT?
  6005.     JZ    CLRS        ; If yes, go clear screen
  6006. ;
  6007.     MOV    B,A        ; Save inputted character
  6008.     XCHG            ; Save 'HL' in 'DE'
  6009.     POP    H        ; Get address of buffer in 'HL'
  6010.     PUSH    H        ; Restore stack
  6011.     INX    H        ; Address count byte
  6012.     INR    M        ; Increase count byte
  6013.     DCX    H        ; Address maximum
  6014.     MOV    A,M        ; Put maximum in 'A'
  6015.     INX    H        ; Address count
  6016.     CMP    M        ; Compare count to maximum
  6017.     JC    ALERTL        ; If maximum, ring bell and wait for CR
  6018.     XCHG            ; Restore buffer pointer to 'HL'
  6019.     MOV    M,B        ; Put inputted character in buffer
  6020.     MOV    A,B        ; Output it
  6021.     CPI    20H        ; Printing character?
  6022.     CNC    TYPE        ; If yes, print it
  6023.     INX    H        ; Bump pointer
  6024.     JMP    INBUFB        ; Get next character
  6025. ;...
  6026. ;
  6027. ;
  6028. DELETE:    XCHG            ; Save buffer pointer in 'DE'
  6029.     POP    H        ; Address beginning of buffer
  6030.     PUSH    H        ; Restore stack
  6031.     INX    H        ; Address count field
  6032.     MOV    A,M
  6033.     SUI    1        ; Decrease count
  6034.     MOV    M,A
  6035.     JC    NODEL        ; Don't delete past beginning of buffer
  6036.     XCHG            ; Restore buffer pointer to 'HL'
  6037.     DCX    H        ; Point to last byte inputted
  6038.     MOV    A,M        ; Get the character being deleted
  6039.     MVI    M,' '        ; Restore blank
  6040.     CPI    ' '        ; See if a non-printing character
  6041.     JC    INBUFB        ; If yes, skip the CRT backup
  6042.     MVI    A,BKSP
  6043.     CALL    TYPE        ; True erase if 08H
  6044.     MVI    A,' '
  6045.     CALL    TYPE
  6046.     MVI    A,BKSP
  6047.     CALL    TYPE
  6048.     JMP    INBUFB
  6049. ;.....
  6050. ;
  6051. ;
  6052. NODEL:    INR    M        ; Don't leave count negative
  6053.     XCHG            ; Restore pointer to 'HL'
  6054.     MVI    A,BELL        ; Says can go no further
  6055.     CALL    TYPE
  6056.     JMP    INBUFB
  6057. ;.....
  6058. ;
  6059. ;
  6060. INBUFO:    MVI    A,'#'        ; Announces the line has been removed
  6061.     CALL    TYPE
  6062.     CALL    CRLF
  6063.     JMP    INBUFA
  6064. ;.....
  6065. ;
  6066. ;
  6067. RETYPE:    POP    D
  6068.     PUSH    D
  6069.     INX    D        ; Point to current number of characters
  6070.     LDAX    D
  6071.     MOV    B,A
  6072.     MVI    A,'#'
  6073.     CALL    TYPE
  6074.     CALL    CRLF
  6075.     MOV    A,B        ; Test if zero input
  6076.     ORA    A
  6077.     JZ    INBUFB
  6078. ;...
  6079. ;
  6080. ;
  6081. CTLRLP:    INX    D
  6082.     LDAX    D
  6083.     CALL    TYPE
  6084.     DCR    B
  6085.     JNZ    CTLRLP
  6086.     JMP    INBUFB
  6087. ;.....
  6088. ;
  6089. ;
  6090. ALERTL:    MVI    A,BELL        ; Alarm for full buffer
  6091.     CALL    TYPE
  6092.     DCR    M
  6093.     XCHG
  6094.     JMP    INBUFB
  6095. ;.....
  6096. ;
  6097. ;
  6098. INBUFR:    CALL    CRLF        ; 1st new line after a command character
  6099.     POP    D
  6100.     POP    B
  6101.     POP    H
  6102.     POP    PSW
  6103.     RET
  6104. ;.....
  6105. ;
  6106. ;
  6107. CLEARBUF:
  6108.     POP    D        ; Accounts for call
  6109.     POP    H        ; Address buffer in 'HL'
  6110.     PUSH    H        ; Restore stack
  6111.     PUSH    D
  6112.     MOV    B,M        ; Save maximum in 'B'
  6113.     INX    H        ; Point to first buffer byte
  6114.     INX    H
  6115.     MVI    A,' '
  6116. ;
  6117. CLEARL:    MOV    M,A
  6118.     INX    H
  6119.     DCR    B
  6120.     JNZ    CLEARL
  6121.     RET
  6122. ;.....
  6123. ;
  6124. ;
  6125. ;=======================================================================
  6126. ;
  6127. ; In-line compare.  Compares string addressed by 'DE' to string after
  6128. ; call (ends with zero).  Return with carry set means strings not the
  6129. ; same.  All registers except 'A'-reg are unaffected.
  6130. ;
  6131. INLNCP:    XTHL            ; Point 'HL' to 1st character
  6132.     PUSH    D
  6133. ;
  6134. ILCOMPL:MOV    A,M        ; 'HL' points to in-line string
  6135.     ORA    A        ; End of string if zero
  6136.     JZ    SAME
  6137.     LDAX    D
  6138.     CMP    M
  6139.     JNZ    NOTSAME
  6140.     INX    H
  6141.     INX    D
  6142.     JMP    ILCOMPL
  6143. ;...
  6144. ;
  6145. ;
  6146. NOTSAME:XRA    A
  6147. ;
  6148. NSLP:    INX    H
  6149.     CMP    M
  6150.     JNZ    NSLP
  6151.     STC
  6152. ;
  6153. SAME:    POP    D
  6154.     INX    H        ; Avoids a NOP instruction when done
  6155.     XTHL
  6156.     RET
  6157. ;.....
  6158. ;
  6159. ;
  6160. ;=======================================================================
  6161. ;          MULTI-FILE ACCESS ROUTINE
  6162. ;
  6163. ; Multi-file access subroutine.  Allows processing of multiple files
  6164. ; (i.e., *.ASM) from disk.  Builds the correct name in the FCB each time
  6165. ; it is called.  The command is used in programs to process single or
  6166. ; multiple files.  The FCB is set up with the next name, ready to do
  6167. ; normal processing (open, read, etc.) when routine is called.    Carry is
  6168. ; set if no more names are found.
  6169.  
  6170. MFNAM:    PUSH    B
  6171.     PUSH    D
  6172.     PUSH    H
  6173.     MVI    C,STDMA
  6174.     LXI    D,TBUF
  6175.     CALL    BDOS
  6176.     POP    H
  6177.     POP    D
  6178.     POP    B
  6179.     XRA    A
  6180.     STA    FCBEXT
  6181.     LDA    MFFLG1
  6182.     ORA    A
  6183.     JNZ    MFNAM1
  6184.     MVI    A,1
  6185.     STA    MFFLG1
  6186.     LXI    H,FCB
  6187.     LXI    D,MFNAM5
  6188.     LXI    B,12
  6189.     CALL    MOVER
  6190.     LDA    FCB
  6191.     STA    MFNAM6        ; Save disk in current FCB
  6192.     LXI    H,MFNAM5
  6193.     LXI    D,FCB
  6194.     LXI    B,12
  6195.     CALL    MOVER
  6196.     PUSH    B
  6197.     PUSH    D
  6198.     PUSH    H
  6199.     MVI    C,SRCHF
  6200.     LXI    D,FCB
  6201.     CALL    BDOS
  6202.     POP    H
  6203.     POP    D
  6204.     POP    B
  6205.     JMP    MFNAM2
  6206. ;...
  6207. ;
  6208. ;
  6209. MFNAM1:    LXI    H,MFNAM6
  6210.     LXI    D,FCB
  6211.     LXI    B,12
  6212.     CALL    MOVER
  6213.     PUSH    B
  6214.     PUSH    D
  6215.     PUSH    H
  6216.     MVI    C,SRCHF
  6217.     LXI    D,FCB
  6218.     CALL    BDOS
  6219.     POP    H
  6220.     POP    D
  6221.     POP    B
  6222.     LXI    H,MFNAM5
  6223.     LXI    D,FCB
  6224.     LXI    B,12
  6225.     CALL    MOVER
  6226.     PUSH    B
  6227.     PUSH    D
  6228.     PUSH    H
  6229.     MVI    C,SRCHN
  6230.     LXI    D,FCB
  6231.     CALL    BDOS
  6232.     POP    H
  6233.     POP    D
  6234.     POP    B
  6235. ;
  6236. MFNAM2:    INR    A
  6237.     STC
  6238.     JNZ    MFNAM3
  6239.     STA    MFFLG1
  6240.     RET
  6241. ;.....
  6242. ;
  6243. ;
  6244. MFNAM3:    DCR    A
  6245.     ANI    3
  6246.     ADD    A
  6247.     ADD    A
  6248.     ADD    A
  6249.     ADD    A
  6250.     ADD    A
  6251.     ADI    81H
  6252.     MOV    L,A
  6253.     MVI    H,0
  6254.     PUSH    H        ; Save name pointer
  6255.     LXI    D,MFNAM6+1
  6256.     LXI    B,11
  6257.     CALL    MOVER
  6258.     POP    H
  6259.     LXI    D,FCB+1
  6260.     LXI    B,11
  6261.     CALL    MOVER
  6262.     XRA    A
  6263.     STA    FCBEXT
  6264.     STA    FCBRNO
  6265.     RET
  6266. ;.....
  6267. ;
  6268. ;
  6269. MOVER:    MVI    A,2
  6270.     INR    A
  6271.     JPE    MFNAM4
  6272.     DB    0EDH,0B0H    ; Z-80 'LDIR' instruction
  6273.     RET
  6274. ;.....
  6275. ;
  6276. ;
  6277. MFNAM4:    MOV    A,M        ; Used if an 8080 CPU is active
  6278.     STAX    D
  6279.     INX    H
  6280.     INX    D
  6281.     DCX    B
  6282.     MOV    A,B
  6283.     ORA    C
  6284.     JNZ    MFNAM4
  6285.     RET
  6286. ;.....
  6287. ;
  6288. ;        (END OF MULTI-FILE ACCESS ROUTINE)
  6289. ;=======================================================================
  6290. ;         CALCULATE FILE TRANSFER TIME
  6291. ;
  6292. ;
  6293. ; Shows the time to transfer a file at various baud rates.  (110-19200)
  6294. ;
  6295. SNDTM:    CALL    ILPRT
  6296.     DB    'File open: ',0
  6297.     LHLD    RCNT        ; Get record count
  6298.     CALL    DECOUT        ; Print decimal number of records
  6299.     PUSH    H
  6300.     CALL    ILPRT
  6301.     DB    ' records (',0
  6302.     POP    H        ; Get # of 128 byte records
  6303.     LXI    D,8        ; Divide by 8
  6304.     CALL    DVHLDE        ; To get # of 1024 byte blocks
  6305.     MOV    A,H
  6306.     ORA    L        ; Check if remainder
  6307.     MOV    H,B        ; Get quotient
  6308.     MOV    L,C
  6309.     JZ    $+4        ; If 0 remainder, exact kilobytes
  6310.     INX    H        ; Else, increment to next 'k'
  6311.     CALL    DECOUT        ; Show # of kilobytes
  6312.     LDA    SNDFLG        ; Receiving batch mode now?
  6313.     ORA    A
  6314.     RNZ            ; If yes, all done
  6315. ;
  6316. ;
  6317. ; Show transfer time, first for 1k blocks, then for 128 (skip the 1k
  6318. ; times for slower than 1200 bps.)for 1200 bps
  6319. ;
  6320.     CALL    ILPRT
  6321.     DB    'k)',CR,LF,'Send time: ',0
  6322. ;
  6323.     LDA    MSPEED
  6324.     CPI    5        ; 1200 bps
  6325.     JC    XMDSPD        ; Skip KMD speed if less than 1200 bps
  6326. ;
  6327. KMDSPD:    LXI    H,KECTBL
  6328.     SHLD    RECTBL+1
  6329.     CALL    KTIM        ; Get file transfer time in BC (minutes)
  6330.     CALL    SNDTM1
  6331.     CALL    ILPRT
  6332.     DB    ' - 1k size',CR,LF,'Send time: ',0
  6333. ;
  6334. XMDSPD:    LXI    H,XECTBL
  6335.     SHLD    RECTBL+1
  6336.     CALL    XTIM        ; Get file transfer time in BC (minutes)
  6337.     CALL    SNDTM1
  6338.     CALL    ILPRT
  6339.     DB    ' - 128 size',CR,LF,CR,LF,0
  6340.     CALL    FILNAM
  6341.     CALL    ILPRT
  6342.     DB    CR,LF,'File open, ready to send',CR,LF,0
  6343.     RET
  6344. ;.....
  6345. ;
  6346. ;
  6347. SNDTM1:    PUSH    H        ; Save seconds in 'L'
  6348.     MOV    L,C
  6349.     MOV    H,B
  6350.     CALL    DECOUT        ; Print decimal number of minutes
  6351.     CALL    ILPRT
  6352.     DB    ':',0
  6353.     POP    H        ; Get seconds
  6354. ;
  6355.     CALL    ZERO        ; See if 10 or more seconds
  6356.     CALL    DECOUT        ; Print the seconds portion
  6357.     CALL    ILPRT
  6358.     DB    ' at ',0
  6359.     CALL    PRTBAUD
  6360.     RET
  6361. ;.....
  6362. ;
  6363. ;
  6364. PRTBAUD:LXI    H,SPTBL        ; Start of baud rate speeds
  6365.     MVI    D,0        ; Zero the 'D' register
  6366.     LDA    MSPEED        ; Get speed indicator
  6367.     ADD    A        ; Index into the baud rate table
  6368.     ADD    A
  6369.     MOV    E,A        ; Now have the index factor in 'DE'
  6370.     DAD    D        ; Add to 'HL'
  6371.     XCHG            ; Put address in 'DE' regs.
  6372.     MVI    C,PRINT        ; Show the baud
  6373.     CALL    BDOS
  6374.     LDA    MSPEED
  6375.     CPI    5
  6376.     JC    PRTBD1        ; Adds a zero for 2400, 4800, 9600 bps
  6377.     CALL    ILPRT
  6378.     DB    '0',0
  6379. ;
  6380. PRTBD1:    CALL    ILPRT
  6381.     DB    ' bps',0
  6382.     RET
  6383. ;.....
  6384. ;
  6385. ;
  6386. KTABLE:     IF    NOT STOPBIT    ; One stop bit
  6387.     DW    5,14,21,27,32,54,101,190,330,525,0
  6388.      ENDIF            ; NOT STOPBIT
  6389. ;
  6390.      IF    STOPBIT        ; Two stop bits
  6391.     DW    5,13,19,25,29,49,92,173,300,477,0
  6392.      ENDIF            ; STOPBIT
  6393.  
  6394. KECTBL:     IF    NOT STOPBIT    ; One stop bit
  6395.     DB    192,69,46,36,30,18,9,5,3,2,0
  6396.      ENDIF            ; NOT STOPBIT
  6397. ;
  6398.      IF    STOPBIT        ; Two stop bits
  6399.     DB    192,74,51,38,33,20,10,6,3,2,0
  6400.      ENDIF            ; STOPBIT
  6401. ;
  6402. ;
  6403. XTABLE:     IF    NOT STOPBIT    ; One stop bit
  6404.     DW    5,13,19,25,30,48,86,141,210,280,0
  6405.      ENDIF            ; NOT STOPBIT
  6406. ;
  6407.      IF    STOPBIT        ; Two stop bits
  6408.     DW    5,12,18,23,27,44,79,128,191,255,0
  6409.      ENDIF            ; STOPBIT
  6410.  
  6411. XECTBL:     IF    NOT STOPBIT    ; One stop bit
  6412.     DB    192,74,51,38,32,20,11,8,5,3,0
  6413.      ENDIF            ; NOT STOPBIT
  6414. ;
  6415.      IF    STOPBIT        ; Two stop bits
  6416.     DB    192,80,53,42,36,22,12,7,5,4,0
  6417.      ENDIF            ; STOPBIT
  6418. ;
  6419. SPTBL:    DB    '110$','300$','450$','600$','710$','120$','240$'
  6420.     DB    '480$','960$','1920$'
  6421. ;.....
  6422. ;
  6423. ;
  6424. ; Pass record count in RCNT: returns file's approximate download/upload
  6425. ; time in minutes in BC, seconds in 'L', also stuffs the # of mins/secs
  6426. ; values in PGSIZE if LOGCAL is YES.
  6427. ;
  6428. KTIM:    LXI    H,KTABLE
  6429.     JMP    FILTIM
  6430. ;
  6431. XTIM:    LXI    H,XTABLE    ; Point to baud factor table
  6432. ;
  6433. FILTIM:    LDA    MSPEED        ; Get speed indicator
  6434.     MVI    D,0
  6435.     MOV    E,A        ; Set up for table access
  6436.     DAD    D        ; Index to proper factor
  6437.     DAD    D
  6438.     MOV    E,M
  6439.     INX    H
  6440.     MOV    D,M
  6441.     LHLD    RCNT        ; Get number of records
  6442.     CALL    DVHLDE        ; Divide HL by value in DE (records/min)
  6443.     PUSH    H        ; Save remainder
  6444. ;
  6445. RECTBL:    LXI    H,KECTBL    ; Point to divisors for seconds calc.
  6446.     MVI    D,0
  6447.     LDA    MSPEED        ; Get speed indicator
  6448.     MOV    E,A
  6449.     DAD    D        ; Index into table
  6450.     MOV    A,M        ; Get multiplier
  6451.     POP    H        ; Get remainder
  6452.     CALL    MULHLA        ; Multiply 'H' by 'A'
  6453.     CALL    SHFTHL
  6454.     CALL    SHFTHL
  6455.     CALL    SHFTHL
  6456.     CALL    SHFTHL
  6457.     MVI    H,0        ; HL now = seconds (L=secs,H=0)
  6458.     MOV    A,L        ; See if 59 or less seconds
  6459.     CPI    60
  6460.     RC            ; If yes, all done
  6461.     SUI    60        ; Otherwise subtract 60 seconds
  6462.     MOV    L,A        ; Store what is left
  6463.     INR    C        ; Increments the minutes count
  6464.     RET            ; End of SNDTM routine
  6465. ;.....
  6466. ;
  6467. ;
  6468. ZERO:    MOV    A,L        ; Get the number of seconds
  6469.     CPI    9+1        ; 10 seconds or more?
  6470.     RNC            ; If yes, disregard
  6471.     CALL    ILPRT
  6472.     DB    '0',0
  6473.     RET
  6474. ;.....
  6475. ;
  6476. ;
  6477. ;---->    DVHLDE: Divides 'HL' by value in 'DE',
  6478. ;    Upon exit: 'BC'=quotient,'L'=remainder
  6479. ;
  6480. DVHLDE:    PUSH    D        ; Save divisor
  6481.     MOV    A,E
  6482.     CMA            ; Negate divisor
  6483.     MOV    E,A
  6484.     MOV    A,D
  6485.     CMA
  6486.     MOV    D,A
  6487.     INX    D        ; 'DE' is now two's complemented
  6488.     LXI    B,0        ; Init quotient
  6489. ;
  6490. DIVL1:    DAD    D        ; Subtract divisor from dividend
  6491.     INX    B        ; Bump quotient
  6492.     JC    DIVL1        ; Loop till sign changes
  6493.     DCX    B        ; Adjust quotient
  6494.     POP    D        ; Retrieve divisor
  6495.     DAD    D        ; Adjust remainder
  6496.     RET
  6497. ;.....
  6498. ;
  6499. ;
  6500. ;---->    MULHLA:  Multiply the value in 'HL' by the value in 'A'
  6501. ;         Return with answer in 'HL'
  6502. ;
  6503. MULHLA:    XCHG            ; Multiplicand to 'DE'
  6504.     LXI    H,0        ; Init product
  6505.     INR    A        ; Adjust multiplier for zero test
  6506. ;
  6507. MULLP:    DCR    A
  6508.     RZ
  6509.     DAD    D
  6510.     JMP    MULLP
  6511. ;.....
  6512. ;
  6513. ;
  6514. ; Shift 'HL' register pair one bit to the right
  6515. ;
  6516. SHFTHL:    MOV    A,L
  6517.     RAR
  6518.     MOV    L,A
  6519.     ORA    A        ; Clear the carry
  6520.     MOV    A,H
  6521.     RAR
  6522.     MOV    H,A
  6523.     RNC
  6524.     MVI    A,128
  6525.     ORA    L
  6526.     MOV    L,A
  6527.     RET
  6528. ;.....
  6529. ;
  6530. ;        (END OF FILE TRANSFER TIME ROUTINE)
  6531. ;=======================================================================
  6532. ;             CRC SUBROUTINES
  6533. ;
  6534. ;
  6535. ; Check 'CRC' bytes of record just received
  6536. ;
  6537. CRCCHK:    PUSH    H
  6538.     LHLD    CRCVAL
  6539.     MOV    A,H
  6540.     ORA    L
  6541.     POP    H
  6542.     RZ
  6543.     MVI    A,0FFH
  6544.     RET
  6545. ;.....
  6546. ;
  6547. ;
  6548. ; Generate the CRC tables for fast calculations
  6549. ;
  6550. CRCGN:    LXI    H,CRCTBL    ; Address at start of 'CRC' lookup table
  6551.     MVI    C,0
  6552. ;
  6553. CRCGN1:    XCHG            ; Store table location into 'DE'
  6554.     LXI    H,0        ; Clear 'HL' pair
  6555.     MOV    A,C
  6556.     PUSH    B
  6557.     MVI    B,8
  6558.     XRA    H
  6559.     MOV    H,A
  6560. ;
  6561. CRCGN2:    DAD    H        ; Index into the table
  6562.     JNC    CRCGN3
  6563.     MVI    A,16        ; Using x^ 16 + x^12 + x^5 + 1 algorithm
  6564.     XRA    H
  6565.     MOV    H,A
  6566.     MVI    A,32+1
  6567.     XRA    L
  6568.     MOV    L,A
  6569. ;
  6570. CRCGN3:    DCR    B
  6571.     JNZ    CRCGN2        ; Make 8 loops, one for each bit
  6572. ;
  6573. ;
  6574. ; Value now in 'HL', table address still stored in 'DE'.  Exchange, and
  6575. ; store the 'CRC' value in the two tables after splitting.
  6576. ;
  6577.     POP    B        ; Finished borrowing the 'B' reg.
  6578.     XCHG            ; Address back in 'HL', 'CRC' in 'DE'
  6579.     MOV    M,D        ; Store 1st part of 'CRC' value
  6580.     INR    H        ; Move up 256 bytes
  6581.     MOV    M,E        ; Store 2nd part of 'CRC' value
  6582.     DCR    H        ; Move back 256 bytes
  6583.     INX    H        ; Increment to next location
  6584.     INR    C        ; Done when 'C' reg. turns zero again
  6585.     JNZ    CRCGN1        ; Now go do the next location
  6586.     RET
  6587. ;.....
  6588. ;
  6589. ;
  6590. ; Update the CRC value from a character in the 'A' register
  6591. ;
  6592. CRCUPD:    PUSH    PSW        ; Save all registers just in case
  6593.     PUSH    B
  6594.     PUSH    D
  6595.     PUSH    H
  6596.     LHLD    CRCVAL        ; Get current value
  6597.     XCHG            ; Put in 'DE' for now
  6598.     MVI    B,0
  6599.     XRA    D
  6600.     MOV    C,A        ; Now have the character in 'BC' pair
  6601.     LXI    H,CRCTBL    ; Start of 'CRC' lookup-table
  6602.     DAD    B        ; Index into the 'CRC' table
  6603.     MOV    A,M        ; Get the value from the table
  6604.     XRA    E
  6605.     MOV    D,A
  6606.     INR    H        ; Move 256 bytes for 2nd table location
  6607.     MOV    E,M        ; Put value there into 'E' register
  6608.     XCHG            ; Put 'DE' into 'HL'
  6609.     SHLD    CRCVAL        ; Updated 'CRC' value with this character
  6610.     POP    H        ; Restore all registers
  6611.     POP    D
  6612.     POP    B
  6613.     POP    PSW
  6614.     RET
  6615. ;.....
  6616. ;
  6617. ;
  6618. ;==================== END OF CRC SUBROUTINE ============================
  6619. ;
  6620. ;
  6621. ;=========================START OF MENU ================================
  6622. ;
  6623. ;
  6624. MENU0:    LDA    NFILFLG
  6625.     ORA    A
  6626.     JZ    MENU        ; Exit if not saving memory for disk file
  6627.     CALL    ILPRT        ; Else print message
  6628.     DB    CR,LF,'** File still open, use DEL, DIR, WRT, E, L '
  6629.     DB    'or T ** ',CR,LF,BELL,0
  6630.     JMP    MENU1
  6631. ;
  6632. MENU:    XRA    A
  6633.     STA    ABORTFLG    ; Null the flag
  6634. ;
  6635. MENU1:    LXI    H,RESTSN    ; Restore record numbers..
  6636.     LXI    D,RECNOB    ; For new file transfer.
  6637.     MVI    B,RECNOE-RECNOB
  6638.     CALL    MOVE
  6639.     LXI    H,RESTROPT    ; Restore option table
  6640.     LXI    D,OPTBL
  6641.     MVI    B,OPTBE-OPTBL
  6642.     CALL    MOVE
  6643.     XRA    A
  6644.     STA    FLTRFLG        ; Reset multi-file trans
  6645.     STA    FSTFLG
  6646.     STA    MFFLG1        ; Reset MFACCESS routine
  6647.     STA    TIMFLG
  6648.     JMP    XPRT
  6649. ;.....
  6650. ;
  6651. ;
  6652. ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  6653. ;
  6654. ;               MENU OF COMMANDS
  6655. ;
  6656. ; * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  6657. ;
  6658. MENU2:    CALL    CLRTST
  6659.     CALL    ILPRT
  6660.     DB    '                  Single Letter Commands',CR,LF,LF
  6661.     DB    ' ?  - Display current settings',CR,LF
  6662. MENU3:    DB    ' ^  - Function key intercept character, '
  6663.     DB    'then (0-9)',CR,LF
  6664.     DB    ' M  - Display the menu',CR,LF
  6665.     DB    ' E  - Terminal mode with echo',CR,LF
  6666.     DB    ' L  - Terminal mode with local echo',CR,LF
  6667.     DB    ' T  - Terminal mode',CR,LF
  6668.     DB    '^Z  - Clears screen (command mode only)',CR,LF
  6669.     DB    ' R  - Receive an 8-bit binary CP/M file',CR,LF
  6670.     DB    ' S  - Send an 8-bit binary CP/M file',CR,LF,CR,LF
  6671.     DB    '         COMMAND: R (or S) FILENAME.TYP',CR,LF
  6672.     DB    '         R and S can use the following subcommands:'
  6673.     DB    CR,LF
  6674.     DB    '            B  - Batch transfer, can use wildcards '
  6675.     DB    '(e.g., *.*)',CR,LF
  6676.     DB    '            D  - Disconnect when done'
  6677.     DB    CR,LF
  6678.     DB    '            K  - Manual request for 1k transmissions'
  6679.     DB    CR,LF
  6680.     DB    '            Q  - Quiet mode (no messages to console)'
  6681.     DB    CR,LF
  6682.     DB    '            V  - View ASCII files on CRT during a '
  6683.     DB    'file transfer',CR,LF
  6684.     DB    '            X  - Inhibits auto 1k request to sender'
  6685.     DB    CR,LF
  6686.     DB    '            Z  - When done, disconnect, go to CP/M'
  6687.     DB    CR,LF,CR,LF
  6688.     DB    '         For copying text to disk use T (E or L) '
  6689.     DB    'FILENAME.TYP',CR,LF,0
  6690. ;
  6691.     CALL    NXTSCR        ; Wait at end of 1nd page
  6692. ;
  6693. ;
  6694. ; Start of 2nd menu page
  6695. ;
  6696.     CALL    ILPRT
  6697.     DB    '                Three Letter Commands',CR,LF,LF
  6698.     DB    'BYE - Disconnect, then return to CP/M',CR,LF
  6699.     DB    'CAL - Dial number',CR,LF
  6700.     DB    'CPM - Exit from this program to CP/M',CR,LF
  6701.     DB    'DIR - List directory and space free (may specify '
  6702.     DB    'drive)',CR,LF
  6703.     DB    'DSC - Disconnect from the phone line',CR,LF
  6704.     DB    'ERA - Erase file (may specify drive)',CR,LF
  6705.     DB    'LOG - Change default drive/user no. (specify '
  6706.     DB    'drive/user)',CR,LF
  6707.     DB    '         and reset disks i.e., LOG A0: or LOG B:  '
  6708.     DB    '(user # unchanged)',CR,LF
  6709.     DB    'SET - Set modem baud rate',CR,LF
  6710.     DB    'SPD - Set file output speed in terminal mode',CR,LF
  6711.     DB    'TBM - Toggle MODEM7/KMD batch mode selection',CR,LF
  6712.     DB    'TCC - Toggle CRC/Checksum mode on receive',CR,LF
  6713.     DB    'TIG - Toggle ''ignore CTL characters'' on/off',CR,LF
  6714.     DB    'TLF - Toggle LF after CR in "L" or "T" mode for '
  6715.     DB    'a disk file',CR,LF
  6716.     DB    'TRB - Toggle rubout to backspace conversion',CR,LF,LF
  6717.     DB    '      The following are terminal text buffer '
  6718.     DB    'commands:',CR,LF,LF
  6719.     DB    'DEL - Delete memory buffer and file',CR,LF
  6720.     DB    'WRT - Write memory buffer to disk file'
  6721.     DB    CR,LF,LF,0
  6722. ;
  6723.     CALL    NXTSCR        ; Wait at end of 2nd page
  6724. ;
  6725. ;
  6726. ; Write 3rd (and last) menu screen
  6727. ;
  6728.     CALL    ILPRT
  6729.     DB    '        Local Commands while in Terminal Mode'
  6730.     DB    CR,LF,LF,0
  6731.     LDA    EXITCHR
  6732.     CALL    SHFTYPE
  6733.     DB    '  - Exit to command mode',CR,LF,0
  6734.     LDA    FILESND
  6735.     CALL    SHFTYPE
  6736.     DB    '  - Send file to remote system',CR,LF,0
  6737.     LDA    LOGCHR
  6738.     CALL    SHFTYPE
  6739.     DB    '  - Send log-on message',CR,LF,0
  6740.     LDA    NOCONCT
  6741.     CALL    SHFTYPE
  6742.     DB    '  - Disconnect from the phone line',CR,LF,0
  6743.     LDA    LSTCHR
  6744.     CALL    SHFTYPE
  6745.     DB    '  - Turn printer on (or off)',CR,LF,0
  6746.     LDA    BRKCHR
  6747.     CALL    SHFTYPE
  6748.     DB    '  - Send break tone',CR,LF,0
  6749.     LDA    CLEARS
  6750.     CALL    SHFTYPE
  6751.     DB    '  - Clears screen, terminal mode',CR,LF,LF,0
  6752.     LDA    UNSAVCH
  6753.     CALL    SHFTYPE
  6754.     DB    '  - Stop copy into buffer',CR,LF,0
  6755.     LDA    SAVECHR
  6756.     CALL    SHFTYPE
  6757.     DB    '  - Start copy into buffer',CR,LF,LF
  6758.     DB    '             Start and stop may be toggled as often '
  6759.     DB    'as desired.',CR,LF
  6760.     DB    '             A ";" at start of line indicates buffer '
  6761.     DB    'is copying.',CR,LF
  6762.     DB    '             X-off automatically used to stop input '
  6763.     DB    'when writing',CR,LF
  6764.     DB    '                   full buffer to disk, X-on sent to '
  6765.     DB    'resume.'
  6766.     DB    CR,LF,LF,LF,LF,LF,LF,0 ; Falls on through to "XPRT"
  6767. ;
  6768. ;             (END OF COMMAND MENU)
  6769. ;=======================================================================
  6770. ;            START OF COMMAND LINE HANDLING
  6771. ;
  6772. ;
  6773. ; Check first to see if a file was opened for copying incoming to disk
  6774. ;
  6775. XPRT:    CALL    CRLF        ; Turn up a blank line to look nice
  6776.     LDA    NFILFLG        ; Have a file open for text mode copy?
  6777.     ORA    A
  6778.     JZ    XPRT1        ; If not, exit
  6779. ;
  6780.     CALL    GETSPC        ; Otherwise show remaining space
  6781.     CALL    ILPRT
  6782.     DB    ' Bytes of buffer free',CR,LF,LF,0
  6783. ;
  6784. ;
  6785. ; Show disk drive and user number, then command line
  6786. ;
  6787. XPRT1:    MVI    C,CURDSK    ; Current disk function
  6788.     CALL    BDOS
  6789.     ADI    'A'        ; Make ASCII
  6790.     CALL    TYPE
  6791.     CALL    GETUSER        ; Get current user number
  6792.     ORA    A
  6793.     JZ    XPRT2        ; Skip if user 0
  6794.     MVI    H,0
  6795.     MOV    L,A
  6796.     CALL    DECOUT        ; Show current user area
  6797. ;
  6798. XPRT2:    CALL    ILPRT
  6799.     DB    '>>COMMAND: ',0
  6800.     XRA    A
  6801.     STA    XFLG        ; Null the buffer-length flag
  6802. ;
  6803. ;
  6804. ; Get the command line parameters
  6805. ;
  6806. GTCMD:    LXI    D,CMDBUF    ; Enter command
  6807.     CALL    INBUF        ; Get keyboard-entered command
  6808.     LDA    CMDBUF+2    ; Check first command character
  6809. ;
  6810. GTCMD1:    CPI    '^'        ; Function key intercept character
  6811.     JZ    FUNCT        ; (supplied from 'INTCPT' table)
  6812.     CPI    '?'        ; Want to see current parameters?
  6813.     JZ    CURPAR
  6814.     CPI    ' '        ; If a space, ask again
  6815.     JZ    XPRT+3        ; Skip the extra line feed
  6816.     CALL    STDRV        ; See if request for new drive/user
  6817.     LXI    D,CMDBUF+2    ; Point to command
  6818.     CALL    INLNCP        ; Compare request with available commands
  6819.     DB    'BYE',0
  6820.     JNC    BYEBYE
  6821.     CALL    INLNCP
  6822.     DB    'CPM',0
  6823.     JNC    EXIT
  6824.     CALL    INLNCP
  6825.     DB    'LOG',0
  6826.     JNC    LOGNW
  6827.     CALL    INLNCP
  6828.     DB    'WRT',0
  6829.     JNC    WRFIL
  6830.     CALL    CRLF        ; (1st CR/LF at 'INBUFR')
  6831.     CALL    INLNCP
  6832.     DB    'DIR',0
  6833.     JNC    DIR
  6834.     CALL    INLNCP
  6835.     DB    'ERA',0
  6836.     JNC    ERASEF
  6837.     CALL    INLNCP
  6838.     DB    'SPD',0
  6839.     JNC    STSPD
  6840.     CALL    INLNCP
  6841.     DB    'TBM',0
  6842.     JNC    TGBAT
  6843.     CALL    INLNCP
  6844.     DB    'TCC',0
  6845.     JNC    TGCRC
  6846.     CALL    INLNCP
  6847.     DB    'TIG',0
  6848.     JNC    TIGNR
  6849.     CALL    INLNCP
  6850.     DB    'TRB',0
  6851.     JNC    TGRUB
  6852.     CALL    INLNCP
  6853.     DB    'TLF',0
  6854.     JNC    TGLF
  6855.     CALL    INLNCP
  6856.     DB    'SET',0
  6857.     JNC    STUPENT
  6858.     CALL    INLNCP
  6859.     DB    'DEL',0
  6860.     JNC    NEWFILE
  6861.     CALL    INLNCP
  6862.     DB    'DSC',0
  6863.     JNC    DONETD
  6864.     CALL    INLNCP        ; 'DE' set from 1st 'INLNCP' call
  6865.     DB    'CALL',0
  6866.     JNC    NOTVLD
  6867.     CALL    INLNCP
  6868.     DB    'CAL',0
  6869.     JNC    J$DIAL
  6870. ;
  6871. ;
  6872. ; If none of these, compare single characters with the table
  6873. ;
  6874.     LDA    CMDBUF+2
  6875.     LXI    H,COMPLIST
  6876.     CALL    COMPARE        ; Compares list pointed to by HL..
  6877.     JC    NOTVLD        ; Carry set = no match
  6878.     CALL    STFCB        ; Loads command buffer into FCB
  6879.     CALL    PROCOPT        ; Check out the options
  6880.     JMP    RSTRT        ; Go to work
  6881. ;.....
  6882. ;
  6883. ;
  6884. NOTVLD:    CALL    NTVLDMSG
  6885.     JMP    XPRT
  6886. ;.....
  6887. ;
  6888. ;
  6889. NTVLDMSG:
  6890.     CALL    ILPRT
  6891.     DB    '++ Invalid command ++',CR,LF,BELL,0
  6892.     RET
  6893. ;.....
  6894. ;
  6895. ;
  6896. ; Clears the screen with a "Z" as first character of the command line
  6897. ;
  6898. CLRS:    CALL    CLRTST        ; Clear the CRT
  6899.     LXI    SP,STACK    ; Cancel all the INBUF PUSHes
  6900.     JMP    XPRT1        ; Show the command line again
  6901. ;.....
  6902. ;
  6903. ;
  6904. ; Displays the function key table
  6905. ;
  6906. FUNCT:    LDA    INTCPT        ; Get the function key intercept char.
  6907.     ANI    07FH        ; Strip off any parity
  6908.     PUSH    PSW        ; Save the character for now
  6909.     CALL    CLRTST
  6910.     CALL    ILPRT
  6911.     DB    '         SPECIAL FUNCTION KEY TABLE'
  6912.     DB    CR,LF,LF,0
  6913.     POP    PSW        ; Get the character back
  6914.     CPI    ' '        ; See if a printing character
  6915.     JNC    FUNCT2        ; If a printing character, show it
  6916.     CPI    ESC
  6917.     JNZ    FUNCT1
  6918.     MVI    A,'E'
  6919.     CALL    TYPE
  6920.     MVI    A,'S'
  6921.     CALL    TYPE
  6922.     MVI    A,'C'
  6923.     JMP    FUNCT2
  6924. ;
  6925. FUNCT1:    PUSH    PSW
  6926.     CALL    ILPRT
  6927.     DB    'CTL-',0
  6928.     POP    PSW
  6929.     ADI    40H        ; Convert binary to ASCII character
  6930. ;
  6931. FUNCT2:    CALL    TYPE        ; Show on the CRT
  6932.     CALL    ILPRT
  6933.     DB    ' current function key intercept character',CR,LF,LF,0
  6934. ;
  6935. ;
  6936. ; Shows the functions of the (0-9) keys
  6937. ;
  6938.     LXI    H,FNCTBL-1    ; Index into the function key table
  6939.     MVI    B,10        ; Has ten entries
  6940. ;
  6941. FUNCT3:    INX    H        ; Next table location
  6942.     MOV    A,M        ; Get the binary function number
  6943.     ADI    '1'        ; Convert binary to ASCII digits
  6944.     CPI    '9'+1
  6945.     JNZ    FUNCT4
  6946.     MVI    A,'0'
  6947. ;
  6948. FUNCT4:    CALL    TYPE
  6949.     MVI    A,' '
  6950.     CALL    TYPE
  6951. ;
  6952. FUNCT5:    INX    H        ; Next table location
  6953.     MOV    A,M
  6954.     ORA    A        ; See if a binary zero
  6955.     JZ    FUNCT7
  6956.     CPI    CR
  6957.     JNZ    FUNCT6
  6958.     CALL    ILPRT
  6959.     DB    '<CR>',0
  6960.     JMP    FUNCT5
  6961. ;
  6962. FUNCT6:    CALL    TYPE
  6963.     JMP    FUNCT5
  6964. ;
  6965. FUNCT7:    CALL    CRLF
  6966.     DCR    B
  6967.     JNZ    FUNCT3
  6968.     CALL    J$ILPRT
  6969.     DB    CR,LF,LF,LF,LF,LF,LF,0
  6970.     JMP    XPRT
  6971. ;.....
  6972. ;
  6973. ;
  6974. BYEBYE:    CALL    ILPRT
  6975.     DB    CR,LF,'  wait... ',0
  6976.     CALL    STPCHR        ; Stop any incoming if possible
  6977.     LDA    NODTR        ; Support DTR?
  6978.     ORA    A
  6979.     JNZ    $+9        ; If not, call J$DSCONT
  6980.     CALL    J$GOODBYE    ; Else disconnect normally with DTR
  6981.     JMP    $+6
  6982.     CALL    J$DSCONT
  6983.     CALL    ILPRT
  6984.     DB    CR,'<< Disconnected, exit to CP/M >>',CR,LF,0
  6985.     JMP    EXIT        ; Return to CP/M
  6986. ;.....
  6987. ;
  6988. ;
  6989. DIR:    MVI    C,CURDSK
  6990.     CALL    BDOS
  6991.     STA    DISKSAV
  6992.     CALL    DRLST
  6993.     LDA    DISKSAV
  6994.     MOV    E,A
  6995.     MVI    C,SELDSK
  6996.     CALL    BDOS
  6997.     JMP    XPRT
  6998. ;.....
  6999. ;
  7000. ;
  7001. ERASEF:    LXI    D,CMDBUF    ; Put command line into FCB at 'HL'
  7002.     LXI    H,FCB
  7003.     CALL    CMDLINE
  7004.     CALL    MOVEFCB        ; Move FCB+16 to FCB
  7005.     LDA    FCB+1
  7006.     CPI    ' '
  7007.     JZ    NOTVLD        ; Go if no file specified
  7008.     LXI    D,FCB
  7009.     MVI    C,SRCHF
  7010.     CALL    BDOS
  7011.     INR    A        ; 0 if file not found
  7012.     JNZ    ERAFILE        ; Ok, go erase
  7013.     CALL    ILPRT
  7014.     DB    '++ File not found ++',CR,LF,BELL,0
  7015.     JMP    XPRT
  7016. ;.....
  7017. ;
  7018. ;
  7019. ERAFILE:LXI    D,FCB
  7020.     MVI    C,ERASE
  7021.     CALL    BDOS
  7022.     CALL    ILPRT
  7023.     DB    'File erased',CR,LF,0
  7024.     JMP    XPRT
  7025. ;.....
  7026. ;
  7027. ;
  7028. LOGNW:    LDA    NFILFLG        ; File open for memory save to disk?
  7029.     ORA    A
  7030.     JNZ    NORESET        ; If yes, do not reset disk drive now
  7031.     LDA    CMDBUF+6    ; Any disk drive specified?
  7032.     CPI    ' '
  7033.     JNZ    LOGNW1        ; If not a blank, exit
  7034.     CALL    GETDISK        ; If not, use current drive
  7035.     ADI    'A'        ; To compensate for next line
  7036. ;
  7037. LOGNW1:    SUI    'A'
  7038.     CPI    15+1        ; For drives 0-15
  7039.     JNC    NOTVLD        ; If more than 15, display error message
  7040.     STA    DISKSAV        ; Store requested drive
  7041.     CALL    GETUSER        ; Pick up current user number
  7042.     MOV    B,A        ; Save it
  7043.     LDA    CMDBUF+7    ; Get new user number
  7044.     CALL    CHRCK        ; Check the character
  7045.     CALL    FINDUSER
  7046.     LDA    CMDBUF+8    ; Get 2nd digit
  7047.     CALL    CHRCK        ; Check the character
  7048.     CALL    FINDUSER+2
  7049. ;
  7050. LOGNW2:    CALL    SAVEUSER
  7051.     MVI    C,RESET
  7052.     CALL    BDOS
  7053.     LDA    DISKSAV
  7054.     MOV    E,A
  7055.     MVI    C,SELDSK
  7056.     CALL    BDOS
  7057.     LDA    SAVUSR
  7058.     MOV    E,A
  7059.     CALL    STUSER
  7060.     JMP    XPRT
  7061. ;.....
  7062. ;
  7063. ;
  7064. CHRCK:    CPI    ' '
  7065.     JZ    CHRCK1
  7066.     CPI    ':'        ; In case of A: or A1: or A11:    (etc.)
  7067.     RNZ
  7068. ;
  7069. CHRCK1:    POP    PSW        ; Reset the 'CALL' on the stack
  7070.     JMP    LOGNW2
  7071. ;.....
  7072. ;
  7073. ;
  7074. FINDUSER:
  7075.     MVI    B,0        ; Zero the 'B' reg. for 1st time through
  7076.     CALL    NUMCHK        ; If neither, see if a valid number
  7077.     MOV    C,A        ; Save
  7078.     MOV    A,B        ; Get save first digit
  7079.     ADD    A        ; X2
  7080.     ADD    A        ; X4
  7081.     ADD    A        ; X8
  7082.     ADD    B        ; X9
  7083.     ADD    B        ; X10
  7084.     ADD    C
  7085.     MOV    B,A        ; Save
  7086.     RET
  7087. ;.....
  7088. ;
  7089. ;
  7090. SAVEUSER:
  7091.     MOV    A,B
  7092.     CPI    15+1        ; User numbers are 0-15
  7093.     JNC    NOTVLD
  7094.     STA    SAVUSR
  7095.     RET
  7096. ;.....
  7097. ;
  7098. ;
  7099. NUMGET:    LXI    D,CMDBUF
  7100.     CALL    INBUF
  7101.     LDA    CMDBUF+2    ; Get number
  7102.     CPI    ' '
  7103.     RZ
  7104. ;
  7105. NUMCHK:    SUI    '0'        ; Remove ASCII bias
  7106.     CPI    9+1
  7107.     RC            ; Ok if 9 or less
  7108.     POP    H        ; Remove 1st call from the stack
  7109.     POP    H        ; Remove 2nd call from the stack
  7110.     JMP    NOTVLD
  7111. ;
  7112. GETUSER:MVI    E,0FFH        ; Get current user
  7113. ;
  7114. STUSER:    MVI    C,USER        ; Set up BDOS call
  7115.     JMP    BDOS
  7116. ;.....
  7117. ;
  7118. ;
  7119. GETDISK:MVI    C,CURDSK    ; Get current drive
  7120.     JMP    BDOS
  7121. ;.....
  7122. ;
  7123. ;
  7124. NORESET:CALL    ILPRT
  7125.     DB    '++      Terminal mode file open      ++',CR,LF
  7126.     DB    '++ Use WRT or DEL before LOG command ++',CR,LF
  7127.     DB    CR,LF,BELL,0
  7128.     XRA    A
  7129.     JMP    XPRT
  7130. ;.....
  7131. ;
  7132. ;
  7133. STSPD:    CALL    ILPRT
  7134.     DB    'Delay between chars. (0-9): ',0
  7135. ;
  7136. STSPD1:    CALL    STAT
  7137.     JZ    STSPD1
  7138.     CALL    KEYIN
  7139.     CALL    TYPE
  7140.     CALL    SAVEA
  7141.     CPI    CR
  7142.     JZ    STSPD2
  7143.     SUI    '0'
  7144.     CPI    9+1
  7145.     JNC    NOTVLD
  7146.     ADD    A
  7147.     ADD    A
  7148.     STA    BYTDLY
  7149. ;
  7150. STSPD2:    CALL    ILPRT
  7151.     DB    'Delay at end of line (0-9): ',0
  7152. ;
  7153. STSPD3:    CALL    STAT
  7154.     JZ    STSPD3
  7155.     CALL    KEYIN
  7156.     CALL    TYPE
  7157.     CALL    SAVEA
  7158.     CPI    CR
  7159.     JZ    STSPD4
  7160.     SUI    '0'
  7161.     CPI    9+1
  7162.     JNC    NOTVLD
  7163.     STA    CRDLY
  7164. ;
  7165. STSPD4:    CALL    SPDMSG
  7166.     JMP    XPRT
  7167. ;.....
  7168. ;
  7169. ;
  7170. SPDMSG:    CALL    ILPRT
  7171.     DB    CR,LF,'Char. delay (terminal file mode) is:  ',0
  7172.     LDA    BYTDLY
  7173.     CPI    10
  7174.     JNC    SPDMSG1
  7175.     PUSH    PSW
  7176.     CALL    ILPRT
  7177.     DB    ' ',0
  7178.     POP    PSW
  7179. ;
  7180. SPDMSG1:PUSH    H
  7181.     MOV    L,A
  7182.     MVI    H,0
  7183.     CALL    DECOUT
  7184.     POP    H
  7185.     CALL    ILPRT
  7186.     DB    ' ms. per character',CR,LF
  7187.     DB    'Line  delay (terminal file mode) is: ',0
  7188.     LDA    CRDLY
  7189.     PUSH    H
  7190.     MOV    L,A
  7191.     MVI    H,0
  7192.     CALL    DECOUT
  7193.     POP    H
  7194.     CALL    ILPRT
  7195.     DB    '00 ms. per CR character',CR,LF,0
  7196.     RET
  7197. ;......
  7198. ;
  7199. ;
  7200. SAVEA:    PUSH    PSW
  7201.     CALL    ILPRT
  7202.     DB    CR,LF,0
  7203.     POP    PSW
  7204.     RET
  7205. ;.....
  7206. ;
  7207. ;
  7208. ; Set the drive/user area if any requested
  7209. ;
  7210. STDRV:    LDA    CMDBUF+3    ; Allow for B: or B2: or B15:, etc.
  7211.     CPI    ':'
  7212.     JZ    STDRV1
  7213.     LDA    CMDBUF+4
  7214.     CPI    ':'
  7215.     JZ    STDRV1
  7216.     LDA    CMDBUF+5
  7217.     CPI    ':'
  7218.     RNZ            ; If no drive/user requested, return
  7219.     LDA    CMDBUF+2
  7220.     CPI    'S'        ; Allows S B:FILENAME.EXT
  7221.     RZ
  7222.     CPI    'R'        ; Allows R B:FILENAME.EXT
  7223.     RZ
  7224. ;
  7225. ;
  7226. ; First check for the drive
  7227. ;
  7228. STDRV1:    POP    H        ; Remove "CALL STDRV" from stack
  7229.     LDA    CMDBUF+2    ; Get the disk drive
  7230.     SUI    'A'        ; Convert to binary value
  7231.     CPI    15+1        ; For drives 0-15
  7232.     JNC    NOTVLD        ; Answers over 15 not valid this program
  7233. ;
  7234.     MOV    E,A
  7235.     MVI    C,SELDSK    ; Select requested drive
  7236.     CALL    BDOS
  7237. ;
  7238. ;
  7239. ; See if any user area requested
  7240. ;
  7241.     LDA    CMDBUF+3    ; See if just plain B: and no user area
  7242.     CPI    ':'
  7243.     JZ    XPRT        ; If yes, finished
  7244. ;
  7245. ;
  7246. ; Since there was, enter the request
  7247. ;
  7248.     SUI    '0'        ; Convert to binary value
  7249.     CPI    1        ; If a '1', could be units or tens
  7250.     JNZ    STDRV3        ; If not, numbers stop at 15 so exit
  7251.     LDA    CMDBUF+4    ; Check for a 2nd digit
  7252.     CPI    ':'        ; Accecpt '1' for  B1:    etc.
  7253.     JNZ    STDRV2
  7254.     MVI    A,1
  7255.     JMP    STDRV4
  7256. ;
  7257. STDRV2:    CPI    '0'
  7258.     JC    STDRV5        ; If less, not a valid number, ignore
  7259.     SUI    '0'-10        ; Leave the '10' in as two digits used
  7260. ;
  7261. STDRV3:    CPI    15+1        ; User areas are 0-15 for this program
  7262.     JNC    NOTVLD
  7263. ;
  7264. STDRV4:    MOV    E,A
  7265.     CALL    STUSER
  7266.     JMP    XPRT        ; Back to work
  7267. ;
  7268. STDRV5:    MVI    A,1
  7269.     JMP    STDRV2
  7270. ;.....
  7271. ;
  7272. ;
  7273. ; Set MODEM7/KMD batch selection
  7274. ;
  7275. TGBAT:    LDA    KMDODE        ; Get current selection and switch it
  7276.     CMA
  7277.     STA    KMDODE
  7278.     CALL    TGBAT1        ; Show on CRT it has been changed
  7279.     JMP    XPRT
  7280. ;.....
  7281. ;
  7282. ;
  7283. ; Set CRC/checksum toggle
  7284. ;
  7285. TGCRC:    LDA    CRCDFLT        ; Get present value and switch it
  7286.     CMA
  7287.     STA    CRCDFLT
  7288.     CALL    TGCRC1        ; Show on CRT it has been changed
  7289.     JMP    XPRT
  7290. ;.....
  7291. ;
  7292. ;
  7293. TGBAT1:    LDA    KMDODE
  7294.     ORA    A
  7295.     JZ    TGBAT2
  7296.     CALL    ILPRT
  7297.     DB    'MODEM7 batch mode',CR,LF,0
  7298.     RET
  7299. ;
  7300. TGBAT2:    CALL    ILPRT
  7301.     DB    'KMD batch mode',CR,LF,0
  7302.     RET
  7303. ;.....
  7304. ;
  7305. ;
  7306. TGCRC1:    CALL    ILPRT
  7307.     DB    'Mode: ',0
  7308.     LDA    CRCDFLT        ; See if set for 'CRC' or 'checksum'
  7309.     ORA    A
  7310.     JZ    CHEKMSG
  7311.     CALL    ILPRT
  7312.     DB    'CRC',CR,LF,0
  7313.     RET
  7314. ;
  7315. CHEKMSG:CALL    ILPRT
  7316.     DB    'checksum',CR,LF,0
  7317.     RET
  7318. ;.....
  7319. ;
  7320. ;
  7321. TIGNR:    LDA    IGNRCTL
  7322.     CMA
  7323.     STA    IGNRCTL
  7324.     CALL    TIGNR1
  7325.     JMP    XPRT
  7326. ;.....
  7327. ;
  7328. ;
  7329. TIGNR1:    CALL    ILPRT
  7330.     DB    'Incoming control characters ',0
  7331.     LDA    IGNRCTL
  7332.     ORA    A
  7333.     JZ    NOIGNR
  7334.     CALL    ILPRT
  7335.     DB    'ignored',CR,LF,0
  7336.     RET
  7337. ;.....
  7338. ;
  7339. ;
  7340. NOIGNR:
  7341.     CALL    ILPRT
  7342.     DB    'received',CR,LF,0
  7343.     RET
  7344. ;.....
  7345. ;
  7346. ;
  7347. TGRUB:    LDA    CONVRUB
  7348.     CMA
  7349.     STA    CONVRUB
  7350.     CALL    TGRUB1
  7351.     JMP    XPRT
  7352. ;.....
  7353. ;
  7354. ;
  7355. TGRUB1:    LDA    CONVRUB
  7356.     ORA    A
  7357.     JZ    NORUBMSG
  7358.     CALL    ILPRT
  7359.     DB    'Rub is backspace',CR,LF,0
  7360.     RET
  7361. ;.....
  7362. ;
  7363. ;
  7364. NORUBMSG:
  7365.     CALL    ILPRT
  7366.     DB    'Rub is rub',CR,LF,0
  7367.     RET
  7368. ;.....
  7369. ;
  7370. ;
  7371. TGLOC1:    CALL    ILPRT
  7372.     DB    'Use ESC before local command in terminal mode',CR,LF,0
  7373.     RET
  7374. ;.....
  7375. ;
  7376. ;
  7377. TGLF:    LDA    ADDLFD
  7378.     CMA
  7379.     STA    ADDLFD
  7380.     CALL    TGLF1
  7381.     JMP    XPRT
  7382. ;.....
  7383. ;
  7384. ;
  7385. TGLF1:    CALL    ILPRT
  7386.     DB    'LF ',0
  7387.     LDA    ADDLFD        ; Adding LF after CR?
  7388.     ORA    A
  7389.     JNZ    LFMSG        ; If yes, exit
  7390.     CALL    ILPRT
  7391.     DB    'NOT ',0
  7392. ;
  7393. LFMSG:    CALL    ILPRT
  7394.     DB    'sent after CR in "L" or "T" for a disk file',CR,LF,0
  7395.     RET
  7396. ;.....
  7397. ;
  7398. ;
  7399. RATE:    CALL    ILPRT
  7400.     DB    'Modem speed is: ',0
  7401.     CALL    PRTBAUD        ; Display the speed
  7402.     CALL    ILPRT
  7403.     DB    CR,LF,0
  7404.     RET
  7405. ;.....
  7406. ;
  7407. ;
  7408. XOFFMSG:CALL    ILPRT
  7409.     DB    'XOFF testing used in terminal mode file output'
  7410.     DB    CR,LF,0
  7411.     RET
  7412. ;.....
  7413. ;
  7414. ;
  7415. GETANS:    LXI    D,CMDBUF
  7416.     CALL    INBUF
  7417.     LDA    CMDBUF+2    ; Get answer
  7418.     CPI    ' '
  7419.     CMC            ; Set the carry flag
  7420.     RZ
  7421.     MOV    B,A
  7422.     CPI    'N'
  7423.     MVI    A,0
  7424.     RZ
  7425.     MOV    A,B
  7426.     CPI    'Y'
  7427.     MVI    A,1
  7428.     RZ
  7429.     POP    PSW        ; Preserve stack
  7430.     JMP    NOTVLD
  7431. ;.....
  7432. ;
  7433. ;
  7434. STUPENT:MVI    A,1
  7435.     STA    MANUAL        ; Speed is being manually selected
  7436.     LXI    D,CMDBUF+1
  7437.     CALL    J$STUPR        ; Go set the speed
  7438.     CALL    RATE
  7439.     JMP    XPRT
  7440. ;.....
  7441. ;
  7442. ;
  7443. NEWFILE:LDA    NFILFLG        ; File open for disk save?
  7444.     ORA    A
  7445.     JZ    NOFILOPN    ; If not, show "no file open" message
  7446.     LDA    FCB3+1        ; Check that file was requested
  7447.     CPI    ' '
  7448.     JZ    NOFILOPN    ; If no file, do not erase
  7449.     LXI    D,FCB3        ; Otherwise erase the old file
  7450.     MVI    C,ERASE
  7451.     CALL    BDOS
  7452.     XRA    A
  7453.     STA    NFILFLG        ; No file mentioned, reset flags
  7454.     STA    SAVEFLG
  7455.     LXI    H,FCB3
  7456.     CALL    INITFCB
  7457.     LXI    H,BUFFER    ; Reset flags to bottom of ram just to
  7458.     SHLD    HLSAV        ; Insure they are there
  7459.     JMP    XPRT
  7460. ;.....
  7461. ;
  7462. ;
  7463. WRFIL:    LDA    NFILFLG        ; Saving memory for a disk file?
  7464.     ORA    A
  7465.     JZ    NOFILOPN    ; If not, nothing to write to disk
  7466.     CALL    WRFIL1        ; Close the file
  7467.     STA    SAVEFLG
  7468.     STA    WRFLG
  7469.     LXI    H,FCB3
  7470.     CALL    INITFCB        ; Blank out 'FCB' to written file
  7471.     LXI    H,BUFFER    ; Can't be erased
  7472.     SHLD    HLSAV        ; Reset to buffer start for next time
  7473.     JMP    XPRT
  7474. ;...
  7475. ;
  7476. ;
  7477. WRFIL1:    LDA    FCB3+1        ; Check that file was requested
  7478.     CPI    ' '
  7479.     RZ
  7480.     CALL    WRDSK        ; Write buffer to disk if not empty
  7481. ;
  7482. WRFIL2:    LXI    D,FCB3        ; Close the file
  7483.     MVI    C,CLOSE
  7484.     CALL    BDOS
  7485. ;
  7486. ;
  7487. ; Show name of file that is being closed
  7488. ;
  7489.     MVI    A,CR
  7490.     CALL    TYPE
  7491.     MVI    A,LF
  7492.     CALL    TYPE
  7493.     MVI    B,8
  7494.     LXI    H,FCB3+1
  7495.     CALL    WRFIL4
  7496.     MOV    A,M
  7497.     CPI    ' '+1
  7498.     JC    WRFIL3
  7499.     MVI    A,'.'
  7500.     CALL    TYPE
  7501. ;
  7502. WRFIL3:    MVI    B,3
  7503.     CALL    WRFIL4
  7504.     CALL    ILPRT
  7505.     DB    ' closed',CR,LF,0
  7506.     XRA    A
  7507.     STA    NFILFLG        ; File written, reset flags
  7508.     RET
  7509. ;...
  7510. ;
  7511. ;
  7512. WRFIL4:    MOV    A,M
  7513.     CPI    ' '
  7514.     JZ    WRFIL5
  7515.     CALL    TYPE
  7516. ;
  7517. WRFIL5:    INX    H
  7518.     DCR    B
  7519.     JNZ    WRFIL4
  7520.     RET
  7521. ;.....
  7522. ;
  7523. ;
  7524. NOFILOPN:
  7525.     CALL    ILPRT
  7526.     DB    CR,LF,'++ No file open ++',CR,LF,BELL,0
  7527.     JMP    XPRT
  7528. ;.....
  7529. ;
  7530. ;
  7531. NEWLINE:MVI    A,CR        ; Puts CRLF at memory pointed by 'DE'
  7532.     STAX    D        ; Store it
  7533.     MVI    A,LF        ; Line feed
  7534.     INX    D        ; Bump pointer
  7535.     STAX    D        ; Store lf
  7536.     INX    D        ; Bump pointer
  7537.     RET
  7538. ;.....
  7539. ;
  7540. ;
  7541. SPACES:    MVI    A,' '        ; Space
  7542.     STAX    D
  7543.     INX    D        ; 1
  7544.     STAX    D
  7545.     INX    D        ; 2
  7546.     STAX    D
  7547.     INX    D        ; 3
  7548.     RET
  7549. ;.....
  7550. ;
  7551. ;
  7552. COMPARE:MOV    B,M        ; Compares 'A' reg. with list
  7553. ;
  7554. COMPLP:    INX    H
  7555.     CMP    M
  7556.     JZ    VALID
  7557.     DCR    B
  7558.     JNZ    COMPLP
  7559.     STC
  7560. ;
  7561. VALID:    RET
  7562. ;.....
  7563. ;
  7564. ;
  7565. NXTSCR:    CALL    ILPRT
  7566.     DB    '[more] ',0
  7567. ;
  7568. NOKEY1:    CALL    STAT        ; Get keyboard status
  7569.     JZ    NOKEY1        ; Keep looping until keypress
  7570.     CALL    KEYIN        ; Gobble up keypress
  7571.     MVI    B,CLEARSC    ; CTL-Z to clear screen?
  7572.     CMP    B
  7573.     JNZ    NOKEY2        ; If not, exit
  7574.     JMP    CLRS        ; Erase screen, back to command
  7575. ;
  7576. NOKEY2:    CPI    'C'-40H        ; CTL-C to abort?
  7577.     JNZ    CLRTST
  7578.     POP    H        ; Clear stack of return address
  7579.     CALL    CRLF        ; Turn up a blank line
  7580.     JMP    XPRT
  7581. ;.....
  7582. ;
  7583. ;
  7584. CLRTST:    LDA    CLEAR        ; "Clear screen" character used?
  7585.     ORA    A
  7586.     JZ    CLRT2        ; If not, exit
  7587. ;
  7588.     CPI    ' '        ; See if a control character
  7589.     JC    CLRT1
  7590.     PUSH    PSW        ; Save the "Clear screen" character
  7591.     MVI    A,ESC        ; Send an 'Escape' character first
  7592.     CALL    TYPE
  7593.     POP    PSW        ; Get the "Clear screen" character back
  7594. ;
  7595. CLRT1:    JMP    TYPE        ; Send it, done
  7596. ;
  7597. CLRT2:    MVI    A,CR        ; Else use a bunch of line feeds
  7598.     CALL    TYPE
  7599.     MVI    B,24
  7600.     MVI    A,LF
  7601. ;
  7602. LFLOOP:    CALL    TYPE
  7603.     DCR    B
  7604.     JNZ    LFLOOP
  7605.     RET
  7606. ;.....
  7607. ;
  7608. ;
  7609. CURPAR:    CALL    CLRTST
  7610.     CALL    ILPRT
  7611.     DB    '                Current Settings',CR,LF,LF,0
  7612.     CALL    TGCRC1        ; CRC/checksum mode
  7613.     CALL    TGBAT1        ; MODEM7/KMD batch mode
  7614.     CALL    TGRUB1        ; Toggle rub to backspace
  7615.     CALL    LSTMS
  7616.     CALL    RATE
  7617.     CALL    TIGNR1        ; Toggle incoming CTL-characters
  7618.     CALL    ILPRT
  7619.     DB    'Terminal mode file buffer is ',0
  7620.     LDA    NFILFLG        ; Saving memory for a disk file?
  7621.     ORA    A
  7622.     JNZ    ACTIVE        ; If yes, go say "active"
  7623.     CALL    ILPRT
  7624.     DB    'in',0        ; If not, say "inactive"
  7625. ;
  7626. ACTIVE:    CALL    ILPRT
  7627.     DB    'active',CR,LF,'Unused portion of buffer is ',0
  7628.     CALL    GETSPC
  7629.     CALL    ILPRT
  7630.     DB    ' bytes',CR,LF,0
  7631.     CALL    TGLOC1
  7632.     CALL    XOFFMSG
  7633.     CALL    TGLF1
  7634.     CALL    SPDMSG
  7635.     CALL    ILPRT
  7636.     DB    CR,LF,LF,LF,LF,LF,LF,0
  7637.     JMP    XPRT
  7638. ;.....
  7639. ;
  7640. ;
  7641. GETSPC:    LXI    D,BUFTOP    ; Top of memory buffer
  7642.     LHLD    HLSAV        ; Current buffer location
  7643.     XCHG
  7644.     XRA    A        ; Clear the carry bit, if set
  7645.     SUB    E
  7646.     MOV    L,A
  7647.     MOV    A,H
  7648.     SBB    D
  7649.     MOV    H,A
  7650.     CALL    DECOUT        ; Print the space remaining
  7651.     RET
  7652. ;.....
  7653. ;
  7654. ;
  7655. ;***********************************************************************
  7656. ;
  7657. ;    D - A - T - A     A - R - E - A
  7658. ;
  7659. ;***********************************************************************
  7660. ;
  7661. ;
  7662. COMPLIST: DB    6, 'S',    'R', 'T', 'E', 'L', 'M'
  7663. ;.....
  7664. ;
  7665. ;
  7666. ; OPTION TABLE
  7667. ;
  7668. OPTBL    EQU    $
  7669. BATCHFLG: DB    'B'
  7670. DISCFLG:DB    'D'
  7671. KKMD:    DB    'K'
  7672. QFLG:    DB    'Q'
  7673. RSEEFLG:DB    'R'
  7674. SSEEFLG:DB    'S'
  7675. VSEEFLG:DB    'V'
  7676. XMODEM:    DB    'X'
  7677. XITFLG:    DB    'Z'
  7678. OPTBE    EQU    $        ; Transfer when program initially called
  7679. ;
  7680. ;
  7681. ; The following must be in the same order as the table above:
  7682. ;
  7683. RESTROPT: DB    'B','D','K','Q','R','S','V','X','Z'
  7684. ;
  7685. ;
  7686. ; The next 16 bytes equal the number of bytes between RECNOB and
  7687. ; RECNOE.
  7688. ;
  7689. RESTSN:    DB    0,0,0,0,0
  7690.     DB    0,0,0,0,0
  7691.     DB    0,0,0,0
  7692.     DW    BUFFER
  7693. ;
  7694. RECNOB    EQU    $        ; Start of table marker
  7695. ACCERR:    DB    0,0        ; \ No 'ACK' error count for 1k ratio
  7696. CHKEOT:    DB    0        ; \
  7697. DATAFLG:DB    0        ; \
  7698. EOFLG:    DB    0        ; \
  7699. ERRCT:    DB    0        ; \  16 bytes between table markers
  7700. FRSTIM:    DB    0        ; /
  7701. RCDCNT:    DB    0,0        ; /  (These get reset each batch mode
  7702. RCNT:    DB    0,0        ; /  file that is sent)
  7703. RECNBF:    DB    0        ; /
  7704. RECNO:    DB    0,0        ; /
  7705. RECPTR:    DW    BUFFER        ; /
  7706. RECNOE    EQU    $        ; End of table marker
  7707. ;
  7708. ;
  7709. ; Additional 16-bit initialized storage
  7710. ;
  7711. CRCVAL:    DW    0
  7712. DIALCT:    DW    0
  7713. HLSAV:    DW    BUFFER
  7714. HLSAV1:    DW    PBUFF
  7715. HLSAV2:    DW    PBUFF
  7716. ;
  7717. ;
  7718. ; Additional general purpose initialized storage
  7719. ;
  7720. ABORTFLG: DB    0
  7721. CRCFLG:    DB    0
  7722. CRFLAG:    DB    0
  7723. DLYFLG:    DB    0
  7724. ECHOFLG:DB    0
  7725. EXACFLG:DB    0
  7726. DONEFLG:DB    0
  7727. FNKFLG:    DB    0        ; Function key activity flag
  7728. FSTFLG:    DB    0
  7729. GOTONE:    DB    0
  7730. KFLG:    DB    0        ; Flag for 1k blocks
  7731. LISTFLG:DB    0
  7732. LOCFLG:    DB    0
  7733. MFFLG1:    DB    0
  7734. NFILFLG:DB    0
  7735. OPTION:    DB    0
  7736. RCVCNT:    DB    0        ; Record number received
  7737. RCVTRY:    DB    0        ; Limits tries for batch mode header
  7738. SAVEFLG:DB    0
  7739.     DB    0
  7740. KMDODE:    DB    0        ; Selects MODEM7/KMD batch
  7741. WRFLG:    DB    0
  7742. XFLG:    DB    0
  7743. CMDBUF:    DB    80H,0        ; Command buffer control area
  7744. ;
  7745. ;
  7746. ; General purpose unitialized storage area
  7747. ;
  7748.     DS    128        ; Storage area for 'CMDBUF'
  7749. BGNMS:    DS    2
  7750. TIMFLG:    DS    1
  7751. FLTRFLG:DS    1
  7752. CHRFLG:    DS    1
  7753. TIMVAL:    DS    2
  7754. QUIKTIM:DS    2
  7755. DISKNO:    DS    1
  7756. DISKSAV:DS    1
  7757. DSTORE:    DS    1
  7758. FILECT:    DS    1
  7759. FTYCNT:    DS    1
  7760. MAXRAM:    DS    1
  7761. NAMECT:    DS    1
  7762. NBSAVE:    DS    2
  7763. OLDUSER:DS    1
  7764. SAVUSR:    DS    1
  7765. SNDFLG:    DS    1
  7766. ;
  7767. FCB3:    DS    33
  7768. FCB4:    DS    33
  7769. FCBBUF:    DS    15
  7770. MFNAM5:    DS    12        ; Requested name
  7771. MFNAM6:    DS    12        ; Current name
  7772.     DS    100        ; Stack depth
  7773. ;
  7774. ;
  7775. EVNPAGE    EQU    ($+255)/256*256    ; Sets buffers on even page
  7776. ;
  7777. ;
  7778.     ORG    EVNPAGE
  7779. ;
  7780. ;
  7781. STACK    EQU    EVNPAGE-2    ; Store original stack pointer
  7782. CRCTBL:    DS    512        ; Two tables of 128 bytes each
  7783. BUFFDSK:DS    128        ; Buffer for disk save
  7784. BUFFPNT:DS    128        ; Buffer for printer
  7785. BUFFER:    DS    1024*BUFSIZ    ; Send/receive file buffer
  7786. BUFSTR    EQU    BUFFER+126    ; For storing batch mode file length
  7787. BUFTOP:    DS    0        ; Filled in when length is found
  7788. PBUFF    EQU    $        ; Printer buffer starts here
  7789. NAMEBUF    EQU    $        ; Batch-mode filenames buffer
  7790. ;.....
  7791. ;
  7792. ;
  7793. ; BDOS EQUATES
  7794. ;
  7795. RDCON    EQU    1
  7796. WRCON    EQU    2
  7797. LIST    EQU    5
  7798. PRINT    EQU    9
  7799. CONST    EQU    11
  7800. CPMVER    EQU    12
  7801. RESET    EQU    13
  7802. SELDSK    EQU    14
  7803. OPEN    EQU    15
  7804. CLOSE    EQU    16
  7805. SRCHF    EQU    17
  7806. SRCHN    EQU    18
  7807. ERASE    EQU    19
  7808. READ    EQU    20
  7809. WRITE    EQU    21
  7810. MAKE    EQU    22
  7811. CURDSK    EQU    25
  7812. STDMA    EQU    26
  7813. DSKALL    EQU    27
  7814. DSKPAR    EQU    31
  7815. USER    EQU    32
  7816. FILSIZ    EQU    35
  7817. BDOS    EQU    0005H
  7818. FCB    EQU    5CH
  7819. FCBEXT    EQU    FCB+12
  7820. FCBSNO    EQU    FCB+32
  7821. FCBRNO    EQU    FCB+32
  7822. FCB2    EQU    6CH
  7823. TBUF    EQU    80H
  7824. ;.....
  7825. ;
  7826. ;
  7827.     END
  7828.