home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol008 / modem5a.asm < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  45.7 KB  |  2,059 lines

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