home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / MODEMS / MODEM2 / MODM221A.AQM / MODM221A.ASM
Assembly Source File  |  2000-06-30  |  88KB  |  3,384 lines

  1. ;MODEM.ASM V2.21, ORIGINALLY BY WARD CHRISTENSEN
  2. ; This version will assemble directly for an Intel MDS Series II
  3. ;
  4. ;    (REVISED 04/19/82)
  5. ;
  6. ;CP/M - CP/M FILE TRANSFER PROGRAM, AND TERMINAL PROGRAM.
  7. ;
  8. ;
  9. ;--PRESENT CONFIGURATION--
  10. ;THIS FILE WILL ASSEMBLE WITHOUT EDITING FOR THE FOLLOWING:
  11. ;
  12. ; A 2 MHz clock
  13. ; External modem
  14. ; Ported I/O
  15. ; Standart CP/M
  16. ; Retry 10 times on block transfer error
  17. ; 5 drives (A-E) <-- see MAXDRV equate
  18. ; 16K disk buffer size
  19. ; Send stop 4 characters early for ascii capture
  20. ; Don't go to terminal mode before a file transfer.
  21. ;
  22. ;--> IF YOU CHANGE ANY CONDITIONALS
  23. ;    PLEASE CHANGE THESE COMMENTS, TOO.
  24. ;
  25. ;--> SEE EQUATES FOR OTHER MODEMS & ADDITIONAL OPTIONS.
  26. ;
  27. ;* * * * * * * * * * * * * * * * * * * * * * * * *
  28. ;*                         *
  29. ;*    THIS PROGRAM DOCUMENTED IN "MODEM.DOC"     *
  30. ;*                         *
  31. ;* * * * * * * * * * * * * * * * * * * * * * * * *
  32. ;* THIS PROGRAM WAS "MODEM.ASM" BUT IS         *
  33. ;* TEMPORARILY NAMED "MODEM2XX.ASM" SO PEOPLE     *
  34. ;* WILL REALIZE IT IS AN ENHANCEMENT OF THE     *
  35. ;* ORIGINAL PROGRAM "MODEM.ASM" ON CP/M USER'S     *
  36. ;* GROUP DISK 25.                 *
  37. ;* * * * * * * * * * * * * * * * * * * * * * * * *
  38. ;
  39. ;MODIFICATIONS/FIXES:
  40. ;(IN REVERSE ORDER TO MINIMIZE READING TIME)
  41. ;        (4/19/82)
  42. ; Added a section of code to reset the receiving
  43. ; device (usart, etc) on detection of an error
  44. ; (framing, parity, or overrun). The routine used
  45. ; is called RESRCVR ("reset receiver") and has
  46. ; conditional assemblies for the different types
  47. ; of devices. I have an i8251 usart and have
  48. ; implemented the particular code for that device,
  49. ; but since I no very little about the other
  50. ; commonly used devices, you will have to insert
  51. ; code for your device.
  52. ; This code was necessary for me since when toggling
  53. ; between terminal mode and send/receive mode it
  54. ; is very likely that the usart will detect an
  55. ; overrun error and since until now there was no
  56. ; reset to the usart, the one overrun would be
  57. ; detected as many times as the program "retried"
  58. ; the transfer and would always terminate.
  59. ; Again, remember to add your code if you don't
  60. ; have an i8251 usart. Put it in a conditional in
  61. ; the routine RESRCVR and put the reset code in
  62. ; the symbol RSTCODE.
  63. ;            Dave Mabry
  64. ;
  65. ;    04/14/82
  66. ;SET DMA TO DEFAULT BUFFER IN CNREC TO CALC PROG
  67. ;SIZE CORRECTLY AFTER ASCII CAPTURE AND BEFORE
  68. ;FILE XFER. LEAVE ROOM FOR CCP BEYOND ASCBUF BY
  69. ;FIXING MEMEND. SEPARATE EQUATES FOR X6850 AND X8251
  70. ;FOR BASE I/O ADDRESS TO ALLOW BOTH IN FILE AT
  71. ;ONCE FOR MULTIPLE LOCAL MACHINES. MAKE FILE XFERS
  72. ;BUFFER SIZE ALTERABLE WITH DBUFSIZ EQUATE. CHECK
  73. ;FOR FILE ALREADY EXISTS ON ASCII CAPTURE THEN
  74. ;VERIFY BEFORE DELETING IT. PRINT OUT SECTOR #'S
  75. ;IN DECIMAL AND HEX ON SEND OR RECEIVE. ADJUST
  76. ;SEND AND RECEIVE MSG ALGORITHMS TO LEAVE CURSOR
  77. ;AT END OF MSG, NOT FRONT. ALL THE ABOVE CHANGES
  78. ;MADE BY ADAPTING THE SAME CODE FROM MODEM7X WHEN
  79. ;POSSIBLE TO FACILITATE FUTURE MAINTENANCE.
  80. ;
  81. ;  THERE IS A TIMEOUT PROBLEM WITH CRC RECEIVE
  82. ;WHEN THE SENDING PROGRAM HAS A LARGE BUFFER,
  83. ;LIKE 16K. THE PROBLEM IS THAT THE RECEIVING
  84. ;PROGRAM SENDS THE INITIAL "C" INSTEAD OF NAK,
  85. ;THEN THE SENDING PROGRAM GOES INTO CRC MODE
  86. ;AND GOES OFF TO LOAD UP THE 1ST BUFFER OF FILE.
  87. ;IF THE SENDING PROGRAM TAKES MORE THAN THE
  88. ;COMMON TIMEOUT OF 3 SECONDS TO LOAD UP BEFORE
  89. ;SENDING THE 1ST SECTOR, THEN THE RECEIVING
  90. ;PROGRAM MAY DECIDE TO SWITCH TO CHECKSUM MODE,
  91. ;AND EXPECT A CHECKSUM AFTER THE 1ST SECTOR.
  92. ;THE SENDING PROGRAM SENDS A CRC INSTEAD, WHICH
  93. ;LOOKS LIKE A BAD CHECKSUM, SO THE RECEIVING
  94. ;PROGRAM NAK'S IT. THIS GOES ON UNTIL BOTH
  95. ;REACH THEIR ERROR LIMITS, THEN GIVE UP. WHY
  96. ;HASN'T THIS PROBLEM SHOWN UP BEFORE? THE COMMON
  97. ;XMODEM PROGRAM V4.7 AND UP HAS A 10 SEC TIMEOUT
  98. ;ON THE RESPONSE TO THE 1ST "C", NOT 3 SEC,
  99. ;WHICH SHOULD BE LONG ENUFF FOR 16K TO LOAD.
  100. ;FURTHUR, XMODEM AND MODEM2XX PROGRAMS TRADITIONALLY
  101. ;ONLY LOADED 2K BUFFERS, WHICH LOAD UP IN UNDER
  102. ;3 SECS. THE ONLY COMMON CASE WOULD BE TRANSFERRING
  103. ;A FILE OF 16K OR MORE BETWEEN TWO MODEM7X PROGRAMS,
  104. ;WITH CRC, WHERE THE RECEIVER HAD 3 SEC TIMEOUT.
  105. ;NOTE THAT IF CRC IS NOT SPECIFIED, THERE IS NO
  106. ;PROBLEM. MY VOTE IS TO LENGTHEN THE TIMEOUT
  107. ;EVERYWHERE TO 7 SEC OR SO, TO GIVE THE SENDER
  108. ;PLENTY OF TIME, BECAUSE THE 16K IS MUCH EASIER
  109. ;ON THE DISK, AND A SHADE FASTER TOO. SO THAT HAS
  110. ;BEEN DONE HERE. IF YOU GET BIT BY THIS, CHANGE
  111. ;DBUFSIZ TO 2K, AND THE 3 SEC LIMITATION SHOULD
  112. ;THEN SUFFICE. IF YOU CONTROL BOTH POINTS, WHICH
  113. ;SHOULD BE THE ONLY TIME TWO MODEMXX PROGRAMS
  114. ;TALK TO EACH OTHER, FIX BOTH ENDS. I REPEAT,
  115. ;THERE IS NO PROBLEM TALKING TO XMODEM.
  116. ;
  117. ;  SINCE ASCII CAPTURE IS NOT IN EFFECT WHEN XFER
  118. ;IS GOING ON, EQUATE DBUF AND ASCBUF AT END OF
  119. ;PROGRAM. DID NOT CHANGE ASCBUF IN CASE FUTURE
  120. ;ENTERPRISING INDIVIDUALS CARE TO PRESERVE ASCII
  121. ;CAPTURE STATE OVER AN XFER.  -- Steve Bogolub
  122. ;
  123. ;    3/31/82
  124. ;Added code to convert lower case to upper case and
  125. ;trap any illegal characters in filename given for
  126. ;ASCII capture.  Added MAXDRV equate so that a non-
  127. ;valid drive will be trapped here, rather that bomb
  128. ;out of modem program with a BDOS error.  Added code
  129. ;to force ASCII capture file closed if it is open
  130. ;when terminal mode is exited, or disconnect command
  131. ;is given.  Added several new messages.
  132. ;            James Underwood (N6CFI)
  133. ;
  134. ;    3/28/82
  135. ;Removed a call to PRINTER in the terminal mode that
  136. ;caused double printing of locally typed characters because
  137. ;they were printed when sent, and when echoed by the
  138. ;remote system.  Also changed all occurances of 'H89' in IF
  139. ;statements to 'X8250' so that external 8250 chips are
  140. ;properly supported.  Added a place for modem base port
  141. ;equate when X8250 and NOT H89 to eliminate an undefined
  142. ;symbol error.  Fixed TRS and PMMI equates to eliminate
  143. ;doubly defined symbol errors.  Cleaned up file and
  144. ;greatly simplified TRS and H89 sections.
  145. ;            James Underwood (N6CFI)
  146. ;
  147. ;       2/21/82
  148. ;Cleaned up file, corrected HELP menu, changed
  149. ;settings for more "standard" machine, set error
  150. ;retries back to 10, made all lines 80 chars or less,
  151. ;added check for null filename in capture routines, and
  152. ;since the program already suffers from the most advanced
  153. ;case of RAMPANT FEATUREITIS known, added VIDEO mode for 
  154. ;for use on VIDEO terminals.  (Error msgs will be printed
  155. ;on separate lines, but successful "awaiting" or "sending"
  156. ;messages will overprint.) The spooling function still doesn't
  157. ;work the way I think it should, but it does work the way the
  158. ;original author intended it to (I think).
  159. ;                             (Dave Hardy)
  160. ;
  161. ;    1/31/82
  162. ;Implemented ascii capture feature and hardcopy
  163. ;option similar to that found in CCP. Added code
  164. ;for Heath H89/Zenith Z89 and for the 8250 ACE.
  165. ;            (Mark McGee)
  166. ;
  167. ;    10/22/81
  168. ;Changed PMMI port equates to be relative to the
  169. ;first port equ, thus to change PMMI port values
  170. ;one only has to change one address.  Removed the
  171. ;PMMI from the IF for INITREQ since PMMI does not
  172. ;require port initialization and in fact if it is
  173. ;initialized with INITREQ, the line will be lost.
  174. ;Changed receive sector routine so that on the
  175. ;first time thru when CRC is being used, it only
  176. ;waits for 3 seconds to receive the SOH after
  177. ;sending the initial 'C'.  If a character is not
  178. ;received in 3 seconds, then a NAK is sent and this
  179. ;program switches to checksum mode.  This allows
  180. ;the CRC MODEM to be used with versions of XMODEM
  181. ;that do not support CRC, even when MODEM has
  182. ;specified a CRC transmission.    The transmission
  183. ;will then take place using checksum instead of
  184. ;CRC.
  185. ;    Changed the default baud rate for the PMMI
  186. ;to an equate.    By changing the 'DEFBAUD EQU', the
  187. ;default baud rate for the PMMI can set to any rate.
  188. ;Grouped all of the EQU's for the PMMI under one 'IF'
  189. ;statement for ease of maintenance and documentation
  190. ;purposes.
  191. ;    Added equate(TERMNL EQU) to give one the option
  192. ;of whether or not to go to terminal mode before a
  193. ;file transfer.
  194. ;                (John Mahr)
  195. ;
  196. ;    10/19/81
  197. ;FIXED 'SEND #' AND 'AWAITING #' STATEMENTS TO
  198. ;PROPERLY DISPLAY THE CURRENT SECTOR # BEING SENT OR
  199. ;RECEIVED.  FIXED SEND MSG TO DISPLAY PROPER NUMBER
  200. ;OF RECORDS IN THE FILE TO BE SENT (FILES LARGER THAN
  201. ;1 EXTENT) USING THE SAME ROUTINES FOUND IN XMODEM43.
  202. ;IF NO OPTIONS SELECTED ON INITIAL ENTRY, JUMP TO
  203. ;'BADOPT' WITHOUT INITIALIZING MODEM.  FIXED THE EQUATES
  204. ;FOR THE DCH ERROR MASKS FOR PARITY, OVERRUN & FRAMING.
  205. ;MADE A SEPARATE CONDITIONAL ASSEMBLY FOR DCH & X6850
  206. ;UART EQUATES (JUST IN CASE THE X6850 INFO WAS CORRECT)
  207. ;AND ELIMINATED THE DCH "INITC1" THRU "INITC4" EQUATES
  208. ;SINCE THEY ARE NOT USED BY DCH DURING THE "INITMD"
  209. ;CONDITIONAL ASSEMBLY.  (BILL ATEN)
  210. ;
  211. ;    10/12/81
  212. ;ADDED CYCLIC REDUNDANCY CHECK OPTION ON THE FILE
  213. ;RECEIVE OPTION.  THIS IN ANOTHER SECONDARY OPTION
  214. ;THAT IS SPECIFIED BY SPECIFYING A 'C'.
  215. ;    MODEM RC.600 fn.ft
  216. ;    MODEM ROC.300 fn.ft, etc.
  217. ;        NOTE: CANNOT HAVE MORE THAN 6 SEC OPTIONS.
  218. ;WHEN THE FILE RECEIVE SPECIFIES CRC, THE LETTER 'C' IS
  219. ;SENT IN PLACE OF THE INITIAL NAK.  THIS SIGNALS THE SENDER
  220. ;(XMODEM45+ or MODEM213+) THAT CRC IS IN EFFECT.  THE SENDING
  221. ;PROGRAM WILL AUTOMATICALLY SWITCH TO CRC MODE.  THE CRC
  222. ;WILL REPLACE THE CHECKSUM METHOD OF CHECKING FOR DATA
  223. ;INTEGRITY ON FILE TRANSMISSIONS.  CRC WILL GIVE BETTER
  224. ;THAN A 99.99% PROBABILITY THAT THERE ARE NO DATA INTEGRITY
  225. ;ERRORS.  ACKNOWLEDGEMENT AND THANKS TO PAUL HANSKNECHT
  226. ;WHO DESIGNED AND WROTE CRC120.  IT IS THE CRC120 MACRO
  227. ;THAT WAS USED TO IMPLEMENT CRC IN THIS PROGRAM.
  228. ;                    (JOHN MAHR)
  229. ;
  230. ;    10/08/81
  231. ;ADDED TRS80 MODEL I SUPPORT INCLUDING BAUD RATE 
  232. ;SELECT FROM COMMAND LINE.   (MARK C WEHMHOEFER)
  233. ;
  234. ;    10/02/81
  235. ;FIXED RCVFILE BUG IN 10/1 VERSION.  REVISED MOST
  236. ;MESSAGES TO UPPER & LOWER CASE.  CHANGED RCVFILE SO
  237. ;IT SENDS THE INITIAL NAK AS SOON AS THE FILE IS OPEN,
  238. ;WITHOUT WAITING FOR A TIMEOUT FIRST.  (DHH)
  239. ;    *NOTE: A FILE TRANSFER WILL FAIL IF THE SEND
  240. ;        END IS NOT STARTED BEFORE THE RECEIVE
  241. ;        END WHEN THERE IS NO WAIT BEFORE
  242. ;        SENDING THE INITIAL NAK OR CRC
  243. ;        REQUEST. (10/12/81, JRM)
  244. ;
  245. ;    10/02/81
  246. ;FIXED DUPLICATE EQUATE FOR BASE ADDRESS, REMOVED UNUSED
  247. ;EQUATE FOR H8CPM.  (KBP)
  248. ;
  249. ;    10/01/81
  250. ;ADDED ERROR MASKS FOR HAYES MICROMODEM & 6850 ACIA.
  251. ;ADDED "X6850" CONDITIONAL.  ADDED "PORTED" CONDITIONAL
  252. ;TO ALLOW USE ON MEMORY-MAPPED SYSTEMS SUCH AS THE
  253. ;APPLE II.  COLLECTED MODEM PRIMITIVE OPERATIONS TO
  254. ;FRONT OF PROGRAM.  MADE RCV ERROR CHECKING ACTIVE FOR
  255. ;ALL MODEMS.  (DAV HOLLE)
  256. ;
  257. ;    9/11/81
  258. ;FIXED BUG IN 6/2 MOD.  ADDED BELL TO CERTAIN ERROR MSGS.
  259. ;ADDED R & S OPTIONS MSGS.  CHANGED MULTI TO X8251
  260. ;CONDITIONAL & MOVED WITH MODEM TYPES. CHANGED SIGNON
  261. ;VERSION MESSAGE. (TED SHAPIN)
  262. ;
  263. ;       06/02/81
  264. ;ADDED BELL WHEN TRANSFER IS FINISHED.  SHORTENED LABELS
  265. ;TO 6 CHARS SO OTHER ASSEMBLERS WILL WORK.
  266. ;ADDED CALL TO 'TERM' FROM BOTH SEND AND RECEIVE. THIS
  267. ;LETS YOU CONTROL THE REMOTE SYSTEM BEFORE TRANSMISSION.
  268. ;AFTER YOU LOG ON, ETC., AND TYPE "XMODEM R FOO.ASM"
  269. ;OR WHATEVER. YOU CAN THEN TYPE CONTROL-E TO PUT THIS PROGRAM
  270. ;INTO SEND OR RECEIVE MODE. (TED SHAPIN, ORANGE, CA.)
  271. ;
  272. ;    05/07/81
  273. ;ADDED TRAPS FOR AMBIGUOUS FILE NAME OR NONE AT ALL.
  274. ;REARRANGED EQUATES FOR GREATER CLARITY.  CLEANED UP
  275. ;FILE.  (KBP)
  276. ;
  277. ;    05/02/81
  278. ;ADDED THE ABILITY TO DISPLAY MODEM STATUS ON A
  279. ;FRONT PANEL, IF ONE HAS ONE (SUCH AS AN ITHACA
  280. ;INTERSYSTEMS DPS-1).
  281. ;    1. FRNTPNL EQU TRUE TURNS IT ON
  282. ;    2. PANEL EQU 0FFH (SETS UP PORT ADDRESS
  283. ;        OF FRONT PANEL)  (JOHN MAHR)
  284. ;
  285. ;    05/01/81
  286. ;RESTORED HELP DISPLAY.  LOWER CASG CHARS AND TABS
  287. ;HAD BEEN TAKEN OUT.  ADDED TYPICAL EXTERNAL PORT
  288. ;EQUATES AND INIT VALUES.  REARRANGED ORDER OF
  289. ;MODIFICATION/FIXES INFO.  (KBP)
  290. ;
  291. ;    04/18/81
  292. ;ADDED DETECTION OF FRAMING ERRORS, OVERRUN ERRORS,
  293. ;PARITY ERRORS (IF PARITY IS USED) FOR THE RECEIVE
  294. ;FILE ROUTINE.  THIS FEATURE IS ONLY ACTIVE FOR
  295. ;THE PMMI MODEM, SINCE I DO NOT KNOW WHAT THE MODEM
  296. ;STATUS BITS ARE FOR IDS AND D.C. HAYES MODEMS.
  297. ;IF THERE IS ONE OF THE MENTIONED ERRORS, THE LINE
  298. ;WILL BE PURGED FOR THAT BLOCK AND A NAK WILL BE
  299. ;SENT TO THE SENDER FOR THAT BLOCK.  A MESSAGE TO
  300. ;OPERATOR WILL ALSO BE DISPLAYED.  (BY JOHN MAHR)
  301. ;
  302. ;    05/27/80
  303. ;ELIMINATED CONTROL-X CANCEL OF SEND FEATURE, AT
  304. ;SUGGESTION OF WARD CHRISTENSEN. A LINE GLITCH COULD
  305. ;CAUSE PREMATURE ABORT WHEN THIS FEATURE WAS ACTIVE.
  306. ;ADDED EQUATES FOR FALSE AND TRUE TO MAKE ASSEMBLY
  307. ;OPTIONS CLEARER. REMOVED H8 PORT EQUATES (THEY CAN
  308. ;BE PUT IN EXTERNAL MODEM EQUATES). (KBP)
  309. ;
  310. ;    12/06/79
  311. ;CORRECTED ERROR IN HELP FILE. SAID T.110, NOW SAYS
  312. ;TO.110. BY WARD CHRISTENSEN. CORRECTED RECEIVE FILE
  313. ;ROUTINE SO TERMINAL OR ECHO MODE WORKS AFTER FILE
  314. ;TRANSFER IN QUIET MODE. MOVED CHECKS FOR "H" AND
  315. ;"X" OPTIONS SO MODEM IS NOT REINITIALIZED. (KBP)
  316. ;
  317. ;    08/06/79
  318. ;ADDED EQUATES FOR EXTERNAL MODEM (NOT S-100 PLUG-IN)
  319. ;(KBP)
  320. ;
  321. ;    08/05/79
  322. ;ADDED D.C. HAYES MODEM SUPPORT BY JIM BELL  (KBP)
  323. ;
  324. ;    07/24/79
  325. ;MOVE INITIALIZE LOCAL STACK TO BEGINNING OF PROGRAM
  326. ;SO DEFAULT STACK IS NOT USED. ADD CONDITIONAL ASSEMBLY
  327. ;OPTION TO TERMINAL ROUTINE FOR TIMESHARE SYSTEMS.
  328. ;CORRECT ERROR IN LOCAL ABORT ROUTINE (WAS LOOKING FOR
  329. ;CONTROL-E - NOW CORRECTLY LOOKS FOR CONTROL-X). ADD
  330. ;REGISTER SAVES TO CONOUT, KEYIN AND KEYBOARD STATUS
  331. ;ROUTINES, AS SOME CBIOS ROUTINES CLOBBER THEM. (KBP)
  332. ;
  333. ;    07/01/79
  334. ;MODIFIED PROGRAM TO ALLOW FOR NON-STANDARD VERSIONS OF
  335. ;CP/M. ALL REFERENCES TO ENTRIES INTO CP/M SHOULD BE MADE
  336. ;RELATIVE TO THE VARIABLE SYMBOL CALLED "BASE". FOR EXAMPLE,
  337. ;THE EQUATE TO BDOS SHOULD BE BASE+5 INSTEAD OF 5. BASE
  338. ;WILL BE SET TO 0 WHEN THE VARIABLE STDCPM IS SET TO TRUE.
  339. ;(BOB MATHIAS).
  340. ;
  341. ;    05/24/79
  342. ;FIXED MISSING RETURN INSTRUCTION AT END OF
  343. ;INITIALIZATION ROUTINE.  (KBP)
  344. ;
  345. ;    05/22/79
  346. ;ADDED FEATURE TO MAKE RECEIVE FILE ROUTINE SAY
  347. ;FILE SUCCESSFULLY OPENED, WHEN IN QUIET MODE.
  348. ;MOVED INITIAL 'GOBBLE GARBAGE INPUTS' TO BEFORE
  349. ;COMMAND CPI'S SO ALL MODES ARE CLEARED. CHANGED
  350. ;INITIAL SEND WAIT TO 80 SECS TO ALLOW MORE TIME
  351. ;FOR RECEIVING END TO COME UP. ADDED 'H' AFTER MSG
  352. ;THAT SHOWS NUMBER OF SECTORS IN EXTENT ABOUT TO
  353. ;BE SENT.  (KBP)
  354. ;
  355. ;    05/09/79
  356. ;ALLOW 'T' AND 'E' SUB-OPTIONS TO GO TO TERMINAL
  357. ;OR ECHO MODE AFTER TRANSFERRING A FILE.  (WLC)
  358. ;
  359. ;    04/26/79
  360. ;REWRITTEN BY WARD CHRISTENSEN TO COMBINE
  361. ;IMPROVEMENTS TO THE ORIGINAL MADE BY WARD
  362. ;AND BY KEITH PETERSEN, W8SDZ, AND SUGGESTIONS
  363. ;BY JIM BELL WHICH KEITH IMPLEMENTED.  SEE
  364. ;MODEM.DOC FOR ADDITIONAL HISTORICAL
  365. ;INFORMATION AND DOCUMENTATION.
  366. ;
  367. ;    09/23/77
  368. ;ORIGINALLY WRITTEN BY WARD CHRISTENSEN
  369. ;
  370. ;    --------------
  371. ;
  372. ;NOTE: IF YOU ADD IMPROVEMENTS OR OTHERWISE UPDATE
  373. ;THIS PROGRAM, PLEASE MODEM A COPY OF THE NEW FILE
  374. ;TO "TECHNICAL CBBS" IN DEARBORN, MICHIGAN - PHONE
  375. ;313-846-6127 (110, 300, 450 OR 600 BAUD).  USE THE
  376. ;FILENAME MODEM.NEW.    (KBP)
  377. ;
  378. ;    --------------
  379. ; DEFINE EQUATES
  380. ;
  381. FALSE    EQU    0
  382. TRUE    EQU    NOT FALSE
  383. ;
  384. STDCPM    EQU    TRUE        ;TRUE, IS STANDARD CP/M
  385. ALTCPM    EQU    FALSE        ;TRUE, IS ALTERNATE CP/M FOR H8 OR TRS80
  386. DBUFSIZ    EQU    16        ;BUFFER SIZE IN KBYTES
  387. ;
  388. ; DEFINE TYPE OF CP/M IN USE
  389. ;
  390.     IF    STDCPM
  391. BASE    EQU    0        ;CP/M BASE ADDRESS
  392.     ENDIF
  393. ;
  394.     IF    ALTCPM
  395. BASE    EQU    4200H        ;CP/M BASE ADDRESS FOR ALTERNATE CP/M
  396.     ENDIF
  397. ;
  398. ; DEFINE MODEM INTERFACE
  399. ;
  400. DCH    EQU    FALSE        ;TRUE, IS D.C. HAYES MODEM
  401. PMMI    EQU    FALSE        ;TRUE, IS PMMI MODEM
  402. H89    EQU    FALSE        ;TRUE, IS HEATH H89
  403.                 ;BE SURE X8250 IS ALSO TRUE
  404. TRS    EQU    FALSE        ;TRUE FOR TRS80 MODEL I
  405.                 ;BE SURE X8251 IS ALSO TRUE
  406. ;
  407. X8250    EQU    FALSE        ;TRUE, IS EXTERNAL 8250 ACE
  408. X8251    EQU    TRUE        ;TRUE, IS EXTERNAL 8251 USART
  409. X6850    EQU    FALSE        ;TRUE, IS EXTERNAL 6850 ACIA
  410. ;
  411. PORTED    EQU    TRUE        ;TRUE FOR IN/OUT PORTS, FALSE FOR LDA/STA
  412. INITREQ EQU    TRUE        ;TRUE IF PORT MODEM CONNECTED TO...
  413. ;                 ...REQUIRES INITIALIZATION.
  414. MAXDRV    EQU    'E'        ;MAX DRIVE ON SYSTEM
  415. ;
  416. ; DEFINE OTHER SYSTEM PARAMETERS
  417. ;
  418. FASTCLK EQU    FALSE        ;TRUE FOR 4 MHZ CLOCK, FALSE FOR 2 MHZ
  419. FRNTPNL EQU    FALSE        ;TRUE FOR FRONT PANEL DISPLAY
  420. VIDEO    EQU    FALSE        ;TRUE FOR USE WITH VIDEO TERMINAL
  421. TERMNL    EQU    FALSE        ;TRUE, GO TO TERMINAL MODE BEFORE..
  422. ;                 ...FILE TRANSFER.
  423. ;
  424.     IF    FRNTPNL
  425. PANEL    EQU    0FFH        ;PORT ADDRESS FOR FRONT PANEL
  426.     ENDIF
  427. ;
  428. ; SOME TIME-SHARE COMPUTERS REQUIRE TERMINALS TO
  429. ; HAVE BIT 7 HIGH (MARKING), SO IN THE TERMINAL
  430. ; MODE WE FORCE IT TO HIGH IF THE FOLLOWING OPTION
  431. ; IS SELECTED:
  432. ;
  433. TIMESHR EQU    FALSE        ;TRUE TO MAKE BIT 7 HIGH
  434. ;*****************************************************************************
  435.     IF    PMMI
  436. ; SET DCH=FALSE,H89=FALSE,PMMI=TRUE,X8250=FALSE,X8251=FALSE,
  437. ; X6850=FALSE,PORTED=TRUE,INITREQ=FALSE
  438. ;
  439. ; THESE EQUATES SET ALL OF THE VALUES NECESSARY TO USE A PMMI.
  440. ; THE ONLY ONE THAT SHOULD EVER HAVE TO BE CHANGED IS MDCTLP
  441. ; WHICH IS THE ADDRESS OF THE FIRST PORT ON THE PMMI.  THIS
  442. ; ADDRESS IS SET BY SWITCHES ON THE PMMI CARD.
  443. ;
  444. MDCTLP    EQU    0E0H        ;PMMI VALUES (BASE ADDR OF I/O PORTS)
  445. MDDATP    EQU    MDCTLP+1    ;DATA PORT
  446. BAUDRP    EQU    MDCTLP+2    ;BAUD RATE OUTPUT
  447. MDCTL2    EQU    MDCTLP+3    ;SECOND CTL PORT
  448. ORIGMD    EQU    1DH        ;8 DATA, NO PARITY, ORIG
  449. ANSWMD    EQU    1EH        ;8 DATA, NO PARITY, ANSW
  450. ;
  451. FRMER    EQU    20H        ;FRAMING ERROR MASK
  452. ORUNER    EQU    10H        ;OVERRUN ERROR MASK
  453. PARER    EQU    08H        ;PARITY ERROR MASK
  454. ;
  455. MDSNDB    EQU    1        ;BIT TO TEST FOR SEND
  456. MDSNDR    EQU    1        ;VALUE WHEN READY
  457. MDRCVB    EQU    2        ;BIT TO TEST FOR RECEIVE
  458. MDRCVR    EQU    2        ;VALUE WHEN READY
  459. ;
  460. DEFBAUD EQU    52        ;DEFAULT TO 300 BAUD
  461.                 ;USE 52 FOR 300 BAUD
  462.                 ;USE 26 FOR 600 BAUD
  463.                 ;USE 104 FOR 150 BAUD
  464.                 ;USE 142 FOR 110 BAUD
  465.     ENDIF            ;PMMI
  466. ;*****************************************************************************
  467.     IF    DCH
  468. MDCTLP    EQU    82H        ;D. C. HAYES VALUES
  469. MDDATP    EQU    80H        ;DATA PORT
  470. MDCTL2    EQU    81H        ;SECOND CTL PORT
  471. ;
  472. ; NOTE: BAUD RATE DEFAULTS TO 300 - 1 STOP BIT.
  473. ; DO NOT CHANGE NEXT EQUATES:
  474. ;
  475. ORIGMD    EQU    86H        ;OFF HOOK, 110 BAUD, CAR. ON, ORIG.
  476. ANSWMD    EQU    82H        ;OFF HOOK, 110 BAUD, CAR. ON, ANSW.
  477.     ENDIF            ;DCH
  478. ;*****************************************************************************
  479. ;
  480. ; FOR APPLE CARDS:  PORTED=FALSE AND X6850=TRUE, AND
  481. ; MDDATP IS 1 MORE THAN MDCTLP. FOR SSM AIO, APPLE COM
  482. ; CARD, OR CCS 7710 USE MDCTLP=0E0ACH (FOR SLOT 2), OR
  483. ; USE 0E0AEH FOR MICROMODEM II. FOR DIFFERENT SLOTS,
  484. ; ADD (SLOT-2)*10H TO THE ABOVE ADDRESSES.
  485. ;
  486. ;-->IF USING EXTERNAL MODEM WITH 8250, 8251 OR 6850
  487. ;-->CHIP, CHANGE THESE EQUATES TO YOUR SYSTEM REQUIREMENTS
  488. ;
  489.     IF    X6850
  490. MDCTLP    EQU    0E0AEH        ;MODEM CONTROL PORT
  491. MDDATP    EQU    MDCTLP+1    ;MODEM DATA PORT
  492.     ENDIF    ;X6850
  493. ;
  494.     IF    X8251
  495. MDCTLP    EQU    0F7H        ;MODEM CONTROL PORT
  496. MDDATP    EQU    MDCTLP-1    ;MODEM DATA PORT
  497.     ENDIF    ;X8251
  498. ;
  499.     IF    X8250 AND NOT H89
  500. MDDATP    EQU    60H    ;YOUR MODEM DATA PORT
  501.     ENDIF            ;X8250 AND NOT H89
  502. ;
  503. ;-->END OF EXTERNAL MODEM BASE EQUATES
  504. ;
  505. ;*****************************************************************************
  506.     IF    H89
  507. ;FOR H89 SET THESE TRUE, ALL OTHERS FALSE:
  508. ;    H89,X8250,PORTED,STDCPM
  509. ;
  510. MDDATP    EQU    0D8H        ;HEATH MODEM PORT BASE ADDRESS
  511.     ENDIF            ;H89
  512. ;*****************************************************************************
  513.     IF    TRS
  514. ;FOR TRS SET THESE TRUE, ALL OTHERS FALSE:
  515. ;    TRS,X8251,PORTED,ALTCPM
  516. ;
  517. MDCTLP    EQU    0EAH        ;TRS-80 WITH RS232 VALUES
  518. MDDATP    EQU    0EBH        ;DATA PORT
  519.     ENDIF            ;H89
  520. ;*****************************************************************************
  521.     IF    X8250
  522. MDCTL1    EQU    MDDATP+1    ;INTERRUPT CONTROL
  523. MDCTL3    EQU    MDDATP+3    ;WORD CHARACTERISTICS
  524. MDCTL4    EQU    MDDATP+4    ;LINE CONTROL
  525. MDCTL5    EQU    MDDATP+5    ;LINE STATUS
  526.     ENDIF            ;X8250
  527. ;*****************************************************************************
  528. ;
  529. ; THESE EQUATES SPECIFY THE INITIALIZATION SEQUENCE
  530. ; AND STATUS FLAGS USED BY YOUR TYPE OF MODEM.
  531. ;
  532. ;
  533.     IF    X8251
  534. INITC1    EQU    00H        ;1ST INIT CHAR TO 8251 CTL PORT
  535. INITC2    EQU    00H        ;2ND
  536. INITC3    EQU    00H        ;3RD
  537. INITC4    EQU    37H        ;4TH
  538. ;
  539. RSTCODE    EQU    37H        ; Reset error, set DTR,
  540.                 ;  enable receiver and
  541.                 ;  transmitter
  542. ;
  543. FRMER    EQU    20H        ;FRAMING ERR MASK
  544. ORUNER    EQU    10H        ;OVERRUN ERR MASK
  545. PARER    EQU    08H        ;PARITY ERR MASK
  546. ;
  547. MDSNDB    EQU    1        ;BIT TO TEST FOR SEND
  548. MDSNDR    EQU    1        ;VALUE WHEN READY
  549. MDRCVB    EQU    2        ;BIT TO TEST FOR RECEIVE
  550. MDRCVR    EQU    2        ;VALUE WHEN READY
  551.     ENDIF            ;X8251
  552. ;*****************************************************************************
  553.     IF    X8250
  554. INITC1    EQU    83H        ;ACCESS DIVISOR LATCHES
  555. INITC2    EQU    03H        ;SET DTR AND RTS
  556. INITC3    EQU    80H        ;LOW BAUD DIVISOR (300 BAUD)
  557. INITC4    EQU    01H        ;HIGH BAUD DIVISOR (300 BAUD)
  558. INITC5    EQU    03H        ;8 BITS,1 STOP, NO PARITY
  559. INITC6    EQU    00H        ;DISABLE ALL INTERRUPTS
  560. ;
  561. FRMER    EQU    08H        ;FRAMING ERR MASK
  562. ORUNER    EQU    02H        ;OVERRUN ERR MASK
  563. PARER    EQU    04H        ;PARITY ERR MASK
  564. ;
  565. MDSNDB    EQU    20H        ;BIT TO TEST FOR SEND
  566. MDSNDR    EQU    20H        ;VALUE WHEN READY
  567. MDRCVB    EQU    01H        ;BIT TO TEST FOR RECEIVE
  568. MDRCVR    EQU    01H        ;VALUE WHEN READY
  569.     ENDIF            ;X8250
  570. ******************************************************************************
  571.     IF    DCH
  572. PARER    EQU    04H        ;PARITY ERR MASK
  573. FRMER    EQU    08H        ;FRAMING ERR MASK
  574. ORUNER    EQU    10H        ;OVERRUN ERR MASK
  575. ;
  576. MDSNDB    EQU    2        ;BIT TO TEST FOR SEND
  577. MDSNDR    EQU    2        ;VALUE WHEN READY
  578. MDRCVB    EQU    1        ;BIT TO TEST FOR RECEIVE
  579. MDRCVR    EQU    1        ;VALUE WHEN READY
  580.     ENDIF            ;DCH
  581. ;*****************************************************************************
  582.     IF    X6850
  583. INITC1    EQU    3        ;1ST INIT CHAR TO 6850 CTL PORT
  584. INITC2    EQU    15H        ;2ND, 8 DATA + 1 STOP + NO PARITY,
  585.                 ; 16X CLOCK. USE 16H FOR SAME WITH 64X
  586.                 ; CLOCK TO SWITCH FROM 1200 TO 300 BAUD,
  587.                 ; FOR EXAMPLE.
  588. INITC3    EQU    INITC1        ;3RD (ONLY 2 NEEDED, REUSE 1 & 2)
  589. INITC4    EQU    INITC2        ;4TH
  590. ;
  591. FRMER    EQU    10H        ;FRAMING ERR MASK
  592. ORUNER    EQU    20H        ;OVERRUN ERR MASK
  593. PARER    EQU    40H        ;PARITY ERR MASK
  594. ;
  595. MDSNDB    EQU    2        ;BIT TO TEST FOR SEND
  596. MDSNDR    EQU    2        ;VALUE WHEN READY
  597. MDRCVB    EQU    1        ;BIT TO TEST FOR RECEIVE
  598. MDRCVR    EQU    1        ;VALUE WHEN READY
  599.     ENDIF            ;X6850
  600. ;*****************************************************************************
  601. ;
  602. ; DEFINE SOME OTHER THINGS (NORMALLY NOT CHANGED)
  603. ;
  604. ERRLIM    EQU    10        ;MAX ALLOWABLE ERRORS (10 STANDARD)
  605. STPTIME EQU    4        ;SEND STOP THIS MANY CHARS EARLY
  606. CPTRKEY EQU    'Y'-40H     ;CTL-Y TOGGLES ASCII CAPTURE MODE
  607. DISCCHR EQU    'D'-40H     ;CTL-D DISCONNECTS MODEM T/E
  608. EXITCHR EQU    'E'-40H     ;CTL-E EXIT FROM T OR E
  609. PRTCHAR EQU    'P'-40H     ;CTL-P TOGGLES PRINTER OPTION
  610. STRTCHR EQU    'Q'-40H     ;CTL-Q TO MAKE OTHER END RESUME (MOST SYSTEMS
  611.                 ;WILL ACCEPT ANY CHAR,SO CTL-Q IS TO INCLUDE
  612.                 ;THE XON/XOFF PROTOCALL)
  613. STOPCHR EQU    'S'-40H     ;CTL-S TO MAKE OTHER END PAUSE
  614. ;
  615. ; DEFINE ASCII CHARACTERS USED
  616. ;
  617. SOH    EQU    1        ;START OF HEADER
  618. EOT    EQU    4        ;END OF TRANSMISSION
  619. ACK    EQU    6        ;ACKNOWLEDGE
  620. NAK    EQU    15H        ;NEG ACKNOWLEDGE
  621. CRC    EQU    'C'        ;USED TO REQUEST CRC INSTEAD OF CHECKSUM
  622. CAN    EQU    18H        ;CANCEL
  623. LF    EQU    10        ;LINEFEED
  624. CR    EQU    13        ;CARRIAGE RETURN
  625. BELL    EQU    'G'-40H     ;BELLS
  626. ;*****************************************************************************
  627.     ORG    BASE+100H
  628. ;
  629. ;INIT PRIVATE STACK
  630.     LXI    H,0        ;HL=0
  631.     DAD    SP        ;HL=STACK FROM CP/M
  632.     SHLD    STACK        ;..SAVE IT
  633.     LXI    SP,STACK    ;SP=MY STACK
  634.     LDA    BASE+0007H    ;BDOS PAGE ADDRESS
  635.     SUI    8+1        ;ACCOUNT FOR CCP (2K) + 1 PG SLOP
  636.     STA    MEMEND        ;  AND SAVE THE RESULT
  637.     CALL    START        ;GO PRINT ID
  638.     DB    'MODEM ver 2.21A of 04/19/82'
  639.     DB    CR,LF,'$'
  640. ;
  641. ; MODEM I/O PRIMITIVES
  642. ;
  643. ; COLLECTED HERE FOR EASIER PATCHING & MAINTENANCE.
  644. ; PORTED I/O ROUTINES HAVE NOP'S TO LEAVE ROOM
  645. ; FOR LATER PATCHING TO LDA'S & STA'S IF NECESSARY.
  646. ;
  647.     IF    PORTED AND (NOT X8250)
  648. OUTDATA OUT    MDDATP
  649.     RET
  650.     NOP
  651. INDATA    IN    MDDATP
  652.     RET
  653.     NOP
  654. OUTCTL    OUT    MDCTLP
  655.     RET
  656.     NOP
  657. INCTL    IN    MDCTLP
  658.     RET
  659.     NOP
  660.     ENDIF            ;PORTED AND (NOT X8250)
  661. ;
  662.     IF    PORTED AND X8250
  663. OUTDATA OUT    MDDATP
  664.     RET
  665.     NOP
  666. INDATA    IN    MDDATP
  667.     RET
  668.     NOP
  669. OUTCTL1 OUT    MDCTL1
  670.     RET
  671.     NOP
  672. OUTCTL3 OUT    MDCTL3
  673.     RET
  674.     NOP
  675. OUTCTL4 OUT    MDCTL4
  676.     RET
  677.     NOP
  678. INCTL5    IN    MDCTL5
  679.     RET
  680.     NOP
  681.     ENDIF            ;PORTED AND X8250
  682. ;
  683.     IF    PORTED AND (DCH OR PMMI)
  684. OUTCT2    OUT    MDCTL2
  685.     RET
  686.     NOP
  687. INCT2    IN    MDCTL2
  688.     RET
  689.     NOP
  690.     ENDIF            ;PORTED AND (DCH OR PMMI)
  691. ;
  692.     IF    PORTED AND PMMI
  693. OUTBRP    OUT    BAUDRP
  694.     RET
  695.     NOP
  696.     ENDIF            ;PORTED AND PMMI
  697. ;
  698.     IF    PORTED AND FRNTPNL
  699. OUTPAN    OUT    PANEL
  700.     RET
  701.     NOP
  702.     ENDIF            ;PORTED AND FRNTPNL
  703. ;
  704.     IF    NOT PORTED
  705. OUTDATA STA    MDDATP
  706.     RET
  707. INDATA    LDA    MDDATP
  708.     RET
  709. OUTCTL    STA    MDCTLP
  710.     RET
  711. INCTL    LDA    MDCTLP
  712.     RET
  713.     ENDIF            ;NOT PORTED
  714. ;
  715.     IF    (NOT PORTED) AND (DCH OR PMMI)
  716. OUTCT2    STA    MDCTL2
  717.     RET
  718. INCT2    LDA    MDCTL2
  719.     RET
  720.     ENDIF            ;(NOT PORTED) AND (DCH OR PMMI)
  721. ;
  722.     IF    PMMI AND NOT PORTED
  723. OUTBRP    STA    BAUDRP
  724.     RET
  725.     ENDIF            ;PMMI AND NOT PORTED
  726. ;
  727.     IF    FRNTPNL AND NOT PORTED
  728. OUTPAN    STA    PANEL
  729.     RET
  730.     ENDIF            ;FRNTPNL AND NOT PORTED
  731. ;
  732. START    POP    D        ;GET ID MESSAGE
  733.     MVI    C,PRINT
  734.     CALL    BDOS        ;PRINT ID MESSAGE
  735. ;
  736. ; INITIALIZE THE JMPS TO CP/M BIOS
  737. ;
  738.     CALL    INITADR
  739. ;
  740.     LDA    FCB+1        ;GET PRIMARY OPTION
  741.     CPI    'H'        ;MODEM H(ELP)?
  742.     JZ    HELP        ;..YES, GIVE HELP
  743.     CPI    ' '        ;NO OPTIONS?
  744.     JZ    BADOPT        ;..EXPLAIN & GIVE HELP
  745.     CPI    'X'        ;MODEM X(AMPLES)?
  746.     JZ    EXAM        ;GIVE EXAMPLES
  747. ;
  748. ; SAVE PRIMARY OPTION, VALIDATE SECONDARY OPT.
  749. ;
  750.     CALL    PROCOPT
  751. ;
  752. ; INIT THE MODEM OR SERIAL PORT
  753. ;
  754.     CALL    INITMD
  755. ;
  756. ; MOVE THE FILENAME FROM FCB 2 TO FCB 1
  757. ;
  758.     CALL    MOVEFCB
  759. ;
  760. ; GOBBLE UP GARBAGE CHARS FROM THE LINE
  761. ; PRIOR TO RECEIVE OR SEND
  762. ;
  763.     CALL    INDATA
  764.     CALL    INDATA
  765. ;
  766. ; JMP TO APPROPRIATE FUNCTION
  767. ;
  768.     LDA    OPTION        ;GET PRIMARY OPTION
  769. ;
  770.     CPI    'C'        ;(COMPAT W/EARLIER
  771.     JZ    TRMECHO     ;OPTION "COMPUTER")
  772. ;
  773.     CPI    'E'        ;TERMINAL IN ECHO
  774.     JZ    TRMECHO     ;..MODE?
  775. ;
  776.     CPI    'T'        ;TERMINAL..
  777.     JZ    TERM        ;..MODE?
  778. ;
  779.     CPI    'D'        ;DISCONNECT?
  780.     JZ    DISCONN
  781. ;
  782.     CPI    'S'        ;SEND..
  783.  
  784.     IF    TERMNL        ;GO TO TERMINAL MODE FIRST.
  785.     JZ    TSND        ;..A FILE?
  786.     ENDIF
  787. ;
  788.     IF    NOT TERMNL    ;GO STRAIGHT TO FILE SEND
  789.     JZ    TERMX        ;GO SEND A FILE
  790.     ENDIF
  791. ;
  792.     CPI    'R'        ;RECEIVE..
  793. ;
  794.     IF    TERMNL        ;GO TO TERMINAL MODE FIRST
  795.     JZ    TRCV        ;..A FILE?
  796.     ENDIF
  797. ;
  798.     IF    NOT TERMNL    ;GO STRAIGHT TO FILE RECEIVE
  799.     JZ    TERMX        ;RECEIVE A FILE
  800.     ENDIF
  801. ;
  802. ;INVALID OPTION
  803. ;
  804.     JMP    BADOPT
  805. ;
  806. TSND:    CALL    ILPRT
  807.     DB    'In terminal mode, Ctl-E to start SEND',CR,LF,0
  808.     JMP    TERM
  809. TRCV:    CALL    ILPRT
  810.     DB    'In terminal mode, Ctl-E to start RECEIVE',CR,LF,0
  811. ;FALL THRU TO TERM
  812. ;
  813. ;* * * * * * * * * * * * * * * * * * * * *
  814. ;*                     *
  815. ;*    TERM: TERMINAL MODE         *
  816. ;*                     *
  817. ;* * * * * * * * * * * * * * * * * * * * *
  818. ;
  819. ; THIS PROGRAM SIMPLY SENDS KEYED CHARACTERS
  820. ; DOWN THE LINE, AND DISPLAYS CHARACTERS
  821. ; RECEIVED FROM THE LINE.  THIS MAKES IT
  822. ; SUITABLE FOR COMMUNICATION WITH TIME SHARING
  823. ; COMPUTERS, CBBS'S, OR ANOTHER PROGRAM
  824. ; RUNNING "MODEM E" (ECHO MODE)
  825. ;
  826. ; TYPE THE "EXITCHR" (ORIGINALLY CTL-E) TO LEAVE TERM MODE,
  827. ; OR THE "DISCCHR" (ORIGINALLY CTL-D) TO DISCONNECT.
  828. ;
  829. ; ASCII CAPTURE IS TOGGLED BY ENTERING CTL-Y, AT WHICH TIME
  830. ; THE PROGRAM WILL PROMPT FOR THE DESIRED FILE NAME. THE FILE
  831. ; IS CLOSED BY AGAIN ENTERING CTL-Y.
  832. ;
  833. ; THE PRINTER OPTION WORKS JUST AS IN CCP - ENTER CTL-P TO
  834. ; TURN THE PRINTER ON, AND AGAIN TO TURN IT OFF.
  835. ;
  836. TERM    CALL    STAT        ;LOCAL CHAR KEYED?
  837.     JZ    TERML        ;..NO, CHECK LINE
  838.     CALL    KEYIN        ;GET CHAR
  839.     CPI    EXITCHR     ;TIME TO END?
  840.     JZ    TERMX        ;YES, LEAVE TERMINAL MODE
  841.     CPI    DISCCHR     ;DISCONNECT REQUEST?
  842.     JZ    DISCONN     ;YES, DO IT
  843. ;
  844.     CPI    CPTRKEY     ;TOGGLE CAPTURE MODE?
  845.     CZ    CPTRTOG     ;YES, DO IT
  846.     JZ    TERM01        ;IF CAPTURE MODE COMMAND, DON'T SEND IT
  847.     CPI    PRTCHAR     ;TOGGLE PRINTER MODE?
  848.     CZ    PRTRTOG     ;YES, DO IT
  849.     JZ    TERM01        ;IF PRINTER TOGGLE, DON'T SEND IT
  850. ;
  851.     IF    TIMESHR
  852.     ORI    80H        ;FORCE BIT 7 TO HIGH
  853.     ENDIF            ;TIMESHR
  854. ;
  855.     CALL    OUTDATA     ;SEND THE CHAR
  856. TERM01    EQU    $
  857. ;
  858. ; SEE IF CHAR FROM LINE
  859. ;
  860.     IF    (NOT DCH) AND (NOT X8250)
  861. TERML    CALL    INCTL        ;READ STATUS
  862.     ENDIF
  863. ;
  864.     IF X8250
  865. TERML    CALL    INCTL5        ;READ STATUS
  866.     ENDIF
  867. ;
  868.     IF    DCH
  869. TERML    CALL    INCT2        ;READ STATUS
  870.     ENDIF
  871. ;
  872.     IF    FRNTPNL AND PMMI
  873.     CALL    OUTPAN        ;DISPLAY STATUS
  874.     ENDIF
  875. ;
  876.     ANI    MDRCVB        ;ISOLATE BIT
  877.     CPI    MDRCVR        ;READY?
  878.     JNZ    TERM        ;..NO, LOOP
  879.     CALL    INDATA        ;READ DATA
  880.     ANI    7FH        ;STRIP PARITY BIT
  881.     CALL    TYPE        ;TYPE IT
  882.     CALL    PRINTER     ;SEND TO PRINTER IF ENABLED
  883.     CALL    ASCPTR        ;SAVE TO DISK IF ENABLED
  884.     JMP    TERM        ;LOOP
  885. ;
  886. TERMX:    LDA    CPTRFLG
  887.     ORA    A
  888.     CNZ    CPTRTOG    ;IF CAPTURE WAS ON, TURN OFF
  889.     LDA    FIRST        ;DON'T JUMP
  890.     INR    A        ;TO SEND OR RECEIVE
  891.     STA    FIRST        ;MORE THAN ONCE
  892.     JNZ    CKDIS        ;CHECK DISCONNECT
  893.     LDA    OPTION        ;PRIMARY OPTION
  894.     CPI    'S'        ;SEND?
  895.     JZ    SENDFIL     ;..A FILE
  896.     CPI    'R'        ;RECEIVE
  897.     JZ    RCVFIL        ;A FILE
  898.     JMP    CKDIS        ;REALLY EXIT
  899. ;
  900. ;* * * * * * * * * * * * * * * * * * * * *
  901. ;*                     *
  902. ;*    TRMECHO: TERMINAL WITH ECHO     *
  903. ;*                     *
  904. ;* * * * * * * * * * * * * * * * * * * * *
  905. ;
  906. ; TERMINAL PROGRAM WITH ECHO - SEE NOTES
  907. ; UNDER "TERM" ABOVE
  908. ;
  909. ; C A U T I O N   DON'T RUN WITH BOTH COMPUTERS
  910. ; IN "ECHO" MODE - LINE ERRORS (OR ANY CHAR)
  911. ; WILL BE ECHOED BACK AND FORTH AD INFINITUM.
  912. ;
  913. ; ASCII CAPTURE IS TOGGLED BY ENTERING CTL-Y, AT WHICH TIME
  914. ; THE PROGRAM WILL PROMPT FOR THE DESIRED FILE NAME. THE FILE
  915. ; IS CLOSED BY AGAIN ENTERING CTL-Y.
  916. ;
  917. ; THE PRINTER OPTION WORKS JUST AS IN CCP - ENTER CTL-P TO
  918. ; TURN THE PRINTER ON, AND AGAIN TO TURN IT OFF.
  919. ;
  920.     IF    (NOT DCH) AND (NOT X8250)
  921. TRMECHO CALL    INCTL        ;GET STATUS
  922.     ENDIF
  923. ;
  924.     IF X8250
  925. TRMECHO CALL    INCTL5        ;GET STATUS
  926.     ENDIF
  927. ;
  928.     IF    DCH
  929. TRMECHO CALL    INCT2        ;GET STATUS
  930.     ENDIF
  931. ;
  932.     IF    FRNTPNL AND PMMI
  933.     OUT    PANEL        ;DISPLAY STATUS
  934.     ENDIF
  935. ;
  936.     ANI    MDRCVB        ;ISOLATE READY BIT
  937.     CPI    MDRCVR        ;ARE WE READY?
  938.     JZ    LINECHR     ;YES, READ THE CHR
  939.     CALL    STAT        ;CHECK LOCAL KB
  940.     JZ    TRMECHO     ;..NO CHAR
  941.     CALL    KEYIN        ;GET LOCAL CHAR
  942.     CPI    EXITCHR     ;END?
  943.     JZ    CKDIS        ;YES, CK DISCONN, EXIT
  944.     CPI    DISCCHR     ;DISCONN?
  945.     JZ    DISCONN     ;..YES, DO IT.
  946.     CPI    CPTRKEY     ;TOGGLE CAPTURE MODE?
  947.     CZ    CPTRTOG     ;..YES, DO IT
  948.     JZ    TERM02        ;IF CAPTURE MODE COMMAND, DON'T SEND IT
  949.     CPI    PRTCHAR     ;TOGGLE PRINTER MODE?
  950.     CZ    PRTRTOG     ;..YES, DO IT
  951.     JZ    TERM02        ;IF PRINTER TOGGLE, DON'T SEND IT
  952.     CALL    OUTDATA     ;SEND CHAR
  953.     CALL    TYPE        ;ECHO IT LOCALLY
  954.     CALL    PRINTER     ;SEND TO PRINTER IF ENABLED
  955.     CALL    ASCPTR        ;SAVE IT TO DISK IF ENABLED
  956. TERM02    JMP    TRMECHO     ;..AND LOOP
  957. ;
  958. ; GOT CHAR FROM LINE
  959. ;
  960. LINECHR CALL    INDATA        ;GET CHAR
  961.     ANI    7FH        ;STRIP PARITY BIT
  962.     CALL    OUTDATA     ;ECHO IT
  963.     CALL    TYPE        ;TYPE IT
  964.     CALL    PRINTER     ;SEND TO PRINTER IF ENABLED
  965.     JMP    TRMECHO     ;LOOP
  966. ;
  967. ;* * * * * * * * * * * * * * * * * * * * *
  968. ;*                     *
  969. ;*    SENDFIL: SENDS A CP/M FILE     *
  970. ;*                     *
  971. ;* * * * * * * * * * * * * * * * * * * * *
  972. ;
  973. ; THE CP/M FILE SPECIFIED IN THE MODEM COMMAND
  974. ; IS TRANSFERRED OVER THE PHONE TO ANOTHER
  975. ; COMPUTER RUNNING MODEM WITH THE "R" (RECEIVE)
  976. ; OPTION.  THE DATA IS SENT ONE SECTOR AT A
  977. ; TIME WITH HEADERS AND CHECKSUMS OR CYCLIC
  978. ; REDUNDANCY CHECKS.  CYCLIC REDUNDANCY CHECK
  979. ; IS USED IF THE LETTER 'C' IS RECEIVED IN
  980. ; PLACE OF THE INITIAL NAK.  IT IS INCORRECT
  981. ; TO SPECIFY CRC ON THE SEND (MODEM SC fn.ft),
  982. ; SINCE IT IS THE RECEIVER WHO DETERMINES
  983. ; WHETHER CRC IS TO BE USED.  IF THERE IS AN
  984. ; ERROR, THE SECTOR IS RETRANSMITTED.
  985. ;
  986. SENDFIL CALL    TRAP        ;CHECK FOR NO NAME OR AMBIG. NAME
  987.     CALL    CNREC        ;COMPUTE RECORD COUNT
  988.     CALL    OPENFIL     ;OPEN THE FILE
  989.     MVI    E,80        ;WAIT 80 SEC..
  990.     CALL    WAITNAK     ;..FOR INITIAL NAK
  991. ;
  992. SENDLP    CALL    RDSECT        ;READ A SECTOR
  993.     JC    SENDEOF     ;SEND EOF IF DONE
  994.     CALL    INCRSNO     ;BUMP SECTOR #
  995.     XRA    A        ;ZERO ERROR..
  996.     STA    ERRCT        ;..COUNT
  997. ;
  998. SENDRPT CALL    SENDHDR     ;SEND A HEADER
  999.     CALL    SENDSEC     ;SEND DATA SECTOR
  1000.     LDA    CRCFLG        ;GET CRC FLAG
  1001.     ORA    A        ;CRC IN EFFECT?
  1002.     CZ    SENDCRC     ;YES, GO SEND CRC
  1003.     CNZ    SENDCKS     ;NO, SEND CKSUM NOT CRC
  1004.     CALL    GETACK        ;GET THE ACK
  1005.     JC    SENDRPT     ;REPEAT IF NO ACK
  1006.     JMP    SENDLP        ;LOOP UNTIL EOF
  1007. ;
  1008. ; FILE SENT, SEND EOT'S
  1009. ;
  1010. SENDEOF MVI    A,EOT        ;SEND..
  1011.     CALL    SEND        ;..AN EOT
  1012.     CALL    GETACK        ;GET THE ACK
  1013.     JC    SENDEOF     ;LOOP IF NO ACK
  1014.     JMP    DONE        ;ALL DONE
  1015. ;
  1016. ;---->    CNREC: Computes record count, and saves it
  1017. ;           until successful file OPEN.
  1018. ;
  1019. ; LOOK UP THE FCB IN THE DIRECTORY
  1020. CNREC:    MVI    C,STDMA        ;SET DMA ADDR TO
  1021.     LXI    D,BASE+80H    ; DEF BUFFER
  1022.     CALL    BDOS        ; SO DIR INFO WHERE SHOULD BE
  1023.     MVI    A,'?'        ;MATCH ALL EXTENTS
  1024.     STA    FCBEXT
  1025.     MVI    A,0FFH
  1026.     STA    MAXEXT        ;INIT MAX EXT NO.
  1027.     MVI    C,SRCHF     ;GET 'SEARCH FIRST' FNC
  1028.     LXI    D,FCB
  1029.     CALL    BDOS        ;READ FIRST
  1030.     INR    A        ;WERE THERE ANY?
  1031.     JNZ    SOME        ;GOT SOME
  1032.     CALL    ERXIT
  1033.     DB    '++File not found++',CR,LF,'$'
  1034. ;
  1035. ; READ MORE DIRECTORY ENTRIES
  1036. MOREDIR MVI    C,SRCHN     ;SEARCH NEXT
  1037.     LXI    D,FCB
  1038.     CALL    BDOS        ;READ DIR ENTRY
  1039.     INR    A        ;CHECK FOR END (0FFH)
  1040.     JNZ    SOME        ;NOT END OF DIR...PROCESS EXTENT
  1041.     LDA    MAXEXT        ;HIT END...GET HIGHEST EXTENT NO. SEEN
  1042.     MOV    L,A        ;WHICH GIVES EXTENT COUNT - 1
  1043.     MVI    H,0
  1044.     MOV    D,H
  1045.     LDA    RCNT        ;GET RECORD COUNT OF MAX EXTENT SEEN
  1046.     MOV    E,A        ;SAVE IT IN DE
  1047.     DAD    H
  1048.     DAD    H        ;MULTIPLY # OF EXTENTS - 1
  1049.     DAD    H        ; TIMES 128
  1050.     DAD    H
  1051.     DAD    H
  1052.     DAD    H
  1053.     DAD    H
  1054.     DAD    D        ;ADD IN SIZE OF LAST EXTENT
  1055.     SHLD    RCNT        ;SAVE TOTAL RECORD COUNT
  1056.     RET            ;AND EXIT
  1057. ;
  1058. ; POINT TO DIRECTORY ENTRY
  1059. SOME    DCR    A        ;UNDO PREV 'INR A'
  1060.     ANI    3        ;MAKE MODULUS 4
  1061.     ADD    A        ;MULTIPLY...
  1062.     ADD    A        ;..BY 32 BECAUSE
  1063.     ADD    A        ;..EACH DIRECTORY
  1064.     ADD    A        ;..ENTRY IS 32
  1065.     ADD    A        ;..BYTES LONG
  1066.     LXI    H,BASE+80H    ;POINT TO BUFFER
  1067.     ADD    L        ;POINT TO ENTRY
  1068.     ADI    15        ;OFFSET TO RECORD COUNT
  1069.     MOV    L,A        ;HL NOW POINTS TO REC COUNT
  1070.     MOV    B,M        ;GET RECORD COUNT
  1071.     DCX    H
  1072.     DCX    H        ;BACK DOWN TO EXTENT NUMBER
  1073.     DCX    H
  1074.     LDA    MAXEXT        ;COMPARE WITH CURRENT MAX.
  1075.     ORA    A        ;IF NO MAX YET
  1076.     JM    BIGGER        ;THEN SAVE RECORD COUNT ANYWAY
  1077.     CMP    M
  1078.     JNC    MOREDIR
  1079. ;
  1080. BIGGER: MOV    A,B        ;SAVE NEW RECORD COUNT
  1081.     STA    RCNT
  1082.     MOV    A,M        ;SAVE NEW MAX. EXTENT NO.
  1083.     STA    MAXEXT
  1084.     JMP    MOREDIR     ;GO FIND MORE EXTENTS
  1085. ;
  1086. ;
  1087. ;* * * * * * * * * * * * * * * * * * * * *
  1088. ;*                     *
  1089. ;*    RCVFIL: RECEIVE A FILE         *
  1090. ;*                     *
  1091. ;* * * * * * * * * * * * * * * * * * * * *
  1092. ;
  1093. ; RECEIVES A FILE IN BLOCK FORMAT AS SENT
  1094. ; BY ANOTHER PERSON DOING "MODEM S FN.FT".
  1095. ; IF THE CRC SECONDARY OPTION (MODEM RC fn.ft)
  1096. ; WAS CHOSEN, THE LETTER 'C' WILL BE SENT IN
  1097. ; PLACE OF THE INITIAL NAK.  IF A SECTOR IS
  1098. ; RECEIVED IN ERROR, THEN A NAK IS SENT WHICH
  1099. ; REQUESTS THAT THE SECTOR BE RESENT.
  1100. ;
  1101. RCVFIL    CALL    TRAP        ;CHECK FOR NO NAME OR AMBIG. NAME
  1102.     CALL    ERASFIL     ;ERASE THE FILE
  1103.     CALL    MAKEFIL     ;..THEN MAKE NEW
  1104.     CALL    ILPRT        ;PRINT:
  1105.     DB    'File open, ready to receive',CR,LF,0
  1106.     LDA    CRCFLG        ;GET CRC FLAG
  1107.     ORA    A        ;CRC BEING USED?
  1108.     MVI    A,NAK        ;PREPARE FOR CHECKSUM BEING IN EFFECT
  1109.     JNZ    RCVFIL2     ;BRANCH IF CHECKSUM BEING USED
  1110.     MVI    A,CRC        ;REQUEST CYCLIC REDUNDANCY CHECK
  1111. ;
  1112. RCVFIL2 CALL    SEND        ;SEND INITIAL NAK (CHECKSUM) OR CRC REQUEST
  1113. ;
  1114. RCVLP    CALL    RCVSECT     ;GET A SECTOR
  1115.     JC    RCVEOT        ;GOT EOT
  1116.     CALL    WRSECT        ;WRITE THE SECTOR
  1117.     CALL    INCRSNO     ;BUMP SECTOR #
  1118.     CALL    SENDACK     ;ACK THE SECTOR
  1119.     JMP    RCVLP        ;LOOP UNTIL EOF
  1120. ;
  1121. ; GOT EOT ON SECTOR - FLUSH BUFFERS, END
  1122. ;
  1123. RCVEOT    CALL    WRBLOCK     ;WRITE THE LAST BLOCK
  1124.     CALL    SENDACK     ;ACK THE SECTOR
  1125.     CALL    CLOSFIL     ;CLOSE THE FILE
  1126.     JMP    DONE        ;ALL DONE
  1127. ;
  1128. ;* * * * * * * * * * * * * * * * * * * * *
  1129. ;*                     *
  1130. ;*        SUBROUTINES         *
  1131. ;*                     *
  1132. ;* * * * * * * * * * * * * * * * * * * * *
  1133. ;
  1134. ;---->    TRAP: CHECK FOR NO FILE NAME OR AMBIGUOUS NAME
  1135. ;
  1136. TRAP    LXI    H,FCB+1     ;POINT TO FILE NAME
  1137.     MOV    A,M        ;GET FIRST CHAR OF FILE NAME
  1138.     CPI    ' '        ;ANY THERE?
  1139.     JNZ    ATRAP        ;YES, CHECK FOR AMBIGOUS FILE NAME
  1140.     CALL    ERXIT        ;PRINT MSG, EXIT
  1141.     DB    '++No file name specified++',CR,LF,'$'
  1142. ;
  1143. ATRAP    MVI    B,11        ;11 CHARS TO CHECK
  1144. ;
  1145. TRLOOP    MOV    A,M        ;GET CHAR FROM FCB
  1146.     CPI    '?'        ;AMBIGUOUS?
  1147.     JZ    TRERR        ;YES, EXIT WITH ERROR MSG
  1148.     INX    H        ;POINT TO NEXT CHAR
  1149.     DCR    B        ;ONE LESS TO GO
  1150.     JNZ    TRLOOP        ;NOT DONE, CHECK SOME MORE
  1151.     RET            ;NO AMBIGUOUS NAME, RETURN
  1152. ;
  1153. TRERR    CALL    ERXIT        ;PRINT MSG, EXIT
  1154.     DB    '++Can''t use wild card options++',CR,LF,'$'
  1155. ;
  1156. ;---->    RCVSECT: RECEIVE A SECTOR
  1157. ;
  1158. ; RETURNS WITH CARRY SET IF EOT RECEIVED.
  1159. ;
  1160. RCVSECT XRA    A        ;GET 0
  1161.     STA    ERRCT        ;INIT ERROR COUNT
  1162. ;
  1163. RCVRPT    XRA    A        ;GET 0
  1164.     STA    ERRCDE        ;CLEAR RECEIVE ERROR CODE
  1165.     LDA    QFLG        ;QUIET?
  1166.     ORA    A
  1167.     JZ    RCVSQ        ;YES, NO STAT MSG.
  1168. ;
  1169.     IF    NOT VIDEO    ;Then send CRLF
  1170.     CALL    CRLF
  1171.     ENDIF
  1172. ;
  1173.     IF    VIDEO        ;Then send only a CR
  1174.     MVI    A,CR
  1175.     CALL    TYPE
  1176.     ENDIF
  1177. ;
  1178.     CALL    ILPRT        ;PRINT:
  1179.     DB    'Awaiting # ',0
  1180.     PUSH    H        ;SAVE HL
  1181.     LHLD    SECTNO        ;GET SECTOR #
  1182.     INX    H        ;BUMP IT
  1183.     CALL    DECOUT        ;PRINT SECTOR # IN DECIMAL
  1184.     CALL    ILPRT
  1185.     DB    ' (',0
  1186.     CALL    DHXOUT        ;16 BIT HEX CONV & OUTPUT
  1187.     CALL    ILPRT
  1188.     DB    'H) ',0
  1189.     MOV    A,L        ;ONLY LOW BYTE USED BY PROG
  1190.     POP    H        ;RESTORE HL
  1191. ;
  1192. RCVSQ    LDA    FIRSTME     ;GET FIRST TIME SWITCH
  1193.     ORA    A        ;FIRST TIME THRU?
  1194.     JZ    RCVSQ2        ;NO, SKIP TO RECEIVE SOH
  1195.     XRA    A        ;TURN OFF..
  1196.     STA    FIRSTME     ;..FIRST TIME SWITCH
  1197.     LDA    CRCFLG        ;CRC IN..
  1198.     ORA    A        ;..EFFECT?
  1199.     JNZ    RCVSQ2        ;NO, DO LONG WAIT FOR SOH
  1200.     MVI    B,7        ;WAIT FOR UP TO 7 SECONDS
  1201.     CALL    RECV        ;GET A CHARACTER
  1202.     JNC    RCVSQ3        ;GOT A CHAR, GO SEE IF SOH
  1203.     CALL    ILPRT
  1204.     DB    '++Switching to CHECKSUM MODE++',CR,LF,0
  1205.     MVI    A,'C'        ;TURN OFF...
  1206.     STA    CRCFLG        ;...CRC MODE
  1207.     MVI    A,NAK        ;SEND A NAK TO TELL SENDER CHECKSUM..
  1208.     CALL    SEND        ;..IN EFFECT & START SENDING DATA.
  1209.     JMP    RCVSECT     ;GO START RECEIVING SECTOR
  1210. ;
  1211. RCVSQ2    MVI    B,10        ;10 SEC TIMEOUT
  1212.     CALL    RECV        ;GET SOH/EOT
  1213.     JC    RCVSTOT     ;TIMEOUT
  1214.  
  1215. rcvsq3    CALL    RCVR        ;TRANS ERROR?
  1216.     JC    RCERR        ;CARRY ON IF ERROR
  1217.     CPI    SOH        ;GET SOH?
  1218.     JZ    RCVSOH        ;..YES
  1219. ;
  1220. ; EARLIER VERSIONS OF MODEM PROG SENT SOME NULLS -
  1221. ; IGNORE THEM
  1222. ;
  1223.     ORA    A        ;00 FROM SPEED CHECK?
  1224.     JZ    RCVSQ        ;YES, IGNORE IT
  1225.     CPI    EOT        ;END OF TRANSFER?
  1226.     STC            ;RETURN WITH CARRY..
  1227.     RZ            ;..SET IF EOT
  1228. ;
  1229. ; DIDN'T GET SOH OR EOT
  1230. ;
  1231.     MOV    B,A        ;SAVE CHAR
  1232.     LDA    VSEEFLG     ;VIEWING..
  1233.     ORA    A        ;..MODE?
  1234.     JZ    RCVSEH        ;YES, PRT.MSG
  1235.     LDA    QFLG        ;QUIET..
  1236.     ORA    A        ;..MODE?
  1237.     JZ    RCVSERR     ;YES, SKIP MSG
  1238. ;
  1239. RCVSEH    MOV    A,B        ;GET CHAR
  1240.     CALL    HEXO        ;SHOW IN HEX
  1241.     CALL    ILPRT        ;PRINT:
  1242.     DB    'H rcvd, not SOH',CR,LF,0
  1243. ;
  1244. ; DIDN'T GET VALID HEADER - PURGE THE LINE,
  1245. ; THEN SEND NAK.
  1246. ;
  1247. RCVSERR MVI    B,1        ;WAIT FOR 1 SEC..
  1248.     CALL    RECV        ;..WITH NO CHARS
  1249.     JNC    RCVSERR     ;LOOP UNTIL SENDER DONE
  1250.     LDA    ERRCT        ;ABORT IF..
  1251.     INR    A        ;..WE HAVE REACHED..
  1252.     STA    ERRCT        ;..THE ERROR..
  1253.     CPI    ERRLIM        ;..LIMIT?
  1254.     JC    RCVCQ2        ;..NO, TRY AGAIN (FIRST, SEND NAK)
  1255. ;
  1256. ; 10 ERRORS IN A ROW -
  1257. ;
  1258.     LDA    VSEEFLG     ;VIEWING..
  1259.     ORA    A        ;..FILE?
  1260.     JZ    RCVCKQ        ;YES, ASK RETRY/QUIT
  1261.     LDA    QFLG        ;QUIET..
  1262.     ORA    A        ;..MODE?
  1263.     JZ    RCVSABT     ;ABORT
  1264. ;
  1265. RCVCKQ    CALL    CKQUIT        ;RETRY/QUIT?
  1266.     JNZ    RCVSABT     ;QUIT, THEN ABORT
  1267. ;
  1268. ; LINE MUST BE PURGED BECAUSE SENDER PROBABLY STARTED
  1269. ; RESENDING WHILE OPERATOR ANSWERED RETRY/QUIT PROMPT.
  1270. ;
  1271. RCVCQ2    MVI    A,NAK        ;SEND NAK TO CANCEL SECTOR
  1272.     CALL    SEND
  1273.     JMP    RCVRPT        ;GO RE-RECEIVE SECTOR
  1274. ;
  1275. RCVSABT CALL    CLOSFIL     ;KEEP WHATEVER WE GOT
  1276.     CALL    ERXIT
  1277.     DB    '++Unable to receive block -- Aborting++',BELL,CR,LF,'$'
  1278. ;
  1279. ; TIMED OUT ON RECEIVE
  1280. ;
  1281. RCVSTOT LDA    VSEEFLG     ;VIEWING..
  1282.     ORA    A        ;..MODE?
  1283.     JZ    RCVSPT        ;YES, PRT MSG
  1284.     LDA    QFLG        ;QUIET..
  1285.     ORA    A        ;..MODE?
  1286.     JZ    RCVSERR     ;YES, NO MSG
  1287. ;
  1288. RCVSPT    CALL    ILPRT
  1289.     DB    '++Timeout++ ',0
  1290. ;
  1291. RCVPRN    LDA    ERRCT        ;PRINT ERROR..
  1292.     CALL    HEXO        ;..COUNT
  1293.     CALL    CRLF
  1294.     JMP    RCVSERR     ;BUMP ERR CT, ETC.
  1295. ;
  1296. ;---->    RCVR: CHECKS FOR FRAMING ERROR, OVERRUN ERROR,
  1297. ;          AND PARITY ERROR.
  1298. ;    1.  ERROR CODE (ERRCDE) WAS SET IN RECV ROUTINE.
  1299. ;    2.  ERRCDE=0 FOR NO ERRORS, ERRCDE<>0 FOR ERRORS.
  1300. ;    3.  IF THERE IS AN ERROR, THE CARRY BIT IS SET ON.
  1301. ;
  1302. RCVR    PUSH    PSW        ;SAVE CHAR TRANSMITTED
  1303.     LDA    ERRCDE        ;GET RECEIVE ERROR CODE
  1304.     ANA    A        ;IS IT ZERO?
  1305.     JZ    RCVR2        ;YES, NO RECEIVE ERROR
  1306.     POP    PSW        ;RESTORE CHAR TRANSMITTED
  1307.     STC            ;SET CARRY ON TO INDICATE AN ERROR
  1308.     RET
  1309. ;
  1310. RCVR2    POP    PSW        ;RESTORE CHAR TRANSMITTED
  1311.     ORA    A        ;CLEAR CARRY BIT
  1312.     RET
  1313. ;
  1314. ;---->    RCERR: CHECKS FOR A RECEIVE ERROR AND DISPLAYS
  1315. ;    APROPRIATE ERROR MESSAGE.  THEN GOES TO RCVSERR
  1316. ;    TO PURGE THE LINE AND SEND A NAK.
  1317. ;
  1318. RCERR    LDA    VSEEFLG     ;VIEWING
  1319.     ORA    A        ;..MODE?
  1320.     JZ    RCERRP        ;YES,. PRT MSG
  1321.     LDA    QFLG        ;QUIET..
  1322.     ORA    A        ;..MODE?
  1323.     JZ    RCVSERR     ;YES, NO MSG
  1324. ;
  1325. RCERRP:
  1326.     LDA    ERRCDE        ;GET RECEIVE ERR CODE
  1327.     ANI    FRMER        ;WAS THERE A FRAMING ERROR?
  1328.     CPI    FRMER
  1329.     JNZ    RCERR2        ;NO, GO CHECK FOR OVERRUN
  1330.     CALL    ILPRT
  1331.     DB    '++Framing error++ ',0
  1332.     CALL    RCERR5        ;PRINT # OF ERR
  1333. ;
  1334. RCERR2:
  1335.     LDA    ERRCDE        ;GET RECEIVE ERR CODE
  1336.     ANI    ORUNER        ;WAS THERE AN OVERRUN?
  1337.     CPI    ORUNER
  1338.     JNZ    RCERR3        ;NO, CHECK FOR PARITY ERR
  1339.     CALL    ILPRT
  1340.     DB    '++Overrun error++ ',0
  1341.     CALL    RCERR5
  1342. ;
  1343. RCERR3:
  1344.     LDA    ERRCDE        ;GET RECEIVE ERR CODE
  1345.     ANI    PARER        ;WAS THERE A PARITY ERR?
  1346.     CPI    PARER
  1347.     JNZ    RCERR4        ;NO, GO PURGE LINE
  1348.     CALL    ILPRT
  1349.     DB    '++Parity error++ ',0
  1350.     CALL    RCERR5
  1351. ;
  1352. RCERR4:
  1353.     JMP    RCVSERR     ;GO PURGE LINE, SEND NAK
  1354. ;
  1355. ; DISPLAY THE NUMBER OF THE ERROR, DO A CARRIAGE
  1356. ; RETURN AND LINE FEED.
  1357. ;
  1358. RCERR5:
  1359.     LDA    ERRCT        ;GET ERROR NUMBER
  1360.     CALL    HEXO        ;DISPLAY IT
  1361.     CALL    CRLF        ;DO CR, LF
  1362.     RET
  1363. ;
  1364. ;
  1365. ; GOT SOH - GET BLOCK #, BLOCK # COMPLEMENTED
  1366. ;
  1367. RCVSOH    MVI    B,1        ;TIMEOUT = 1 SEC
  1368.     CALL    RECV        ;GET SECTOR #
  1369.     JC    RCVSTOT     ;GOT TIMEOUT
  1370.     CALL    RCVR        ;TRANSMISSION ERROR?
  1371.     JC    RCERR        ;YES, GO DISP MSG, PURGE LINE
  1372.     MOV    D,A        ;D=BLK #
  1373.     MVI    B,1        ;TIMEOUT = 1 SEC
  1374.     CALL    RECV        ;GET COMPLEMENTED SECTOR #
  1375.     JC    RCVSTOT     ;TIMEOUT
  1376.     CALL    RCVR        ;TRANSMISSION ERROR?
  1377.     JC    RCERR        ;YES IF CARRY ON
  1378.     CMA            ;CALC COMPLEMENT
  1379.     CMP    D        ;GOOD SECTOR #?
  1380.     JZ    RCVDATA     ;YES, GET DATA
  1381. ;
  1382. ; GOT BAD SECTOR #
  1383. ;
  1384.     LDA    VSEEFLG     ;VIEWING..
  1385.     ORA    A        ;..MODE?
  1386.     JZ    RCVBSE        ;..YES, PRT MSG
  1387.     LDA    QFLG        ;QUIET..
  1388.     ORA    A        ;..MODE?
  1389.     JZ    RCVSERR     ;..YES, NO MSG
  1390. ;
  1391. RCVBSE    CALL    ILPRT        ;PRINT:
  1392.     DB    '++Bad sector # in hdr',CR,LF,0
  1393.     JMP    RCVSERR     ;BUMP ERROR CT.
  1394. ;
  1395. RCVDATA MOV    A,D        ;GET SECTOR #
  1396.     STA    RCVSNO        ;SAVE IT
  1397.     MVI    A,1        ;SHOW..
  1398.     STA    DATAFLG     ;GETTING DATA
  1399.     MVI    C,0        ;INIT CKSUM
  1400.     CALL    CLRCRC        ;CLEAR CRC COUNTER
  1401.     LXI    H,BASE+80H    ;POINT TO BUFFER
  1402. ;
  1403. RCVCHR    MVI    B,1        ;1 SEC TIMEOUT
  1404.     CALL    RECV        ;GET CHAR
  1405.     JC    RCVSTOT     ;TIMEOUT
  1406.     CALL    RCVR        ;TRANSMISSION ERROR?
  1407.     JC    RCERR        ;YES IF CARRY ON
  1408.     MOV    M,A        ;STORE CHAR
  1409.     INR    L        ;DONE?
  1410.     JNZ    RCVCHR        ;NO, LOOP
  1411.     LDA    CRCFLG        ;GET CRC FLAG
  1412.     ORA    A        ;CRC IN EFFECT?
  1413.     JZ    RCVCRC        ;YES, GO GET CRC
  1414. ;
  1415. ; VERIFY CHECKSUM
  1416. ;
  1417.     MOV    D,C        ;SAVE CHECKSUM
  1418.     XRA    A        ;SHOW..
  1419.     STA    DATAFLG     ;..END OF DATA
  1420.     MVI    B,1        ;TIMEOUT LEN.
  1421.     CALL    RECV        ;GET CHECKSUM
  1422.     JC    RCVSTOT     ;TIMEOUT
  1423.     CALL    RCVR        ;TRANSMISSION ERROR?
  1424.     JC    RCERR        ;YES IF CARRY ON
  1425.     CMP    D        ;CHECKSUM OK?
  1426.     JNZ    RCVCERR     ;NO, ERROR
  1427. ;
  1428. ; GOT A SECTOR, IT'S A DUP IF = PREV,
  1429. ; OR OK IF = 1 + PREV SECTOR
  1430. ;
  1431. CHKSNUM LDA    RCVSNO        ;GET RECEIVED
  1432.     MOV    B,A        ;SAVE IT
  1433.     LDA    SECTNO        ;GET PREV
  1434.     CMP    B        ;PREV REPEATED?
  1435.     JZ    RECVACK     ;ACK TO CATCH UP
  1436.     INR    A        ;CALC NEXT SECTOR #
  1437.     CMP    B        ;MATCH?
  1438.     JNZ    ABORT        ;NO MATCH - STOP SENDER, EXIT
  1439.     RET            ;CARRY OFF - NO ERRORS
  1440. ;
  1441. ; RECEIVE THE CYCLIC REDUNDANCY CHECK CHARACTERS (2 BYTES),
  1442. ; AND CHECK TO SEE IF THE SENT CRC MATCHES THE CALCULATED
  1443. ; CRC.    IF THEY MATCH GET NEXT SECTOR, ELSE PRINT ERROR
  1444. ; MESSAGE IF NOT IN QUIET MODE AND SEND A NAK REQUESTING
  1445. ; THAT THE SECTOR BE RESENT.
  1446. ;
  1447. RCVCRC    MVI    E,2        ;NUMBER OF CRC BYTES TO RECEIVE
  1448. ;
  1449. RCVCRC2 MVI    B,1        ;1 SEC TIMEOUT
  1450.     CALL    RECV        ;GET CRC BYTE
  1451.     JC    RCVSTOT     ;CARRY SET IF TIMEOUT
  1452.     CALL    RCVR        ;TRANSMISSION ERR?
  1453.     JC    RCERR        ;CARRY SET IF TRANS ERR
  1454.     DCR    E        ;GOT BOTH CRC BYTES?
  1455.     JNZ    RCVCRC2     ;NO, GO GET 2ND BYTE
  1456.     CALL    CHKCRC        ;CHECK RECVD CRC AGAINST CALCD CRC
  1457.     ORA    A        ;IS CRC OKAY?
  1458.     JZ    CHKSNUM     ;YES, GO CHECK SECTOR NUMBERS
  1459. ;
  1460. ;PRINT CRC ERROR MESSAGE
  1461. ;
  1462.     LDA    VSEEFLG     ;VIEWING..
  1463.     ORA    A        ;..MODE?
  1464.     JZ    RCVCRER     ;..YES, PRINT MESSAGE
  1465.     LDA    QFLG        ;QUIET..
  1466.     ORA    A        ;..MODE?
  1467.     JZ    RCVSERR     ;YES, NO MESSAGE
  1468. ;
  1469. RCVCRER CALL    ILPRT
  1470.     DB    '++CRC error++ ',0
  1471.     JMP    RCVPRN
  1472. ;
  1473. ; GOT CKSUM
  1474. ;
  1475. RCVCERR LDA    VSEEFLG     ;VIEWING..
  1476.     ORA    A        ;..MODE?
  1477.     JZ    RCVCPR        ;..YES, PRT MSG
  1478.     LDA    QFLG        ;QUIET..
  1479.     ORA    A        ;..MODE?
  1480.     JZ    RCVSERR     ;YES, NO MSG
  1481. ;
  1482. RCVCPR    CALL    ILPRT
  1483.     DB    '++CKSUM error++ ',0
  1484.     JMP    RCVPRN        ;PRINT ERROR #
  1485. ;
  1486. ; PREVIOUS SECTOR REPEATED, DUE TO THE LAST ACK
  1487. ; BEING GARBAGED.  ACK IT SO SENDER WILL CATCH UP
  1488. ;
  1489. RECVACK CALL    SENDACK     ;SEND THE ACK,
  1490.     JMP    RCVSECT     ;GET NEXT BLOCK
  1491. ;
  1492. ; SEND AN ACK FOR THE SECTOR
  1493. ;
  1494. SENDACK MVI    A,ACK        ;GET ACK
  1495.     CALL    SEND        ;..AND SEND IT
  1496.     RET
  1497. ;
  1498. ;---->    SENDHDR: SEND THE SECTOR HEADER
  1499. ;
  1500. ; SEND: (SOH) (BLOCK #) (COMPLEMENTED BLOCK #)
  1501. ;
  1502. SENDHDR LDA    QFLG        ;QUIET..
  1503.     ORA    A        ;..MODE?
  1504.     JZ    SENDHNM     ;YES, SKIP STATUS MSG.
  1505. ;
  1506.     IF    NOT VIDEO    ;Then send CRLF
  1507.     CALL    CRLF
  1508.     ENDIF
  1509. ;
  1510.     IF    VIDEO        ;Then send only a CR
  1511.     MVI    A,CR
  1512.     CALL    TYPE
  1513.     ENDIF
  1514. ;
  1515.     CALL    ILPRT        ;PRINT:
  1516.     DB    'Send # ',0
  1517.     PUSH    H        ;SAVE HL
  1518.     LHLD    SECTNO        ;GET SECTOR #
  1519.     CALL    DECOUT        ;PRINT SECTOR # IN DECIMAL
  1520.     CALL    ILPRT
  1521.     DB    ' (',0
  1522.     CALL    DHXOUT        ;16 BIT HEX CONV & OUTPUT
  1523.     CALL    ILPRT
  1524.     DB    'H) ',0
  1525.     POP    H        ;RESTORE HL
  1526. ;
  1527. SENDHNM MVI    A,SOH        ;SEND..
  1528.     CALL    SEND        ;..SOH,
  1529.     LDA    SECTNO        ;THEN SEND..
  1530.     CALL    SEND        ;..SECTOR #
  1531.     LDA    SECTNO        ;THEN SECTOR #
  1532.     CMA            ;..COMPLEMENTED..
  1533.     CALL    SEND        ;..SECTOR #
  1534.     RET            ;FROM SENDHDR
  1535. ;
  1536. ;---->    SENDSEC: SEND THE DATA SECTOR
  1537. ;
  1538. ;    WHILE SENDING THE SECTOR, THE "DATAFLG" IS SET
  1539. ;    SUCH THAT IF "V" (VIEW THE FILE) WAS REQUESTED,
  1540. ;    THE "SHOW" ROUTINE WILL PRINT THE DATA, BUT NOT
  1541. ;    THE HDR OR CKSUM, OR ANY NON-FATAL MSGS.
  1542. ;
  1543. SENDSEC MVI    A,1        ;SHOW NOW AT DATA..
  1544.     STA    DATAFLG     ;..FOR VIEW COMMAND
  1545.     MVI    C,0        ;INIT CKSUM
  1546.     CALL    CLRCRC        ;CLEAR CRC COUNTER
  1547.     LXI    H,BASE+80H    ;POINT TO BUFFER
  1548. ;
  1549. SENDC    MOV    A,M        ;GET A CHAR
  1550.     CALL    SEND        ;SEND IT
  1551.     INR    L        ;POINT TO NEXT CHAR
  1552.     JNZ    SENDC        ;LOOP IF <100H
  1553.     XRA    A        ;SHOW NOT INTO DATA..
  1554.     STA    DATAFLG     ;..FOR VIEW COMMAND
  1555.     RET            ;FROM SENDSEC
  1556. ;
  1557. ;---->    SENDCKS: SEND THE CHECKSUM
  1558. ;
  1559. SENDCKS MOV    A,C        ;SEND THE..
  1560.     CALL    SEND        ;..CHECKSUM
  1561.     RET            ;FROM SENDCKS
  1562. ;
  1563. ;---->    SENDCRC: CALCULATE THE CYCLIC REDUNDANCY CHECK
  1564. ;         AND THEN SEND IT.  FINCRC CALCS THE
  1565. ;         FINAL CRC AND PLACES IT IN D,E REGS.
  1566. ;
  1567. SENDCRC CALL    FINCRC        ;CALC CRC FOR THE SECTOR
  1568.     MOV    A,D        ;PUT FIRST CHAR OF CRC IN ACCUM
  1569.     CALL    SEND        ;SEND IT
  1570.     MOV    A,E        ;PUT SECOND CHAR OF CRC IN ACCUM
  1571.     CALL    SEND
  1572.     XRA    A        ;MAKE SURE ZERO FLAG IS OFF
  1573.     RET
  1574. ;
  1575. ;---->    GETACK: GET THE ACK ON THE SECTOR
  1576. ;
  1577. ;    RETURNS WITH CARRY CLEAR IF ACK RECEIVED.
  1578. ;    IF AN ACK IS NOT RECEIVED, THE ERROR COUNT
  1579. ;    IS INCREMENTED, AND IF LESS THAN "ERRLIM",
  1580. ;    CARRY IS SET AOD CONTROL RETURNS.  IF THE
  1581. ;    ERROR COUNT IS AT "ERRLIM", THE PROGRAM
  1582. ;    ABORTS IF IN "QUIET" MODE, OR ASKS THE
  1583. ;    USER FOR QUIT/RETRY IF NOT.
  1584. ;
  1585. GETACK    MVI    B,10        ;WAIT 10 SECONDS MAX
  1586.     CALL    RECVDG        ;RECV W/GARBAGE COLLECT
  1587.     JC    GETATOT     ;TIMED OUT
  1588.     CPI    ACK        ;OK? (CARRY OFF IF =)
  1589.     RZ            ;YES, RET FROM GETACK
  1590.     MOV    B,A        ;SAVE CHAR
  1591.     LDA    QFLG        ;QUIET..
  1592.     ORA    A        ;..MODE?
  1593.     JZ    ACKERR        ;..YES, NO MSG
  1594.     MOV    A,B        ;GET CHAR
  1595.     CALL    HEXO        ;PRINT IN HEX
  1596.     CALL    ILPRT        ;PRINT:
  1597.     DB    'H rcvd, not ACK',CR,LF,0
  1598. ;
  1599. ; TIMEOUT OR ERROR ON ACK - BUMP ERROR COUNT
  1600. ;
  1601. ACKERR    LDA    ERRCT        ;GET COUNT
  1602.     INR    A        ;BUMP IT
  1603.     STA    ERRCT        ;SAVE BACK
  1604.     CPI    ERRLIM        ;AT LIMIT?
  1605.     RC            ;NOT AT LIMIT
  1606. ;
  1607. ; REACHED ERROR LIMIT
  1608. ;
  1609.     LDA    VSEEFLG     ;VIEWING..
  1610.     ORA    A        ;..FILE?
  1611.     JZ    GACKV        ;YES, ASK QUIT/RETRY
  1612.     LDA    QFLG        ;QUIET..
  1613.     ORA    A        ;..MODE?
  1614.     JZ    CSABORT     ;..YES, NO MSG
  1615. ;
  1616. GACKV    CALL    CKQUIT        ;SEE IF WANT TO QUIT
  1617.     STC            ;TO SHOW NO ACK
  1618.     RZ            ;KEEP ON TRYIN'
  1619. ;
  1620. CSABORT CALL    ERXIT
  1621.     DB    '++Can''t send sector -- Aborting++',BELL,CR,LF,'$'
  1622. ;
  1623. ; TIMEOUT GETTING ACK
  1624. ;
  1625. GETATOT LDA    QFLG        ;QUIET..
  1626.     ORA    A        ;..MODE?
  1627.     JZ    ACKERR        ;YES, NO MSG
  1628.     CALL    ILPRT        ;PRINT:
  1629.     DB    '++Timeout on ACK',CR,LF,0
  1630.     JMP    ACKERR
  1631. ;
  1632. ABORT    LXI    SP,STACK
  1633. ;
  1634. ABORTL    MVI    B,1        ;1 SEC. W/O CHARS.
  1635.     CALL    RECV
  1636.     JNC    ABORTL        ;LOOP UNTIL SENDER DONE
  1637.     MVI    A,NAK        ;NEGATIVE ACK
  1638.     CALL    SEND        ;TELL SENDING END
  1639.     CALL    ILPRT        ;EXIT WITH ABORT MSG
  1640.     DB    'MODEM program cancelled',CR,LF,0
  1641.     JMP    CKDIS        ;CHECK FOR DISCONN.
  1642. ;
  1643. ;---->    INCRSNO: INCREMENT SECTOR #
  1644. ;
  1645. INCRSNO: PUSH    H
  1646.     LHLD    SECTNO        ;GET SECTOR #
  1647.     INX    H        ;BOP IT
  1648.     SHLD    SECTNO        ;STORE UPDATED BACK
  1649.     MOV    A,L        ;COPY LOW TO ACC FOR CALLERS
  1650.     POP    H
  1651.     RET
  1652. ;
  1653. ;---->    ERASFIL: ERASE THE INCOMING FILE.
  1654. ;
  1655. ; IF IT EXISTS, ASK IF IT MAY BE ERASED.
  1656. ;
  1657. ERASFIL LXI    D,FCB        ;POINT TO CTL BLOCK
  1658.     MVI    C,SRCHF     ;SEE IF IT..
  1659.     CALL    BDOS        ;..EXISTS
  1660.     INR    A        ;FOUND?
  1661.     RZ            ;..NO, RETURN
  1662.     CALL    ILPRT        ;PRINT:
  1663.     DB    '++File exists, type ''Y'' to erase: ',BELL,0
  1664.     CALL    KEYIN        ;GET CHAR
  1665.     PUSH    PSW
  1666.     CALL    TYPE        ;ECHO
  1667.     CALL    CRLF        ;BACK TO START OF LINE
  1668.     POP    PSW
  1669.     ANI    5FH        ;MAKE UPPER CASE
  1670.     CPI    'Y'        ;WANT ERASED?
  1671.     JNZ    CKDIS        ;QUIT IF NOT ERASE
  1672. ;
  1673. ;ERASE OLD FILE
  1674. ;
  1675.     LXI    D,FCB        ;POINT TO FCB
  1676.     MVI    C,ERASE     ;GET BDOS FNC
  1677.     CALL    BDOS        ;DO THE ERASE
  1678.     RET            ;FROM "ERASFIL"
  1679. ;
  1680. ;---->    MAKEFIL: MAKES THE FILE TO BE RECEIVED
  1681. ;
  1682. MAKEFIL LXI    D,FCB        ;POINT TO FCB
  1683.     MVI    C,MAKE        ;GET BDOS FNC
  1684.     CALL    BDOS        ;TO THE MAKE
  1685.     INR    A        ;FF=BAD?
  1686.     RNZ            ;OPEN OK
  1687. ;
  1688. ; DIRECTORY FULL - CAN'T MAKE FILE
  1689. ;
  1690.     CALL    ERXIT
  1691.     DB    '++ERROR -- Can''t make file',CR,LF
  1692.     DB    '++Directory must be full',CR,LF,'$'
  1693. ;
  1694. ;---->    OPENFIL: OPENS THE FILE TO BE SENT
  1695. ;
  1696. OPENFIL XRA    A        ;SET EXT & REC # TO 0 FOR PROPER OPEN
  1697.     STA    FCBEXT
  1698.     STA    FCBSNO
  1699.     LXI    D,FCB        ;POINT TO FILE
  1700.     MVI    C,OPEN        ;GET FUNCTION
  1701.     CALL    BDOS        ;OPEN IT
  1702.     INR    A        ;OPEN OK?
  1703.     JNZ    OPENOK        ;..YES
  1704.     CALL    ERXIT        ;..NO, ABORT
  1705.     DB    '++Can''t open file',CR,LF,'$'
  1706. ;
  1707. OPENOK    CALL    ILPRT        ;PRINT:
  1708.     DB    'File open - Size: ',0
  1709.     LHLD    RCNT        ; Get record count.
  1710.     CALL    DECOUT        ;PRINT DECIMAL NUMBER OF SECTORS
  1711.     CALL    ILPRT        ;Print:
  1712.     DB    ' (',0
  1713.     CALL    DHXOUT        ;Now print size in hex.
  1714.     CALL    ILPRT        ;PRINT:
  1715.     DB    'H) sectors',CR,LF,0
  1716.     RET
  1717. ;
  1718. ;----> DECOUT: Decimal output routine
  1719. ;
  1720. DECOUT: PUSH    B
  1721.     PUSH    D
  1722.     PUSH    H
  1723.     LXI    B,-10
  1724.     LXI    D,-1
  1725. ;
  1726. DECOU2: DAD    B
  1727.     INX    D
  1728.     JC    DECOU2
  1729.     LXI    B,10
  1730.     DAD    B
  1731.     XCHG
  1732.     MOV    A,H
  1733.     ORA    L
  1734.     CNZ    DECOUT
  1735.     MOV    A,E
  1736.     ADI    '0'
  1737.     CALL    CTYPE
  1738.     POP    H
  1739.     POP    D
  1740.     POP    B
  1741.     RET
  1742. ;
  1743. ;---->    DHXOUT: - double precision hex output routine.
  1744. ;    Call with hex value in HL.
  1745. ;
  1746. DHXOUT    PUSH    H        ;Save H,L
  1747.     PUSH    PSW        ;Save A
  1748.     MOV    A,H        ;Get MS byte.
  1749.     CALL    HEXO        ;Output hi order byte.
  1750.     MOV    A,L        ;Get LS byte.
  1751.     CALL    HEXO        ;Output lo order byte.
  1752.     POP    PSW        ;Restore A
  1753.     POP    H        ;Restore H,L
  1754.     RET            ;Return to caller.
  1755. ;
  1756. ;
  1757. ;
  1758. ;---->    CLOSFIL: CLOSES THE RECEIVED FILE
  1759. ;
  1760. CLOSFIL LXI    D,FCB        ;POINT TO FILE
  1761.     MVI    C,CLOSE     ;GET FUNCTION
  1762.     CALL    BDOS        ;CLOSE IT
  1763.     INR    A        ;CLOSE OK?
  1764.     RNZ            ;..YES, RETURN
  1765.     CALL    ERXIT        ;..NO, ABORT
  1766.     DB    BELL,'++Can''t close file',CR,LF,'$'
  1767. ;
  1768. ;--->    ASCPTR - CHECK TO SEE IF ASCII CAPTURE IS ENABLED-IF
  1769. ;         IT IS, SAVE THE INCOMING CHARACTER IN THE
  1770. ;         MEMORY BUFFER, WRITING IT WHEN FULL
  1771. ;
  1772. ASCPTR:    PUSH    PSW        ;SAVE CHARACTER
  1773.     LDA    CPTRFLG     ;LOOK AT CAPTURE FLAG
  1774.     ORA    A        ;CAPTURE ENABLED?
  1775.     JZ    ASCQEND     ;  NO, TAKE QUICK EXIT
  1776.     POP    PSW        ;GET THE CHARACTER
  1777.     PUSH    PSW        ;  AND SAVE ALL THE REGISTERS
  1778.     PUSH    B
  1779.     PUSH    D
  1780.     PUSH    H
  1781.     LHLD    CAPPTR        ;GET THE BUFFER POINTER
  1782.     MOV    M,A        ;  PUT CHARACTER IN BUFFER
  1783.     INX    H        ;  INCREMENT POINTER
  1784.     SHLD    CAPPTR        ;  AND SAVE IT
  1785.     LDA    MEMEND        ;GET LAST PAGE ADDRESS
  1786.     CMP    H        ;ARE WE THERE YET?
  1787.     JZ    ASCPTR1     ;  YES, TIME TO WRITE THE BUFFER
  1788.     DCR    A        ;NEXT TO LAST PAGE ADDRESS
  1789.     CMP    H        ;NEARING THE END?
  1790.     JNZ    ASCEND        ;  NO, EXIT ROUTINE
  1791.     MOV    A,L        ;CHECK LOWER BYTE OF ADDRESS
  1792.     CPI    -STPTIME AND 0FFH
  1793.     JNZ    ASCEND        ;NOT TIME FOR STOP CHAR, SO EXIT
  1794.     MVI    A,STOPCHR    ;TELL OTHER END TO STOP
  1795.     CALL    OUTDATA     ;  IN ADVANCE
  1796.     JMP    ASCEND
  1797. ASCPTR1 LXI    D,ASCBUF
  1798.     LDA    MEMEND
  1799.     SUB    D
  1800.     MOV    B,A        ;NUMBER OF PAGES TO SAVE
  1801. ASCPTR2 MOV    C,2        ;NUMBER OF SECTORS/PAGE
  1802. ASCPTR3 CALL    AWRITE
  1803.     LXI    H,128
  1804.     DAD    D
  1805.     XCHG            ;MOVE TO NEXT SECTOR TO WRITE
  1806.     DCR    C
  1807.     JNZ    ASCPTR3     ;UNTIL PAGE IS WRITTEN
  1808.     DCR    B
  1809.     JNZ    ASCPTR2     ;UNTIL ALL PAGES ARE WRITTEN
  1810.     LXI    H,ASCBUF    ;RESET BUFFER POINTER
  1811.     SHLD    CAPPTR
  1812.     MVI    A,STRTCHR    ;TELL OTHER END TO START
  1813.     CALL    OUTDATA
  1814. ASCEND    POP    H
  1815.     POP    D
  1816.     POP    B
  1817. ASCQEND POP    PSW
  1818.     RET
  1819. AWRITE    PUSH    D
  1820.     MVI    C,STDMA     ;SET BUFFER ADDRESS
  1821.     CALL    BDOS
  1822.     LXI    D,ASCFCB
  1823.     MVI    C,21        ;WRITE SEQUENTIAL
  1824.     CALL    BDOS
  1825.     INR    A
  1826.     JNZ    AWRITE1
  1827.     CALL    ILPRT
  1828.     DB    BELL,'++Out of disk space',CR,LF,0
  1829. AWRITE1 POP    D
  1830.     RET
  1831. ;
  1832. ;---->    RDSECT: READS A SECTOR
  1833. ;
  1834. ;    FOR SPEED, THIS ROUTINE BUFFERS UP DBUFSIZ*8
  1835. ;    SECTORS AT A TIME.
  1836. ;
  1837. RDSECT    LDA    SECINBF     ;GET # SECT IN BUFF.
  1838.     DCR    A        ;DECREMENT..
  1839.     STA    SECINBF     ;..IT
  1840.     JM    RDBLOCK     ;EXHAUSTED?  NEED MORE.
  1841.     LHLD    SECPTR        ;GET POINTER
  1842.     LXI    D,BASE+80H    ;TO DATA
  1843.     CALL    MOVE128     ;MOVE TO BUFFER
  1844.     SHLD    SECPTR        ;SAVE BUFFER POINTER
  1845.     RET            ;FROM "READSEC"
  1846. ;
  1847. ; BUFFER IS EMPTY - READ IN ANOTHER BLOCK OF DBUFSIZ*8
  1848. ;
  1849. RDBLOCK LDA    EOFLG        ;GET EOF FLAG
  1850.     CPI    1        ;IS IT SET/
  1851.     STC            ;TO SHOW EOF
  1852.     RZ            ;GOT EOF
  1853.     MVI    C,0        ;SECTORS IN BLOCK
  1854.     LXI    D,DBUF        ;TO DISK BUFFER
  1855. ;
  1856. RDSECLP PUSH    B
  1857.     PUSH    D
  1858.     MVI    C,STDMA     ;SET DMA..
  1859.     CALL    BDOS        ;..ADDR
  1860.     LXI    D,FCB
  1861.     MVI    C,READ
  1862.     CALL    BDOS
  1863.     POP    D
  1864.     POP    B
  1865.     ORA    A        ;READ OK?
  1866.     JZ    RDSECOK     ;YES
  1867.     DCR    A        ;EOF?
  1868.     JZ    REOF        ;GOT EOF
  1869. ;
  1870. ; READ ERROR
  1871. ;
  1872.     CALL    ERXIT
  1873.     DB    BELL,'++File read error',CR,LF,'$'
  1874. ;
  1875. RDSECOK LXI    H,80H        ;ADD LENGTH OF ONE SECTOR...
  1876.     DAD    D        ;...TO NEXT BUFF
  1877.     XCHG            ;BUFF TO DE
  1878.     INR    C        ;MORE SECTORS?
  1879.     MOV    A,C        ;GET COUNT
  1880.     CPI    DBUFSIZ*8    ;DONE?
  1881.     JZ    RDBFULL     ;..YES, BUFF IS FULL
  1882.     JMP    RDSECLP     ;READ MORE
  1883. ;
  1884. REOF    MVI    A,1
  1885.     STA    EOFLG        ;SET EOF FLAG
  1886.     MOV    A,C
  1887. ;
  1888. ; BUFFER IS FULL, OR GOT EOF
  1889. ;
  1890. RDBFULL STA    SECINBF     ;STORE SECTOR COUNT
  1891.     LXI    H,DBUF        ;INIT BUFFER..
  1892.     SHLD    SECPTR        ;..POINTER
  1893.     LXI    D,BASE+80H    ;RESET..
  1894.     MVI    C,STDMA     ;..DMA..
  1895.     CALL    BDOS        ;..ADDR
  1896.     JMP    RDSECT        ;PASS SECT TO CALLER
  1897. ;
  1898. ;---->    WRSECT: WRITE A SECTOR
  1899. ;
  1900. ;    WRITES THE SECTOR INTO A BUFFER.  WHEN DBUFSIZ*8
  1901. ;    HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK.
  1902. ;
  1903. ;    ENTRY POINT "WRBLOCK" FLUSHES THE BUFFER AT EOF.
  1904. ;
  1905. WRSECT    LHLD    SECPTR        ;GET BUFF ADDR
  1906.     XCHG            ;TO DE FOR MOVE
  1907.     LXI    H,BASE+80H    ;FROM HERE
  1908.     CALL    MOVE128     ;MOVE TO BUFFER
  1909.     XCHG            ;SAVE NEXT..
  1910.     SHLD    SECPTR        ;..BLOCK POINTER
  1911.     LDA    SECINBF     ;BUMP THE..
  1912.     INR    A        ;..SECTOR #..
  1913.     STA    SECINBF     ;..IN THE BUFF
  1914.     CPI    DBUFSIZ*8    ;HAVE WE DBUFSIZ*8?
  1915.     RNZ            ;NO, RETURN
  1916. ;
  1917. ;---->    WRBLOCK: WRITES A BLOCK TO DISK
  1918. ;
  1919. WRBLOCK LDA    SECINBF     ;# SECT IN BUFFER
  1920.     ORA    A        ;0 MEANS END OF FILE
  1921.     RZ            ;NONE TO WRITE
  1922.     MOV    C,A        ;SAVE COUNT
  1923.     LXI    D,DBUF        ;POINT TO DISK BUFF
  1924. ;
  1925. DKWRLP    PUSH    H
  1926.     PUSH    D
  1927.     PUSH    B
  1928.     MVI    C,STDMA     ;SET DMA
  1929.     CALL    BDOS        ;TO BUFFER
  1930.     LXI    D,FCB        ;THEN WRITE
  1931.     MVI    C,WRITE     ;..THE..
  1932.     CALL    BDOS        ;..BLOCK
  1933.     POP    B
  1934.     POP    D
  1935.     POP    H
  1936.     ORA    A
  1937.     JNZ    WRERR        ;OOPS, ERROR
  1938.     LXI    H,80H        ;LENGTH OF 1 SECT
  1939.     DAD    D        ;HL= NEXT BUFF
  1940.     XCHG            ;TO DE FOR SETDMA
  1941.     DCR    C        ;MORE SECTORS?
  1942.     JNZ    DKWRLP        ;..YES, LOOP
  1943.     XRA    A        ;GET A ZERO
  1944.     STA    SECINBF     ;RESET # OF SECTORS
  1945.     LXI    H,DBUF        ;RESET BUFFER..
  1946.     SHLD    SECPTR        ;..POINTER
  1947. ;
  1948. RSDMA    LXI    D,BASE+80H    ;RESET..
  1949.     MVI    C,STDMA     ;..DMA..
  1950.     CALL    BDOS        ;..ADDR
  1951.     RET
  1952. ;
  1953. WRERR    CALL    RSDMA        ;RESET DMA TO NORM.
  1954.     CALL    ILPRT        ;PRINT:
  1955.     DB    BELL,'++Error writing file',CR,LF,0
  1956.     JMP    ABORT        ;EXIT
  1957. ;
  1958. ;---->    RECV: RECEIVE A CHARACTER
  1959. ;
  1960. ;    TIMEOUT TIME IS IN B, IN SECONDS.  ENTRY VIA
  1961. ;    "RECVDG" DELETES GARBAGE CHARACTERS ON THE
  1962. ;    LINE.  FOR EXAMPLE, HAVING JUST SENT A SECTOR,
  1963. ;    CALLING RECVDG WILL DELETE ANY LINE-NOISE-INDUCED
  1964. ;    CHARACTERS "LONG" BEFORE THE ACK/NAK WOULD
  1965. ;    BE RECEIVED.
  1966. ;
  1967. RECVDG    EQU    $        ;RECEIVE W/GARBAGE DELETE
  1968.     CALL    INDATA        ;GET A CHAR
  1969.     CALL    INDATA        ;..TOTALLY PURGE UART
  1970. ;
  1971. RECV    PUSH    D        ;SAVE
  1972. ;
  1973.     IF    FASTCLK     ;4MHZ?
  1974.     MOV    A,B        ;GET TIME REQUEST
  1975.     ADD    A        ;DOUBLE IT
  1976.     MOV    B,A        ;NEW TIME IN B
  1977.     ENDIF
  1978. ;
  1979. MSEC    LXI    D,50000     ;1 SEC DCR COUNT
  1980. ;
  1981.     IF    (NOT DCH) AND (NOT X8250)
  1982. MWTI    CALL    INCTL        ;CHECK STATUS
  1983.     ENDIF
  1984. ;
  1985.     IF    X8250
  1986. MWTI    CALL    INCTL5        ;CHECK STATUS
  1987.     ENDIF
  1988. ;
  1989.     IF    DCH
  1990. MWTI    CALL    INCT2        ;CHECK STATUS
  1991.     ENDIF
  1992. ;
  1993.     IF    FRNTPNL AND PMMI
  1994.     CALL    OUTPAN        ;DISPLAY STATUS
  1995.     ENDIF
  1996. ;
  1997.     ANI    MDRCVB        ;ISOLATE BIT
  1998.     CPI    MDRCVR        ;READY?
  1999.     JZ    MCHAR        ;GOT CHAR
  2000.     DCR    E        ;COUNT..
  2001.     JNZ    MWTI        ;..DOWN..
  2002.     DCR    D        ;..FOR..
  2003.     JNZ    MWTI        ;..TIMEOUT
  2004.     DCR    B        ;MORE SECONDS?
  2005.     JNZ    MSEC        ;YES, WAIT
  2006. ;
  2007. ; MODEM TIMED OUT RECEIVING
  2008. ;
  2009.     POP    D        ;RESTORE D,E
  2010.     STC            ;CARRY SHOWS TIMEOUT
  2011.     RET
  2012. ;
  2013. ; GOT CHAR FROM MODEM
  2014. ;
  2015. ; CHECK TO SEE IF THERE WAS A FRAMING, OVERRUN,
  2016. ; AND/OR PARITY ERROR.
  2017. ;
  2018. MCHAR:    IF    (NOT DCH) AND (NOT X8250)
  2019.     CALL    INCTL        ;GET STATUS
  2020.     ENDIF
  2021. ;
  2022.     IF    X8250
  2023.     CALL    INCTL5        ;GET STATUS
  2024.     ENDIF
  2025. ;
  2026.     IF    DCH
  2027.     CALL    INCT2        ;GET STATUS
  2028.     ENDIF
  2029. ;
  2030.     MOV    D,A        ;SAVE STATUS
  2031.     ANI    FRMER        ;FRAMING ERR?
  2032.     JZ    MCHAR2        ;NO, CHECK FOR OVERRUN
  2033.     LDA    ERRCDE        ;GET RECV ERR CODE
  2034.     ORI    FRMER        ;TURN ON RECV ERR CODE
  2035.     STA    ERRCDE
  2036. ;
  2037. MCHAR2: MOV    A,D        ;RESTORE STATUS
  2038.     ANI    ORUNER        ;OVERRUN ERR?
  2039.     JZ    MCHAR3        ;NO, CHECK FOR PARITY
  2040.     LDA    ERRCDE        ;GET RECV ERR CODE
  2041.     ORI    ORUNER        ;TURN ON RECV ERR CODE
  2042.     STA    ERRCDE
  2043. ;
  2044. MCHAR3: MOV    A,D        ;RESTORE STATUS
  2045.     ANI    PARER        ;PARITY ERR?
  2046.     JZ    MCHAR4        ;NO, GET DATA CHAR
  2047.     LDA    ERRCDE        ;GET RECV ERR CODE
  2048.     ORI    PARER        ;TURN ON RECV ERR CODE
  2049.     STA    ERRCDE
  2050. ;
  2051. ; Check for error and call reset code if yes
  2052. ;
  2053. MCHAR4:
  2054.     LDA    ERRCDE        ; Retrieve error code
  2055.     ORA    A        ; Set flags
  2056.     CNZ    RESRCVR        ; Reset if necessary
  2057. ;
  2058. ; GET THE DATA CHAR
  2059. ;
  2060.     CALL    INDATA        ;GET MODEM DATA CHAR
  2061.     POP    D        ;RESTORE DE
  2062. ;
  2063. ; CALC CHECKSUM AND CYCLIC REDUNDANCY CHECK
  2064. ;
  2065.     PUSH    PSW        ;SAVE THE CHAR
  2066.     CALL    UPDCRC        ;CALC CYCLIC REDUNDANCY CHECK
  2067.     ADD    C        ;ADD TO CHECKSUM
  2068.     MOV    C,A        ;SAVE CHECKSUM
  2069. ;
  2070. ; CHECK IF MONITORING REC'D DATA
  2071. ;
  2072.     LDA    RSEEFLG     ;SEE RECEIVED..
  2073.     ORA    A        ;..DATA?
  2074.     JZ    MONIN        ;..YES
  2075. ;
  2076. ; CHECK IF "VIEWING" AND THIS IS A DATA CHAR
  2077. ;
  2078.     LDA    VSEEFLG     ;VIEWING..
  2079.     ORA    A        ;..DATA?
  2080.     JNZ    NOMONIN     ;..NO
  2081. ;
  2082. ; "VIEW" REQUESTED.  SHOW THE CHAR IF IT IS DATA
  2083. ;
  2084.     LDA    DATAFLG     ;GET DATA FLAG
  2085.     ORA    A        ;TEST IT
  2086.     JZ    NOMONIN     ;..OFF, NOT DATA
  2087. ;
  2088. MONIN    POP    PSW        ;..IS DATA,
  2089.     PUSH    PSW        ;GET IT,
  2090.     CALL    SHOW        ;..AND SHOW IT
  2091. ;
  2092. NOMONIN POP    PSW        ;RESTORE CHAR
  2093.     ORA    A        ;CARRY OFF: NO ERROR
  2094.     RET            ;FROM "RECV"
  2095. ;
  2096. ; This is the section of code that resets the error
  2097. ; bit in the receiving device. (from parity, framing,
  2098. ; and overrun)
  2099. ; NOTE: I have implemented the code for an Intel 8251
  2100. ;    usart, but since I know nothing about other
  2101. ;    commonly used devices, you must add your own
  2102. ;    reset code here in a conditional.
  2103. ;
  2104. RESRCVR:
  2105.     IF    X8251
  2106.     MVI    A,RSTCODE    ; Load reset code
  2107.     CALL    OUTCTL        ; Send to control port
  2108.     ENDIF            ; X8251
  2109.  
  2110. ;  Add code here for other than 8251 !!!!
  2111.  
  2112.     RET        ; <=== This "RET" must be here
  2113.             ;  outside the conditional !
  2114.  
  2115. ;
  2116. ;---->    SEND: SEND A CHARACTER TO THE MODEM
  2117. ;
  2118. ;    THE CHARACTER TO BE SENT IS SAVED
  2119. ;    IN REG D.  IF VIEWING IS IN EFFECT,
  2120. ;    THE CHARACTER IS DISPLAYED.  THEN
  2121. ;    BOTH THE CHECKSUM AND CRC ARE CALCU-
  2122. ;    LATED.
  2123. ;
  2124. SEND    PUSH    D        ;SAVE D,E REGS
  2125.     MOV    D,A        ;SAVE THE CHAR
  2126. ;
  2127. ; CHECK IF MONITORING SENT DATA
  2128. ;
  2129.     LDA    SSEEFLG     ;CHECK IF MONITORING..
  2130.     ORA    A        ;..SENT DATA
  2131.     JZ    MONOUT        ;..YES
  2132. ;
  2133. ; CHECK IF "VIEWING" THE FILE
  2134. ;
  2135.     LDA    VSEEFLG     ;GET VIEW FLAG
  2136.     ORA    A        ;TEST IT
  2137.     JNZ    NOMONOT     ;NO
  2138.     LDA    DATAFLG     ;IS THIS
  2139.     ORA    A        ;..DATA?
  2140.     JZ    NOMONOT     ;..NO.
  2141. ;
  2142. MONOUT    MOV    A,D        ;GET THE CHAR
  2143.     CALL    SHOW        ;SHOW IT
  2144. ;
  2145. NOMONOT MOV    A,D        ;RESTORE THE CHAR
  2146.     CALL    UPDCRC        ;CALC CRC
  2147.     ADD    C        ;CALC CKSUM
  2148.     MOV    C,A        ;SAVE CKSUM
  2149. ;
  2150.     IF    (NOT DCH) AND (NOT X8250)
  2151. SENDW    CALL    INCTL        ;GET STATUS
  2152.     ENDIF
  2153. ;
  2154.     IF    X8250
  2155. SENDW    CALL    INCTL5        ;GET STATUS
  2156.     ENDIF
  2157. ;
  2158.     IF    DCH
  2159. SENDW    CALL    INCT2        ;GET STATUS
  2160.     ENDIF
  2161. ;
  2162.     IF    FRNTPNL
  2163.     CALL    OUTPAN        ;DISPLAY STATUS
  2164.     ENDIF
  2165. ;
  2166.     ANI    MDSNDB        ;ISOLATE READY BIT
  2167.     CPI    MDSNDR        ;READY?
  2168.     JNZ    SENDW        ;..NO, WAIT
  2169.     MOV    A,D        ;GET CHAR
  2170.     POP    D        ;RESTORE D,E
  2171.     CALL    OUTDATA     ;OUTPUT IT
  2172.     RET            ;FROM "SEND"
  2173. ;
  2174. ;---->    WAITNAK: WAITS FOR INITIAL NAK
  2175. ;
  2176. ;    TO ENSURE NO DATA IS SENT UNTIL THE RECEIVING
  2177. ;    PROGRAM IS READY, THIS ROUTINE WAITS FOR
  2178. ;    THE FIRST TIMEOUT-NAK FROM THE RECEIVER/
  2179. ;    (E) CONTAINS THE # OF SECONDS TO WAIT.
  2180. ;
  2181. WAITNAK LDA    VSEEFLG     ;VIEWING?
  2182.     ORA    A
  2183.     JZ    WAITNPR     ;PRINT MSG
  2184.     LDA    QFLG        ;QUIET..
  2185.     ORA    A        ;..MODE?
  2186.     JZ    WAITNLP     ;YES, SKIP MSG
  2187. ;
  2188. WAITNPR CALL    ILPRT        ;PRINT:
  2189.     DB    'Awaiting initial NAK or CRC request',CR,LF,0
  2190. ;
  2191. WAITNLP MVI    B,1        ;TIMEOUT DELAY
  2192.     CALL    RECV        ;DID WE GET..
  2193.     CPI    NAK        ;..A NAK?
  2194.     RZ            ;YES, SEND BLOCK
  2195.     CPI    CRC        ;CRC REQUEST?
  2196.     JZ    WAITCRC     ;YES, GO SET CRC FLAG
  2197.     DCR    E        ;80 TRIES?
  2198.     JZ    ABORT        ;YES, ABORT
  2199.     JMP    WAITNLP     ;NO, LOOP
  2200. ;
  2201. WAITCRC CALL    ILPRT
  2202.     DB    'CRC request received',CR,LF,0
  2203.     XRA    A        ;ZERO ACCUM
  2204.     STA    CRCFLG        ;INDICATE CRC IN EFFECT
  2205.     RET
  2206. ;
  2207. ;---->    INITADR: INIT'S CP/M BIOS ADDRESSES
  2208. ;
  2209. ;    THIS ROUTINE FILLS IN THE ADDRESSES OF VARIOUS
  2210. ;    JMP AND CALL INSTRUCTIONS, SO THAT CP/M BDOS
  2211. ;    IS BYPASSED WHILE ACCESSING THE CONSOLE.  THIS
  2212. ;    IS DONE TO ALLOW CHARACTERS SUCH AS CONTROL-C
  2213. ;    AND CONTROL-S TO BE KEYED WHILE IN TERMINAL
  2214. ;    MODE, WITHOUT CP/M INTERPRETING THEM.
  2215. ;
  2216. INITADR LHLD    BASE+1        ;GET WARM BOOT ADDR
  2217.     LXI    D,3        ;LENGTH OF A 'JMP'
  2218.     DAD    D        ;TO CONSOLE STAT
  2219.     SHLD    VSTAT+1     ;MODIFY CALL
  2220.     DAD    D        ;TO CONSOLE IN
  2221.     SHLD    VKEYIN+1    ;MODIFY CALL
  2222.     DAD    D        ;TO CONSOLE OUT
  2223.     SHLD    VTYPE+1     ;MODIFY CALL
  2224.     RET
  2225. ;
  2226. ;---->    CPTRTOG - toggles ASCII capture mode on and off
  2227. ;
  2228. CPTRTOG PUSH    H        ;SAVE ALL REGISTERS
  2229.     PUSH    D
  2230.     PUSH    B
  2231.     PUSH    PSW
  2232.     MVI    A,STOPCHR
  2233.     CALL    OUTDATA
  2234.     LDA    CPTRFLG     ;GET CAPTURE FLAG
  2235.     CMA            ;  INVERT IT
  2236.     STA    CPTRFLG     ;  AND SAVE IT
  2237.     ORA    A        ;DO WE OPEN OR CLOSE A FILE?
  2238.     JZ    CPTRCLS     ;  CAPTURE DISABLED, SO CLOSE
  2239.     LXI    H,ASCBUF    ;INITIALIZE BUFFER STARTING ADDRESS
  2240.     SHLD    CAPPTR
  2241. GETNAM    CALL    ILPRT
  2242.     DB    CR,LF,'Enter ASCII capture file name --> ',BELL,0
  2243.     LXI    H,ASCFCB
  2244.     MVI    M,0        ;DEFAULT DRIVE IF NOT SPECIFIED
  2245. ;
  2246.     INX    H        ;POINT TO FILE NAME
  2247.     MVI    B,11        ;FILL NAME AND TYPE WITH BLANKS
  2248.     MVI    A,' '
  2249. CPTRT01 MOV    M,A
  2250.     INX    H
  2251.     DCR    B
  2252.     JNZ    CPTRT01
  2253. ;
  2254.     LXI    H,ASCBUF    ;GET FILE NAME FROM USER
  2255.     MVI    M,15        ;MAX NUMBER OF CHARACTERS TO ACCEPT
  2256.     XCHG
  2257.     MVI    C,10        ;USE READ CONSOLE BUFFER FUNCTION
  2258.     CALL    BDOS        ;TO GET INPUT
  2259. ;
  2260.     MVI    E,LF        ;PUT USER BACK ON CLEAN LINE
  2261.     MVI    C,2
  2262.     CALL    BDOS
  2263. ;
  2264.     LXI    H,ASCBUF
  2265.     INX    H
  2266.     MOV    B,M        ;NUMBER OF CHARACTERS INPUT
  2267.     MOV    A,B        ;MAKE SURE SOMETHING WAS INPUT
  2268.     CPI    0        ;IF NOTHING INPUT, THEN
  2269.     JZ    NULNAM        ;  ASK FOR FILENAME AGAIN...
  2270.     MVI    C,0        ;NUMBER OF FCB CHARS FILLED
  2271.     INX    H
  2272.     INX    H        ;LOOK AT 2ND CHARACTER INPUT
  2273.     MOV    A,M
  2274.     CPI    ':'        ;DRIVE CODE SPECIFIED?
  2275.     DCX    H        ;POINT BACK TO 1ST CHAR INPUT
  2276.     JNZ    CPTRSET     ;SKIP IF NO DRIVE SPECIFIED
  2277.     MOV    A,M        ;GET DRIVE CODE
  2278.     CALL    VFYCHR        ;LEGAL CHARACTER ????
  2279.     CPI    'A'
  2280.     JM    BADDRV        ;JUMP IF < A:
  2281.     CPI    MAXDRV+1
  2282.     JP    BADDRV        ;JUMP IF > MAXDRV
  2283.     ANI    0FH        ;CONVERT FROM ASCII
  2284.     STA    ASCFCB        ;PUT IT IN THE FCB
  2285.     INX    H
  2286.     INX    H        ;POINT TO FIRST CHAR OF FILE NAME
  2287.     DCR    B
  2288.     DCR    B        ;ADJUST CHAR COUNT
  2289.     JZ    NONAME
  2290. CPTRSET LXI    D,ASCFCB+1    ;START OF FILE NAME IN FCB
  2291. CPTRSE1 MOV    A,M        ;GET CHAR
  2292.     CPI    '.'        ;END OF FILE NAME?
  2293.     JZ    CPTRTYP
  2294.     CALL    VFYCHR        ;LEGAL CHARACTER ????
  2295.     STAX    D        ;NO, STORE IT
  2296.     INX    H
  2297.     INX    D
  2298.     INR    C
  2299.     DCR    B
  2300.     JNZ    CPTRSE1     ;LOOP IF MORE CHARS WERE INPUT
  2301.     JMP    CPTROPN     ;NO FILE TYPE GIVEN, SO USE BLANK DEFAULT
  2302. ;
  2303. CPTRTYP    INX    H        ;MOVE PAST PERIOD IN SPECIFIED NAME
  2304.     LXI    D,ASCFCB+9    ;POINT TO FILE TYPE IN FCB
  2305.     DCR    B        ;ACCOUNT FOR THE SKIPPED PERIOD
  2306.     JZ    CPTROPN     ;IF NO MORE, SKIP IT
  2307.     MOV    A,M        ;GET THE CHAR
  2308.     CALL    VFYCHR        ;LEGAL CHARACTER ????
  2309.     STAX    D        ;  AND SAVE IT
  2310.     INX    H
  2311.     INX    D
  2312.     DCR    B
  2313.     JZ    CPTROPN     ;SKIP IF NO MORE
  2314.     MOV    A,M        ;GET NEXT CHAR
  2315.     CALL    VFYCHR        ;LEGAL CHARACTER ????
  2316.     STAX    D        ;  AND SAVE IT
  2317.     INX    H
  2318.     INX    D
  2319.     DCR    B
  2320.     JZ    CPTROPN     ;SKIP IF NO MORE
  2321.     MOV    A,M        ;GET LAST CHAR
  2322.     CALL    VFYCHR        ;LEGAL CHARACTER ????
  2323.     STAX    D        ;  AND SAVE IT
  2324. CPTROPN    PUSH    H
  2325.     LXI    H,ASCFCB+1    ;POINT TO 1ST CHAR. IN NAME
  2326.     MOV    A,M
  2327.     POP    H
  2328.     CPI    ' '
  2329.     JZ    NONAME        ;IF = ' ' THEN NO NAME GIVEN
  2330.     MVI    A,0
  2331.     STA    ASCFCB+12    ;CLEAR EXTENT
  2332.     STA    ASCFCB+32    ;  AND CURRENT RECORD
  2333.     LXI    D,ASCFCB    ;SEE IF THERE ALREADY
  2334.     MVI    C,SRCHF
  2335.     CALL    BDOS
  2336.     INR    A
  2337.     JZ    CPTRNF        ;PASS IF NOT
  2338.     CALL    ILPRT
  2339.     DB    '++File exists, type ''Y'' to erase: ',BELL,0
  2340.     CALL    KEYIN        ;GET RESPONSE
  2341.     PUSH    PSW        ;SAVE IT
  2342.     CALL    TYPE        ;ECHO IT
  2343.     CALL    CRLF        ; THEN EJECT LINE
  2344.     POP    PSW
  2345.     ANI    5FH        ;FOLD TO UPPER CASE
  2346.     CPI    'Y'        ;GOT A YES?
  2347.     JNZ    GETNAM        ;ASK AGAIN IF NOT
  2348.     LXI    D,ASCFCB    ;PRE-DELETE FILE
  2349.     MVI    C,ERASE
  2350.     CALL    BDOS
  2351. ;
  2352. CPTRNF:    LXI    D,ASCFCB
  2353.     MVI    C,22        ; MAKE FILE
  2354.     CALL    BDOS
  2355.     INR    A        ;0FFH ERROR CODE BECOMES 00H
  2356.     JNZ    CPTROP2     ;SKIP IF NO ERROR
  2357.     CALL    ILPRT
  2358.     DB    CR,LF,'++Directory full',CR,LF,0
  2359.     XRA    A
  2360.     STA    CPTRFLG
  2361.     JMP    CPTRRET
  2362. CPTROP2    CALL    ILPRT
  2363.     DB    CR,LF,'ASCII capture now activated',CR,LF,0
  2364.     JMP    CPTRRET
  2365. CPTRCLS LHLD    CAPPTR        ;GET CURRENT BUFFER POINTER
  2366. CPTRCL1 MVI    M,1AH        ;FILL OUT THE RECORD WITH CTL-Z
  2367.     MOV    A,L
  2368.     ANI    7FH        ;ARE WE ON A MULTIPLE OF 128?
  2369.     JZ    CPTRCL2     ;  YES, EXIT LOOP
  2370.     INX    H        ;ELSE INCREMENT POINTER
  2371.     JMP    CPTRCL1     ;  AND CONTINUE
  2372. CPTRCL2 LXI    D,ASCBUF    ;START OF BUFFER
  2373.     MOV    A,D        ;IF THE BUFFER IS EMPTY
  2374.     CMP    H        ;  THEN DON'T WRITE ANYTHING
  2375.     JNZ    CPTRCL3     ;  AND CLOSE THE FILE
  2376.     MOV    A,E
  2377.     CMP    L
  2378.     JZ    CPTRCL4
  2379. CPTRCL3 CALL    AWRITE        ;WRITE A RECORD
  2380.     LXI    H,128        ;INCREMENT WRITE POINTER BY 1 SECTOR
  2381.     DAD    D
  2382.     XCHG
  2383.     LDAX    D        ;GET THE FIRST CHAR OF NEXT SECTOR
  2384.     CPI    1AH        ;END OF FILE?
  2385.     JNZ    CPTRCL3     ;  IF NOT, WRITE SOME MORE
  2386. CPTRCL4 LXI    D,ASCFCB
  2387.     MVI    C,16        ; CLOSE FILE
  2388.     CALL    BDOS
  2389.     INR    A        ;0FFH ERROR CODE BECOMES 00H
  2390.     JZ    CPTRCL5     ;SKIP IF ERROR
  2391.     CALL    ILPRT
  2392.     DB    CR,LF,'ASCII capture now off, '
  2393.     DB    'file closed',CR,LF,0
  2394.     JMP    CPTRRET
  2395. CPTRCL5    CALL    ILPRT
  2396.     DB    CR,LF,'++Error in closing file',CR,LF,0
  2397. CPTRRET MVI    A,STRTCHR
  2398.     CALL    OUTDATA
  2399.     POP    PSW
  2400.     POP    B
  2401.     POP    D
  2402.     POP    H
  2403.     RET
  2404. ;
  2405. ;---->  VFYCHR - CONVERT LOWER CASE TO UPPER, AND TRAP
  2406. ;---->         ALL ILLEGAL CHARACTERS IN FILE NAME
  2407. VFYCHR    ANI    7FH        ;FORCE PARITY OFF
  2408.     CPI    061H
  2409.     JM    VFYCH1        ;BEGIN LOWER->UPPER
  2410.     CPI    7BH
  2411.     JP    VFYCH1
  2412.     SUI    20H        ;WAS LOWER, FIX IT
  2413. VFYCH1    CPI    ' '
  2414.     JM    BADNAM        ;NO CTRL CHARS IN FILE NAME
  2415.     CPI    '9'+1
  2416.     JM    VFYCH2
  2417.     CPI    '@'
  2418.     JM    BADNAM
  2419. VFYCH2    CPI    5FH
  2420.     JP    BADNAM
  2421.     CPI    '.'
  2422.     JZ    BADNAM
  2423.     CPI    ','
  2424.     JZ    BADNAM
  2425.     CPI    '*'
  2426.     JZ    BADNAM
  2427.     CPI    '['
  2428.     JZ    BADNAM
  2429.     CPI    ']'
  2430.     JZ    BADNAM
  2431.     RET            ;GOOD CHARACTER !!!!
  2432.     ;
  2433. BADNAM    CALL    ILPRT
  2434.     DB    '++Invalid character in '
  2435.     DB    'file name++',BELL,CR,LF,LF,0
  2436.     POP    H        ;REMOVE LAST CALL
  2437.     JMP    GETNAM
  2438.     ;
  2439. NULNAM    CALL    ILPRT
  2440.     DB    '++Null file name specified,'
  2441.     DB    ' ASCII capture not activated'
  2442.     DB    '++',CR,LF,LF,0
  2443.     XRA    A
  2444.     STA    CPTRFLG        ;FORCE CPATURE OFF
  2445.     JMP    CPTRRET        ;EXIT
  2446.     ;
  2447. BADDRV    CALL    ILPRT
  2448.     DB    '++Invalid drive specified, '
  2449.     DB    'try again++',BELL,CR,LF,0
  2450.     JMP    GETNAM
  2451.     ;
  2452. NONAME    CALL    ILPRT
  2453.     DB    '++Can''t specify filetype '
  2454.     DB    'without a filename++',BELL,CR,LF,0
  2455.     JMP    GETNAM
  2456.     ;
  2457.     ;
  2458. ;---->    PRINTER - SEND A CHARACTER TO THE PRINTER
  2459. ;
  2460. PRINTER PUSH    H        ;SAVE REGISTERS
  2461.     PUSH    D
  2462.     PUSH    B
  2463.     PUSH    PSW
  2464.     LDA    PRTRFLG     ;GET PRINTER FLAG
  2465.     ORA    A        ;ENABLED?
  2466.     JZ    PRTREND     ;NO, SKIP IT
  2467.     POP    PSW        ;GET THE CHAR
  2468.     PUSH    PSW        ;  AND SAVE IT AGAIN
  2469.     MOV    E,A
  2470.     MVI    C,5
  2471.     CALL    BDOS        ;PRINT IT
  2472. PRTREND POP    PSW        ;RESTORE REGISTERS
  2473.     POP    B
  2474.     POP    D
  2475.     POP    H
  2476.     RET
  2477. ;
  2478. ;---->    PRTRTOG - ENABLE/DISABLE THE PRINTER
  2479. ;
  2480. PRTRTOG PUSH    PSW
  2481.     LDA    PRTRFLG
  2482.     CMA
  2483.     STA    PRTRFLG
  2484.     POP    PSW
  2485.     RET
  2486. ;
  2487. ;---->    PROCOPT: PROCESS COMMAND OPTIONS
  2488. ;
  2489. ;    1) SAVED THE PRIMARY OPTION IN 'OPTION';
  2490. ;    2) SCANS THE SUB-OPTION CHARACTERS, AND FOR
  2491. ;       EACH FOUND, ZEROS THE APPROPRIATE ENTRY IN
  2492. ;       THE OPTION TABLE.  FOR EXAMPLE, IF 'Q' IS
  2493. ;       CODED (QUIT/DISCONNECT) THEN THE 'D' STORED AT
  2494. ;       'DISCFLG' IS SET TO 0 SO IT CAN BE TESTED
  2495. ;       LATER.
  2496. ;
  2497. PROCOPT LXI    D,FCB+1     ;TO PRIMARY OPT.
  2498.     LDAX    D        ;GET PRIMARY
  2499.     STA    OPTION        ;SAVE IT
  2500. ;
  2501. OPTLP    INX    D        ;TO SECONDARY OPTION
  2502.     LDAX    D        ;GET CHAR
  2503. ;
  2504. ; IF YOU MOD THIS PROGRAM FOR >7 OPTIONS,
  2505. ; YOU MUST CHANGE THE FOLLOWING, SINCE
  2506. ; THERE WON'T BE A ' ' AFTER THE OPTION
  2507. ; IF A BAUD RATE WAS SPECIFIED.
  2508. ;
  2509.     CPI    ' '        ;NO MORE OPT'NS?
  2510.     JZ    ENDOPT        ;..YES
  2511. ;
  2512. ; SET THE APPROP. OPTION: STORE 0 IN IT
  2513. ;
  2514.     LXI    H,OPTBL     ;HL = ADDR OF 'OAQDSRV'
  2515.     MVI    B,OPTBE-OPTBL    ;OPT TABLE LEN
  2516. ;
  2517. OPTCK    CMP    M        ;FOUND THE OPTION?
  2518.     JNZ    OPTNO        ;NO, DON'T SET IT
  2519.     MVI    M,0        ;SET THE OPTION
  2520.     JMP    OPTLP        ;GET NEXT OPTION
  2521. ;
  2522. OPTNO    INX    H        ;TO NEXT
  2523.     DCR    B        ;MORE?
  2524.     JNZ    OPTCK
  2525. ;
  2526. ; OPTION NOT IN TABLE
  2527. ;
  2528.     JMP    BADOPT        ;SHOW BAD SUB OPTION
  2529. ;
  2530. ENDOPT    LDA    CRCFLG        ;GET CRC FLAG
  2531.     ORA    A        ;CRC IN EFFECT?
  2532.     JNZ    ENDOPT2     ;NO, EVERYTHING OKAY
  2533.     LDA    OPTION        ;GET PRIMARY OPTION
  2534.     CPI    'R'        ;WAS IT 'FILE RECEIVE'
  2535.     JNZ    BADOPT        ;NO, CRC ONLY ALLOWED FOR RECV
  2536. ;
  2537. ; IF "VIEW" WAS ASKED FOR, SET QUIET FLAG
  2538. ;
  2539. ENDOPT2 LDA    VSEEFLG     ;VIEW..
  2540.     ORA    A        ;..ASKED FOR?
  2541.     RNZ            ;..NO, RET FROM 'PROCOPT'
  2542.     STA    QFLG        ;YES, NO HDR/CKSUM PRT
  2543.     RET            ;FROM 'PROCOPT'
  2544. ;
  2545. ; DONE - CLOSE UP SHOP
  2546. ;
  2547. DONE    LDA    VSEEFLG     ;VIEWING?
  2548.     ORA    A
  2549.     JZ    DONETC        ;SHOW MSG
  2550.     LDA    QFLG        ;QUIET
  2551.     ORA    A        ;..MODE?
  2552.     JZ    DONECTE     ;YES, CK TERM/ECHO
  2553. ;
  2554. DONETC    CALL    ILPRT
  2555.     DB    BELL,CR,LF,'Transfer complete'
  2556.     DB    CR,LF,BELL,0
  2557. ;
  2558. ; CHECK IF TERMINAL OR ECHO SUB COMMAND
  2559. ; WAS SPECIFIED
  2560. ;
  2561. DONECTE LDA    TERMFLG     ;TERM?
  2562.     ORA    A
  2563.     JZ    TERM        ;..YES
  2564.     LDA    ECHOFLG     ;ECHO?
  2565.     ORA    A
  2566.     JZ    TRMECHO     ;..YES
  2567. ;
  2568. ; FALL INTO 'CKDIS'
  2569. ;
  2570. ;---->    CKDIS: CHECK IF DISCONNECT REQUESTED
  2571. ;
  2572. ;    THIS ROUTINE IS JUMPED TO AT THE END OW
  2573. ;    PROCESSING, AND DISCONNECTS THE PHONE IF
  2574. ;    'D' WAS SPECIFIED AS A SUB-OPTION.
  2575. ;
  2576. CKDIS    LDA    DISCFLG     ;CHECK 'D' FLAG
  2577.     ORA    A        ;REQUESTED?
  2578. ;
  2579.     IF    PMMI OR DCH
  2580.     JNZ    NDIS        ;..NO, JUST EXIT
  2581.     ENDIF
  2582. ;
  2583.     IF    NOT PMMI AND NOT DCH
  2584.     JNZ    EXIT
  2585.     ENDIF
  2586. ;
  2587. ; AWAIT C/R TO DISC. SO WE DON'T LOSE THE PHONE
  2588. ;
  2589.     CALL    ILPRT
  2590.     DB    CR,LF,'Press RETURN to disconnect:',0
  2591.     CALL    KEYIN
  2592.     PUSH    PSW
  2593.     CALL    CRLF
  2594.     POP    PSW
  2595.     CPI    CR
  2596.     JNZ    CKDIS        ;ASK AGAIN
  2597. ;
  2598. ;---->    DISCONN: DISCONNECT THE PHONE
  2599. ;
  2600. DISCONN:LDA    CPTRFLG
  2601.     ORA    A
  2602.     CNZ    CPTRTOG    ;IF CAPTURE WAS ON, TURN OFF
  2603. ;
  2604.     IF    PMMI
  2605.     XRA    A        ;GET DISCONN VALUE
  2606.     CALL    OUTCTL        ;RESET ORIG/ANSW
  2607.     CALL    OUTCT2        ;TURN OFF DTR, DO BREAK
  2608.     ENDIF
  2609. ;
  2610.     IF    DCH
  2611.     XRA    A        ;GET DISCONNECT VALUE
  2612.     CALL    OUTCTL        ;DISCONNECT
  2613.     ENDIF
  2614. ;
  2615.     CALL    ILPRT        ;PRINT:
  2616.     DB    '++Disconnected++',0
  2617.     JMP    EXIT
  2618. ;
  2619. ; NO DISCONNECT, TYPE MSG AS REMINDER THAT PHONE'S
  2620. ; OFF HOOK
  2621. ;
  2622.     IF    PMMI OR DCH
  2623. NDIS    LDA    QFLG        ;QUIET..
  2624.     ORA    A        ;..MODE?
  2625.     JZ    EXIT        ;..YES, NO MSG
  2626.     CALL    ILPRT
  2627.     DB    CR,LF,'++The MODEM is still connected++',CR,LF
  2628.     DB    'Use "MODEM D" to disconnect',CR,LF,0
  2629.     JMP    EXIT
  2630.     ENDIF            ;PMMI OR DCH
  2631. ;
  2632. ;---->    INITMOD: INITIALIZES THE MODEM
  2633. ;
  2634. ;    THIS ROUTINE IS USED TO INITIALIZE SERIAL
  2635. ;    BOARDS, OR SETUP S-100 MODEM BOARDS.
  2636. ;    JUST RETURNS IF NO INITIALIZATION REQUIRED.
  2637. ;
  2638. INITMD:
  2639.     IF    INITREQ AND (NOT DCH) AND (NOT X8250)
  2640.     MVI    A,INITC1    ;GET 1ST INIT CHAR
  2641.     CALL    OUTCTL        ;OUTPUT IT
  2642.     NOP
  2643.     NOP            ;DELAY FOR USART
  2644.     NOP
  2645.     NOP
  2646.     MVI    A,INITC2    ;GET 2ND INIT CHAR
  2647.     CALL    OUTCTL        ;OUTPUT IT
  2648.     NOP
  2649.     NOP            ;DELAY FOR USART
  2650.     NOP
  2651.     NOP
  2652.     MVI    A,INITC3    ;GET 3RD INIT CHAR
  2653.     CALL    OUTCTL        ;OUTPUT IT
  2654.     NOP
  2655.     NOP            ;DELAY FOR USART
  2656.     NOP
  2657.     NOP
  2658.     MVI    A,INITC4    ;GET 4TH INIT CHAR
  2659.     CALL    OUTCTL        ;OUTPUT IT
  2660.     ENDIF            ;INITREQ AND (NOT DCH) AND (NOT X8250)
  2661. ;
  2662.     IF    DCH
  2663.     CALL    GETBAUD     ;GET BAUD RATE
  2664.     ENDIF
  2665. ;
  2666.     IF    PMMI
  2667.     CALL    GETBAUD     ;GET BAUD RATE
  2668.     CALL    OUTBRP        ;OUT BAUD RATE PORT
  2669. ;
  2670. ; SET MODEM CHIP BIT FOR >300 BAUD IF REQ'D
  2671. ;
  2672.     CPI    52        ;>300?
  2673.     MVI    A,5FH        ;VALUE FOR >300
  2674.     JC    GT300
  2675.     MVI    A,7FH        ;VALUE FOR <=300
  2676. GT300    CALL    OUTCT2        ;SET IT
  2677. ;
  2678. ; SET ORIG/ANSW IF REQUESTED
  2679. ;
  2680.     LDA    ORIGFLG
  2681.     ORA    A        ;ORIG MODE?
  2682.     MVI    A,ORIGMD
  2683.     JZ    OFFHOOK     ;YES
  2684.     LDA    ANSWFLG
  2685.     ORA    A        ;ANSW MODE?
  2686.     MVI    A,ANSWMD
  2687.     RNZ            ;NO
  2688.     ENDIF            ;PMMI
  2689. ;
  2690.     IF    DCH
  2691.     LDA    ANSWFLG
  2692.     ORA    A        ;ANSW MODE?
  2693.     MVI    B,ANSWMD
  2694.     JZ    INITM1        ;YES
  2695.     LDA    ORIGFLG
  2696.     ORA    A        ;ORIG MODE?
  2697.     MVI    B,ORIGMD
  2698.     JZ    INITM1        ;YES
  2699.     LDA    HOLDD        ;NEITHER - GET LAST VALUE
  2700.     MOV    B,A        ;STORE IN B
  2701. ;
  2702. INITM1: MOV    A,B        ;GET MODE
  2703.     STA    HOLDD        ;SAVE VALUE
  2704.     MOV    A,C        ;GET BAUD RATE INDICATOR
  2705.     ORA    A        ;ZERO IF 110 BAUD
  2706.     MOV    A,B        ;GET MODE
  2707.     JZ    OFFHOOK     ;DO OFFHOOK
  2708.     ORI    1        ;SET 300 BAUD
  2709.     ENDIF            ;DCH
  2710. ;
  2711.     IF    PMMI OR DCH
  2712. ;
  2713. ; GO OFFHOOK IN REQUESTED (ORIG/ANSW) MODE
  2714. ;
  2715. OFFHOOK LXI    H,4000        ;DELAY AMT
  2716. ;
  2717. OFFDLY    DCR    L
  2718.     JNZ    OFFDLY
  2719.     DCR    H
  2720.     JNZ    OFFDLY
  2721.     CALL    OUTCTL        ;GO OFF HOOK
  2722.     RET
  2723.     ENDIF            ;PMMI OR DCH
  2724. ;
  2725.     IF    X8250
  2726.     MVI    A,INITC1    ;ACCESS DIVISOR LATCHES
  2727.     CALL    OUTCTL3
  2728.     MVI    A,INITC2    ;SET DTR AND RTS
  2729.     CALL    OUTCTL4
  2730.     MVI    A,INITC3    ;BAUD DIVISOR LOW BYTE
  2731.     CALL    OUTDATA
  2732.     MVI    A,INITC4    ;BAUD DIVISOR HIGH BYTE
  2733.     CALL    OUTCTL1
  2734.     MVI    A,INITC5    ;DISABLE DIVISOR LATCHES,
  2735.     CALL    OUTCTL3     ;  SET 8 BIT WORD, 1 STOP, NO PAR
  2736.     MVI    A,INITC6    ;DISABLE INTERRUPTS FROM 8250
  2737.     CALL    OUTCTL1
  2738.     ENDIF            ;X8250
  2739. ;
  2740. ;---->    GETBAUD: GETS BAUD RATE FROM COMMAND
  2741. ;
  2742. ;    THIS ROUTINE CHECKS IF A BAUD RATE HAS
  2743. ;    BEEN ASKED FOR, (SUCH AS MODEM T.450),
  2744. ;    AND IF SO, CALCULATES THE PMMI BAUD RATE
  2745. ;    VALUE TO BE OUTPUT.  DEFAULTS TO 300.
  2746. ;
  2747.     IF    PMMI
  2748. GETBAUD LDA    FCB+9        ;GET 'FILETYPE'
  2749.     CPI    ' '        ;DEFAULT?
  2750.     MVI    A,DEFBAUD    ;DEFAULT BAUD RATE
  2751.     RZ            ;NO BAUD RATE, USE 300
  2752. ;
  2753. ; GOT BAUD RATE - CONVERT TO PROPER TIMER VALUE
  2754. ;
  2755.     CALL    CVBIN    ;CONVERT NUMBER TO BINARY
  2756. ;
  2757. ; CALCULATE THE VALUE TO OUTPUT:
  2758. ;   RATE = 250000/16/BAUD RATE
  2759. ;   DIVIDE BY USING REPETITIVE SUBTRACTION
  2760. ;
  2761. ; COMPLEMENT THE BAUD RATE
  2762. ;
  2763.     MOV    A,H        ;GET HI
  2764.     CMA            ;COMPLEMENT
  2765.     MOV    D,A        ;SAVE
  2766.     MOV    A,L        ;GET LO
  2767.     CMA            ;COMPLEMENT
  2768.     MOV    E,A        ;SAVE
  2769.     INX    D        ;DE=2'S COMPLEMENT
  2770. ; DIVIDE
  2771.     LXI    H,15625     ;250000/16
  2772.     LXI    B,-1        ;INIT QUOTIENT
  2773. ;
  2774. DIVLP    INX    B        ;BUMP QUOTIENT
  2775.     DAD    D        ;'SUBTRACT'
  2776.     JC    DIVLP        ;LOOP TIL DOOE
  2777. ; VALIDATE THE RESULT
  2778.     MOV    A,B        ;CAN'T HAVE >255
  2779.     ORA    A
  2780.     MOV    A,C        ;GET ACTUAL
  2781.     RZ            ;RET IF <256
  2782.     JMP    BADRATE     ;INVALID
  2783.     ENDIF            ;PMMI
  2784. ;
  2785.     IF    DCH
  2786. GETBAUD LDA    FCB+9        ;GET 'FILETYPE'
  2787.     CPI    ' '        ;DEFAULT?
  2788.     JNZ    GETBAU1     ;NO - DO BAUD RATE STUFF
  2789.     MVI    C,1        ;SET 300 BAUD
  2790.     MVI    B,17H        ;SET 1 STOP BIT
  2791.     JMP    GETBAU2
  2792. ;
  2793. GETBAU1 CALL    CVBIN        ;CONVERT TO BINARY
  2794.     PUSH    H        ;SAVE BAUD RATE
  2795.     MVI    C,0        ;ANTICIPATE 110 BAUD
  2796.     MVI    B,1FH        ;SET 2 STOP BITS
  2797.     LXI    D,-110        ;GET CONSTANT
  2798.     DAD    D        ;SUBTRACT
  2799.     MOV    A,H
  2800.     ORA    L
  2801.     POP    H
  2802.     JZ    GETBAU2     ;110 BAUD
  2803.     MVI    B,17H        ;SET 1 STOP BIT
  2804.     INR    C
  2805.     LXI    D,-300        ;GET CONSTANT
  2806.     DAD    D
  2807.     MOV    A,H
  2808.     ORA    L
  2809.     JNZ    BADRATE     ;INVALID
  2810. ;
  2811. GETBAU2 MOV    A,B        ;GET SET UP
  2812.     CALL    OUTCT2        ;INIT STOP & DATA BITS, ETC
  2813.     RET
  2814.     ENDIF            ;DCH
  2815. ;
  2816. ; ROUTINE TO CONVERT BAUD RATE TO BINARY
  2817. ;
  2818.     IF    PMMI OR DCH
  2819. CVBIN:    LXI    D,FCB+9     ;TO ASCII VALUE
  2820.     LXI    H,0        ;INIT BINARY RESULT
  2821. ;
  2822. DECLP    LDAX    D        ;GET ASCII DIGIT
  2823.     INX    D        ;TO NEXT DIGIT
  2824.     CPI    ' '        ;BLANK ONE?
  2825.     JZ    DECLP        ;..YES, SKIP IT
  2826.     CPI    '0'        ;VAMIDATE IT
  2827.     JC    BADRATE     ;ERROR
  2828.     CPI    '9'+1        ;VALIDATE
  2829.     JNC    BADRATE     ;ERROR
  2830.     SUI    '0'        ;MAKE DIGIT BINARY
  2831. ;
  2832. ; MULTIPLY PREV VALUE BY 10
  2833. ;
  2834.     MOV    B,H        ;SET UP FOR
  2835.     MOV    C,L        ;MULTIPLY BY 10
  2836.     DAD    H        ;MULTIPLY BY 2
  2837.     DAD    H        ;X 2 = 4
  2838.     DAD    B        ;+ 1 = 5
  2839.     DAD    H        ;X 2 = 10
  2840.     ADD    L        ;ADD IN DIGIT
  2841.     MOV    L,A        ;SAVE BACK
  2842.     JNZ    DIGNC        ;NO CARRY?
  2843.     INR    H        ;ADD IN CARRY
  2844. ;
  2845. ; CHECK IF DONE
  2846. ;
  2847. DIGNC    MOV    A,E        ;SEE IF PAST
  2848.     CPI    FCB+12        ;..LAST DIGIT
  2849.     JNZ    DECLP        ;NO, LOOP
  2850.     RET
  2851. ;
  2852. ; INVALID BAUD RATE
  2853. ;
  2854. BADRATE CALL    ERXIT
  2855.     DB    '++Invalid baud rate++',CR,LF,'$'
  2856.     ENDIF            ;PMMI OR DCH
  2857. ;
  2858. ; THE FOLLOWING PROVIDES A RETURN FROM INITMOD
  2859. ;
  2860.     IF    (NOT PMMI) AND (NOT DCH)
  2861.     RET            ;**THIS MUST BE HERE**
  2862.     ENDIF            ;(NOT PMMI) AND (NOT DCH)
  2863. ;
  2864. ;---->    MOVEFCB: MOVES FCB(2) TO FCB
  2865. ;
  2866. ;    I ATTEMPTED TO MAKE THE MODEM COMMAND 'NATURAL',
  2867. ;    I.E. MODEM SEND FILENAME (MODEM S FN.FT) RATHER
  2868. ;    THAN MODEM FILENAME SEND (MODEM FN.FT S) SO THIS
  2869. ;    ROUTINE MOVES THE FILENAME FROM THE SECOND FCB
  2870. ;    TO THE FIRST
  2871. ;
  2872. MOVEFCB LXI    H,FCB+16    ;FROM
  2873.     LXI    D,FCB        ;TO
  2874.     MVI    B,16        ;LEN
  2875.     CALL    MOVE        ;DO THE MOVE
  2876.     XRA    A        ;GET 0
  2877.     STA    FCBSNO        ;ZERO SECTOR #
  2878.     STA    FCBEXT        ;..AND EXTENT
  2879.     RET
  2880. ;
  2881. ;---->    SHOW: SHOWS CHAR SENT/RECEIVED
  2882. ;
  2883. ;    CR, LF, AND TAB ARE SHOWN.  ALL OTHER
  2884. ;    NON-PRINTABLE CHARACTERS ARE SHOWN IN
  2885. ;    HEX AS (XX)
  2886. ;
  2887. SHOW    CPI    LF        ;LF?
  2888.     JZ    CTYPE        ;..YES, TYPE IT
  2889.     CPI    CR        ;CR?
  2890.     JZ    CTYPE        ;..YES, TYPE IT
  2891.     CPI    09        ;TAB
  2892.     JZ    CTYPE        ;..YES, TYPE IT
  2893.     CPI    ' '        ;CTL-CHR?
  2894.     JC    SHOWHEX     ;YES, SHOW IN HEX
  2895.     CPI    7FH        ;DEL?
  2896.     JC    CTYPE        ;NO, TYPE THE CHAR
  2897. ;
  2898. SHOWHEX PUSH    PSW        ;SAVE THE CHAR
  2899.     MVI    A,'('        ;TYPE..
  2900.     CALL    CTYPE        ;..'('
  2901.     POP    PSW        ;THEN..
  2902.     CALL    HEXO        ;..THE CHAR
  2903.     MVI    A,')'        ;THEN..
  2904.     JMP    CTYPE        ;..')' AND RETURN.
  2905. ;
  2906. ;---->    CTYPE: TYPES VIA CP/M SO TABS ARE EXPANDED
  2907. ;
  2908. CTYPE    PUSH    B        ;SAVE..
  2909.     PUSH    D        ;..ALL..
  2910.     PUSH    H        ;..REGS
  2911.     MOV    E,A        ;CHAR TO E
  2912.     MVI    C,WRCON     ;GET BDOS FNC
  2913.     CALL    BDOS        ;PRIN THE CHR
  2914.     POP    H        ;RESTORE..
  2915.     POP    D        ;..ALL..
  2916.     POP    B        ;..REGS
  2917.     RET            ;FROM "CTYPE"
  2918. ;
  2919. CRLF    MVI    A,CR
  2920.     CALL    TYPE
  2921.     MVI    A,LF
  2922. ;
  2923. ;---->    TYPE: TYPE VIA DIRECT CBIOS ACCESS.
  2924. ;    WE ASSUME CBIOS MAY DESTROY SOME REGISTERS,
  2925. ;    SO SAVE THEM ALL.
  2926. ;
  2927. ;    THIS ROUTINE BYPASSES CP/M'S CTL-S, CTL-C
  2928. ;    TESTS.
  2929. ;
  2930. TYPE    PUSH    PSW        ;SAVE CHAR
  2931.     PUSH    B        ;AND OTHER REGISTERS
  2932.     PUSH    D
  2933.     PUSH    H
  2934.     MOV    C,A        ;FOR BIOS
  2935. VTYPE    CALL    $-$        ;MODIFIED AT INIT
  2936.     POP    H        ;RESTORE REGISTERS
  2937.     POP    D
  2938.     POP    B
  2939.     POP    PSW        ;..AND CHAR
  2940.     RET            ;FROM "TYPE"
  2941. ;
  2942. ;---->    STAT: KEYBOARD STATUS
  2943. ;
  2944. ;    SAVE ALL REGISTERS, EXCEPT A, IN CASE
  2945. ;    CBIOS CLOBBERS THEM.
  2946. ;
  2947. STAT    PUSH    B
  2948.     PUSH    D
  2949.     PUSH    H
  2950. VSTAT    CALL    $-$        ;ADDR SET AT INIT
  2951.     POP    H
  2952.     POP    D
  2953.     POP    B
  2954.     ORA    A        ;0 => NOT READY
  2955.     RET
  2956. ;
  2957. ;---->    KEYIN: KEYBOARD INPUT
  2958. ;
  2959. ;    SAVE ALL REGISTERS, EXCEPT A, IN CASE
  2960. ;    CBIOS CLOBBERS THEM.
  2961. ;
  2962. KEYIN    PUSH    B
  2963.     PUSH    D
  2964.     PUSH    H
  2965. VKEYIN    CALL    $-$        ;ADDR SET AT INIT
  2966.     POP    H
  2967.     POP    D
  2968.     POP    B
  2969.     ANI    7FH        ;STRIP PARITY IF THERE
  2970.     RET            ;FROM KEYIN
  2971. ;
  2972. ;---->    HEXO: HEX OUTPUT
  2973. ;
  2974. HEXO    PUSH    PSW        ;SAVE FOR RIGHT DIGIT
  2975.     RAR            ;RIGHT..
  2976.     RAR            ;..JUSTIFY..
  2977.     RAR            ;..LEFT..
  2978.     RAR            ;..DIGIT..
  2979.     CALL    NIBBL        ;PRINT LEFT DIGIT
  2980.     POP    PSW        ;RESTORE RIGHT
  2981. ;
  2982. NIBBL    ANI    0FH        ;ISOLATE DIGIT
  2983.     CPI    10        ;IS IS <10?
  2984.     JC    ISNUM        ;YES, NOT ALPHA
  2985.     ADI    7        ;ADD ALPHA BIAS
  2986. ;
  2987. ISNUM    ADI    '0'        ;MAKE PRINTABLE
  2988.     JMP    TYPE        ;..THEN TYPE IT
  2989. ;
  2990. ;---->    CKQUIT: QUIT/RETRY AFTER X8251 MULTIPLE ERRORS
  2991. ;
  2992. ;    RETURNS W/ZERO SET IF "RETRY" ASKED FOR
  2993. ;
  2994. CKQUIT    XRA    A        ;ZERO..
  2995.     STA    ERRCT        ;..ERROR COUNT
  2996.     CALL    ILPRT        ;PRINT:
  2997.     DB    BELL,'Multiple errors encountered.  '
  2998.     DB    'Type ''Q'' to quit, ''R'' to retry: ',0
  2999.     CALL    KEYIN        ;QUIT/RETRY
  3000.     PUSH    PSW
  3001.     CALL    TYPE
  3002.     CALL    CRLF
  3003.     POP    PSW
  3004.     ANI    5FH        ;MAKE UPPER CASE
  3005.     CPI    'R'        ;RETRY?
  3006.     RZ            ;'KEEP ON TRUCKIN'
  3007.     CPI    'Q'        ;QUIT?
  3008.     JNZ    CKQUIT        ;NO, ASK AGAIN
  3009.     ORA    A        ;SET NON-ZERO
  3010.     RET
  3011. ;
  3012. ;---->    ILPRT: INLINE PRINT OF MSG
  3013. ;
  3014. ;    THE CALL TO ILPRT IS FOLLOWED BY A MESSAGE,
  3015. ;    BINARY 0 AS THE END.  BINARY 1 MAY BE USED TO
  3016. ;    PAUSE (MESSAGE 'PRESS RETURN TO CONTINUE')
  3017. ;
  3018. ILPRT    XTHL            ;SAVE HL, GET HL=MSG
  3019. ;
  3020. ILPLP    MOV    A,M        ;GET CHAR
  3021.     ORA    A        ;END OF MSG?
  3022.     JZ    ILPRET        ;..YES, RETURN
  3023.     CPI    1        ;PAUSE WITH MSG?
  3024.     JZ    ILPAUSE     ;..YES
  3025.     CPI    2        ;PAUSE, NO MSG?
  3026.     JZ    ILPAUSE1    ;..YES
  3027.     CALL    CTYPE        ;TYPE THE MSG
  3028. ;
  3029. ILPNEXT INX    H        ;TO NEXT CHAR
  3030.     JMP    ILPLP        ;LOOP
  3031. ;
  3032. ; PAUSE WHILE TYPING HELP SO INFO DOESN'T
  3033. ; SCROLL OFF OF VIDEO SCREENS
  3034. ;
  3035. ILPAUSE CALL    ILPRT        ;PRINT:
  3036.     DB    CR,LF,'Press RETURN to continue: ',0
  3037. ILPAUSE1 CALL    KEYIN        ;GET ANY CHAR
  3038.     CPI    'C'-40H     ;REBOOT?
  3039.     JZ    EXIT        ;YES.
  3040.     CALL    ILPRT        ;PRINT
  3041.     DB    CR,LF,0
  3042.     JMP    ILPNEXT     ;LOOP
  3043. ;
  3044. ILPRET    XTHL            ;RESTORE HL
  3045.     RET            ;PAST MSG
  3046. ;
  3047. ;---->    PRTMSG: PRINTS MSG POINTED TO BY (DE)
  3048. ;
  3049. ;    A '$' IS THE ENDING DELIMITER FOR THE PRINT.
  3050. ;    NO REGISTERS SAVED.
  3051. ;
  3052. PRTMSG    MVI    C,PRINT     ;GET BDOS FNC
  3053.     JMP    BDOS        ;PRINT MESSAGE, RETURN
  3054. ;
  3055. ;---->    ERXIT: EXIT PRINTING MSG FOLLOWING CALL
  3056. ;
  3057. ERXIT    POP    D        ;GET MESSAGE
  3058.     CALL    PRTMSG        ;PRINT IT
  3059.     CALL    CKDIS        ;DISCONNECT?
  3060. ;
  3061. EXIT    CALL    ILPRT        ;PRINT:
  3062.     DB    CR,LF,0
  3063.     LHLD    STACK        ;GET ORIGINAL STACK
  3064.     SPHL            ;RESTORE IT
  3065.     RET            ;--EXIT-- TO CP/M
  3066. ;
  3067. ; MOVE 128 CHARACTERS
  3068. ;
  3069. MOVE128 MVI    B,128        ;SET MOVE COUNT
  3070. ;
  3071. ; MOVE FROM (HL) TO (DE) LENGTH IN (B)
  3072. ;
  3073. MOVE    MOV    A,M        ;GET A CHAR
  3074.     STAX    D        ;STORE IT
  3075.     INX    H        ;TO NEXT "FROM"
  3076.     INX    D        ;TO NEXT "TO"
  3077.     DCR    B        ;MORE?
  3078.     JNZ    MOVE        ;..YES, LOOP
  3079.     RET            ;..NO, RETURN
  3080. ;************************************************************************
  3081. ;* CRCSUBS (Cyclic Redundancy Code Subroutines) version 1.20        *
  3082. ;* 8080 Mnemonics                            *
  3083. ;*                                    *
  3084. ;*    These subroutines will compute and check a true 16-bit        *
  3085. ;*    Cyclic Redundancy Code for a message of arbitrary length.    *
  3086. ;*                                    *
  3087. ;*    The  use  of this scheme will guarantee detection of all    *
  3088. ;*    single and double bit errors, all  errors  with  an  odd    *
  3089. ;*    number    of  error bits, all burst errors of length 16 or    *
  3090. ;*    less, 99.9969% of all 17-bit error bursts, and    99.9984%    *
  3091. ;*    of  all  possible  longer  error bursts.  (Ref: Computer    *
  3092. ;*    Networks, Andrew S.  Tanenbaum, Prentiss-Hall, 1981)        *
  3093. ;*                                    *
  3094. ;*                                    *
  3095. ;*    There are four entry points, which are used as follows:     *
  3096. ;*                                    *
  3097. ;*    CLRCRC - A call to this entry resets the CRC accumulator.    *
  3098. ;*         It must be called at the start of each message.    *
  3099. ;*                                    *
  3100. ;*         Entry Parameters: None.                *
  3101. ;*                                    *
  3102. ;*         Exit Conditions:  CRC accumulator cleared.        *
  3103. ;*                   All registers preserved.        *
  3104. ;*                                    *
  3105. ;*                                    *
  3106. ;*    UPDCRC - A call to this entry updates the CRC accumulator.    *
  3107. ;*         It must be called once for each byte in the        *
  3108. ;*         message for which the CRC is being calculated.     *
  3109. ;*                                    *
  3110. ;*         Entry Parameters: (A) = a byte to be included        *
  3111. ;*                     in the CRC calculation.    *
  3112. ;*                                    *
  3113. ;*         Exit Conditions:  CRC accumulator updated.        *
  3114. ;*                   All registers preserved.        *
  3115. ;*                                    *
  3116. ;*                                    *
  3117. ;*    FINCRC - A call to this entry finishes the CRC calculation    *
  3118. ;*         for a message which is to be TRANSMITTED. It must    *
  3119. ;*         be called after the last byte of the message has    *
  3120. ;*         been passed thru UPDCRC. It returns the calculated    *
  3121. ;*         CRC bytes, which must be transmitted as the final    *
  3122. ;*         two bytes of the message (first D, then E).        *
  3123. ;*                                    *
  3124. ;*         Entry Parameters: None.                *
  3125. ;*                                    *
  3126. ;*         Exit Conditions:  (DE) = calculated CRC bytes.     *
  3127. ;*                   All other registers preserved.    *
  3128. ;*                                    *
  3129. ;*                                    *
  3130. ;*    CHKCRC - A call to this routine checks the CRC bytes of     *
  3131. ;*         a RECEIVED message and returns a code to indicate    *
  3132. ;*         whether the message was received correctly. It must    *
  3133. ;*         be called after the message AND the two CRC bytes    *
  3134. ;*         have been received AND passed thru UPDCRC.        *
  3135. ;*                                    *
  3136. ;*         Entry Parameters: None.                *
  3137. ;*                                    *
  3138. ;*         Exit Conditions:  (A) =  0 if message ok.        *
  3139. ;*                   (A) = -1 if message garbled.     *
  3140. ;*                   All other registers preserved.    *
  3141. ;*                                    *
  3142. ;************************************************************************
  3143. ;*                                    *
  3144. ;*    Designed & coded by Paul Hansknecht, June 13, 1981        *
  3145. ;*                                    *
  3146. ;*                                    *
  3147. ;*    Copyright (c) 1981, Carpenter Associates            *
  3148. ;*                Box 451                    *
  3149. ;*                Bloomfield Hills, MI 48013            *
  3150. ;*                313/855-3074                *
  3151. ;*                                    *
  3152. ;*    This program may be freely reproduced for non-profit use.    *
  3153. ;*                                    *
  3154. ;************************************************************************
  3155. ;
  3156. CLRCRC: EQU    $        ; Reset CRC Accumulator for a new message.
  3157.     PUSH    H
  3158.     LXI    H,0
  3159.     SHLD    CRCVAL
  3160.     POP    H
  3161.     RET
  3162. ;
  3163. UPDCRC: EQU    $        ; Update CRC Accumulator using byte in (A).
  3164.     PUSH    PSW
  3165.     PUSH    B
  3166.     PUSH    H
  3167.     MVI    B,8
  3168.     MOV    C,A
  3169.     LHLD    CRCVAL
  3170. ;
  3171. UPDLOOP:MOV    A,C
  3172.     RLC
  3173.     MOV    C,A
  3174.     MOV    A,L
  3175.     RAL
  3176.     MOV    L,A
  3177.     MOV    A,H
  3178.     RAL
  3179.     MOV    H,A
  3180.     JNC    SKIPIT
  3181.     MOV    A,H        ; The generator is X^16 + X^12 + X^5 + 1
  3182.     XRI    10H        ; as recommended by CCITT.
  3183.     MOV    H,A        ; An alternate generator which is often
  3184.     MOV    A,L        ; used in synchronous transmission protocols
  3185.     XRI    21H        ; is X^16 + X^15 + X^2 + 1. This may be
  3186.     MOV    L,A        ; used by substituting XOR 80H for XOR 10H
  3187. SKIPIT: DCR    B        ; and XOR 05H for XOR 21H in the adjacent code.
  3188.     JNZ    UPDLOOP
  3189.     SHLD    CRCVAL
  3190.     POP    H
  3191.     POP    B
  3192.     POP    PSW
  3193.     RET
  3194. ;
  3195. FINCRC: EQU    $        ; Finish CRC calc for outbound message.
  3196.     PUSH    PSW
  3197.     XRA    A
  3198.     CALL    UPDCRC
  3199.     CALL    UPDCRC
  3200.     PUSH    H
  3201.     LHLD    CRCVAL
  3202.     MOV    D,H
  3203.     MOV    E,L
  3204.     POP    H
  3205.     POP    PSW
  3206.     RET
  3207. ;
  3208. CHKCRC: EQU    $        ; Check CRC bytes of received message.
  3209.     PUSH    H
  3210.     LHLD    CRCVAL
  3211.     MOV    A,H
  3212.     ORA    L
  3213.     POP    H
  3214.     RZ
  3215.     MVI    A,0FFH
  3216.     RET
  3217. ;
  3218. CRCVAL    DW    0    ;CRC VALUE STORAGE
  3219. ;
  3220. OPTION    DB    0    ;PRIMARY OPTION
  3221. ;
  3222. ; DATAFLG IS USED BY THE "V" SUBCOMMAND -
  3223. ; IT IS 0 WHEN A HEADER OR CKSUM IS BEING
  3224. ; SENT/RCD, AND 1 IF "VIEWABLE" DATA (THE
  3225. ; SECTOR ITSELF)
  3226. ;
  3227. DATAFLG DB    0    ;AT HEADER, FIRST
  3228. ;
  3229. ; SUB-OPTION TABLE.  IF AN OPTION IS IN EFFECT,
  3230. ; THE CHARACTER IS SET TO BINARY 0
  3231. ;
  3232. OPTBL    EQU    $
  3233. ANSWFLG DB    'A'        ;ANSWER MODE
  3234. DISCFLG DB    'D'        ;DISCONNECT WHEN DONE
  3235. ECHOFLG DB    'E'        ;TO ECHO AFTER XFER
  3236. ORIGFLG DB    'O'        ;ORIGINATE MODE
  3237. QFLG    DB    'Q'        ;QUIET TRANSFER (NO MSGS)
  3238. RSEEFLG DB    'R'        ;SEE WHAT'S RECEIVED
  3239. SSEEFLG DB    'S'        ;SEE WHAT'S SENT
  3240. TERMFLG DB    'T'        ;TO TERM AFTER XFER
  3241. VSEEFLG DB    'V'        ;VIEW MESSAGES (NO HDR, ETC)
  3242. CRCFLG    DB    'C'        ;USE CRC INSTEAD OF CHECKSUM
  3243. OPTBE    EQU    $        ;END OF OPTIONS
  3244. ;
  3245. FIRST    DB    0FFH        ;FLAG FOR FIRST TIME THRU SND OR RCV
  3246. FIRSTME DB    0FFH        ;FLAG FOR FIRST SOH RCVD IN CRC MODE
  3247. ;
  3248. MAXEXT    DB    0        ;EXT COUNT USED BY 'CNREC'
  3249. RCNT    DW    0        ;EXTENT RECORD COUNT USED BY 'CNREC'
  3250. RCVSNO    DB    0        ;SECT # RECEIVED
  3251. SECTNO:    DW    0        ;CURRENT SECTOR NUMBER (LO, THEN HI)
  3252. ERRCT    DB    0        ;ERROR COUNT
  3253. ERRCDE    DB    0        ;RECEIVE ERROR CODE
  3254. HOLDD    DB    86H        ;DC HAYES MODEM DEFAULT HOLDING AREA
  3255. ;
  3256. ; FOLLOWING USED BY ASCII CAPTURE AND PRINTER FUNCTIONS
  3257. ;
  3258. CPTRFLG DB    0        ;CAPTURE ENABLED FLAG
  3259. PRTRFLG DB    0        ;PRINTER ENABLED FLAG
  3260. ASCFCB    DS    33        ;CAPTURE FCB
  3261. MEMEND    DS    1        ;LAST PAGE OF TPA
  3262. CAPPTR    DS    2        ;BUFFER POINTER
  3263. ;
  3264. ; FOLLOWING 3 USED BY DISK BUFFERING ROUTINES
  3265. ;
  3266. EOFLG    DB    0        ;EOF FLAG (1=TRUE)
  3267. SECPTR    DW    DBUF
  3268. SECINBF DB    0        ;# OF SECTORS IN BUFFER
  3269. ;
  3270.     DB    055H,0AAH    ;GUARD BYTES TO HELP
  3271.                 ; IDENTIFY STACK OVERFLOWS,
  3272.                 ; NOT USED BY PROGRAM, ONLY
  3273.                 ; FOR DUMP ANALYSIS
  3274.     DS    128        ;STACK AREA
  3275. STACK    DS    2        ;STACK POINTER
  3276. ;
  3277. ; DISK BUFFER (OVERLAYS HELP MSGS), SIZE=128*DBUFSIZ*8.
  3278. ; NO PROGRAM CHECK IS DONE TO VERIFY THAT THE BUFFER
  3279. ; WILL NOT OVERLAY THE CCP AND/OR BDOS ON A GIVEN SYSTEM,
  3280. ; SO THE BURDEN IS ON THE USER TO MAKE SURE OF THIS.
  3281. ; A REASONABLE BUFFER SIZE IS 16K. TRADITIONALLY, BUFFER
  3282. ; SIZE HAS BEEN 2K.
  3283. ;
  3284. DBUF    EQU    $
  3285. ;
  3286. ;  ASCII CAPTURE BUFFER, MUST START ON PAGE BOUNDARY
  3287. ;
  3288. ASCBUF:    EQU    DBUF+0FFH AND 0FF00H    ;USE SAME DISK BUFFER FOR ASCII
  3289.                 ;CAPTURE, SINCE CAPTURE NOT DONE
  3290.     ;WHILE XFER IN PROGRESS. TO HAVE SEPARATE BUFFERS LIKE IN
  3291.     ;MODEM220:    ASCBUF    EQU    (DBUF+(DBUFSIZ*1024)+0FFH) AND 0FF00H
  3292. ;
  3293. ; INVALID COMMAND
  3294. ;
  3295. BADOPT    PUSH    PSW        ;SAVE BAD OPTION
  3296.     CALL    CRLF
  3297.     CALL    ILPRT
  3298.     DB    '++''',0
  3299.     POP    PSW    ;RETRIEVE BAD OPTION
  3300.     CALL    TYPE    ;PRINT BAD OPTION
  3301.     CALL    ILPRT    ;EXIT W/ERROR
  3302.     DB    ''' is an invalid MODEM command option++',CR,LF,CR,LF
  3303.     DB    'Press RETURN for help, Ctl-C to exit: ',2,0
  3304. ;
  3305. HELP    CALL    ILPRT
  3306.     DB    '(T)erminal and (E)cho mode commands:',CR,LF
  3307.     DB    '   Ctl-Y = Ascii capture enable/disable toggle',CR,LF
  3308.     DB    '   Ctl-E = Exit to CP/M',CR,LF
  3309.     DB    '   Ctl-D = Disconnect phone',CR,LF
  3310.     DB    '   Ctl-P = Printer enable/disable toggle',CR,LF,CR,LF
  3311.     DB    'Format for command is:',CR,LF,CR,LF
  3312.     DB    'MODEM # Filename',CR,LF,CR,LF
  3313.     DB    'Where # is a 1 character primary option,',CR,LF
  3314.     DB    ' which may be followed by sub-options,',CR,LF
  3315.     DB    ' and by ".xxx" to set baud rate to xxx',CR,LF,CR,LF,1
  3316.     DB    'Primary Options:',CR,LF,CR,LF
  3317.     DB    '   S to send a file',CR,LF
  3318.     DB    '   R to receive a file',CR,LF
  3319.     DB    '   T to act as a terminal',CR,LF
  3320.     DB    '   E to act as a computer (echo data)',CR,LF
  3321.     DB    '   D to disconnect the phone',CR,LF
  3322.     DB    '   H to print this help file',CR,LF,CR,LF,1
  3323.     DB    'Secondary options:',CR,LF
  3324.     DB    '   A answer mode',CR,LF
  3325.     DB    '   O originate mode',CR,LF
  3326.     DB    '   D disconnect after execution',CR,LF
  3327.     DB    '   T go to terminal mode after file xfer',CR,LF
  3328.     DB    '   E go to echo mode after file xfer',CR,LF
  3329.     DB    '   Q quiet mode - no status msgs',CR,LF
  3330.     DB    '   R show chars received',CR,LF
  3331.     DB    '   S show chars sent',CR,LF
  3332.     DB    '   V view file sent/received (no status)',CR,LF
  3333.     DB    '   C use cyclic redundancy check for file xfers',CR,LF
  3334.     DB    CR,LF,'For examples, type: MODEM X',CR,LF,0
  3335.     JMP    EXIT
  3336. ;
  3337. EXAM    CALL    ILPRT
  3338.     DB    'Send file, originate mode, 300 baud:',CR,LF
  3339.     DB    '   MODEM SO fn.ft',CR,LF
  3340.     DB    'Send another file:',CR,LF
  3341.     DB    '   MODEM S fn/ft',CR,LF
  3342.     DB    'Then send a third file at 450 baud and disconnect:'
  3343.     DB    CR,LF,'     MODEM SD.450 fn.ft',CR,LF
  3344.     DB    'Act as a terminal, originate mode, at 110 baud:',CR,LF
  3345.     DB    '   MODEM TO.110',CR,LF
  3346.     DB    '   (Use ctl-D to disconnect)',CR,LF
  3347.     DB    'Receive file, answer mode, view it, 600 baud:',CR,LF
  3348.     DB    '   MODEM RAV.600 fn.ft',CR,LF
  3349.     DB    'Receive file, use cyclic redundancy check, 600 baud:',CR,LF
  3350.     DB    '   MODEM RC.600 fn,ft',CR,LF
  3351.     DB    'Turn printer mode on/off in terminal or echo mode:',CR,LF
  3352.     DB    '   ^P     (printer now toggled)',CR,LF
  3353.     DB    'Turn on ascii capture mode:',CR,LF
  3354.     DB    '   ^Y ',CR,LF
  3355.     DB    '   FILE NAME --> b:test.doc [CR] (file now open)',CR,LF
  3356.     DB    'Turn off ascii capture mode:',CR,LF
  3357.     DB    '   ^Y    (ascii capture disabled, file closed)',CR,LF,0
  3358.  
  3359.     JMP    EXIT
  3360. ;
  3361. ; BDOS EQUATES (VERSION 2)
  3362. ;
  3363. RDCON    EQU    1
  3364. WRCON    EQU    2
  3365. PRINT    EQU    9
  3366. CONST    EQU    11        ;CONSOLE STAT
  3367. OPEN    EQU    15        ;0FFH=NOT FOUND
  3368. CLOSE    EQU    16        ;    "    "
  3369. SRCHF    EQU    17        ;    "    "
  3370. SRCHN    EQU    18        ;    "    "
  3371. ERASE    EQU    19        ;NO RET CODE
  3372. READ    EQU    20        ;0=OK- 1=EOF
  3373. WRITE    EQU    21        ;0=OK, 1=ERR, 2=?, 0FFH=NO DIR SPC
  3374. MAKE    EQU    22        ;0FFH=BAD
  3375. REN    EQU    23        ;0FFH=BAD
  3376. STDMA    EQU    26        ;SET DMA
  3377. BDOS    EQU    BASE+5
  3378. REIPL    EQU    BASE
  3379. FCB    EQU    BASE+5CH    ;SYSTEM FCB
  3380. FCBEXT    EQU    FCB+12        ;FILE EXTENT
  3381. FCBSNO    EQU    FCB+32        ;SECTOR #
  3382. FCB2    EQU    FCB+6CH     ;2ND FCB
  3383.     END
  3384.