home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol007 / modem926.asm < prev    next >
Assembly Source File  |  1984-04-29  |  46KB  |  1,989 lines

  1. ;
  2. ;MODEM.ASM V2.0, BY WARD CHRISTENSEN
  3. ;    (revised 9/26/80)
  4. ;
  5. ;CP/M - CP/M FILE TRANSFER PROGRAM, AND
  6. ;TERMINAL PROGRAM.
  7. ;
  8. ;NOTE: THIS FILE WILL ASSEMBLE, WITHOUT NEED FOR
  9. ;EDITING, TO WORK WITH A D.C. HAYES 80-103A MODEM
  10. ;AT *NON-STANDARD* PORT 90H WITH 4MHZ Z80 CPU.
  11. ;SEE EQUATES FOR OTHER OPTIONS INCLUDING SYSTEM CLOCK
  12. ;FREQUENCY.
  13. ;
  14. * * * * * * * * * * * * * * * * * * * * * * * * *
  15. *                        *
  16. *    THIS PROGRAM DOCUMENTED IN "MODEM.DOC"    *
  17. *                        *
  18. * * * * * * * * * * * * * * * * * * * * * * * * *
  19. * THIS PROGRAM WAS "MODEM.ASM" BUT IS         *
  20. * TEMPORARILY NAMED "MODEM926.ASM" SO PEOPLE    *
  21. * WILL REALIZE IT IS AN ENHANCEMENT OF        *
  22. * THE ORIGINAL PROGRAM "MODEM.ASM" ON CP/M    *
  23. * USER'S GROUP DISK 25.                *
  24. * * * * * * * * * * * * * * * * * * * * * * * * *
  25. ;
  26. ;PLEASE PASS ON MODS, BUGS, ETC, SO YOUR
  27. ;FIXES OR ENHANCEMENTS MAY BE SHARED BY ALL,
  28. ;         TO:
  29. ;    Ward Christensen
  30. ;    688 E. 154th St. #5D
  31. ;    Dolton, Il. 60419
  32. ;
  33. ;    (312) 849-6279
  34. ;
  35. ;You may send a self-addressed stamped postcard
  36. ;to be informed of changes/bugs as they become
  37. ;known.
  38. ;
  39. ;    --------------
  40. ;
  41. ;    09/23/77
  42. ;ORIGINALLY WRITTEN BY WARD CHRISTENSEN
  43. ;
  44. ;    04/26/79
  45. ;REWRITTEN BY WARD CHRISTENSEN TO COMBINE
  46. ;IMPROVEMENTS TO THE ORIGINAL MADE BY WARD
  47. ;AND BY KEITH PETERSEN, W8SDZ, AND SUGGESTIONS
  48. ;BY JIM BELL WHICH KEITH IMPLEMENTED.  SEE
  49. ;MODEM.DOC FOR ADDITIONAL HISTORICAL
  50. ;INFORMATION AND DOCUMENTATION.
  51. ;
  52. ;    05/09/79
  53. ;ALLOW 'T' AND 'E' SUB-OPTIONS TO GO TO TERMINAL
  54. ;OR ECHO MODEM AFTER TRANSFERRING A FILE.  (WLC)
  55. ;
  56. ;    05/22/79
  57. ;ADD FEATURE TO MAKE RECEIVE FILE ROUTINE SAY
  58. ;FILE SUCCESSFULLY OPENED, WHEN IN QUIET MODE.
  59. ;MOVE INITIAL GOBBLE GARBAGE INPUTS TO BEFORE
  60. ;COMMAND CPI'S SO ALL MODES ARE CLEARED. CHANGE
  61. ;INITIAL SEND WAIT TO 80 SECS TO ALLOW MORE TIME
  62. ;FOR RECEIVING END TO COME UP. ADD 'H' AFTER MSG
  63. ;THAT SHOWS NUMBER OF SECTORS IN EXTENT ABOUT TO
  64. ;BE SENT.  (KBP)
  65. ;
  66. ;    05/24/79
  67. ;FIX MISSING RETURN INSTRUCTION AT END OF
  68. ;INITIALIZATION ROUTINE.  (KBP)
  69. ;
  70. ;    07/01/79
  71. ;MODIFIED PROGRAM TO ALLOW FOR NON-STANDARD VERSIONS OF
  72. ;CP/M. ALL REFERENCES TO ENTRIES INTO CP/M SHOULD BE MADE
  73. ;RELATIVE TO THE VARIABLE SYMBOL CALL "BASE". FOR EXAMPLE,
  74. ;THE EQUATE TO BDOS SHOULD BE BASE+5 INSTEAD OF 5. BASE
  75. ;WILL BE SET TO 0 WHEN THE VARIABLE STDCPM IS SET TO TRUE.
  76. ;(BOB MATHIAS).
  77. ;
  78. ;    07/24/79
  79. ;MOVE INITIALIZE LOCAL STACK TO BEGINNING OF PROGRAM
  80. ;SO DEFAULT STACK IS NOT USED. ADD CONDITIONAL ASSEMBLY
  81. ;OPTION TO TERMINAL ROUTINE FOR TIMESHARE SYSTEMS.
  82. ;CORRECT ERROR IN LOCAL ABORT ROUTINE (WAS LOOKING FOR
  83. ;CONTROL E - NOW CORRECTLY LOOKS FOR CONTROL X). ADD
  84. ;REGISTER SAVES TO CONOUT, KEYIN AND AND KEYBOARD STATUS
  85. ;ROUTINES, AS SOME CBIOS ROUTINES CLOBBER THEM. (KBP)
  86. ;
  87. ;    08/05/79
  88. ;ADDED D. C. HAYES MODEM SUPPORT BY JIM BELL  (KBP)
  89. ;
  90. ;    08/06/79
  91. ;ADDED EQUATES FOR EXTERNAL MODEM (NOT S-100 PLUG-IN)
  92. ;(KBP)
  93. ;
  94. ;    12/06/79
  95. ;CORRECTED ERROR IN HELP FILE. SAID T.110, NOW SAYS
  96. ;TO.110. BY WARD CHRISTENSEN. CORRECTED RECEIVE FILE
  97. ;ROUTINE SO TERMINAL OR ECHO MODE WORKS AFTER FILE
  98. ;TRANSFER IN QUIET MODE. MOVED CHECKS FOR "H" AND
  99. ;"X" OPTIONS SO MODEM IS NOT REINITIALIZED. (KBP)
  100. ;
  101. ;    05/27/80
  102. ;ELIMINATED CONTROL-X CANCEL OF SEND FEATURE, AT
  103. ;SUGGESTION OF WARD CHRISTENSEN. A LINE GLITCH COULD
  104. ;CAUSE PREMATURE ABORT WHEN THIS FEATURE WAS ACTIVE.
  105. ;ADDED EQUATES FOR FALSE AND TRUE TO MAKE ASSEMBLY
  106. ;OPTIONS CLEARER. REMOVED H8 PORT EQUATES (THEY CAN
  107. ;BE PUT IN EXTERNAL MODEM EQUATES). (KBP)
  108. ;
  109. ;    09/26/80
  110. ;ADDED AUTO-DIAL AND AUTO-REDIAL LOGIC FOR D.C. HAYES
  111. ;CONDITIONAL ASSEMBLY.  DO I HEAR A VOLUNTEER TO ADAPT
  112. ;THIS TO PMMI? (BRUCE R. RATOFF)
  113. ;
  114. ;
  115. ;DEFINE FALSE AND TRUE
  116. ;
  117. FALSE    EQU    0
  118. TRUE    EQU    NOT FALSE
  119. ;
  120. STDCPM    EQU    TRUE    ;TRUE, IS STANDARD CP/M
  121. ALTCPM    EQU    FALSE    ;TRUE, IS ALTERNATE CP/M FOR H8 OR TRS80
  122. ;
  123.     IF    STDCPM
  124. BASE    EQU    0    ;CP/M BASE ADDRESS
  125.     ENDIF
  126. ;
  127.     IF    ALTCPM
  128. BASE    EQU    4200H    ;CP/M BASE ADDRESS FOR ALTERNATE CP/M
  129.     ENDIF
  130. ;
  131. PMMI    EQU    FALSE    ;TRUE, IS PMMI MODEM
  132. ;
  133. DCH    EQU    TRUE     ;TRUE, IS D.C. HAYES MODEM
  134. ;
  135.     IF    PMMI
  136. MODCTLP    EQU    0C0H    ;PMMI VALUES
  137. MODSNDB EQU    1    ;BIT TO TEST FOR SEND
  138. MODSNDR    EQU    1    ;VALUE WHEN READY
  139. MODRCVB EQU    2    ;BIT TO TEST FOR RECEIVE
  140. MODRCVR    EQU    2    ;VALUE WHEN READY
  141. MODDATP EQU    0C1H    ;DATA PORT
  142. BAUDRP    EQU    0C2H    ;BAUD RATE OUTPUT
  143. MODCTL2    EQU    0C3H    ;SECOND CTL PORT
  144.     ENDIF
  145. ;
  146.     IF    DCH
  147. MODCTLP    EQU    92H    ;D. C. HAYES VALUES
  148. MODSNDB EQU    2    ;BIT TO TEST FOR SEND
  149. MODSNDR    EQU    2    ;VALUE WHEN READY
  150. MODRCVB EQU    1    ;BIT TO TEST FOR RECEIVE
  151. MODRCVR    EQU    1    ;VALUE WHEN READY
  152. MODDATP EQU    90H    ;DATA PORT
  153. MODCTL2    EQU    91H    ;SECOND CTL PORT
  154.     ENDIF
  155. ;
  156.     IF    PMMI
  157. ORIGMOD    EQU    1DH    ;8 DATA, NO PARITY, ORIG
  158. ANSWMOD    EQU    1EH    ;8 DATA, NO PARITY, ANSW
  159.     ENDIF
  160. ;
  161. ;NOTE: IF DC HAYES THEN BAUD RATE DEFAULTS TO
  162. ;300 - 1 STOP BIT.  DO NOT CHANGE NEXT EQUATES
  163.     IF    DCH
  164. ORIGMOD EQU    86H    ;OFF HOOK, 110 BAUD, CAR. ON, ORIG.
  165. ANSWMOD    EQU    82H    ;OFF HOOK, 110 BAUD, CAR. ON, ANSW.
  166.     ENDIF
  167. ;
  168. ;IF YOU ARE USING AN EXTERNAL MODEM (NOT S-100 PLUG-IN)
  169. ;CHANGE THESE EQUATES FOR YOUR MODEM PORT REQUIREMENTS
  170. ;
  171. INITREQ    EQU    FALSE    ;TRUE, IF MODEM PORT INIT. REQ'D
  172. INITC1    EQU    64H    ;1ST INIT CHAR TO CTL PORT
  173. INITC2    EQU    64H    ;2ND INIT CHAR TO CTL PORT
  174. INITC3    EQU    64H    ;3RD INIT CHAR TO CTL PORT
  175. INITC4    EQU    64H    ;4TH INIT CHAR TO CTL PORT
  176. ;
  177.     IF    NOT PMMI AND NOT DCH
  178. MODCTLP    EQU    02H    ;PUT YOUR MODEM CONTROL PORT HERE
  179. MODSNDB    EQU    80H    ;YOUR BIT TO TEST FOR SEND
  180. MODSNDR    EQU    80H    ;YOUR VALUE WHEN READY
  181. MODRCVB    EQU    40H    ;YOUR BIT TO TEST FOR RECEIVE
  182. MODRCVR    EQU    40H    ;YOUR VALUE WHEN READY
  183. MODDATP    EQU    03H    ;YOUR MODEM DATA PORT
  184.     ENDIF        ;END OF EXTERNAL MODEM EQUATES
  185. ;
  186. ERRLIM    EQU    10    ;MAX ALLOWABLE ERRORS
  187. EXITCHR    EQU    'E'-40H ;CTL-E EXIT FROM T OR C
  188. DISCCHR    EQU    'D'-40H    ;CTL-D DISCONNECTS MODEM T/E
  189. ;
  190. FASTCLK    EQU    TRUE     ;TRUE FOR 4 MHZ CLOCK
  191. ;
  192. ;SOME TIME-SHARE COMPUTERS REQUIRE TERMINALS TO
  193. ;HAVE BIT 7 HIGH (MARKING), SO IN THE TERMINAL
  194. ;MODE WE FORCE IT TO HIGH IF THE FOLLOWING OPTION
  195. ;IS SELECTED:
  196. ;
  197. TIMESHR    EQU    FALSE    ;TRUE TO MAKE BIT 7 HIGH
  198. ;DEFINE ASCII CHARACTERS USED
  199. ;
  200. SOH    EQU    1    ;START OF HEADER
  201. EOT    EQU    4    ;END OF TRANSMISSION
  202. ACK    EQU    6    ;ACKNOWLEDGE
  203. BEL    EQU    7    ;BELL
  204. NAK    EQU    15H    ;NEG ACKNOWLEDGE
  205. CAN    EQU    18H    ;CANCEL
  206. LF    EQU    10    ;LINEFEED
  207. CR    EQU    13    ;CARRIAGE RETURN
  208.     ORG    BASE+100H
  209. ;
  210. ;INIT PRIVATE STACK
  211.     LXI    H,0    ;HL=0
  212.     DAD    SP    ;HL=STACK FROM CP/M
  213.     SHLD    STACK    ;..SAVE IT
  214.     LXI    SP,STACK ;SP=MY STACK
  215.     CALL    START    ;GO PRINT ID
  216.     DB    'MODEM PROGRAM as of '
  217.     DB    '09/26/80',CR,LF,'$'
  218. START    POP    D    ;GET ID MESSAGE
  219.     MVI    C,PRINT
  220.     CALL    BDOS    ;PRINT ID MESSAGE
  221. ;
  222. ;INITIALIZE THE JMPS TO CP/M BIOS
  223. ;
  224.     CALL    INITADR
  225. ;
  226.     LDA    FCB+1    ;GET PRIMARY OPTION
  227.     CPI    'H'    ;MODEM H(ELP)?
  228.     JZ    HELP    ;..YES, GIVE HELP
  229.     CPI    'X'    ;MODEM X(AMPLES)?
  230.     JZ    EXAM    ;GIVE EXAMPLES
  231. ;
  232. ;SAVE PRIMARY OPTION, VALIDATE SECONDARY OPT.
  233. ;
  234.     CALL    PROCOPT
  235. ;
  236. ;INIT THE MODEM OR SERIAL PORT
  237. ;
  238.     CALL    INITMOD
  239. ;
  240. ;MOVE THE FILENAME FROM FCB 2 TO FCB 1
  241. ;
  242.     CALL    MOVEFCB
  243. ;
  244.     IF    DCH
  245.     CALL    DIALMOD        ; CHECK FOR PHONE # AND DIAL IT IF PRESENT
  246.     ENDIF
  247. ;
  248. ;GOBBLE UP GARBAGE CHARS FROM THE LINE
  249. ;PRIOR TO RECEIVE OR SEND
  250. ;
  251.     IN    MODDATP
  252.     IN    MODDATP
  253. ;
  254. ;JMP TO APPROPRIATE FUNCTION
  255. ;
  256.     LDA    OPTION    ;GET PRIMARY OPTION
  257. ;
  258.     CPI    'C'    ;(COMPAT W/EARLIER
  259.     JZ    TRMECHO    ;OPTION "COMPUTER")
  260. ;
  261.     CPI    'E'    ;TERMINAL IN ECHO
  262.     JZ    TRMECHO    ;..MODE?
  263. ;
  264.     CPI    'T'    ;TERMINAL..
  265.     JZ    TERM    ;..MODE?
  266. ;
  267.     CPI    'D'
  268.     JZ    DISCONN
  269. ;
  270.            CPI    'S'    ;SEND..
  271.     JZ    SENDFIL    ;..A FILE?
  272. ;
  273.     CPI    'R'    ;RECEIVE..
  274.     JZ    RCVFIL    ;..A FILE?
  275. ;
  276. ;INVALID OPTION
  277. ;
  278.     JMP    BADOPT
  279. ;
  280. * * * * * * * * * * * * * * * * * * * * *
  281. *                    *
  282. *    TERM: TERMINAL MODE        *
  283. *                    *
  284. * * * * * * * * * * * * * * * * * * * * *
  285. ;
  286. ;THIS PROGRAM SIMPLY SENDS KEYED CHARACTERS
  287. ;DOWN THE LINE, AND DISPLAYS CHARACTERS
  288. ;RECEIVED FROM THE LINE.  THIS MAKES IT
  289. ;SUITABLE FOR COMMUNICATION WITH TIME SHARING
  290. ;COMPUTERS, CBBS'S, OR ANOTHER PROGRAM
  291. ;RUNING "MODEM E" (ECHO MODE)
  292. ;
  293. ;TYPE THE "EXITCHR" (ORIGINALLY CTL-E) TO EXIT.
  294. ;OR THE "DISCCHR" (ORIGINALLY CTL-D) TO DISCONN.
  295. ;
  296. ;A FUTURE ENHANCEMENT WILL BE TO WRITE THE
  297. ;RECEIVED DATA IN MEMORY, AND ALLOW IT TO
  298. ;BE WRITTEN TO DISK
  299. ;
  300. TERM    CALL    STAT    ;LOCAL CHAR KEYED?
  301.     JZ    TERML    ;..NO, CHECK LINE
  302.     CALL    KEYIN    ;GET CHAR
  303.     CPI    EXITCHR    ;TIME TO END?
  304.     JZ    CKDIS    ;YES, CK DISCONN
  305.     CPI    DISCCHR    ;DISCONNECT REQUEST?
  306.     JZ    DISCONN    ;YES, DO IT
  307.     IF    TIMESHR
  308.     ORI    80H    ;FORCE BIT 7 TO HIGH
  309.     ENDIF        ;TIMESHR
  310.     OUT    MODDATP    ;SEND THE CHAR
  311. ;
  312. ;SEE IF CHAR FROM LINE
  313. ;
  314.     IF    NOT DCH
  315. TERML    IN    MODCTLP    ;READ STATUS
  316.     ENDIF
  317. ;
  318.     IF    DCH
  319. TERML    IN    MODCTL2    ;READ STATUS
  320.     ENDIF
  321. ;
  322.     ANI    MODRCVB    ;ISOLATE BIT
  323.     CPI    MODRCVR    ;READY?
  324.     JNZ    TERM    ;..NO, LOOP
  325.     IN    MODDATP    ;READ DATA
  326.     ANI    7FH    ;STRIP PARITY BIT
  327.     CALL    TYPE    ;TYPE IT
  328.     JMP    TERM    ;LOOP
  329. ;
  330. * * * * * * * * * * * * * * * * * * * * *
  331. *                    *
  332. *    TRMECHO: TERMINAL WITH ECHO    *
  333. *                    *
  334. * * * * * * * * * * * * * * * * * * * * *
  335. ;
  336. ;TERMINAL PROGRAM WITH ECHO - SEE NOTES
  337. ;UNDER "TERM" ABOVE
  338. ;
  339. ;C A U T I O N   DON'T RUN WITH BOTH COMPUTERS
  340. ;IN "ECHO" MODE - LINE ERRORS (OR ANY CHAR)
  341. ;WILL BE ECHOED BACK AND FORTH AD INFINITUM.
  342. ;
  343.     IF    NOT DCH
  344. TRMECHO    IN    MODCTLP    ;GET STATUS
  345.     ENDIF
  346. ;
  347.     IF    DCH
  348. TRMECHO    IN    MODCTL2    ;GET STATUS
  349.     ENDIF
  350. ;
  351.     ANI    MODRCVB    ;ISOLATE READY BIT
  352.     CPI    MODRCVR    ;ARE WE READY?
  353.     JZ    LINECHR    ;YES, READ THE CHR
  354.     CALL    STAT    ;CHECK LOCAL KB
  355.     JZ    TRMECHO    ;..NO CHAR
  356.     CALL    KEYIN    ;GET LOCAL CHAR
  357.     CPI    EXITCHR    ;END?
  358.     JZ    CKDIS    ;YES, CK DISCONN, EXIT
  359.     CPI    DISCCHR    ;DISCONN?
  360.     JZ    DISCONN    ;..YES, DO IT.
  361.     OUT    MODDATP    ;SEND CHAR
  362.     CALL    TYPE    ;ECHO IT LOCALLY
  363.     JMP    TRMECHO    ;..AND LOOP
  364. ;
  365. ;GOT CHAR FROM LINE
  366. ;
  367. LINECHR    IN    MODDATP    ;GET CHAR
  368.     OUT    MODDATP    ;ECHO IT
  369.     ANI    7FH    ;STRIP PARITY BIT
  370.     CALL    TYPE    ;TYPE IT
  371.     JMP    TRMECHO    ;LOOP
  372. ;
  373. * * * * * * * * * * * * * * * * * * * * *
  374. *                    *
  375. *    SENDFIL: SENDS A CP/M FILE    *
  376. *                    *
  377. * * * * * * * * * * * * * * * * * * * * *
  378. ;
  379. ;THE CP/M FILE SPECIFIED IN THE MODEM COMMAND
  380. ;IS TRANSFERRED OVER THE PHONE TO ANOTHER
  381. ;COMPUTER RUNNING MODEM WITH THE "R" (RECEIVE)
  382. ;OPTION.  THE DATA IS SENT ONE SECTOR AT A
  383. ;TIME WITH HEADERS AND CHECKSUMS, AND RE-
  384. ;TRANSMISSION ON ERRORS.  
  385. ;
  386. SENDFIL    CALL    OPENFIL    ;OPEN THE FILE
  387.     MVI    E,80    ;WAIT 80 SEC..
  388.     CALL    WAITNAK    ;..FOR INITIAL NAK
  389. ;
  390. SENDLP    CALL    RDSECT    ;READ A SECTOR
  391.     JC    SENDEOF    ;SEND EOF IF DONE
  392.     CALL    INCRSNO    ;BUMP SECTOR #
  393.     XRA    A    ;ZERO ERROR..
  394.     STA    ERRCT    ;..COUNT
  395. ;
  396. SENDRPT    CALL    SENDHDR    ;SEND A HEADER
  397.     CALL    SENDSEC    ;SEND DATA SECTOR
  398.     CALL    SENDCKS    ;SEND CKSUM
  399.     CALL    GETACK    ;GET THE ACK
  400.     JC    SENDRPT    ;REPEAT IF NO ACK
  401.     JMP    SENDLP    ;LOOP UNTIL EOF
  402. ;
  403. ;FILE SENT, SEND EOT'S
  404. ;
  405. SENDEOF    MVI    A,EOT    ;SEND..
  406.     CALL    SEND    ;..AN EOT
  407.     CALL    GETACK    ;GET THE ACK
  408.     JC    SENDEOF    ;LOOP IF NO ACK
  409.     JMP    DONE    ;ALL DONE
  410. ;
  411. * * * * * * * * * * * * * * * * * * * * *
  412. *                    *
  413. *    RCVFIL: RECEIVE A FILE        *
  414. *                    *
  415. * * * * * * * * * * * * * * * * * * * * *
  416. ;
  417. ;RECEIVES A FILE IN BLOCK FORMAT AS SENT
  418. ;BY ANOTHER PERSON DOING "MODEM S FN.FT".
  419. ;
  420. RCVFIL    CALL    ERASFIL    ;ERASE THE FILE
  421.     CALL    MAKEFIL    ;..THEN MAKE NEW
  422.     CALL    ILPRT    ;PRINT:
  423.     DB    'FILE OPEN, READY TO RECEIVE',CR,LF,0
  424. ;
  425. RCVLP    CALL    RCVSECT    ;GET A SECTOR
  426.     JC    RCVEOT    ;GOT EOT
  427.     CALL    WRSECT    ;WRITE THE SECTOR
  428.     CALL    INCRSNO    ;BUMP SECTOR #
  429.     CALL    SENDACK    ;ACK THE SECTOR
  430.     JMP    RCVLP    ;LOOP UNTIL EOF
  431. ;
  432. ;GOT EOT ON SECTOR - FLUSH BUFFERS, END
  433. ;
  434. RCVEOT    CALL    WRBLOCK    ;WRITE THE LAST BLOCK
  435.     CALL    SENDACK    ;ACK THE SECTOR
  436.     CALL    CLOSFIL    ;CLOSE THE FILE
  437.     JMP    DONE    ;ALL DONE
  438. ;
  439. * * * * * * * * * * * * * * * * * * * * *
  440. *                    *
  441. *        SUBROUTINES        *
  442. *                    *
  443. * * * * * * * * * * * * * * * * * * * * *
  444. ;
  445. ;
  446. ;---->    RCVSECT: RECEIVE A SECTOR
  447. ;
  448. ;RETURNS WITH CARRY SET IF EOT RECEIVED.
  449. ;
  450. RCVSECT    XRA    A    ;GET 0
  451.     STA    ERRCT    ;INIT ERROR COUNT
  452. ;
  453. RCVRPT    LDA    QFLG    ;QUIET?
  454.     ORA    A
  455.     JZ    RCVSQ    ;YES, NO STAT MSG.
  456.     CALL    ILPRT    ;PRINT:
  457.     DB    'AWAITING #',0
  458.     LDA    SECTNO    ;GET SECTOR #
  459.     INR    A    ;(REAL INR LATER)
  460.     CALL    HEXO    ;PRINT IN HEX
  461.     CALL    CRLF    ;..THEN CRLF
  462. ;
  463. RCVSQ    MVI    B,10    ;10 SEC TIMEOUT
  464.     CALL    RECV    ;GET SOH/EOT
  465.     JC    RCVSTOT    ;TIMEOUT
  466.     CPI    SOH    ;GET SOH?
  467.     JZ    RCVSOH    ;..YES
  468. ;
  469. ;EARLIER VERS. OF MODEM PROG SENT SOME NULLS -
  470. ;IGNORE THEM
  471. ;
  472.     ORA    A    ;00 FROM SPEED CHECK?
  473.     JZ    RCVSQ    ;YES, IGNORE IT
  474.     CPI    EOT    ;END OF TRANSFER?
  475.     STC        ;RETURN WITH CARRY..
  476.     RZ        ;..SET IF EOT
  477. ;
  478. ;DIDN'T GET SOH  OR EOT - 
  479. ;
  480.     MOV    B,A    ;SAVE CHAR
  481.     LDA    VSEEFLG    ;VIEWING..
  482.     ORA    A    ;..MODE?
  483.     JZ    RCVSEH    ;YES, PRT.MSG
  484.     LDA    QFLG    ;QUIET..
  485.     ORA    A    ;..MODE?
  486.     JZ    RCVSERR    ;YES, SKIP MSG
  487. RCVSEH    MOV    A,B    ;GET CHAR
  488.     CALL    HEXO    ;SHOW IN HEX
  489.     CALL    ILPRT    ;PRINT:
  490.     DB    'H RCD, NOT SOH',CR,LF,0
  491. ;
  492. ;DIDN'T GET VALID HEADER - PURGE THE LINE,
  493. ;THEN SEND NAK.
  494. ;
  495. RCVSERR    MVI    B,1    ;WAIT FOR 1 SEC..
  496.     CALL    RECV    ;..WITH NO CHARS
  497.     JNC    RCVSERR    ;LOOP UNTIL SENDER DONE
  498.     MVI    A,NAK    ;SEND..
  499.     CALL    SEND    ;..THE NAK
  500.     LDA    ERRCT    ;ABORT IF..
  501.     INR    A    ;..WE HAVE REACHED..
  502.     STA    ERRCT    ;..THE ERROR..
  503.     CPI    ERRLIM    ;..LIMIT?
  504.     JC    RCVRPT    ;..NO, TRY AGAIN
  505. ;
  506. ;10 ERRORS IN A ROW - 
  507. ;
  508.     LDA    VSEEFLG    ;VIEWING..
  509.     ORA    A    ;..FILE?
  510.     JZ    RCVCKQ    ;YES, ASK RETRY/QUIT
  511.     LDA    QFLG    ;QUIET..
  512.     ORA    A    ;..MODE?
  513.     JZ    RCVSABT    ;ABORT
  514. ;
  515. RCVCKQ    CALL    CKQUIT    ;RETRY/QUIT?
  516.     JZ    RCVSECT    ;TRY AGAIN
  517. ;
  518. RCVSABT    CALL    CLOSFIL    ;KEEP WHATEVER WE GOT
  519.     CALL    ERXIT
  520.     DB    '++UNABLE TO RECEIVE BLOCK'
  521.     DB    CR,LF,'++ABORTING++$'
  522. ;
  523. ;TIMEDOUT ON RECEIVE
  524. ;
  525. RCVSTOT    LDA    VSEEFLG    ;VIEWING..
  526.     ORA    A    ;..MODE?
  527.     JZ    RCVSPT    ;YES, PRT MSG
  528.     LDA    QFLG    ;QUIET..
  529.     ORA    A    ;..MODE?
  530.     JZ    RCVSERR    ;YES, NO MSG
  531. ;
  532. RCVSPT    CALL    ILPRT
  533.     DB    '++TIMEOUT++ ',0
  534. ;
  535. RCVPRN    LDA    ERRCT    ;PRINT ERROR..
  536.     CALL    HEXO    ;..COUNT
  537.     CALL    CRLF
  538.     JMP    RCVSERR    ;BUMP ERR CT, ETC.
  539. ;
  540. ;GOT SOH - GET BLOCK #, BLOCK # COMPLEMENTED
  541. ;
  542. RCVSOH    MVI    B,1    ;TIMEOUT = 1 SEC
  543.     CALL    RECV    ;GET SECTOR
  544.     JC    RCVSTOT    ;GOT TIMEOUT
  545.     MOV    D,A    ;D=BLK #
  546.     MVI    B,1    ;TIMEOUT = 1 SEC
  547.     CALL    RECV    ;GET CMA'D SECT #
  548.     JC    RCVSTOT    ;TIMEOUT
  549.     CMA        ;CALC COMPLEMENT
  550.     CMP    D    ;GOOD SECTOR #?
  551.     JZ    RCVDATA    ;YES, GET DATA
  552. ;
  553. ;GOT BAD SECTOR #
  554. ;
  555.     LDA    VSEEFLG    ;VIEWING..
  556.     ORA    A    ;..MODE?
  557.     JZ    RCVBSE    ;..YES, PRT MSG
  558.     LDA    QFLG    ;QUIET..
  559.     ORA    A    ;..MODE?
  560.     JZ    RCVSERR    ;..YES, NO MSG
  561. ;
  562. RCVBSE    CALL    ILPRT    ;PRINT:
  563.     DB    '++BAD SECTOR # IN HDR',CR,LF,0
  564.     JMP    RCVSERR    ;BUMP ERROR CT.
  565. ;
  566. RCVDATA    MOV    A,D    ;GET SECTOR #
  567.     STA    RCVSNO    ;SAVE IT
  568.     MVI    A,1    ;SHOW..
  569.     STA    DATAFLG    ;GETTING DATA
  570.     MVI    C,0    ;INIT CKSUM
  571.     LXI    H,BASE+80H    ;POINT TO BUFFER
  572. RCVCHR    MVI    B,1    ;1 SEC TIMEOUT
  573.     CALL    RECV    ;GET CHAR
  574.     JC    RCVSTOT    ;TIMEOUT
  575.     MOV    M,A    ;STORE CHAR
  576.     INR    L    ;DONE?
  577.     JNZ    RCVCHR    ;NO, LOOP
  578. ;
  579. ;VERIFY CHECKSUM
  580. ;
  581.     MOV    D,C    ;SAVE CHECKSUM
  582.     XRA    A    ;SHOW..
  583.     STA    DATAFLG    ;..END OF DATA
  584.     MVI    B,1    ;TIMEOUT LEN.
  585.     CALL    RECV    ;GET CHECKSUM
  586.     JC    RCVSTOT    ;TIMEOUT
  587.     CMP    D    ;CHECKSUM OK?
  588.     JNZ    RCVCERR    ;NO, ERROR
  589. ;
  590. ;GOT A SECTOR, IT'S A DUP IF = PREV,
  591. ;    OR OK IF = 1 + PREV SECTOR
  592. ;
  593.     LDA    RCVSNO    ;GET RECEIVED
  594.     MOV    B,A    ;SAVE IT
  595.     LDA    SECTNO    ;GET PREV
  596.     CMP    B    ;PREV REPEATED?
  597.     JZ    RECVACK    ;ACK TO CATCH UP
  598.     INR    A    ;CALC NEXT SECTOR #
  599.     CMP    B    ;MATCH?
  600.     JNZ    ABORT    ;NO MATCH - STOP SENDER, EXIT
  601.     RET        ;CARRY OFF - NO ERRORS
  602. ;
  603. ;GOT CKSUM
  604. ;
  605. RCVCERR    LDA    VSEEFLG    ;VIEWING..
  606.     ORA    A    ;..MODE?
  607.     JZ    RCVCPR    ;..YES, PRT MSG
  608.     LDA    QFLG    ;QUIET..
  609.     ORA    A    ;..MODE?
  610.     JZ    RCVSERR    ;YES, NO MSG
  611. ;
  612. RCVCPR    CALL    ILPRT
  613.     DB    '++CKSUM++ ',0
  614.     JMP    RCVPRN    ;PRINT ERROR #
  615. ;
  616. ;PREV SECT REPEATED, DUE TO THE LAST ACK
  617. ;BEING GARBAGED.  ACK IT SO SENDER WILL CATCH UP 
  618. ;
  619. RECVACK    CALL    SENDACK    ;SEND THE ACK,
  620.     JMP    RCVSECT    ;GET NEXT BLOCK
  621. ;
  622. ;SEND AN ACK FOR THE SECTOR
  623. ;
  624. SENDACK    MVI    A,ACK    ;GET ACK
  625.     CALL    SEND    ;..AND SEND IT
  626.     RET
  627. ;
  628. ;---->    SENDHDR: SEND THE SECTOR HEADER
  629. ;
  630. ;SEND: (SOH) (BLOCK #) (COMPLEMENTED BLOCK #)
  631. ;
  632. SENDHDR    LDA    QFLG    ;QUIET..
  633.     ORA    A    ;..MODE?
  634.     JZ    SENDHNM    ;YES, SKIP STATUS MSG.
  635.     CALL    ILPRT    ;PRINT:
  636.     DB    'SEND # ',0
  637.     LDA    SECTNO    ;PRINT..
  638.     CALL    HEXO    ;..SECT #
  639.     CALL    CRLF    ;..THEN CR/LF
  640. ;
  641. SENDHNM    MVI    A,SOH    ;SEND..
  642.     CALL    SEND    ;..SOH,
  643.     LDA    SECTNO    ;THEN SEND..
  644.     CALL    SEND    ;..SECTOR #
  645.     LDA    SECTNO    ;THEN SECTOR #
  646.     CMA        ;..COMPLEMENTED..
  647.     CALL    SEND    ;..SECTOR #
  648.     RET        ;FROM SENDHDR
  649. ;
  650. ;---->    SENDSEC: SEND THE DATA SECTOR
  651. ;
  652. ;WHILE SENDING THE SECTOR, THE "DATAFLG" IS SET
  653. ;SUCH THAT IF "V" (VIEW THE FILE) WAS REQUESTED,
  654. ;THE "SHOW" ROUTINE WILL PRINT THE DATA, BUT NOT
  655. ;THE HDR OR CKSUM, OR ANY NON-FATAL MSGS.
  656. ;
  657. SENDSEC    MVI    A,1    ;SHOW NOW AT DATA..
  658.     STA    DATAFLG    ;..FOR VIEW COMMAND
  659.     MVI    C,0    ;INIT CKSUM
  660.     LXI    H,BASE+80H    ;POINT TO BUFFER
  661. SENDC    MOV    A,M    ;GET A CHAR
  662.     CALL    SEND    ;SEND IT
  663.     INR    L    ;POINT TO NEXT CHAR
  664.     JNZ    SENDC    ;LOOP IF <100H
  665.     XRA    A    ;SHOW NOT INTO DATA..
  666.     STA    DATAFLG    ;..FOR VIEW COMMAND
  667.     RET        ;FROM SENDSEC
  668. ;
  669. ;---->    SENDCKS: SEND THE CHECKSUM
  670. ;
  671. SENDCKS    MOV    A,C    ;SEND THE..
  672.     CALL    SEND    ;..CHECKSUM
  673.     RET        ;FROM SENDCKS
  674. ;
  675. ;---->    GETACK: GET THE ACK ON THE SECTOR
  676. ;
  677. ;RETURNS WITH CARRY CLEAR IF ACK RECEIVED.
  678. ;IF AN ACK IS NOT RECEIVED, THE ERROR COUNT
  679. ;IS INCREMENTED, AND IF LESS THAN "ERRLIM",
  680. ;CARRY IS SET AND CONTROL RETURNS.  IF THE
  681. ;ERROR COUNT IS AT "ERRLIM", THE PROGRAM
  682. ;ABORTS IF IN "QUIET" MODE, OR ASKS THE
  683. ;USER FOR QUIT/RETRY IF NOT.
  684. ;
  685. GETACK    MVI    B,10    ;WAIT 10 SECONDS MAX
  686.     CALL    RECVDG    ;RECV W/GARBAGE COLLECT
  687.     JC    GETATOT    ;TIMED OUT
  688.     CPI    ACK    ;OK? (CARRY OFF IF =)
  689.     RZ        ;YES, RET FROM GETACK
  690.     MOV    B,A    ;SAVE CHAR
  691.     LDA    QFLG    ;QUIET..
  692.     ORA    A    ;..MODE?
  693.     JZ    ACKERR    ;..YES, NO MSG
  694.     MOV    A,B    ;GET CHAR
  695.     CALL    HEXO    ;PRINT IN HEX
  696.     CALL    ILPRT    ;PRINT:
  697.     DB    'H RCD, NOT ACK',CR,LF,0
  698. ;
  699. ;TIMEOUT OR ERROR ON ACK - BUMP ERROR COUNT
  700. ;
  701. ACKERR    LDA    ERRCT    ;GET COUNT
  702.     INR    A    ;BUMP IT
  703.     STA    ERRCT    ;SAVE BACK
  704.     CPI    ERRLIM    ;AT LIMIT?
  705.     RC        ;NOT AT LIMIT
  706. ;
  707. ;REACHED ERROR LIMIT
  708. ;
  709.     LDA    VSEEFLG    ;VIEWING..
  710.     ORA    A    ;..FILE?
  711.     JZ    GACKV    ;YES, ASK QUIT/RETRY
  712.     LDA    QFLG    ;QUIET..
  713.     ORA    A    ;..MODE?
  714.     JZ    CSABORT ;..YES, NO MSG
  715. ;
  716. GACKV    CALL    CKQUIT    ;SEE IF WANT TO QUIT
  717.     STC        ;TO SHOW NO ACK
  718.     RZ        ;KEEP ON TRYIN'
  719. ;
  720. CSABORT    CALL    ERXIT
  721.     DB    'CAN''T SEND SECTOR '
  722.     DB    '- ABORTING',CR,LF,'$'
  723. ;
  724. ;TIMEOUT GETTING ACK
  725. ;
  726. GETATOT    LDA    QFLG    ;QUIET..
  727.     ORA    A    ;..MODE?
  728.     JZ    ACKERR    ;YES, NO MSG
  729.     CALL    ILPRT    ;PRINT:
  730.     DB    'TIMEOUT ON ACK',CR,LF,0
  731.     JMP    ACKERR
  732. ABORT    LXI    SP,STACK
  733. ;
  734. ABORTL    MVI    B,1    ;1 SEC. W/O CHARS.
  735.     CALL    RECV
  736.     JNC    ABORTL    ;LOOP UNTIL SENDER DONE
  737.     MVI    A,NAK    ;NEGATIVE ACK
  738.     CALL    SEND    ;TELL SENDING END
  739.     CALL    ILPRT    ;EXIT WITH ABORT MSG
  740.     DB    'MODEM PROGRAM CANCELLED',CR,LF,0
  741.     JMP    CKDIS    ;CHECK FOR DISCONN.
  742. ;
  743. ;---->    INCRSNO: INCREMENT SECTOR #
  744. ;
  745. INCRSNO    LDA    SECTNO    ;INCR..
  746.     INR    A    ;..SECT..
  747.     STA    SECTNO    ;..NUMBER
  748.     RET
  749. ;
  750. ;---->    ERASFIL: ERASE THE INCOMING FILE.
  751. ;
  752. ;IF IT EXISTS, ASK IF IT MAY BE ERASED.
  753. ;
  754. ERASFIL    LXI    D,FCB    ;POINT TO CTL BLOCK
  755.     MVI    C,SRCHF ;SEE IF IT..
  756.     CALL    BDOS    ;..EXISTS
  757.     INR    A    ;FOUND?
  758.     RZ        ;..NO, RETURN
  759.     CALL    ILPRT    ;PRINT:
  760.     DB    '++FILE EXISTS, TYPE Y TO ERASE: ',0
  761.     CALL    KEYIN    ;GET CHAR
  762.     PUSH    PSW
  763.     CALL    TYPE    ;ECHO
  764.     CALL    CRLF    ;BACK TO START OF LINE
  765.     POP    PSW
  766.     ANI    5FH    ;MAKE UPPER CASE
  767.     CPI    'Y'    ;WANT ERASED?
  768.     JNZ    CKDIS    ;QUIT IF NOT ERASE
  769. ;
  770. ;ERASE OLD FILE
  771. ;
  772.     LXI    D,FCB    ;POINT TO FCB
  773.     MVI    C,ERASE    ;GET BDOS FNC
  774.     CALL    BDOS    ;DO THE ERASE
  775.     RET        ;FROM "ERASFIL"
  776. ;
  777. ;---->    MAKEFIL: MAKES THE FILE TO BE RECEIVED
  778. ;
  779. MAKEFIL    LXI    D,FCB    ;POINT TO FCB
  780.     MVI    C,MAKE    ;GET BDOS FNC
  781.     CALL    BDOS    ;TO THE MAKE
  782.     INR    A    ;FF=BAD?
  783.     RNZ        ;OPEN OK
  784. ;DIRECTORY FULL - CAN'T MAKE FILE
  785.     CALL    ERXIT
  786.     DB    '++ERROR - CAN''T MAKE FILE',CR,LF
  787.     DB    '++DIRECTORY MUST BE FULL',CR,LF,'$'
  788. ;
  789. ;---->    OPENFIL: OPENS THE FILE TO BE SENT
  790. ;
  791. OPENFIL    LXI    D,FCB    ;POINT TO FILE
  792.     MVI    C,OPEN    ;GET FUNCTION
  793.     CALL    BDOS    ;OPEN IT
  794.     INR    A    ;OPEN OK?
  795.     JNZ    OPENOK    ;..YES
  796.     CALL    ERXIT    ;..NO, ABORT
  797.     DB    'CAN''T OPEN FILE$'
  798. ;
  799. OPENOK    CALL    ILPRT    ;PRINT:
  800.     DB    'FILE OPEN, EXTENT LENGTH: ',0
  801.     LDA    FCB+15    ;GET # SECTORS
  802.     CALL    HEXO    ;PRINT IN HEX
  803.     CALL    ILPRT    ;PRINT:
  804.     DB    'H',CR,LF,0
  805.     RET
  806. ;
  807. ;---->    CLOSFIL: CLOSES THE RECEIVED FILE
  808. ;
  809. CLOSFIL    LXI    D,FCB    ;POINT TO FILE
  810.     MVI    C,CLOSE    ;GET FUNCTION
  811.     CALL    BDOS    ;CLOSE IT
  812.     INR    A    ;CLOSE OK?
  813.     RNZ        ;..YES, RETURN
  814.     CALL    ERXIT    ;..NO, ABORT
  815.     DB    'CAN''T CLOSE FILE$'
  816. ;
  817. ;---->    RDSECT: READS A SECTOR
  818. ;
  819. ;FOR SPEED, THIS ROUTINE BUFFERS UP 16
  820. ;SECTORS AT A TIME.
  821. ;
  822. RDSECT    LDA    SECINBF    ;GET # SECT IN BUFF.
  823.     DCR    A    ;DECREMENT..
  824.     STA    SECINBF    ;..IT
  825.     JM    RDBLOCK    ;EXHAUSTED?  NEED MORE.
  826.     LHLD    SECPTR    ;GET POINTER
  827.     LXI    D,BASE+80H    ;TO DATA
  828.     CALL    MOVE128    ;MOVE TO BUFFER
  829.     SHLD    SECPTR    ;SAVE BUFFER POINTER
  830.     RET        ;FROM "READSEC"
  831. ;
  832. ;BUFFER IS EMPTY - READ IN ANOTHER BLOCK OF 16
  833. ;
  834. RDBLOCK    LDA    EOFLG    ;GET EOF FLAG
  835.     CPI    1    ;IS IT SET/
  836.     STC        ;TO SHOW EOF
  837.     RZ        ;GOT EOF
  838.     MVI    C,0    ;SECTORS IN BLOCK
  839.     LXI    D,DBUF    ;TO DISK BUFFER
  840. ;
  841. RDSECLP    PUSH    B
  842.     PUSH    D
  843.     MVI    C,STDMA    ;SET DMA..
  844.     CALL    BDOS    ;..ADDR
  845.     LXI    D,FCB
  846.     MVI    C,READ
  847.     CALL    BDOS
  848.     POP    D
  849.     POP    B
  850.     ORA    A    ;READ OK?
  851.     JZ    RDSECOK    ;YES
  852.     DCR    A    ;EOF?
  853.     JZ    REOF    ;GOT EOF
  854. ;
  855. ;READ ERROR
  856. ;
  857.     CALL    ERXIT
  858.     DB    '++FILE READ ERROR$'
  859. ;
  860. RDSECOK    LXI    H,80H    ;ADD LENGTH OF ONE SECTOR...
  861.     DAD    D    ;...TO NEXT BUFF
  862.     XCHG        ;BUFF TO DE
  863.     INR    C    ;MORE SECTORS?
  864.     MOV    A,C    ;GET COUNT
  865.     CPI    16    ;DONE?
  866.     JZ    RDBFULL    ;..YES, BUFF IS FULL
  867.     JMP    RDSECLP    ;READ MORE
  868. ;
  869. REOF    MVI    A,1
  870.     STA    EOFLG    ;SET EOF FLAG
  871.     MOV    A,C
  872. ;
  873. ;BUFFER IS FULL, OR GOT EOF
  874. ;
  875. RDBFULL    STA    SECINBF    ;STORE SECTOR COUNT
  876.     LXI    H,DBUF    ;INIT BUFFER..
  877.     SHLD    SECPTR    ;..POINTER
  878.     LXI    D,BASE+80H    ;RESET..
  879.     MVI    C,STDMA    ;..DMA..
  880.     CALL    BDOS    ;..ADDR
  881.     JMP    RDSECT    ;PASS SECT TO CALLER
  882. ;
  883. ;---->    WRSECT: WRITE A SECTOR
  884. ;
  885. ;WRITES THE SECTOR INTO A BUFFER.  WHEN 16
  886. ;HAVE BEEN WRITTEN, WRITES THE BLOCK TO DISK.
  887. ;
  888. ;ENTRY POINT "WRBLOCK" FLUSHES THE BUFFER AT EOF.
  889. ;
  890. WRSECT    LHLD    SECPTR    ;GET BUFF ADDR
  891.     XCHG        ;TO DE FOR MOVE
  892.     LXI    H,BASE+80H    ;FROM HERE
  893.     CALL    MOVE128    ;MOVE TO BUFFER
  894.     XCHG        ;SAVE NEXT..
  895.     SHLD    SECPTR    ;..BLOCK POINTER
  896.     LDA    SECINBF    ;BUMP THE..
  897.     INR    A    ;..SECTOR #..
  898.     STA    SECINBF    ;..IN THE BUFF
  899.     CPI    16    ;HAVE WE 16?
  900.     RNZ        ;NO, RETURN
  901. ;
  902. ;---->    WRBLOCK: WRITES A BLOCK TO DISK
  903. ;
  904. WRBLOCK    LDA    SECINBF    ;# SECT IN BUFFER
  905.     ORA    A    ;0 MEANS END OF FILE
  906.     RZ        ;NONE TO WRITE
  907.     MOV    C,A    ;SAVE COUNT
  908.     LXI    D,DBUF    ;POINT TO DISK BUFF
  909. ;
  910. DKWRLP    PUSH    H
  911.     PUSH    D
  912.     PUSH    B
  913.     MVI    C,STDMA    ;SET DMA
  914.     CALL    BDOS    ;TO BUFFER
  915.     LXI    D,FCB    ;THEN WRITE
  916.     MVI    C,WRITE    ;..THE..
  917.     CALL    BDOS    ;..BLOCK
  918.     POP    B
  919.     POP    D
  920.     POP    H
  921.     ORA    A
  922.     JNZ    WRERR    ;OOPS, ERROR
  923.     LXI    H,80H    ;LENGTH OF 1 SECT
  924.     DAD    D    ;HL= NEXT BUFF
  925.     XCHG        ;TO DE FOR SETDMA
  926.     DCR    C    ;MORE SECTORS?
  927.     JNZ    DKWRLP    ;..YES, LOOP
  928.     XRA    A    ;GET A ZERO
  929.     STA    SECINBF    ;RESET # OF SECTORS
  930.     LXI    H,DBUF    ;RESET BUFFER..
  931.     SHLD    SECPTR    ;..POINTER
  932. ;
  933. RSDMA    LXI    D,BASE+80H ;RESET..
  934.     MVI    C,STDMA    ;..DMA..
  935.     CALL    BDOS    ;..ADDR
  936.     RET
  937. ;
  938. WRERR    CALL    RSDMA    ;RESET DMA TO NORM.
  939.     CALL    ILPRT    ;PRINT:
  940.     DB    '++ERROR WRITING FILE',CR,LF,0
  941.     JMP    ABORT    ;EXIT
  942. ;
  943. ;---->    RECV: RECEIVE A CHARACTER
  944. ;
  945. ;TIMEOUT TIME IS IN B, IN SECONDS.  ENTRY VIA
  946. ;"RECVDG" DELETES GARBAGE CHARACTERS ON THE
  947. ;LINE.  FOR EXAMPLE, HAVING JUST SENT A SECTOR,
  948. ;CALLING RECVDG WILL DELETE ANY LINE-NOISE-INDUCED
  949. ;CHARACTERS "LONG" BEFORE THE ACK/NAK WOULD
  950. ;BE RECEIVED.
  951. ;
  952. RECVDG    EQU    $    ;RECEIVE W/GARBAGE DELETE
  953.     IN    MODDATP    ;GET A CHAR
  954.     IN    MODDATP    ;..TOTALLY PURGE UART
  955. ;
  956. RECV    PUSH    D    ;SAVE
  957. ;
  958.     IF    FASTCLK    ;4MHZ?
  959.     MOV    A,B    ;GET TIME REQUEST
  960.     ADD    A    ;DOUBLE IT
  961.     MOV    B,A    ;NEW TIME IN B
  962.     ENDIF
  963. ;
  964. MSEC    LXI    D,50000    ;1 SEC DCR COUNT
  965. ;
  966.     IF    NOT DCH
  967. MWTI    IN    MODCTLP    ;CHECK STATUS
  968.     ENDIF
  969. ;
  970.     IF    DCH
  971. MWTI    IN    MODCTL2    ;CHECK STATUS
  972.     ENDIF
  973. ;
  974.     ANI    MODRCVB    ;ISOLATE BIT
  975.     CPI    MODRCVR    ;READY?
  976.     JZ    MCHAR    ;GOT CHAR
  977.     DCR    E    ;COUNT..
  978.     JNZ    MWTI    ;..DOWN..
  979.     DCR    D    ;..FOR..
  980.     JNZ    MWTI    ;..TIMEOUT
  981.     DCR    B    ;MORE SECONDS?
  982.     JNZ    MSEC    ;YES, WAIT
  983. ;
  984. ;MODEM TIMED OUT RECEIVING
  985. ;
  986.     POP    D    ;RESTORE D,E
  987.     STC        ;CARRY SHOWS TIMEOUT
  988.     RET
  989. ;
  990. ;GOT CHAR FROM MODEM
  991. ;
  992. MCHAR    IN    MODDATP    ;READ THE CHAR
  993.     POP    D    ;RESTORE DE
  994. ;
  995. ;CALC CHECKSUM
  996. ;
  997.     PUSH    PSW    ;SAVE THE CHAR
  998.     ADD    C    ;ADD TO CHECKSUM
  999.     MOV    C,A    ;SAVE CHECKSUM
  1000. ;
  1001. ;CHECK IF MONITORING REC'D DATA
  1002. ;
  1003.     LDA    RSEEFLG    ;SEE RECEIVED..
  1004.     ORA    A    ;..DATA?
  1005.     JZ    MONIN    ;..YES
  1006. ;
  1007. ;CHECK IF "VIEWING" AND THIS IS A DATA CHAR
  1008. ;
  1009.     LDA    VSEEFLG    ;VIEWING..
  1010.     ORA    A    ;..DATA?
  1011.     JNZ    NOMONIN    ;..NO
  1012. ;
  1013. ;"VIEW" REQUESTED.  SHOW THE CHAR IT IS DATA
  1014. ;
  1015.     LDA    DATAFLG    ;GET DATA FLAG
  1016.     ORA    A    ;TEST IT
  1017.     JZ    NOMONIN    ;..OFF, NOT DATA
  1018. ;
  1019. MONIN    POP    PSW    ;..IS DATA,
  1020.     PUSH    PSW    ;GET IT,
  1021.     CALL    SHOW    ;..AND SHOW IT
  1022. ;
  1023. NOMONIN    POP    PSW    ;RESTORE CHAR
  1024.     ORA    A    ;CARRY OFF: NO ERROR
  1025.     RET        ;FROM "RECV"
  1026. ;
  1027. ;---->    SEND: SEND A CHARACTER TO THE MODEM
  1028. ;
  1029. SEND    PUSH    PSW    ;SAVE THE CHAR
  1030. ;
  1031. ;CHECK IF MONITORING SENT DATA
  1032. ;
  1033.     LDA    SSEEFLG    ;CHECK IF MONITORING..
  1034.     ORA    A    ;..SENT DATA
  1035.     JZ    MONOUT    ;..YES
  1036. ;
  1037. ;CHECK IF "VIEWING" THE FILE
  1038. ;
  1039.     LDA    VSEEFLG    ;GET VIEW FLAG
  1040.     ORA    A    ;TEST IT
  1041.     JNZ    NOMONOT    ;NO
  1042.     LDA    DATAFLG    ;IS THIS
  1043.     ORA    A    ;..DATA?
  1044.     JZ    NOMONOT    ;..NO.
  1045. ;
  1046. MONOUT    POP    PSW    ;GET THE CHAR
  1047.     PUSH    PSW    ;SAVE IT
  1048.     CALL    SHOW    ;SHOW IT
  1049. ;
  1050. NOMONOT    POP    PSW    ;RESTORE CHAR
  1051.     PUSH    PSW    ;SAVE IT
  1052.     ADD    C    ;CALC CKSUM
  1053.     MOV    C,A    ;SAVE CKSUM
  1054. ;
  1055.     IF    NOT DCH
  1056. SENDW    IN    MODCTLP    ;GET STATUS
  1057.     ENDIF
  1058. ;
  1059.     IF    DCH
  1060. SENDW    IN    MODCTL2    ;GET STATUS
  1061.     ENDIF
  1062. ;
  1063.     ANI    MODSNDB    ;ISOLATE READY BIT
  1064.     CPI    MODSNDR    ;READY?
  1065.     JNZ    SENDW    ;..NO, WAIT
  1066.     POP    PSW    ;GET CHAR
  1067.     OUT    MODDATP    ;OUTPUT IT
  1068.     RET        ;FROM "SEND"
  1069. ;
  1070. ;---->    WAITNAK: WAITS FOR INITIAL NAK
  1071. ;
  1072. ;TO ENSURE NO DATA IS SENT UNTIL THE RECEIVING
  1073. ;PROGRAM IS READY, THIS ROUTINE WAITS FOR THE
  1074. ;THE FIRST TIMEOUT-NAK FROM THE RECEIVER.
  1075. ;(E) CONTAINS THE # OF SECONDS TO WAIT.
  1076. ;
  1077. WAITNAK    LDA    VSEEFLG    ;VIEWING?
  1078.     ORA    A
  1079.     JZ    WAITNPR    ;PRINT MSG
  1080.     LDA    QFLG    ;QUIET..
  1081.     ORA    A    ;..MODE?
  1082.     JZ    WAITNLP    ;YES, SKIP MSG
  1083. ;
  1084. WAITNPR    CALL    ILPRT    ;PRINT:
  1085.     DB    'AWAITING INITIAL NAK',CR,LF,0
  1086. ;
  1087. WAITNLP    MVI    B,1    ;TIMEOUT DELAY
  1088.     CALL    RECV    ;DID WE GET..
  1089.     CPI    NAK    ;..A NAK?
  1090.     RZ        ;YES, SEND BLOCK
  1091.     DCR    E    ;80 TRIES?
  1092.     JZ    ABORT    ;YES, ABORT
  1093.     JMP    WAITNLP    ;NO, LOOP
  1094. ;
  1095. ;---->    INITADR: INIT'S CP/M BDOS ADDRESSES
  1096. ;
  1097. ;THIS ROUTINE FILLS IN THE ADDRESSES OF VARIOUS
  1098. ;JMP AND CALL INSTRUCTIONS, SO THAT CP/M BDOS
  1099. ;IS BYPASSED WHILE ACCESSING THE CONSOLE.  THIS
  1100. ;IS DONE TO ALLOW CHARACTERS SUCH AS CONTROL-C
  1101. ;AND CONTROL-S TO BE KEYED WHILE IN TERMINAL
  1102. ;MODE, WITHOUT CP/M INTERPRETING THEM.
  1103. ;
  1104. INITADR    LHLD    BASE+1    ;GET WARM BOOT ADDR
  1105.     LXI    D,3    ;LENGTH OF A 'JMP'
  1106.     DAD    D    ;TO CONSOLE STAT
  1107.     SHLD    VSTAT+1    ;MODIFY CALL
  1108.     DAD    D    ;TO CONSOLE IN
  1109.     SHLD    VKEYIN+1 ;MODIFY CALL
  1110.     DAD    D    ;TO CONSOLE OUT
  1111.     SHLD    VTYPE+1    ;MODIFY CALL
  1112.     RET
  1113. ;
  1114. ;---->    PROCOPT: PROCESS COMMAND OPTIONS
  1115. ;1) SAVES THE PRIMARY OPTION IN 'OPTION';
  1116. ;2) SCANS THE SUB-OPTION CHARACTERS, AND FOR
  1117. ;EACH FOUND, ZEROS THE APPROPRIATE ENTRY IN
  1118. ;THE OPTION TABLE.  FOR EXAMPLE, IF 'D' IS 
  1119. ;CODED (DISCONNECT) THEN THE 'D' STORED AT
  1120. ;'DISCFLG' IS SET TO 0 SO IT CAN BE TESTED
  1121. ;LATER.
  1122. ;
  1123. PROCOPT    LXI    D,FCB+1    ;TO PRIMARY OPT.
  1124.     LDAX    D    ;GET PRIMARY
  1125.     STA    OPTION    ;SAVE IT
  1126. ;
  1127. OPTLP    INX    D    ;TO SECONDARY OPTION
  1128.     LDAX    D    ;GET CHAR
  1129. ;
  1130. ;IF YOU MOD THIS PROGRAM FOR >7 OPTIONS,
  1131. ;YOU MUST CHANGE THE FOLLOWING, SINCE
  1132. ;THERE WON'T BE A ' ' AFTER THE OPTION
  1133. ;IF A BAUD RATE WAS SPECIFIED.
  1134. ;
  1135.     CPI    ' '    ;NO MORE OPT'NS?
  1136.     JZ    ENDOPT    ;..YES
  1137. ;SET THE APPROP. OPT: STORE 0 IN IT
  1138.     LXI    H,OPTBL    ;HL = ADDR OF 'OAQDSRV'
  1139.     MVI    B,OPTBE-OPTBL ;OPT TABLE LEN
  1140. ;
  1141. OPTCK    CMP    M    ;FOUND THE OPTION?
  1142.     JNZ    OPTNO    ;NO, DON'T SET IT
  1143.     MVI    M,0    ;SET THE OPTION
  1144.     JMP    OPTLP    ;GET NEXT OPTION
  1145. ;
  1146. OPTNO    INX    H    ;TO NEXT
  1147.     DCR    B    ;MORE?
  1148.     JNZ    OPTCK
  1149. ;OPTION NOT IN TABLE
  1150.     JMP    BADOPT    ;SHOW BAD SUB OPTION
  1151. ;
  1152. ;IF "VIEW" WAS ASKED FOR, SET QUIET FLAG
  1153. ;
  1154. ENDOPT    LDA    VSEEFLG    ;VIEW..
  1155.     ORA    A    ;..ASKED FOR?
  1156.     RNZ        ;..NO, RET FROM 'PROCOPT'
  1157.     STA    QFLG    ;YES, NO HDR/CKSUM PRT
  1158.     RET        ;FROM 'PROCOPT'
  1159. ;
  1160. ;DONE - CLOSE UP SHOP
  1161. ;
  1162. DONE    LDA    VSEEFLG    ;VIEWING?
  1163.     ORA    A
  1164.     JZ    DONETC    ;SHOW MSG
  1165.     LDA    QFLG    ;QUIET
  1166.     ORA    A    ;..MODE?
  1167.     JZ    DONECTE    ;YES, CK TERM/ECHO
  1168. ;
  1169. DONETC    CALL    ILPRT
  1170.     DB    CR,LF,'TRANSFER COMPLETE' 
  1171.     DB    CR,LF,0
  1172. ;
  1173. ;CHECK IF TERMINAL OR ECHO SUB COMMAND
  1174. ;WAS SPECIFIED
  1175. ;
  1176. DONECTE    LDA    TERMFLG    ;TERM?
  1177.     ORA    A
  1178.     JZ    TERM    ;..YES
  1179.     LDA    ECHOFLG    ;ECHO?
  1180.     ORA    A
  1181.     JZ    TRMECHO    ;..YES
  1182. ;
  1183. ;FALL INTO 'CKDIS'
  1184. ;
  1185. ;---->    CKDIS: CHECK IF DISCONNECT REQUESTED
  1186. ;
  1187. ;THIS ROUTINE IS JUMPED TO AT THE END OF
  1188. ;PROCESSING, AND DISCONNECTS THE PHONE IF
  1189. ;'D' WAS SPECIFIED AS A SUB-OPTION.
  1190. ;
  1191. CKDIS    LDA    DISCFLG    ;CHECK 'D' FLAG
  1192.     ORA    A    ;REQUESTED?
  1193. ;
  1194.     IF    PMMI OR DCH
  1195.     JNZ    NDIS    ;..NO, JUST EXIT
  1196.     ENDIF
  1197. ;
  1198.     IF    NOT PMMI AND NOT DCH
  1199.     JNZ    EXIT
  1200.     ENDIF
  1201. ;
  1202. ;AWAIT C/R TO DISC. SO WE DON'T LOSE THE PHONE
  1203. ;
  1204.     CALL    ILPRT
  1205.     DB    CR,LF,'PRESS RETURN TO DISCONNECT:',0
  1206.     CALL    KEYIN
  1207.     PUSH    PSW
  1208.     CALL    CRLF
  1209.     POP    PSW
  1210.     CPI    CR
  1211.     JNZ    CKDIS    ;ASK AGAIN
  1212. ;
  1213. ;---->    DISCONN: DISCONNECT THE PHONE
  1214. ;
  1215. DISCONN    EQU    $
  1216. ;
  1217.     IF    PMMI
  1218.     XRA    A    ;GET DISCONN VALUE
  1219.     OUT    MODCTLP    ;RESET ORIG/ANSW
  1220.     OUT    MODCTL2    ;TURN OFF DTR, DO BREAK
  1221.     ENDIF
  1222. ;
  1223.     IF    DCH
  1224.     XRA    A    ;GET DISCONNECT VALUE
  1225.     OUT    MODCTLP    ;DISCONNECT
  1226.     ENDIF
  1227. ;
  1228.     CALL    ILPRT    ;PRINT:
  1229.     DB    '++DISCONNECTED++',0
  1230.     JMP    EXIT
  1231. ;
  1232. ;NO DISCONNECT, TYPE MSG AS REMINDER THAT PHONE'S
  1233. ;OFF HOOK
  1234. ;
  1235.     IF    PMMI OR DCH
  1236. NDIS    LDA    QFLG    ;QUIET..
  1237.     ORA    A    ;..MODE?
  1238.     JZ    EXIT    ;..YES, NO MSG
  1239.     CALL    ILPRT
  1240.     DB    CR,LF,'++DON''T FORGET - THE MODEM IS '
  1241.     DB    'NOT DISCONNECTED++',CR,LF
  1242.     DB    'USE "MODEM D" TO DISCONNECT',CR,LF,0
  1243.     JMP    EXIT
  1244. ;
  1245.     ENDIF
  1246. ;
  1247. ;---->    INITMOD: INITIALIZES THE MODEM
  1248. ;
  1249. ;THIS ROUTINE IS USED TO INITIALIZE SERIAL
  1250. ;BOARDS, OR SETUP S-100 MODEM BOARDS.
  1251. ;JUST RETURNS IF NO INITIALIZATION REQUIRED.
  1252. ;
  1253. INITMOD:
  1254. ;
  1255.     IF    INITREQ  ;REQUIRE INIT?
  1256.     MVI    A,INITC1 ;GET 1ST INIT CHAR
  1257.     OUT    MODCTLP     ;OUTPUT IT
  1258.     NOP ! NOP! NOP     ;DELAY FOR USART
  1259.     NOP ! NOP
  1260.     MVI    A,INITC2 ;GET 2ND INIT CHAR
  1261.     OUT    MODCTLP     ;OUTPUT IT
  1262.     NOP ! NOP! NOP     ;DELAY FOR USART
  1263.     NOP ! NOP
  1264.     MVI    A,INITC3 ;GET 3RD INIT CHAR
  1265.     OUT    MODCTLP     ;OUTPUT IT
  1266.     NOP ! NOP! NOP     ;DELAY FOR USART
  1267.     NOP ! NOP
  1268.     MVI    A,INITC4 ;GET 4TH INIT CHAR
  1269.     OUT    MODCTLP     ;OUTPUT IT
  1270.     NOP ! NOP! NOP     ;DELAY FOR USART
  1271.     NOP ! NOP
  1272.     ENDIF
  1273. ;
  1274.     IF    PMMI
  1275.     CALL    GETBAUD    ;GET THE BAUD RATE
  1276.     OUT    BAUDRP    ;OUT BAUD RATE PORT
  1277.     ENDIF        ;PMMI
  1278. ;
  1279.     IF    DCH
  1280.     CALL    GETBAUD    ;GET BAUD RATE
  1281.     ENDIF        ;DCH
  1282. ;
  1283.     IF    PMMI
  1284. ;SET THE MOTOROLA MODEM CHIP BIT FOR >300 IF REQ'D
  1285. ;
  1286.     CPI    52    ;>300?
  1287.     MVI    A,5FH    ;VALUE FOR >300
  1288.     JC    GT300
  1289.     MVI    A,7FH    ;VALUE FOR <= 300
  1290. ;
  1291. GT300    OUT    MODCTL2    ;SET IT
  1292. ;
  1293. ;SET ORIG/ANSW IF REQUESTED
  1294. ;
  1295.     LDA    ORIGFLG    ;ORIGINATE..
  1296.     ORA    A    ;..MODE?
  1297.     MVI    A,ORIGMOD 
  1298.     JZ    OFFHOOK    ;..YES, DO IT
  1299.     LDA    ANSWFLG    ;ANSWER..
  1300.     ORA    A    ;..MODE?
  1301.     MVI    A,ANSWMOD
  1302.     RNZ        ;NEITHER ORIG NOR ANSW.
  1303.     ENDIF        ;PMMI
  1304. ;
  1305.     IF    DCH
  1306.     LDA    ANSWFLG        ;ANSWER..
  1307.     ORA    A
  1308.     MVI    B,ANSWMOD    ;SET ANSWER MODE
  1309.     JZ    INITM1
  1310.     LDA    ORIGFLG        ;GET ORIGINATE FLAG
  1311.     ORA    A
  1312.     MVI    B,ORIGMOD    ;SET ORIGINATE MODE
  1313.     JZ    INITM1
  1314.     LDA    HOLDD        ;NEITHER - GET LAST VALUE
  1315.     MOV    B,A        ;STORE IN B
  1316. ;
  1317. INITM1:    MOV    A,B        ;GET MODE
  1318.     STA    HOLDD        ;SAVE VALUE
  1319.     MOV    A,C        ;GET BAUD RATE INDICATOR
  1320.     ORA    A        ;ZEBO IF 110 BAUD
  1321.     MOV    A,B        ;GET MODE
  1322.     JZ    OFFHOOK        ;DO OFFHOOK
  1323.     ORI    1        ;SET 300 BAUD
  1324.     ENDIF            ;DCH
  1325. ;
  1326.     IF    PMMI OR DCH
  1327. ;
  1328. ;GO OFFHOOK IN REQUESTED (ORIG/ANSW) MODE
  1329. ;
  1330. OFFHOOK    LXI    H,4000    ;DELAY AMT
  1331. ;
  1332. OFFDLY    DCR    L
  1333.     JNZ    OFFDLY
  1334.     DCR    H
  1335.     JNZ    OFFDLY
  1336.     OUT    MODCTLP    ;GO OFF HOOK
  1337.     STA    CURRMOD    ;SAVE CURRENT MODE (NEEDED BY DIALMOD)
  1338.     RET
  1339.     ENDIF        ;PMMI OR DCH
  1340. ;
  1341.     IF    PMMI
  1342. ;---->    GETBAUD: GETS BAUD RATE FROM COMMAND
  1343. ;
  1344. ;THIS ROUTINE CHECKS IF A BAUD RATE HAS
  1345. ;BEEN ASKED FOR, (SUCH AS MODEM T.450),
  1346. ;AND IF SO, CALCULATES THE PMMI BAUD RATE
  1347. ;VALUE TO BE OUTPUT.  DEFAULTS TO 300.
  1348. ;
  1349. GETBAUD    LDA    FCB+9    ;GET 'FILETYPE'
  1350.     CPI    ' '    ;DEFAULT?
  1351.     MVI    A,52    ;300 BAUD VALUE
  1352.     RZ        ;NO BAUD RATE, USE 300
  1353. ;
  1354. ;GOT BAUD RATE - CONVERT TO PROPER TIMER VALUE
  1355. ;
  1356. ;FIRST, CONVERT THE NUMBER TO BINARY
  1357. ;
  1358.     CALL    CVBIN
  1359. ;
  1360. ;CALCULATE THE VALUE TO OUTPUT:
  1361. ;
  1362. ;    RATE = 250000/16/BAUD RATE
  1363. ;
  1364. ;    DIVIDE BY REPETITIVE SUBTRACTION
  1365. ;    ------
  1366. ;COMPLEMENT THE BAUD RATE
  1367. ;
  1368.     MOV    A,H    ;GET HI
  1369.     CMA        ;COMPLEMENT
  1370.     MOV    D,A    ;SAVE
  1371.     MOV    A,L    ;GET LO
  1372.     CMA        ;COMPLEMENT
  1373.     MOV    E,A    ;SAVE
  1374.     INX    D    ;DE=2'S COMPLEMENT
  1375. ;DIVIDE
  1376.     LXI    H,15625    ;250000/16 
  1377.     LXI    B,-1    ;INIT QUOTIENT
  1378. ;
  1379. DIVLP    INX    B    ;BUMP QUOTIENT
  1380.     DAD    D    ;'SUBTRACT'
  1381.     JC    DIVLP    ;LOOP 'TILL DONE
  1382. ;VALIDATE THE RESULT
  1383.     MOV    A,B    ;CAN'T HAVE >255
  1384.     ORA    A
  1385.     MOV    A,C    ;GET ACTUAL
  1386.     RZ        ;RET IF <256
  1387.     JMP    BADRATE    ;INVALID
  1388.     ENDIF        ;PMMI
  1389. ;
  1390.     IF    DCH
  1391. GETBAUD    LDA    FCB+9    ;GET FILETYPE
  1392.     CPI    ' '    ;DEFAULT?
  1393.     JNZ    GETBAU1    ;NO - DO BAUD RATE STUFF
  1394.     MVI    C,1    ;SET 300 BAUD
  1395.     MVI    B,17H    ;SET 1 STOP BIT
  1396.     JMP    GETBAU2
  1397. ;
  1398. ; CONVERT BAUD RATE TO BINARY
  1399. GETBAU1    CALL    CVBIN    ;CONVERT TO BINARY
  1400.     PUSH    H    ;SAVE BAUD RATE
  1401.     MVI    C,0    ;ANTICIPATE 110 BAUD
  1402.     MVI    B,1FH    ;SET 2 STOP BITS
  1403.     LXI    D,-110    ;GET CONSTANT
  1404.     DAD    D    ;SUBTRACT
  1405.     MOV    A,H
  1406.     ORA    L
  1407.     POP    H
  1408.     JZ    GETBAU2    ;110 BAUD
  1409.     MVI    B,17H    ;SET 1 STOP BIT
  1410.     INR    C
  1411.     LXI    D,-300    ;GET CONSTANT
  1412.     DAD    D
  1413.     MOV    A,H
  1414.     ORA    L
  1415.     JNZ    BADRATE    ;INVALID
  1416. ;
  1417. GETBAU2    MOV    A,B    ;GET SET UP
  1418.     OUT    MODCTL2    ;INITIALIZE MODEM FOR STOP BITS..
  1419.     RET        ;..DATA BITS, ETC.
  1420.     ENDIF        ;DCH
  1421. ;
  1422.     IF    PMMI OR DCH
  1423. ; ROUTINE TO CONVERT BAUD RATE TO BINARY
  1424. ;
  1425. CVBIN:    LXI    D,FCB+9    ;TO ASCII VALUE
  1426.     LXI    H,0    ;INIT BINARY RESULT
  1427. ;
  1428. DECLP    LDAX    D    ;GET ASCII DIGIT
  1429.     INX    D    ;TO NEXT DIGIT
  1430.     CPI    ' '    ;BLANK ONE?
  1431.     JZ    DECLP    ;..YES, SKIP IT
  1432.     CPI    '0'    ;VALIDATE IT
  1433.     JC    BADRATE    ;ERROR
  1434.     CPI    '9'+1    ;VALIDATE
  1435.     JNC    BADRATE    ;ERROR
  1436.     SUI    '0'    ;MAKE DIGIT BINARY
  1437. ;
  1438. ;MULTIPLY PREV VALUE BY 10
  1439. ;
  1440.     MOV    B,H    ;SET UP FOR
  1441.     MOV    C,L    ;MULTIPLY BY 10
  1442.     DAD    H    ;MULTIPLY BY 2
  1443.     DAD    H    ;X 2 = 4
  1444.     DAD    B    ;+ 1 = 5
  1445.     DAD    H    ;X 2 = 10
  1446.     ADD    L    ;ADD IN DIGIT
  1447.     MOV    L,A    ;SAVE BACK
  1448.     JNZ    DIGNC    ;NO CARRY?
  1449.     INR    H    ;ADD IN CARRY
  1450. ;CHECK IF DONE?
  1451. DIGNC    MOV    A,E    ;SEE IF PAST
  1452.     CPI    FCB+12    ;..LAST DIGIT
  1453.     JNZ    DECLP    ;NO, LOOP
  1454.     RET
  1455. ;
  1456. ;INVALID BAUD RATE
  1457. ;
  1458. BADRATE    CALL    ERXIT
  1459.     DB    '++INVALID BAUD RATE++$'
  1460.     ENDIF        ;PMMI OR DCH
  1461. ;
  1462. ;THE FOLLOWING PROVIDES A RETURN FROM INITMOD
  1463.     IF    NOT PMMI AND NOT DCH
  1464.     RET        ;**THIS MUST BE HERE**
  1465.     ENDIF        ;NOT PMMI AND NOT DCH
  1466. ;
  1467. ;---->    MOVEFCB: MOVES FCB(2) TO FCB
  1468. ;
  1469. ;I ATTEMPTED TO MAKE THE MODEM COMMAND 'NATURAL',
  1470. ;I.E. MODEM SEND FILENAME (MODEM S FN.FT) RATHER
  1471. ;THAT MODEM FILENAME SEND (MODEM FN.FT S) SO THIS
  1472. ;ROUTINE MOVES THE FILENAME FROM THE SECOND FCB
  1473. ;TO THE FIRST
  1474. ;
  1475. MOVEFCB    LXI    H,FCB+16 ;FROM
  1476.     LXI    D,FCB    ;TO
  1477.     MVI    B,16    ;LEN
  1478.     CALL    MOVE    ;DO THE MOVE
  1479.     XRA    A    ;GET 0
  1480.     STA    FCBSNO    ;ZERO SECTOR #
  1481.     STA    FCBEXT    ;..AND EXTENT
  1482.     RET
  1483. ;
  1484. ;---->    SHOW: SHOWS CHAR SENT/RECEIVED
  1485. ;
  1486. ;CR, LF, AND TAB ARE SHOWN.  ALL OTHER
  1487. ;NON-PRINTABLE CHARACTERS ARE SHOWN IN
  1488. ;HEX AS (XX)
  1489. ;
  1490. SHOW    CPI    LF    ;LF?
  1491.     JZ    CTYPE    ;..YES, TYPE IT
  1492.     CPI    CR    ;CR?
  1493.     JZ    CTYPE    ;..YES, TYPE IT
  1494.     CPI    09    ;TAB
  1495.     JZ    CTYPE    ;..YES, TYPE IT
  1496.     CPI    ' '    ;CTL-CHR?
  1497.     JC    SHOWHEX    ;YES, SHOW IN HEX
  1498.     CPI    7FH    ;DEL?
  1499.     JC    CTYPE    ;NO, TYPE THE CHAR
  1500. ;
  1501. SHOWHEX    PUSH    PSW    ;SAVE THE CHAR
  1502.     MVI    A,'('    ;TYPE..
  1503.     CALL    CTYPE    ;..'('
  1504.     POP    PSW    ;THEN..
  1505.     CALL    HEXO    ;..THE CHAR
  1506.     MVI    A,')'    ;THEN..
  1507.     JMP    CTYPE    ;..')' AND RETURN.
  1508. ;
  1509. ;---->    CTYPE: TYPES VIA CP/M SO TABS ARE EXPANDED
  1510. ;
  1511. CTYPE    PUSH    B    ;SAVE..
  1512.     PUSH    D    ;..ALL..
  1513.     PUSH    H    ;..REGS
  1514.     MOV    E,A    ;CHAR TO E
  1515.     MVI    C,WRCON    ;GET BDOS FNC
  1516.     CALL    BDOS    ;PRIN THE CHR
  1517.     POP    H    ;RESTORE..
  1518.     POP    D    ;..ALL..
  1519.     POP    B    ;..REGS
  1520.     RET        ;FROM "CTYPE"
  1521. ;
  1522. CRLF    MVI    A,CR
  1523.     CALL    TYPE
  1524.     MVI    A,LF
  1525. ;
  1526. ;---->    TYPE: TYPE VIA DIRECT CBIOS ACCESS
  1527. ;WE ASSUME CBIOS MAY DESTROY SOME REGISTERS,
  1528. ;SO SAVE THEM ALL.
  1529. ;
  1530. ;THIS ROUTINE BYPASSES CP/M'S CTL-S, CTL-C
  1531. ;TESTS.
  1532. ;
  1533. TYPE    PUSH    PSW    ;SAVE CHAR
  1534.     PUSH    B    ;AND OTHER REGISTERS
  1535.     PUSH    D
  1536.     PUSH    H
  1537.     MOV    C,A    ;FOR BIOS
  1538. VTYPE    CALL    $-$    ;MODIFIED AT INIT
  1539.     POP    H    ;RESTORE REGISTERS
  1540.     POP    D
  1541.     POP    B
  1542.     POP    PSW    ;..AND CHAR
  1543.     RET        ;FROM "TYPE"
  1544. ;
  1545. ;---->  STAT: KEYBOARD STATUS
  1546. ;
  1547. ;SAVE ALL REGISTERS, EXCEPT A, IN CASE
  1548. ;CBIOS CLOBBERS THEM.
  1549. ;
  1550. STAT    PUSH    B
  1551.     PUSH    D
  1552.     PUSH    H
  1553. VSTAT    CALL    $-$    ;ADDR SET AT INIT
  1554.     POP    H
  1555.     POP    D
  1556.     POP    B
  1557.     ORA    A    ;0 => NOT READY
  1558.     RET
  1559. ;
  1560. ;---->  KEYIN: KEYBOARD INPUT
  1561. ;
  1562. ;SAVE ALL REGISTERS, EXCEPT A, IN CASE
  1563. ;CBIOS CLOBBERS THEM.
  1564. ;
  1565. KEYIN    PUSH    B
  1566.     PUSH    D
  1567.     PUSH    H
  1568. VKEYIN    CALL    $-$    ;ADDR SET AT INIT
  1569.     POP    H
  1570.     POP    D
  1571.     POP    B
  1572.     ANI    7FH    ;STRIP PARITY IF THERE
  1573.     RET        ;FROM KEYIN
  1574. ;
  1575. ;---->  HEXO: HEX OUTPUT
  1576. ;
  1577. HEXO    PUSH    PSW    ;SAVE FOR RIGHT DIGIT
  1578.     RAR        ;RIGHT..
  1579.     RAR        ;..JUSTIFY..
  1580.     RAR        ;..LEFT..
  1581.     RAR        ;..DIGIT..
  1582.     CALL    NIBBL    ;PRINT LEFT DIGIT
  1583.     POP    PSW    ;RESTORE RIGHT
  1584. ;
  1585. NIBBL    ANI    0FH    ;ISOLATE DIGIT
  1586.     CPI    10    ;IS IS <10?
  1587.     JC    ISNUM    ;YES, NOT ALPHA
  1588.     ADI    7    ;ADD ALPHA BIAS
  1589. ;
  1590. ISNUM    ADI    '0'    ;MAKE PRINTABLE
  1591.     JMP    TYPE    ;..THEN TYPE IT
  1592. ;
  1593. ;---->    CKQUIT: QUIT/RETRY AFTER MULTIPLE ERRS.
  1594. ;
  1595. ;RETURNS W/ ZERO SET IF "RETRY" ASKED FOR
  1596. ;
  1597. CKQUIT    XRA    A    ;ZERO..
  1598.     STA    ERRCT    ;..ERROR COUNT
  1599.     CALL    ILPRT    ;PRINT:
  1600.     DB    'MULTIPLE ERRORS ENCOUNTERED.  '
  1601.     DB    'TYPE Q TO QUIT, R TO RETRY: ',0
  1602.     CALL    KEYIN    ;QUIT/RETRY
  1603.     PUSH    PSW
  1604.     CALL    TYPE
  1605.     CALL    CRLF
  1606.     POP    PSW
  1607.     ANI    5FH    ;MAKE UPPER CASE
  1608.     CPI    'R'    ;RETRY?
  1609.     RZ        ;'KEEP ON TRUCKIN'
  1610.     CPI    'Q'    ;QUIT?
  1611.     JNZ    CKQUIT    ;NO, ASK AGAIN
  1612.     ORA    A    ;SET NON-ZERO
  1613.     RET
  1614. ;
  1615. ;---->    ILPRT: INLINE PRINT OF MSG
  1616. ;
  1617. ;THE CALL TO ILPRT IS FOLLOWED BY A MESSAGE,
  1618. ;BINARY 0 AS THE END.  BINARY 1 MAY BE USED TO
  1619. ;PAUSE (MESSAGE 'PRESS RETURN TO CONTINUE')
  1620. ;
  1621. ILPRT    XTHL        ;SAVE HL, GET HL=MSG
  1622. ;
  1623. ILPLP    MOV    A,M    ;GET CHAR
  1624.     ORA    A    ;END OF MSG?
  1625.     JZ    ILPRET    ;..YES, RETURN
  1626.     CPI    1    ;PAUSE?
  1627.     JZ    ILPAUSE    ;..YES
  1628.     CALL    CTYPE    ;TYPE THE MSG
  1629. ;
  1630. ILPNEXT    INX    H    ;TO NEXT CHAR
  1631.     JMP    ILPLP    ;LOOP
  1632. ;
  1633. ;PAUSE WHILE TYPING HELP SO INFO DOESN'T
  1634. ;    SCROLL OFF OF VIDEO SCREENS
  1635. ;
  1636. ILPAUSE    CALL    ILPRT    ;PRINT:
  1637.     DB    CR,LF,'PRESS RETURN TO CONTINUE'
  1638.     DB    CR,LF,0
  1639.     CALL    KEYIN    ;GET ANY CHAR
  1640.     CPI    'C'-40H    ;REBOOT?
  1641.     JZ    EXIT    ;YES.
  1642.     JMP    ILPNEXT    ;LOOP
  1643. ;
  1644. ILPRET    XTHL        ;RESTORE HL
  1645.     RET        ;PAST MSG
  1646. ;
  1647. ;---->    PRTMSG: PRINTS MSG POINTED TO BY (DE)
  1648. ;
  1649. ;A '$' IS THE ENDING DELIMITER FOR THE PRINT.
  1650. ;NO REGISTERS SAVED.
  1651. ;
  1652. PRTMSG    MVI    C,PRINT    ;GET BDOS FNC
  1653.     JMP    BDOS    ;PRINT MESSAGE, RETURN
  1654. ;
  1655. ;---->    ERXIT: EXIT PRINTING MSG FOLLOWING CALL
  1656. ;
  1657. ERXIT    POP    D    ;GET MESSAGE
  1658.     CALL    PRTMSG    ;PRINT IT
  1659.     CALL    CKDIS    ;DISCONNECT?
  1660. ;
  1661. EXIT    LHLD    STACK    ;GET ORIGINAL STACK
  1662.     SPHL        ;RESTORE IT
  1663.     RET        ;--EXIT-- TO CP/M
  1664. ;
  1665. ;MOVE 128 CHARACTERS
  1666. ;
  1667. MOVE128    MVI    B,128    ;SET MOVE COUNT
  1668. ;
  1669. ;MOVE FROM (HL) TO (DE) LENGTH IN (B)
  1670. ;
  1671. MOVE    MOV    A,M    ;GET A CHAR
  1672.     STAX    D    ;STORE IT
  1673.     INX    H    ;TO NEXT "FROM"
  1674.     INX    D    ;TO NEXT "TO"
  1675.     DCR    B    ;MORE?
  1676.     JNZ    MOVE    ;..YES, LOOP
  1677.     RET        ;..NO, RETURN
  1678. ;    ----------------
  1679. ;
  1680. ;
  1681. ;---->    DIALMOD: DETECT PHONE # IN COMMAND LINE AND DIAL IT
  1682. ;
  1683. ;THIS ROUTINE (AND THE CALL TO IT) IS ENABLED ONLY WHEN 'DCH'
  1684. ;IS TRUE BECAUSE I DON'T KNOW HOW TO MAKE THE OTHER MODEM
  1685. ;BOARDS DIAL.  MOST OF THE PHONE NUMBER LOGIC SHOULD CROSS
  1686. ;OVER TO OTHER MODEM BOARDS IF SOMEBODY WILL GIVE IT A TRY.
  1687. ;
  1688. ;THE PHONE NUMBER IS THE LAST PARAMETER IN THE COMMAND LINE.
  1689. ;FOR EXAMPLE:    MODEM T 123-456-7890
  1690. ;        MODEM E 123-456-7890
  1691. ;        MODEM S ABCDEFGH.IJK 123-456-8790
  1692. ;        MODEM R ABCDEFGH.IJK 123-456-7890
  1693. ;IF NO PHONE NUMBER IS GIVEN, THIS ROUTINE RETURNS WITHOUT
  1694. ;DOING ANYTHING.  THE DIALER RECOGNIZES THE DIGITS 0-9 AND
  1695. ;ALSO AN ASTERISK (*), WHICH CAUSES A TWO SECOND DELAY.
  1696. ;THIS IS USEFUL FOR SUCH THINGS AS WAITING FOR THE SECOND
  1697. ;DIAL TONE IN A CENTREX SYSTEM.
  1698. ;THE POUND SIGN CHARACTER (#) MAY BE USED IN PLACE OF A PHONE
  1699. ;NUMBER TO RE-DIAL THE LAST-DIALED PHONE NUMBER.  THIS OF COURSE
  1700. ;WILL ONLY WORK IF NO OTHER PROGRAMS HAVE BEEN EXECUTED IN THE
  1701. ;INTERIM.
  1702. ;ALL OTHER CHARACTERS ARE IGNORED.  (THIS INCLUDES THE DASHES
  1703. ;IN THE ABOVE EXAMPLES, WHICH COULD HAVE BEEN OMITTED.)
  1704. ;THE LENGTH OF THE DIAL STRING MUST BE AT LEAST 7 CHARACTERS
  1705. ;TO BE RECOGNIZED, AND MAY CONSIST OF UP TO 20 CHARACTERS.
  1706. ;
  1707.     IF    FASTCLK
  1708. DIALTIM    EQU    -3390        ;SET DELAY LOOP LENGTH FOR DIALING
  1709.     ENDIF
  1710.     IF    NOT FASTCLK
  1711. DIALTIM    EQU    -1786
  1712.     ENDIF
  1713. ;
  1714.     IF    DCH
  1715. DIALMOD:LXI    H,BASE+80H    ;LOOK AT CP/M COMMAND TAIL
  1716.     MOV    B,M        ;GET BYTE COUNT
  1717.     INX    H        ;BUMP TO FIRST CHAR
  1718.     CALL    SKBLNK        ;SKIP LEADING BLANKS
  1719.     RC            ;NOTHING LEFT...QUIT
  1720.     CALL    SKARG        ;ALWAYS AT LEAST ONE ARG TO SKIP
  1721.     RC            ;NOTHING FOLLOWS...QUIT
  1722.     LDA    OPTION        ;LOOK AT MAIN OPTION TO SEE IF
  1723.     CPI    'T'        ; IT HAS A SECOND PARAMETER
  1724.     JZ    ONEARG        ;T HAS ONLY ONE
  1725.     CPI    'E'        ;SO DOES E
  1726.     JZ    ONEARG
  1727.     CALL    SKARG        ;MUST BE R OR S, SO SKIP FILENAME
  1728.     RC            ;QUIT IF NOTHING LEFT
  1729. ONEARG:    MOV    A,M        ;LOOK AT FIRST CHAR OF PHONE #
  1730.     CPI    '#'        ;REDIAL FLAG?
  1731.     JZ    REDIAL        ;IF SO, DON'T COPY NUMBER
  1732.     LXI    D,DIALBUF
  1733. CNLUP:    STAX    D        ;COPY PHONE NUMBER TO DIALBUF
  1734.     INX    D
  1735.     INX    H
  1736.     MOV    A,M
  1737.     DCR    B
  1738.     JNZ    CNLUP
  1739.     SUB    A        ;TAG END OF NUMBER WITH A NULL
  1740.     STAX    D
  1741. REDIAL:    CALL    ILPRT        ;SAY WE'RE DIALING
  1742.     DB    CR,LF,'DIALING - ',0
  1743.     LDA    CURRMOD        ;PICK UP MODEM COMMAND BYTE
  1744.     ANI    8DH        ;REMOVE CARRIER ENABLE
  1745.     OUT    MODCTLP
  1746.     MVI    B,40
  1747.     CALL    VARDLY        ;GIVE 2 SECOND DELAY FOR DIALTONE
  1748.     LXI    H,DIALBUF
  1749. DL:    MOV    A,M        ;PICK UP DIGIT
  1750.     ORA    A
  1751.     JZ    WAITANS        ;NULL MEANS FINISHED
  1752.     CALL    TYPE        ;ECHO DIGIT
  1753.     CPI    '*'
  1754.     MVI    B,40        ;IF STAR, DO 2 SECOND DELAY
  1755.     CZ    VARDLY
  1756.     INX    H        ;BUMP POINTER
  1757.     SUI    '0'        ;CONVERT DIGIT TO BINARY
  1758.     JNZ    NOTZ        ;CHANGE 0 TO 10
  1759.     MVI    A,10
  1760. NOTZ:    JC    DL        ;IGNORE NON-NUMERIC
  1761.     CPI    11
  1762.     JNC    DL
  1763. PULSE:    PUSH    PSW        ;SAVE PULSE COUNT
  1764.     LDA    CURRMOD
  1765.     ANI    7DH        ;DROP OFF-HOOK
  1766.     OUT    MODCTLP
  1767.     CALL    DELAY        ;FOR ONE HALF PULSE TIME
  1768.     ORI    80H
  1769.     OUT    MODCTLP        ;GO BACK OFF HOOK
  1770.     CALL    DELAY        ;FOR OTHER HALF PULSE TIME
  1771.     POP    PSW        ;GET BACK PULSE COUNT
  1772.     DCR    A        ;COUNT IT DOWN
  1773.     JNZ    PULSE        ;LOOP TILL DIGIT IS OUT
  1774.     MVI    B,10        ;DELAY 500MS BETWEEN DIGITS
  1775.     CALL    VARDLY
  1776.     JMP    DL        ;GO DO NEXT DIGIT
  1777. ;
  1778. VARDLY:    CALL    DELAY        ;DELAY (B) TIMES 50 MS.
  1779.     DCR    B
  1780.     JNZ    VARDLY
  1781.     RET
  1782. ;
  1783. DELAY:    PUSH    H        ;DELAY FOR 50 MILLISECONDS
  1784.     PUSH    D
  1785.     PUSH    PSW
  1786.     CALL    STAT        ;CHECK FOR CONTROL-D
  1787.     CNZ    KEYIN
  1788.     CPI    DISCCHR        ;TO ABORT DIALING
  1789.     JZ    DISCONN
  1790.     POP    PSW
  1791.     LXI    D,1        ;SET UP FOR DELAY LOOP
  1792.     LXI    H,DIALTIM
  1793. DLYLP:    XTHL            ;KILL LOTSA TIME
  1794.     XTHL
  1795.     DAD    D        ;SLOW WAY TO DO AN INX
  1796.     JNC    DLYLP
  1797.     POP    D
  1798.     POP    H        ;RESTORE REGS
  1799.     RET            ;DONE
  1800. ;
  1801. ; COME HERE AFTER DIALING TO WAIT FOR ANSWER
  1802. ;
  1803. WAITANS:CALL    CRLF        ;SHOW NUMBER FINISHED
  1804.     LXI    D,600        ;WE'LL WAIT 30 SECONDS FOR ANSWER
  1805.     LDA    CURRMOD
  1806.     MOV    B,A        ;SAVE CURRENT MODE
  1807.     ANI    4        ;CHECK ORIG/ANS BIT
  1808.     JNZ    CARR        ;IF ORIG, WAIT FOR ANSWERING CARRIER
  1809.     MOV    A,B        ;IF ANS, GIVE OUR CARRIER, THEN WAIT
  1810.     OUT    MODCTLP
  1811. CARR:    IN    MODCTL2        ;WAIT FOR CARRIER DETECT
  1812.     ANI    40H
  1813.     JNZ    GOTCARR
  1814.     CALL    DELAY
  1815.     DCX    D        ;COUNT DOWN DELAY
  1816.     MOV    A,D
  1817.     ORA    E
  1818.     JNZ    CARR
  1819.     CALL    ILPRT        ;SAY WE'RE GIVING UP
  1820.     DB    BEL,'NO ANSWER',CR,LF,0
  1821.     JMP    DISCONN        ;HANG UP
  1822. ;
  1823. GOTCARR:CALL    ILPRT        ;SAY WE GOT IT
  1824.     DB    BEL,'CONNECTION ESTABLISHED',CR,LF,0
  1825.     LDA    CURRMOD        ;RESTORE WHOLE MODE BYTE
  1826.     OUT    MODCTLP
  1827.     RET            ;ALL DONE
  1828. ;
  1829. SKBLNK:    MOV    A,M        ;SCAN PAST BLANKS IN COMMAND LINE
  1830.     CPI    ' '
  1831.     RNZ
  1832.     INX    H
  1833.     DCR    B
  1834.     JNZ    SKBLNK        ;CONTINUE SCAN TILL CHARS EXHAUSTED
  1835.     STC            ;CARRY SET SAYS END OF COMMAND
  1836.     RET
  1837. ;
  1838. SKARG:    MOV    A,M        ;SCAN PAST ONE ARGUMENT AND FOLLOWING BLANKS
  1839.     CPI    ' '
  1840.     JZ    SKBLNK        ;GOT BLANK...GO SKIP BLANKS
  1841.     INX    H
  1842.     DCR    B        ;SCAN TILL STRING GONE
  1843.     JNZ    SKARG
  1844.     STC            ;SET CARRY ON RETURN IF END OF STRING
  1845.     RET
  1846. ;
  1847.     ENDIF            ;(FOR DIALING LOGIC)
  1848. ;
  1849. ;
  1850. OPTION    DB    0    ;PRIMARY OPTION
  1851. ;
  1852. ;DATAFLG IS USED BY THE "V" SUBCOMMAND -
  1853. ;IT IS 0 WHEN A HEADER OR CKSUM IS BEING
  1854. ;SENT/RCD, AND 1 IF "VIEWABLE" DATA (THE
  1855. ;SECTOR ITSELF) IS
  1856. ;
  1857. DATAFLG    DB    0    ;AT HEADER, FIRST
  1858. ;
  1859. ;
  1860. ;SUB-OPTION TABLE.  IF AN OPTION IS IN EFFECT,
  1861. ;    THE CHARACTER IS SET TO BINARY 0
  1862. ;
  1863. OPTBL    EQU    $
  1864. ANSWFLG    DB    'A'    ;ANSWER MODE
  1865. DISCFLG    DB    'D'    ;DISCONNECT WHEN DONE
  1866. ECHOFLG    DB    'E'    ;TO ECHO AFTER XFER
  1867. ORIGFLG    DB    'O'    ;ORIGINATE MODE
  1868. QFLG    DB    'Q'    ;QUIET TRANSFER (NO MSGS)
  1869. RSEEFLG    DB    'R'    ;SEE WHAT'S RECEIVED
  1870. SSEEFLG    DB    'S'    ;SEE WHAT'S SENT
  1871. TERMFLG    DB    'T'    ;TO TERM AFTER XFER
  1872. VSEEFLG    DB    'V'    ;VIEW MESSAGES (NO HDR, ETC)
  1873. OPTBE    EQU    $    ;END OF OPTIONS
  1874. ;
  1875. RCVSNO    DB    0    ;SECT # RECEIVED
  1876. SECTNO    DB    0    ;CURRENT SECTOR NUMBER 
  1877. ERRCT    DB    0    ;ERROR COUNT
  1878. HOLDD    DB    86H    ;HOLD AREA - LAST DC HAYES CONT CHAR.
  1879. CURRMOD    DB    86H    ;CURRENT MODEM COMMAND BYTE
  1880. ;
  1881. ;FOLLOWING 3 USED BY DISK BUFFERING ROUTINES
  1882. EOFLG    DB    0    ;EOF FLAG (1=TRUE)
  1883. SECPTR    DW    DBUF
  1884. SECINBF    DB    0    ;# OF SECTORS IN BUFFER
  1885.     DS    60    ;STACK AREA
  1886. STACK    DS    2    ;STACK POINTER
  1887. ;
  1888. ;16 SECTOR DISK BUFFER (OVERLAYS HELP MSGS)
  1889. ;
  1890. DBUF    EQU    $    ;16 SECTOR DISK BUFFER
  1891. ;
  1892. ;INVALID COMMAND
  1893. ;
  1894. BADOPT    CALL    TYPE
  1895.     CALL    ILPRT    ;EXIT W/ERROR
  1896.     DB    ': INVALID OPTION ON MODEM '
  1897.     DB    'COMMAND - ',CR,LF
  1898.  DB 'PRESS RETURN FOR HELP, CTL-C IF NOT',CR,LF,1,0
  1899. ;
  1900. HELP    CALL    ILPRT
  1901.  DB 'Format for command is:',cr,lf,cr,lf
  1902.  DB 'MODEM ? FILENAME'
  1903.     IF    DCH
  1904.  DB ' PHONENUM'
  1905.     ENDIF
  1906.  DB CR,LF,CR,LF
  1907.  DB 'Where ? is a 1 character primary option,',cr,lf
  1908.  DB ' which may be followed by sub-options,',cr,lf
  1909.  DB ' and by ".xxx" to set baud rate to xxx.',CR,LF
  1910.  DB 'FILENAME is any valid CP/M unambiguous drive and filespec.',CR,LF
  1911.  DB ' It is used only for the "R" and "S" functions.',CR,LF
  1912.     IF    DCH
  1913.  DB 'PHONENUM is an optional parameter which if present',CR,LF
  1914.  DB ' is a telephone number to be automatically dialed.',CR,LF
  1915.  DB ' A "*" may be used to cause a 2 second pause in dialing.',CR,LF
  1916.  DB ' A "#" means to redial the last phone number attempted.',CR,LF
  1917.  DB ' All other characters are ignored.'
  1918.     ENDIF
  1919.  DB cr,lf,cr,lf,1
  1920.  DB 'Primary Options:',cr,lf
  1921.  DB '    S to send a file',cr,lf
  1922.  DB '    R to receive a file',cr,lf
  1923.  DB '    T to act as a terminal',cr,lf
  1924.  DB '    E to act as a computer (echo data)',cr,lf
  1925.  DB '    D to disconnect the phone'
  1926.  DB '    (S100 modems only)',cr,lf
  1927.  DB '    H to print this help file'
  1928.  DB cr,lf,cr,lf,1
  1929.  DB 'Secondary options:',cr,lf
  1930.  DB '    A answer mode',cr,lf
  1931.  DB '    O originate mode',cr,lf
  1932.  DB '    D disconnect after execution',cr,lf
  1933.  DB '    T go to terminal mode after file xfer',cr,lf
  1934.  DB '    E go to echo mode after file xfer',cr,lf
  1935.  DB '    Q quiet mode - no status msgs',cr,lf
  1936.  DB '    R show chars received',cr,lf
  1937.  DB '    S show chars sent',cr,lf
  1938.  DB '    V view file sent/received (no status)',cr,lf
  1939.  DB CR,LF,'FOR EXAMPLES, TYPE: MODEM X',cr,lf,0
  1940.     JMP    EXIT
  1941. ;
  1942. EXAM    CALL    ILPRT
  1943.  DB 'Send file, originate mode, 300 baud:',CR,LF
  1944.  DB '    MODEM SO fn.ft',cr,lf
  1945.  DB 'Send another file:',CR,LF
  1946.  DB '    MODEM S fn.ft',cr,lf
  1947.  DB 'Then send a third file at 450 baud and disconnect:'
  1948.  DB CR,LF,'    MODEM SD.450 fn.ft',cr,lf
  1949.  DB 'Act as a terminal, originate mode, at 110 baud:',cr,lf
  1950.  DB '    MODEM TO.110',CR,LF
  1951.  DB '    (Use ctl-D to disconnect)',cr,lf
  1952.  DB 'Receive file, answer mode, view it, 600 baud:',cr,lf
  1953.  DB '    MODEM RAV.600 fn.ft',cr,lf,0
  1954. JMP EXIT
  1955. ;
  1956. ;
  1957.     DS    128-($ AND 127)    ;FORCE NEXT SECTOR BOUNDARY
  1958. DIALBUF    EQU    $    ;STORAGE FOR NUMBER BEING DIALED
  1959. ;
  1960. ;
  1961. ; BDOS EQUATES (VERSION 2)
  1962. ;
  1963. RDCON    EQU    1
  1964. WRCON    EQU    2
  1965. PRINT    EQU    9
  1966. CONST    EQU    11    ;CONSOLE STAT
  1967. OPEN    EQU    15    ;0FFH=NOT FOUND
  1968. CLOSE    EQU    16    ;    "    "
  1969. SRCHF    EQU    17    ;    "    "
  1970. SRCHN    EQU    18    ;    "    "
  1971. ERASE    EQU    19    ;NO RET CODE
  1972. READ    EQU    20    ;0=OK, 1=EOF
  1973. WRITE    EQU    21    ;0=OK, 1=ERR, 2=?, 0FFH=NO DIR SPC
  1974. MAKE    EQU    22    ;0FFH=BAD
  1975. REN    EQU    23    ;0FFH=BAD
  1976. STDMA    EQU    26    ;SET DMA
  1977. BDOS    EQU    BASE+5
  1978. REIPL    EQU    BASE
  1979. FCB    EQU    BASE+5CH    ;SYSTEM FCB
  1980. FCBEXT    EQU    FCB+12        ;FILE EXTENT
  1981. FCBSNO    EQU    FCB+32        ;SECTOR #
  1982. FCB2    EQU    BASE+6CH    ;SECOND FCB
  1983.     END
  1984.