home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol065 / modem76.asm < prev    next >
Assembly Source File  |  1984-04-29  |  70KB  |  3,434 lines

  1.  
  2.     TITLE    'CP/M MODEM PROGRAM Version 7.6'
  3. ;
  4. ;THE FOLLOWING IS AN EXTENSIVE REVISION OF THE CP/M MODEM PROGRAM
  5. ;CREATED BY WARD CHRISTENSEN FOR THE CP/M USERS LIBRARY.
  6. ;IT ALSO INCORPORATES ROUTINES FOUND IN THE POTOMAC MICRO-MAGIC MODEM
  7. ;MANUAL WHICH MAY BE USED IF YOU HAVE A PMMI MODEM BOARD.
  8.  
  9. ;4/12/82  Merged in changes/enhancements from versions 7.32
  10. ;and 7.4 and MODEM75.FIX.  This should hopefully give us one
  11. ;"master" version again.  B. R. Ratoff
  12. ;Summary:
  13. ; @7.32 - Delay loop at DILAGN1 to allow "smart" terminals time
  14. ;         to process bell character.
  15. ;
  16. ; @MODEM75.FIX - Maintain originate mode on RET command after
  17. ;         transferring files (at TERM:).  Restore option tables correctly
  18. ;         on control-D command (at DIR).  Issue "file open" message on
  19. ;         receive (at RCVC3).
  20. ; @7.41 - Make CRC/checksum switching on Receive automatic....
  21. ;         assumes CRC and defaults to checksum on timeout.
  22. ;
  23.  
  24. ;2/20/82  Changes at TERM and START1 marked by ; @7.5 fix a
  25. ;long standing bug in MODEM7x that causes abort at the end of a
  26. ;batch file transfer or an attempt to transfer a non-existent
  27. ;file.  The call to NOPARIT in DONETCE caused a computer that was
  28. ;in answer mode (but not explicitly by command option) to switch
  29. ;to originate mode thus causing the two ends to no longer communicate
  30. ;with each other.  Also added SAVCCP byte and code to prevent
  31. ;overwriting of the CCP at the users option.       R. L. Plouffe 
  32.  
  33. ;1/23/82  The following changes have been made in this version.
  34. ;                            RLP
  35. ;Extensive cleanup of the file including colons after all labels
  36. ;for easier search with screen editor for the purposes of debug.
  37. ;Also set file capture mode so as not to overwite the CCP and
  38. ;changed EXIT to return to the CCP instead of doing warm boot.
  39. ;
  40. ;TERML routine fix:
  41. ;Added Rick Kawala's fix so that fewer framing errors will occur
  42. ;with hosts that send out characters with high bit set.
  43. ;
  44. ;CAL command fix:
  45. ;   All versions of MODEM7 including MODEM73 are supposed to be
  46. ;able to accept "CAL n" (where n is either a library letter or
  47. ;a phone-number string) as a valid form of the CAL command.  In
  48. ;fact, however, the "n" will simply be ignored.  This is because
  49. ;routine DIALPL checks for a command length >= 4 as a signal to
  50. ;skip the library display, but the menu routine, after
  51. ;recognizing CAL, sets the length to 1 so the L in CAL doesn't
  52. ;look like an illegal secondary option.
  53. ;   The following kludge repairs this defect.  In routine
  54. ;DIALPL, two lines above label DIALPL0, change CMDBUF+5 to
  55. ;CMDBUF+6.  Also, in routine GETCMD, three lines above label
  56. ;NXTOPT2, change MVI A,1 to MVI A,20H and change the next line
  57. ;from STA CMDBUF+1 to STA CMDBUF+4.  This makes the command
  58. ;look to the option processor like "CA  n", and since A is a
  59. ;legal secondary option (which in this case is never used) the
  60. ;line passes muster.  If an actual telephone number is used,
  61. ;you have to type an extra blank: CAL  000-0000, whereas
  62. ;with library numbers one blank only must be typed: CAL A.
  63.  
  64. ;12/16/81 Removed stack imbalance bug at COLONB by adding
  65. ;      a JMP BRK1. Change is marked by ;@   R. L. Plouffe
  66.  
  67. ;11/21/81  Fixed code so byte received is on same line when
  68. ;       messages "XXH RCD, NOT SOH" or "XXH RCD, NOT ACK"
  69. ;          are displayed. Also changed stack size to 50H.
  70. ;       (P.L.Kelley)
  71.  
  72. ;10/29/81 Changed receive sector routine so that on the first
  73. ;time through when CRC is being used, it only waits 3 seconds
  74. ;to receive the SOH after sending the initial 'C'.  If a
  75. ;character is not received within 3 seconds, then a NAK is
  76. ;sent and this program switches to CHECKSUM mode.  The sending
  77. ;of the NAK causes XMODEM or MODEM to start sending the file
  78. ;using checksum checking.  This allows the CRC MODEM7 program
  79. ;to be used with versions of XMODEM, MODEM, and MODEM7 that
  80. ;do not use CRC, even when MODEM7 has specified a CRC
  81. ;transmission. (John Mahr)
  82.  
  83. ;10/18/81 Added CRC option. This is another secondary option
  84. ;that is specified by giving a 'C'.
  85. ;    MODEM RC.600 fn.ft
  86. ;    MODEM ROC.300 fn.ft etc.
  87. ;    note: cannot have more than 6 secondary options.
  88. ;When the file receive cmd. specifies CRC, the ltr. 'C' is
  89. ;sent in place of the initial NAK. This signals the sender
  90. ;(XMODEM54 or equiv.) that CRC is in effect. The sending 
  91. ;program will repalce the checksum with the CRC 2 bytes.
  92. ;CRC will give better than a 99.99% probability that there
  93. ;are no data errors. Code copied from MODEM213, thanks to
  94. ;John Mahr and Paul Hansknecht for the implementation. (WDE)
  95.  
  96. ;10/11/81 Add first NAK to RCVFIL to speed up start
  97. ;Removed monitor scroll from good block messages
  98. ;CTL-^ forces send of next char in T mode (for ctl-E,ctl-D) (WDE)
  99.  
  100. ;07/05/81 Added BRR ctrl char chgs, my number list (Bill Earnest)
  101.  
  102. ;06/05/81 Deleted some unneeded messages in the dial routines. (Bob Clyne)
  103.  
  104. ;05/31/81 Added detection of framing, overrun, and parity errors for
  105. ;      Receive file routine. (A modified version of the routines in
  106. ;      MODEM V2.06)
  107.  
  108. ;      Added provisions to send and receive either even or odd parity
  109. ;      bit with PMMI modem in the 'S'end or 'R'eceive file modes - resets
  110. ;      to no parity in other modes. Use of the parity feature will slow
  111. ;      transfers slightly due to the extra (parity) bit being sent with
  112. ;      each character. Also this is the only program that I KNOW OF that
  113. ;      actually sends, or sets up the PMMI to receive, the parity bit.
  114. ;      Both ends must be set to the same parity for it to work. Parity
  115. ;      is invoked by adding a '0' (ASCII) for even parity or a '1' (ASCII)
  116. ;      for odd parity to the 'S'end or 'R'eceive command string eg. R0.600.
  117.  
  118. ;      Changed timing for sending 'B'reak in the terminal mode.
  119.  
  120. ;      Changed the code so that the 'M'enu command works from the keyboard
  121. ;      even when in XPR (expert) mode.
  122.  
  123. ;      Added display of hex in addition to decimal numbers for file length
  124. ;      and sector numbers.
  125.  
  126. ;      Removed provision for remote cancel of file transfers in the 'S'end
  127. ;      and 'R'eceive modes to prevent line noise from aborting a transfer.
  128. ;      (Bob Clyne)
  129.  
  130.  
  131. ;02/15/81 Patched in the ringback routines from DIAL6/23. It doesn't
  132. ;      seem to be able to recognize when the other phone is ringing
  133. ;      though so it is a little shakey.
  134.  
  135. ;      Put in routines to calculate file sizes and sector numbers in
  136. ;      decimal.
  137.  
  138. ;      Put in code to transmit a "BREAK" with a PMMI for use with
  139. ;      computers which use BREAK instead of Control S to suspend
  140. ;      output. Control P is now the baudrate change request key
  141. ;      and Control @ is the BREAK key.. (Bob Clyne)
  142.  
  143.  
  144. ;12/18/80 Changed disconnect timing.
  145.  
  146. ;10/26/80  Minor revision to allow 25-second 'wait' after PMMI
  147. ;       autodial -- longer time required for Chicago CBBS*.  Jim Mills.
  148. ;       * CBBS is a trademark of Ward Christensen and Randy Suess.
  149.  
  150.     MACLIB MODEM7    ;CONTAINS CMDLINE, INBUF, INLNCOMP,
  151.         ;DIR, AND MFACCESS ROUTINES
  152.         ;changed to MODEM.LIB by Jim Mills
  153.         ;to differentiate from other 'MACROS.LIB'
  154.  
  155.  
  156. TRUE    EQU 0FFH
  157. FALSE    EQU 0
  158.  
  159. CPM2X        EQU TRUE ;true if CP/M 2.X
  160. DBUFSIZ        EQU 16     ;BUFFER SIZE IN KBYTES
  161.  
  162. ; PMMI EQUATES
  163.  
  164. PORT    EQU    0C0H    ;PMMI BASE ADDRESS
  165.  
  166. MODCTLP    EQU    PORT    ;MODEM CONTROL PORT
  167. MODSNDB    EQU    1    ;MODEM SEND BIT (XMIT BUFF EMPTY)
  168. MODSNDR    EQU    1    ;MODEM SEND READY
  169. MODRCVB    EQU    2    ;MODEM RECEIVE BIT (DAV)
  170. MODRCVR    EQU    2    ;MODEM RECEIVE READY
  171. MODDATP    EQU    PORT+1    ;MODEM DATA PORT
  172. BAUDRP    EQU    PORT+2    ;BAUD RATE PORT
  173. MODCTL2    EQU    PORT+3    ;2ND MODEM CONTROL PORT
  174. ORIGMOD    EQU    1DH    ;ORIGINATE MODE
  175. ANSWMOD    EQU    1EH    ;ANSWER MODE
  176. BRKMSK    EQU    0FBH    ;MASK TO SET BREAK
  177. FRMER    EQU    20H    ;FRAMING ERROR MASK
  178. ORUNER    EQU    10H    ;OVERRUN ERROR MASK
  179. PARER    EQU    08H    ;PARITY ERROR MASK
  180. ODPARMSK EQU    0CFH    ;MASK TO SET ODD PARITY
  181. EVPARMSK EQU    20H    ;MASK TO SET EVEN PARITY
  182. NOPARMSK EQU    10H    ;MASK TO RESET TO NO PARITY
  183. ERRCDMSK EQU    38H    ;MASK FOR ALL BITS EXCEPT ERROR CODES
  184.  
  185. WAITCTS    EQU    255    ;number of seconds X 10 to wait for computer
  186.             ;tone after pmmi auto-dial function, 255 MAX.
  187.  
  188. CHGBAUD    EQU 'P'-40H    ;USED IN TERMINAL MODE TO CHANGE
  189.             ;BAUD RATE 'ON THE FLY'
  190. ERRLIM    EQU 10        ;NUMBER OF TIMES TO RETRY
  191.             ;SEND/RECEIVE ERRORS BEFORE QUIT
  192. BRKCHR    EQU '@'-40H    ; ^@ = TRANSMIT "BREAK" WITH PMMI
  193. EXITCHR    EQU 'E'-40H    ; ^E = EXIT WITHOUT DISCONNECT
  194. DISCCHR    EQU 'D'-40H    ; ^D = DISCONNECT
  195. TRANCHR    EQU 'T'-40H    ; ^T = TRANSFER CHARACTER
  196. CAN    EQU 'X'-40H    ; ^X = CANCEL SEND/RECEIVE
  197. EOFCHAR    EQU 'Z'-40H    ; ^Z = END OF FILE
  198. SAVECHR    EQU 'Y'-40H    ; ^Y = SAVE CHARACTER
  199. XOFF    EQU 'S'-40H    ; ^S = XOFF CHARACTER
  200. XON    EQU 'Q'-40H    ; ^Q = XON CHARACTER
  201. EXTCHR    EQU '^'-40H    ; ^^ = SEND NXT CHR
  202. SOH    EQU 1        ; START OF HEADER
  203. EOT    EQU 4        ; END OF TEXT
  204. ACK    EQU 6        ; ACKNOWLEDGE
  205. NAK    EQU 15H        ; NOT ACKNOWLEDGE
  206. CRC    EQU 'C'        ;USED TO RQST CRC INSTEAD OF CLSUM
  207. BDNMCH    EQU 75H        ; BAD NAME MATCH
  208. OKNMCH    EQU ACK        ; OKAY NAME MATCH
  209. LF    EQU 10        ; LINEFEED
  210. CR    EQU 13        ; CARRIAGE RETURN
  211. BELL    EQU 7        ; BELL CHARACTER
  212. FRONTPAN EQU 0FFH    ; IMSAI FRONT PANEL
  213.  
  214. BOTTRAM    SET LAST+100H AND 0FF00H
  215.  
  216.     ORG 100H
  217.  
  218.     JMP    START
  219.  
  220. ;THESE ROUTINES ARE AT THE BEGINNING OF THE PROGRAM SO
  221. ;THEY CAN BE PATCHED BY A MONITER WITHOUT RE-ASSEMBLING
  222. ;THE PROGRAM.
  223.  
  224. PMMIBYTE:    DB  TRUE    ;true=pmmi modem
  225. IMSAIBYTE:    DB  FALSE    ;true=imsai front panel
  226. FASTCLK:    DB  TRUE    ;4 MHz or greater
  227. BAKUPBYTE:    DB  FALSE    ;true=make .BAK file
  228. XPRFLG:        DB  TRUE    ;true=no menu, false=print menu
  229. PULSERATE:    DB  125        ;125 FOR 20PPS, 250 FOR 10PPS dialing
  230. SAVCCP        DB  TRUE    ;true=do not overwrite CCP
  231. IN$MODCTLP:    IN  MODCTLP ! RET ;in modem control port
  232. OUT$MODDATP:    OUT MODDATP ! RET ;out modem data port
  233. ANI$MODSNDB:    ANI MODSNDB ! RET ;bit to test for send ready
  234. CPI$MODSNDR:    CPI MODSNDR ! RET ;value of send bit when ready
  235. IN$MODDATP:    IN  MODDATP ! RET ;in modem data port
  236. ANI$MODRCVB:    ANI MODRCVB ! RET ;bit to test for receive ready
  237. CPI$MODRCVR:    CPI MODRCVR ! RET ;value of receive bit when ready
  238. JMP$INITMOD:    JMP INITMOD      ;to initialize port, if necessary
  239. IN$BAUDRP:    IN  BAUDRP  ! RET ;in baudrate port
  240. OUT$BAUDRP:    OUT BAUDRP  ! RET ;out baudrate port
  241. OUT$MODCTL2:    OUT MODCTL2 ! RET ;out modem control port #2
  242. OUT$MODCTLP:    OUT MODCTLP ! STA UARTCTLB ! RET ;out modem control port
  243.                          ;and store control byte
  244.  
  245. CRFLAG:    DB 0    ;CONTINUOUS REDIAL FLAG
  246.  
  247. ; PHONE NUMBER LIBRARY TABLE FOR DIALING FROM LIBRARY
  248. ; OF NUMBERS STORED IN THESE DB'S AT ASSEMBLY-TIME.
  249. ; EACH DB MUST BE 30 CHARACTERS LONG FOR PROPER OPERATION.
  250. ; A 'DB 0' INDICATES NO DIALING, PROGRAM WILL DISCONNECT
  251. ; AND RETURN TO COMMAND MODE.  LAST DB MUST BE DB 0. UP TO
  252. ; 26 NUMBERS ARE ALLOWED.
  253.  
  254. NUMBLIB:
  255. ;    '----5---10---15---20---25---30'
  256. DB    'A=Amrad           703-734-1387'    ;'A'
  257. DB    'B=Ben Bronson     312-955-4493'    ;'B'
  258. DB    'C=                            '    ;'C'
  259. DB    'D=C.Cliff C.C.    312-234-9257'    ;'D'
  260. DB    'E=Ron Fowler     313-729-1905R'    ;'E'
  261. DB    'F=                            '    ;'F'
  262. DB    'G=Gasnet NASA     301-344-9156'    ;'G'
  263. DB    'H=Dave Hardy      313-846-6127'    ;'H'
  264. DB    'I=Wayne Hammerly  301-953-3753'    ;'I'
  265. DB    'J=                            '    ;'J'
  266. DB    'K=David Kozinn    216-334-4604'    ;'K'
  267. DB    'L=Program Store   202-337-4694'    ;'L'
  268. DB    'M=Kelly Smith     805-527-9321'    ;'M'
  269. DB    'N=                            '    ;'N'
  270. DB    'O=SYSOP Sys       313-885-0506'    ;'O'
  271. DB    'P=K.Petersen     313-759-6569R'    ;'P'
  272. DB    'Q=R.Plouffe       703-524-2549'    ;'Q'
  273. DB    'R=Bruce Ratoff    201-272-1874'    ;'R'
  274. DB    'S=                            '    ;'S'
  275. DB    'T=Tech. CBBS      313-846-6127'    ;'T'
  276. DB    'U=PMMI            703-379-0303'    ;'U'
  277. DB    'V=                            '    ;'V'
  278. DB    'W=                            '    ;'W'
  279. DB    'X=                            '    ;'X'
  280. DB    'Y=                            '    ;'Y'
  281. DB    'Z=                            '    ;'Z'
  282. DB    0                    ; end
  283.  
  284. START:    LXI    H,0
  285.     DAD    SP    ;GET CP/M'S STACK
  286.     SHLD    STACK    ;SAVE IT
  287.     LXI    SP,STACK ;START LOCAL STACK
  288.  
  289.     CALL    START1
  290.  
  291.     DB CR,LF,'MODEM 7.6 as of 4/12/82',cr,lf
  292.     DB 'Originally Written by Ward Christensen',cr,lf,'$'
  293.  
  294.  
  295. START1:    POP    D    ;GET ADDRESS OF ABOVE MESSAGE
  296.     MVI    C,PRINT    ; 9
  297.     CALL    BDOS
  298.  
  299.     CALL    INITADR    ;INITIALIZE ADDRESSES
  300.     MVI    A,TRUE    ; 0FFH
  301.     STA    NFILFLG
  302.     CMA        ; 0
  303.     STA    SAVEFLG
  304.     OUT    FRONTPAN ; IMSAI
  305.  
  306.     CALL    PROCOPT    ;PROCESS CONTROL OPTIONS
  307.     LDA    ORIGFLG    ; @7.5
  308.     ORA    A    ; @7.5 
  309.     MVI    A,ANSWMOD ; @7.5
  310.     STA    UARTCTLB  ; @7.5
  311.     JNZ    START2    ; @7.5
  312.     MVI    A,ORIGMOD ; @7.5
  313.     STA    UARTCTLB  ; @7.5
  314. START2:    LDA    OPTION    ;GET MAIN OPTION
  315.     CPI    'X'    ;EXPERT FLAG?
  316.     JNZ    RESTART    ;NO
  317.     MVI    A,TRUE    ;YES
  318.     STA    XPRFLG    ;MAKE EXPERT
  319.     JMP    MENU
  320.  
  321. RESTART:
  322.     LDA    OPTION    ;GET MAIN OPTION
  323.     MOV    B,A    ;SAVE IT
  324.     LDA    PMMIBYTE ;PMMI?
  325.     ORA    A    ;SET FLAGS
  326.     MOV    A,B    ;GET OPTION BACK
  327.     JZ    S1    ;NOT PMMI
  328.     CPI    'C'    ;CALL (DIAL) FUNCTION?
  329.     JZ    DIALPL    ;YES, GO TO IT
  330.  
  331. S1:    CPI    ' '    ;NO OPTION SPEC'D?
  332.     JZ    MENU    ;TRUE, GO MENU
  333.     CPI    'M'    ;MENU ASKED FOR?
  334.     JZ    MENU2    ;YES, GO MENU
  335.     CALL    JMP$INITMOD
  336.     CALL    MOVEFCB
  337.     MVI    A,FALSE
  338.     STA    NFILFLG
  339.  
  340.     CALL    IN$MODDATP ;GOBBLE UP GARBAGE..
  341.     CALL    IN$MODDATP ;..CHARACTERS ON LINE
  342.  
  343.     LDA    OPTION    ;PROCESS MAIN OPTION
  344.     CPI    'E'    ;ECHO MODE?
  345.     JZ    TRMECHO    ;YES
  346.     CPI    'T'    ;TERMINAL MODE?
  347.     JZ    DSKSAVE    ;YES
  348.  
  349.     CPI    'S'    ;SEND A FILE?
  350.     JZ    SENDFIL    ;YES
  351.     CPI    'R'    ;RECEIVE A FILE?
  352.     JZ    RCVFIL    ;YES
  353.     CPI    'D'    ;DISCONNECT?
  354.     JZ    DISCON1    ;YES, DISCONNECT & GO MENU
  355.     JMP    MENU    ;NO OPTION SPEC'D, GO MENU
  356.  
  357. ;REVISED TERMINAL ROUTINE ALLOWING MEMORY SAVE
  358.  
  359. DSKSAVE:
  360.     LDA    NFILFLG    ;NEW FILE FLAG
  361.     CPI    TRUE    ;OFFH? (TRUE=NORMAL TERMINAL MODE)
  362.     JZ    TERM    ;YES
  363.     LDA    FCB+1    ;FIRST CHAR OF FILENAME
  364.     CPI    ' '    ;FILE SPEC'D
  365.     JNZ    GOODNM    ;YES, GOOD NAME
  366.     MVI    A,TRUE    ;0FFH
  367.     STA    NFILFLG    ;
  368.     OUT    FRONTPAN ;0FFH PORT FOR IMSAI FRONT PANEL
  369.     CMA        ; 0
  370.     STA    SAVEFLG    ;
  371.     JMP    TERM    ;
  372.  
  373. GOODNM:    CALL    ERASFIL
  374.     CALL    MOVE2
  375.     LXI    D,FCB3
  376.     MVI    C,MAKE
  377.     CALL    BDOS
  378.     LXI    D,FCB3
  379.     MVI    C,OPEN
  380.     CALL    BDOS
  381.     LXI    H,BOTTRAM
  382.     SHLD    HLSAVE
  383.     MVI    A,FALSE
  384.     STA    NFILFLG
  385.  
  386. TERM:
  387.     LDA    ORIGFLG    ; @7.5
  388.     sta    origsav    ; @MODEM75.FIX
  389.     ORA    A    ; @7.5 
  390.     MVI    A,ANSWMOD ; @7.5
  391.     STA    UARTCTLB  ; @7.5
  392.     JNZ    TERM2    ; @7.5
  393.     MVI    A,ORIGMOD ; @7.5
  394.     STA    UARTCTLB  ; @7.5
  395. TERM2:    CALL    STAT    ;KEYPRESS?
  396.     JZ    TERML    ;NO, CHECK LINE
  397.     CALL    KEYIN    ;GET CHAR FROM KBD
  398.     MOV    B,A    ;SAVE
  399.     LDA    EXACFL
  400.     ORA    A    ;EXACT?
  401.     MVI    A,0
  402.     STA    EXACFL    ;CLR FOR NEXT TIME
  403.     MOV    A,B    ;RESTORE
  404.     JNZ    NOTOG
  405.     CPI    EXITCHR    ;^E?
  406.     JZ    MENU    ;YES, RETURN TO MENU
  407.     CPI    DISCCHR    ;^D?
  408.     JZ    DISCON1    ;YES, DISCONNECT & RETURN TO MENU
  409.     CPI    EXTCHR    ;^^?
  410.     JZ    EXTFLG    ;YES, SET FLAG FOR NXT CHAR
  411.  
  412.     CPI    TRANCHR    ;TEST FOR TRANSFER REQUEST (^T)
  413.     CZ    TRANSFER ;SEND-A-FILE (BLIND SEND)
  414.     JZ    TERM    ;LOOP
  415.  
  416.     MOV    B,A
  417.     LDA    PMMIBYTE
  418.     ORA    A
  419.     MOV    A,B
  420.     JZ    S2
  421.     CPI    BRKCHR    ;BREAK?
  422.     JZ    BREAK
  423.     CPI    CHGBAUD
  424.     PUSH    PSW
  425.     PUSH    H
  426.     CZ    NEWBAUD
  427.     POP    H
  428.     POP    PSW
  429.     JZ    TERML
  430.  
  431. S2:    CPI    SAVECHR
  432.     JNZ    NOTOG
  433.     LDA    NFILFLG    ;DO NOT ALLOW SAVE IF..
  434.     CPI    TRUE    ;..THIS FLAG IS SET.
  435.     JZ    TERML
  436.     LDA    SAVEFLG
  437.     CMA
  438.     STA    SAVEFLG
  439.     JMP    TERML
  440.  
  441. EXTFLG:    MVI    A,TRUE
  442.     STA    EXACFL
  443.     JMP    TERML
  444.  
  445. NOTOG:    CALL    OUT$MODDATP
  446.  
  447. TERML:    CALL    IN$MODCTLP
  448.     CALL    ANI$MODRCVB
  449.     CALL    CPI$MODRCVR
  450.     JNZ    TERM
  451.     CALL    IN$MODDATP
  452.     ANI    7FH    ;STRIP PARITY
  453.     JZ    TERM        
  454.     CALL    TYPE
  455.     PUSH    PSW
  456.     LDA    SAVEFLG
  457.     CPI    FALSE
  458.     JZ    NOSAVE
  459.     POP    PSW
  460.     MOV    M,A
  461.     INX    H
  462.     SHLD    HLSAVE    ;MENU COMMAND DESTROYS HL-REG..
  463.         ;..GET HL WHEN ENTERING VIA 'RET' CMD.
  464.     MOV    B,A
  465.     LDA    IMSAIBYTE
  466.     ORA    A
  467.     MOV    A,B
  468.     JZ    COLON
  469.     CMA        ;FRONT PANEL SHOWS CHARS WHEN..
  470.     OUT    FRONTPAN ;..MEMORY SAVE IS ACTIVE.
  471.     JMP    NOCOLON
  472. COLON:    CPI    LF    ;IF NO FRONT PANEL, THEN..
  473.     JNZ    NOCOLON    ;..TYPE ":" AFTER EACH LINE FEED..
  474.     MVI    A,':'    ;..WHEN MEMORY SAVE ACTIVE.
  475.     CALL    TYPE
  476. NOCOLON:
  477.     LDA    7    ;CHECK TO SEE IF..
  478.     PUSH    PSW
  479.     LDA    SAVCCP
  480.     ORA    A
  481.     JZ    SUB1
  482.     POP    PSW
  483.     SBI    8    ;..PAGE BELOW CCP ..
  484. SUB1:    DCR    A    ;..OR BDOS HAS BEEN..
  485.     CMP    H    ;..REACHED AND DISKSAVE IS NEEDED.
  486.     CZ    INTDSKSV
  487.  
  488.     JMP    TERM
  489. NOSAVE:    POP    PSW
  490.     JMP    TERM
  491.  
  492. SAVEFLG:    DB FALSE
  493. LASTBYT1:    DB 0
  494. LASTBYT2:    DB 0
  495.  
  496. INTDSKSV:
  497.     MVI    A,XOFF    ;SEND A CTRL-S TO STOP..
  498.     CALL    OUT$MODDATP ;..REMOTE COMPUTER OUTPUT.
  499.  
  500.     MVI    D,0    ;D IS THE BUFFER COUNT
  501.     CALL    INMODEM    ;GET LAST BYTES SENT..
  502.     STA    LASTBYT1 ;..AFTER CTRL-S.
  503.     CALL    INMODEM    ;ADD MORE CALLS TO INMODEM..
  504.     STA    LASTBYT2 ;..AND STA LASTBYT# IF YOU ARE..
  505.             ;..LOSING BYTES WHEN MEMORY IS FULL.
  506.     PUSH    D
  507.     CALL    NUMREC1
  508.     CALL    WRTDSK    ;WRITE THE RECORDS
  509.     POP    D
  510.  
  511.     LXI    H,BOTTRAM
  512.     INR    D
  513.     DCR    D    ;TEST BUFFER COUNT FOR ZERO
  514.     JZ    CTRLQ
  515.     LDA    LASTBYT1 ;GET THE LAST BYTES THAT WERE..
  516.     MOV    M,A    ;..SAVED AND PUT THEM IN..
  517.     INX    H    ;..BOTTRAM.
  518.     CALL    TYPE
  519.     DCR    D
  520.     JZ    CTRLQ
  521.     LDA    LASTBYT2
  522.     MOV    M,A
  523.     INX    H
  524.     CALL    TYPE
  525.  
  526. CTRLQ:    MVI    A,XON    ;SEND START CHARACTER..
  527.     CALL    OUT$MODDATP ;..TO REMOTE COMPUTER.
  528.  
  529.     RET
  530.  
  531. BREAK:    PUSH    D    ;SAVE IT
  532.     LXI    D,0    ;ZERO IT
  533.     LDA    MODCTLB    ;GET THE LAST MODEM CONTROL BYTE
  534.     ANI    0FBH    ;SET THE TRANSMIT BREAK BIT LOW - ACTIVE LOW
  535.     CALL    OUT$MODCTL2 ;SEND IT TO THE MODEM
  536.     LDA    FASTCLK    ;GET FAST CLOCK FLAG
  537.     ORA    A    ;SET FLAGS
  538.     LXI    B,450    ;BREAK DELAY COUNTER FOR SLOW CLOCK
  539.     JZ    BRK1    ;JUMP IF NOT FAST CLOCK
  540.     LXI    B,900    ;BREAK DELAY COUNTER FOR FAST CLOCK
  541. BRK1:    CALL    TIMERL
  542.     JZ    BRK2    ;IF TIME IS UP RESET BREAK
  543.     CPI    0    ;CHECK FOR NULLS
  544.     JZ    BRK1    ;DON'T PROCESS THEM
  545.     ANI    7FH    ;STRIP PARITY
  546.     CALL    TYPE
  547.     PUSH    PSW
  548.     LDA    SAVEFLG
  549.     CPI    FALSE
  550.     JZ    NOSAVEB
  551.     POP    PSW
  552.     MOV    M,A
  553.     INX    H
  554.     SHLD    HLSAVE    ;MENU COMMAND DESTROYS HL-REG..
  555.         ;..GET    HL WHEN ENTERING VIA 'RET' CMD.
  556.     PUSH    D
  557.     MOV    D,A
  558.     LDA    IMSAIBYTE
  559.     ORA    A
  560.     MOV    A,D
  561.     POP    D
  562.     JZ    COLONB
  563.     CMA    ;FRONT    PANEL SHOWS CHARS WHEN..
  564.     OUT    FRONTPAN ;..MEMORY SAVE IS ACTIVE.
  565.     JMP    BRK1
  566. COLONB:    CPI    LF    ;IF NO FRONT PANEL, THEN..
  567.     JNZ    BRK1    ;..TYPE ":" AFTER EACH LINE FEED..
  568.     MVI    A,':'    ;..WHEN MEMORY SAVE ACTIVE.
  569.     CALL    TYPE
  570.     JMP    BRK1    ;@
  571. NOSAVEB: POP    PSW    ;RESTORE IT
  572.     JMP    BRK1
  573.  
  574. BRK2:    LDA    MODCTLB    ;GET MODEM CONTROL BYTE
  575.     CALL    OUT$MODCTL2
  576.     POP    D
  577.     LHLD    HLSAVE    ;LAST ADDRESS WRITTEN IF DATA BEING SAVED
  578.     LDA    7    ;CHECK TO SEE IF..
  579.     PUSH    PSW
  580.     LDA    SAVCCP
  581.     ORA    A
  582.     JZ    SUB2
  583.     POP    PSW
  584.     SBI    8    ;..PAGE BELOW CCP ..
  585. SUB2:    DCR    A    ;..OR BDOS HAS BEEN ..
  586.     CMP    H    ;..REACHED AND DISKSAVE IS NEEDED.
  587.     JNZ    TERM    ;NO PROBLEM - GO BACK TO NORMAL ROUTINE
  588.     CALL    ILPRT
  589. DB    CR,LF,'Memory save buffer full',CR,LF,BELL,0
  590.     JMP    TERM
  591.  
  592.  
  593. ;THIS SUBROUTINE WILL LOOP UNTIL THE MODEM RECEIVES A CHARACTER
  594. ;OR 100 MILLISECONDS. IF A CHARACTER IS RECEIVED, A FLAG IS SET
  595. ;TO STORE THE CHARACTER. A MAXIMUM OF TWO CHARACTERS ARE STORED,
  596. ;BUT MORE MAY BE STORED IF DESIRED (SEE COMMENT IN "INTDSKSV"
  597. ;ABOVE).
  598.  
  599. INMODEM:
  600.     LDA    FASTCLK
  601.     ORA    A
  602.     LXI    B,1250
  603.     JZ    TIMERL
  604.     LXI    B,2500
  605. TIMERL:    CALL    IN$MODCTLP
  606.     CALL    ANI$MODRCVB
  607.     CALL    CPI$MODRCVR
  608.     JZ    GETBYTE
  609.     DCX    B
  610.     MOV    A,B
  611.     ORA    C
  612.     JNZ    TIMERL
  613.     RET
  614. GETBYTE:
  615.     CALL    IN$MODDATP
  616.     INR    D
  617.     RET
  618.  
  619. NUMRECS:
  620.     MVI    M,EOFCHAR
  621.     INX    H
  622.     LXI    D,127
  623.     DAD    D
  624. NUMREC1:
  625.     LXI    D,-(BOTTRAM)
  626.     DAD    D
  627.  
  628.     MOV    A,L    ;DIVIDE HL BY 128..
  629.     ORA    A
  630.     RAL        ;..TO GET THE..
  631.     MOV    L,H    ;..NUMBER OF SECTORS
  632.     MVI    H,0
  633.     PUSH    PSW
  634.     DAD    H
  635.     POP    PSW
  636.     MVI    A,0
  637.     ADC    L
  638.     MOV    L,A    ;RETURNS WITH NUMBER OF..
  639.     RET        ;..128 BYTE RECORDS IN HL.
  640.  
  641. WRTDSK:    LXI    D,BOTTRAM
  642. NEXTWRT:
  643.     MVI    C,STDMA
  644.     CALL    BDOSRT
  645.     PUSH    D
  646.     LXI    D,FCB3
  647.     MVI    C,WRITE
  648.     CALL    BDOSRT
  649.     POP    D
  650.     XCHG
  651.     PUSH    D
  652.     LXI    D,128
  653.     DAD    D
  654.     POP    D
  655.     XCHG
  656.     DCX    H
  657.     MOV    A,H
  658.     ORA    L
  659.     JNZ    NEXTWRT
  660.     RET
  661.  
  662. CLOSE3:    LXI    D,FCB3
  663.     MVI    C,CLOSE
  664.     CALL    BDOS
  665.     RET
  666.  
  667. BDOSRT:    PUSH B ! PUSH D ! PUSH H ! PUSH PSW
  668.     CALL    BDOS
  669.     POP PSW ! POP H ! POP D ! POP B
  670.     RET
  671.  
  672. MOVE2:    LXI    H,FCB3
  673.     CALL    INITFCBS
  674.     LXI    H,FCB
  675.     LXI    D,FCB3
  676.     MVI    B,12
  677.     CALL    MOVE
  678.     RET
  679.  
  680. ;FILE TRANSFER ROUTINE - CALLED WITH 
  681. ;CONTROL-T FROM TERMINAL ROUTINE.
  682. ;TRANSFER MAY BE CANCELLED WHILE SENDING BY USING CONTROL-X.
  683.  
  684. TRANSFER:
  685.     PUSH H ! PUSH D ! PUSH B ! PUSH PSW
  686.     LXI    H,FCB4
  687.     CALL    INITFCBS ;INITIALIZES FCBS POINTED..
  688.     LXI    H,FCB+16 ;..TO BY HL REG.
  689.     CALL    INITFCBS
  690. GET:    CALL    GETNAME
  691.     LDA    CMDBUF+2 ;WAS FILE ENTERED
  692.     CPI    20H
  693.     JZ    TRANSL2
  694.     CALL    MOVE4
  695.     CALL    OPEN4
  696.     CPI    0FFH    ;RETURN WITH 0FFH MEANS
  697.     JNZ    CONTIN    ;FILE DOES NOT EXIST
  698. TRANSL1: CALL    ILPRT
  699. DB    CR,LF,'++File does not exist++',CR,LF,0
  700. TRANSL2: CALL ILPRT
  701. DB    'Type "R" to return to modem',CR,LF
  702. DB    'Type "A" to re-enter name: ',BELL,0
  703.     CALL    KEYIN
  704.     CALL    UCASE
  705.     CALL    TYPE    ;ECHO RESPONSE
  706.     CALL    CRLF
  707.     CPI    'A'
  708.     JZ    GET
  709.     CPI    'R'
  710.     JZ    RETURN
  711.     JMP    TRANSL2
  712.  
  713. CONTIN:    LXI    D,80H
  714.     MVI    C,STDMA
  715.     CALL    BDOS
  716. READMR:    CALL    READ80
  717.     CPI    1    ;END OF FILE
  718.     JZ    RETURNS
  719.     CPI    2    ;BAD READ
  720.     JZ    RETURNU
  721.     CALL    SEND80C
  722.     CPI    EOFCHAR    ;END OF FILE - OMIT IF OBJECT..
  723.     JZ    RETURNS    ;..CODE IS TO BE SENT.
  724.     CPI    CAN    ;CANCELLATION?
  725.     JZ    TRANCAN
  726.     JMP    READMR
  727. RETURNS:
  728.     CALL    ILPRT
  729. DB    CR,LF,'++File transfer completed++',CR,LF,BELL,0
  730.     JMP    RETURN
  731. RETURNU:
  732.     CALL    ILPRT
  733. DB    CR,LF,'++File transfer unsuccessful++',CR,LF,BELL,0
  734.     JMP    RETURN
  735. TRANCAN:
  736.     CALL    ILPRT
  737. DB    CR,LF,CR,LF,'++ Transfer cancelled ++',CR,LF,BELL,0
  738. RETURN:    POP PSW ! POP B ! POP D ! POP H
  739.     RET
  740.  
  741. INITFCBS:        ;ENTRY AT +2 WILL LEAVE..
  742.     MVI    M,0    ;..DRIVE NO. INTACT.
  743.     INX    H    ;WILL INITIALIZE AN FCB..
  744.     MVI    B,11    ;..POINTED TO BY HL-REG. FILLS 1ST POS
  745. LOOP10:    MVI    M,' '    ;..WITH 0, NEXT 11 WITH..
  746.     INX    H    ;..WITH BLANKS, AND LAST..
  747.     DCR    B    ;..21 WITH NULLS.
  748.     JNZ    LOOP10
  749.     MVI    B,21
  750. LOOP11:    MVI    M,0
  751.     INX    H
  752.     DCR    B
  753.     JNZ    LOOP11
  754.     RET
  755.  
  756. GETNAME: CALL ILPRT
  757. DB    CR,LF,'Enter file name to be transferred -  C/R TO QUIT: ',0
  758.     LXI    D,CMDBUF
  759.     CALL    INBUFF
  760.     CALL    CRLF
  761.     RET
  762.  
  763. MOVE4:    LXI    D,CMDBUF
  764.     LXI    H,FCB4
  765.     CALL    CPMLINE
  766.     RET
  767.  
  768. OPEN4:    LXI    D,FCB4
  769.     MVI    C,OPEN
  770.     CALL    BDOS
  771.     RET
  772.  
  773. READ80:    LXI    D,FCB4
  774.     MVI    C,READ
  775.     CALL    BDOS
  776.     RET
  777.  
  778. SEND80C:
  779.     MVI    B,80H
  780.     LXI    H,80H
  781. SENDCH1:
  782.     MOV    A,M
  783.     CALL    MODOUT
  784.     CPI    EOFCHAR
  785.     RZ
  786.     CALL    STAT    ;TEST TO SEE IF
  787.     ORA    A    ;CANCELLATION REQUESTED
  788.     JZ    SKIP12
  789.     CALL    KEYIN
  790.     CPI    CAN
  791.     RZ
  792. SKIP12:    INX    H
  793.     DCR    B
  794.     JNZ    SENDCH1
  795.     RET
  796.  
  797. MODOUT:    PUSH    PSW
  798. MODOUTL:
  799.     CALL    IN$MODCTLP
  800.     CALL    ANI$MODSNDB
  801.     CALL    CPI$MODSNDR
  802.     JNZ    MODOUTL
  803.     POP    PSW
  804.     CALL    OUT$MODDATP
  805.     CALL    TYPE
  806.     RET
  807.  
  808. FCB4:    DS    33
  809.  
  810. ;TERMINAL ECHO MODE
  811.  
  812. TRMECHO:
  813.     CALL    IN$MODCTLP
  814.     CALL    ANI$MODRCVB
  815.     CALL    CPI$MODRCVR
  816.     JZ    LINECHR
  817.     CALL    STAT
  818.     JZ    TRMECHO
  819.     CALL    KEYIN
  820.     CPI    EXITCHR
  821.     JZ    MENU
  822.  
  823.     MOV    B,A
  824.     LDA    PMMIBYTE
  825.     ORA    A
  826.     MOV    A,B
  827.     JZ    S3
  828.     CPI    CHGBAUD    ;SAME ROUTINE AS IN TERMINAL MODE
  829.     PUSH    PSW
  830.     CZ    NEWBAUD
  831.     POP    PSW
  832.     CPI    CHGBAUD
  833.  
  834.     JZ    TRMECHO
  835. S3:    CALL    OUT$MODDATP
  836.     CALL    TYPE
  837.     JMP    TRMECHO
  838.  
  839. LINECHR:
  840.     CALL    IN$MODDATP
  841.     CALL    OUT$MODDATP
  842.     CALL    TYPE
  843.     JMP    TRMECHO
  844.  
  845.  
  846. ;        SEND A CP/M FILE
  847.  
  848. SENDFIL:
  849.     CALL    PARITY    ;SET PARITY IF REQUESTED
  850.     LDA    BATCHFLG ;CHECK IF MULTIPLE FILE..
  851.     ORA    A    ;..MODE IS SET.
  852.     JNZ    SENDC1
  853.     MVI    A,TRUE    ;INDICATE BATCH SEND
  854.     STA    SENDFLG
  855.     LDA    FSTFLG    ;IF FIRST TIME THRU..
  856.     ORA    A    ;..SCAN THE COMMAND LINE..
  857.     CNZ    TNMBUF    ;..FOR MULTIPLE NAMES.
  858.     CALL    SENDFN    ;SENDS FILE NAME TO RECEIVER
  859.     JNC    SENDC2    ;CARRY SET MEANS NO MORE FILES.
  860.     MVI    A,'B'    ;STOP BATCH..
  861.     STA    BATCHFLG ;..MODE OPTION.
  862.     MVI    A,EOT    ;FINAL XFER END
  863.     CALL    SEND
  864.     JMP    DONE
  865. SENDC1:    LDA    FCB+1
  866.     CPI    ' '
  867.     JZ    BLKFILE
  868. SENDC2:    CALL    CNREC    ;GET NUMBER OF RECORDS
  869.     CALL    OPENFIL
  870.     MVI    E,80
  871.     CALL    WAITNAK
  872. SENDLP:    CALL    RDSECT
  873.     JC    SENDEOF
  874.     CALL    INCRSNO
  875.     XRA    A
  876.     STA    ERRCT
  877. SENDRPT:
  878.     CALL    SENDHDR
  879.     CALL    SENDSEC
  880.     LDA    CRCFLG
  881.     ORA    A
  882.     CZ    SENDCRC
  883.     CNZ    SENDCKS
  884.     CALL    GETACK
  885.     JC    SENDRPT
  886.     JMP    SENDLP
  887.  
  888. SENDEOF:
  889.     MVI    A,EOT
  890.     CALL    SEND
  891.     CALL    GETACK
  892.     JC    SENDEOF
  893.     JMP    DONE
  894.  
  895. ;        RECEIVE A FILE
  896.  
  897. RCVFIL:    xra    a    ;@7.41 - default to CRC mode
  898.     sta    CRCFLG    ;@7.41
  899.     CALL    PARITY    ;SET PARITY IF REQUESTED
  900.     LDA    BATCHFLG ;CHECK IF MULT..
  901.     ORA    A    ;..FILE MODE.
  902.     JNZ    RCVC1
  903.     MVI    A,FALSE    ;FLAG WHERE TO RETURN..
  904.     STA    SENDFLG    ;..FOR NEXT FILE TRANS.
  905.     CALL    GETFN    ;GET THE FILE NAME.
  906.     JNC    RCVC2    ;CARRY SET MEANS NO MORE FILES.
  907.     MVI    A,'B'    ;STOP BATCH..
  908.     STA    BATCHFLG ;..MODE OPTION.
  909.     JMP    DONE
  910. RCVC1:    LDA    FCB+1    ;MAKE SURE FILE IS NAMED
  911.     CPI    ' '
  912.     JZ    BLKFILE
  913.     JMP    RCVC3
  914. RCVC2:    CALL    CKCPM2
  915.     CALL    CKBAKUP
  916. RCVC3:    CALL    ERASFIL
  917.     CALL    MAKEFIL
  918.     lda    batchflg;@75.FIX.................
  919.     ora    a    ;DON'T PRINT MSSG IF..
  920.     jnz    rcvc4    ;..IN MULTI AND QUIET.
  921.     lda    qflg
  922.     ora    a
  923.     jz    rcvfst
  924. rcvc4:    CALL    ILPRT    ;@75.FIX.................
  925. DB    'File open, ready to receive',CR,LF,0
  926. RCVFST:    LDA    CRCFLG
  927.     ORA    A
  928.     MVI    A,NAK
  929.     JNZ    RCVFIL2
  930.     MVI    A,CRC
  931. ;
  932. RCVFIL2:
  933.     CALL    SEND
  934.     lda    CRCFLG        ;@7.41...............................
  935.     ora    a
  936.     jnz    RCVNAKM        ;if in CRC mode
  937.     call    ILPRT        ;then say so
  938.     DB    'CRC in effect',cr,lf,0
  939.     jmp    RCVLP
  940. RCVNAKM:
  941.     call    ILPRT        ;else say checksum mode
  942.     DB    'Checksum in effect',cr,lf,0
  943.                 ;@7.41...............................
  944. RCVLP:    CALL    RCVSECT
  945.     JC    RCVEOT
  946.     CALL    WRSECT
  947.     CALL    INCRSNO
  948.     CALL    SENDACK
  949.     JMP    RCVLP
  950.  
  951. RCVEOT:    CALL    WRBLOCK
  952.     CALL    SENDACK
  953.     CALL    CLOSFIL
  954.     JMP    DONE
  955.     
  956. ;SUBROUTINES
  957.  
  958. SENDFN:    LDA    QFLG
  959.     ORA    A
  960.     JZ    SWNAK
  961.     CALL    ILPRT
  962. DB    'Awaiting name NAK',CR,LF,0
  963. SWNAK:    MVI    E,80
  964.     CALL    WAITNLP
  965.     MVI    A,ACK    ;GOT NAK, SEND ACK
  966.     CALL    SEND
  967.     LXI    H,FILECT
  968.     DCR    M
  969.     JM    NOMRNM
  970.     LHLD    NBSAVE    ;GET FILE NAME..
  971.     LXI    D,FCB    ;..IN FCB
  972.     MVI    B,12
  973.     CALL    MOVE
  974.     SHLD    NBSAVE
  975.     CALL    SENDNM    ;SEND IT
  976.     ORA    A    ;CLEAR CARRY
  977.     RET
  978. NOMRNM:    MVI A,EOT
  979.     CALL SEND
  980.     STC
  981.     RET
  982.  
  983. SENDNM:    PUSH    H
  984. SENDNM1:
  985.     MVI    D,11    ;COUNT CHARS IN NAME
  986.     MVI    C,0    ;INIT CHECKSUM
  987.     LXI    H,FCB+1    ;ADDRESS NAME
  988. NAMLPS:    MOV    A,M    ;SEND NAME
  989.     ANI    7FH    ;STRIP HIGH ORDER BIT SO CP/M 2..
  990.     CALL    SEND    ;..WON'T SEND R/O FILE DESIGNATION.
  991.     LDA    QFLG    ;SHOW NAME IF..
  992.     ORA    A    ;..QFLG NOT SET.
  993.     MOV    A,M
  994.     CNZ    TYPE
  995. ACKLP:    PUSH    B    ;SAVE CKSUM
  996.     MVI    B,1    ;WAIT FOR RECEIVER..
  997.     CALL    RECV    ;..TO ACKNOWLEDGE..
  998.     POP    B    ;..GETTING LETTER.
  999.     JC    SCKSER
  1000.     CPI    ACK
  1001.     JNZ    ACKLP
  1002.     INX    H    ;NEXT CHAR
  1003.     DCR    D
  1004.     JNZ    NAMLPS
  1005.     MVI    A,EOFCHAR ;TELL RECEIVER END OF NAME
  1006.     CALL    SEND
  1007.     LDA    QFLG
  1008.     ORA    A
  1009.     CNZ    CRLF
  1010.     MOV    D,C    ;SAVE CHECKSUM
  1011.     MVI    B,1
  1012.     CALL    RECV    ;GET CHECKSUM..
  1013.     CMP    D    ;..FROM RECEIVER.
  1014.     JZ    NAMEOK
  1015. SCKSER:    MVI    A,BDNMCH ;BAD NAME-TELL RECEIVER
  1016.     CALL    SEND
  1017.     LDA    QFLG
  1018.     ORA    A
  1019.     JZ    SKCSER1
  1020.     CALL    ILPRT
  1021. DB    'Checksum error',CR,LF,0
  1022. SKCSER1:
  1023.     MVI    E,80    ;DO HANDSHAKING OVER
  1024.     CALL    WAITNLP    ;DON'T PRINT "AWAITING NAK" MSG
  1025.     MVI    A,ACK
  1026.     CALL    SEND
  1027.     JMP    SENDNM1
  1028. NAMEOK:    MVI    A,OKNMCH ;GOOD NAME-TELL RECEIVER
  1029.     CALL    SEND
  1030.     POP    H
  1031.     RET    
  1032.  
  1033. GETFN:    LXI    H,FCB
  1034.     CALL    INITFCBS+2 ;DOES NOT INITIALIZE DRIVE
  1035.     LDA    QFLG
  1036.     ORA    A
  1037.     JZ    GNAMELP
  1038.     CALL    ILPRT
  1039. DB    'Awaiting file name',CR,LF,0
  1040. GNAMELP:
  1041.     CALL    HSNAK
  1042.     JC    GNAMELP
  1043.     CALL    GETNM    ;GET THE NAME
  1044.     CPI    EOT    ;IF EOT, THEN NO MORE FILES
  1045.     JZ    NOMRNMG
  1046.     ORA    A    ;CLEAR CARRY
  1047.     RET
  1048. NOMRNMG:
  1049.     STC
  1050.     RET
  1051.  
  1052. GETNM:    PUSH    H
  1053. GETNM1:    MVI    C,0    ;INIT CHECKSUM
  1054.     LXI    H,FCB+1
  1055. NAMELPG:
  1056.     MVI    B,5
  1057.     CALL    RECV    ;GET CHAR
  1058.     JNC    GETNM3
  1059.     LDA    QFLG
  1060.     ORA    A
  1061.     JZ    GETNM2
  1062.     CALL    ILPRT
  1063. DB    'Time out receiving filename',CR,LF,0
  1064. GETNM2:    JMP    GCKSER
  1065. GETNM3:    CPI    EOT    ;IF EOT, THEN NO MORE FILES
  1066.     JZ    GNRET
  1067.     CPI    EOFCHAR    ;GOT END OF NAME
  1068.     JZ    ENDNAME
  1069.     MOV    M,A    ;PUT NAME IN FCB
  1070.     LDA    QFLG    ;TYPE IT IF NO QFLG
  1071.     ORA    A
  1072.     MOV    A,M
  1073.     CNZ    TYPE
  1074.     PUSH    B    ;SAVE CKSUM
  1075.     MVI    A,ACK    ;ACK GETTING LETTER
  1076.     CALL    SEND
  1077.     POP    B
  1078.     INX    H    ;GET NEXT CHAR
  1079.     MOV    A,L    ;DON'T LET NOISE...
  1080.     CPI    7FH    ;..CAUSE OVERFLOW..
  1081.     JZ    GCKSER    ;..INTO PROGRAM AREA.
  1082.     JMP    NAMELPG
  1083. ENDNAME:
  1084.     LDA    QFLG
  1085.     ORA    A
  1086.     CNZ    CRLF
  1087.     MOV    A,C    ;SEND CHECKSUM
  1088.     CALL    SEND
  1089.     MVI    B,1
  1090.     CALL    RECV    ;CHECKSUM GOOD?
  1091.     CPI    OKNMCH    ;YES IF OKNMCH SENT..
  1092.     JZ    GNRET    ;..ELSE DO OVER.
  1093. GCKSER:    LXI    H,FCB    ;CLEAR FCB (EXCEPT DRIVE)..
  1094.     CALL    INITFCBS+2 ;..SINCE IT MIGHT BE DAMAGED..
  1095.     LDA    QFLG    ;..BY TOO MANY CHARS.
  1096.     ORA    A
  1097.     JZ    GCKSER1
  1098.     CALL    ILPRT
  1099. DB    'Checksum error',CR,LF,0
  1100. GCKSER1:
  1101.     CALL    HSNAK    ;DO HANDSHAKING OVER
  1102.     JC    GCKSER1
  1103.     JMP    GETNM1
  1104. GNRET:    POP    H
  1105.     RET
  1106.  
  1107. HSNAK:    MVI    A,NAK    ;SEND NAK UNTIL..
  1108.     CALL    SEND    ;..RECEIVING ACK.
  1109.     CALL    CKABORT    ;DON'T GET HUNG UP HERE
  1110.     MVI    B,2    ;WAIT 2 SECONDS..
  1111.     CALL    RECV    ;..IN RECEIVE.
  1112.     CPI    ACK    ;IF ACK,RETURN WITH..
  1113.     RZ        ;..CARRY CLEAR.
  1114.     STC
  1115.     RET
  1116.  
  1117. TNMBUF:    MVI    A,FALSE    ;CALL FROM SENDFIL ONLY ONCE.
  1118.     STA    FSTFLG
  1119.     STA    FILECT
  1120.     CALL    SCAN
  1121.     LXI    H,NAMEBUF
  1122.     SHLD    NBSAVE    ;SAVE ADDR OF 1ST NAME
  1123. TNLP1:    CALL    TRTOBUF
  1124.     LXI    H,FCB
  1125.     LXI    D,FCBBUF
  1126.     CALL    CPMLINE    ;PARSE NAME TO CP/M FORMAT
  1127. TNLP2:    CALL    MFNAME    ;SEARCH FOR NAMES (* FORMAT)
  1128.     JC    NEXTNM
  1129.     LDA    FCB+10    ;IF CP/M 2 $SYS FILE..
  1130.     ANI    80H    ;..DON'T SEND
  1131.     JNZ    TNLP2
  1132.     LHLD    NBSAVE    ;GET NAME
  1133.     LXI    D,FCB    ;MOVE IT TO FCB
  1134.     XCHG
  1135.     MVI    B,12
  1136.     CALL    MOVE
  1137.     XCHG
  1138.     SHLD    NBSAVE    ;ADDR OF NEXT NAME
  1139.     LXI    H,FILECT    ;COUNT FILES FOUND
  1140.     INR    M
  1141.     JMP    TNLP2
  1142. ;
  1143. NEXTNM:    LXI    H,NAMECT ;COUNT NAMES FOUND
  1144.     DCR    M
  1145.     JNZ    TNLP1
  1146.     LXI    H,NAMEBUF ;SAVE START OF BUFFER
  1147.     SHLD    NBSAVE
  1148.     LDA    FILECT
  1149.     CPI    65    ;NO MORE THAN 64 TRANSFERS
  1150.     RC
  1151.     MVI    A,64    ;ONLY X'FER FIRST 64
  1152.     STA    FILECT
  1153.     RET
  1154.  
  1155. ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE)
  1156. ;AFTER LAST NAME
  1157.  
  1158. SCAN:    PUSH    H
  1159.     LXI    H,NAMECT
  1160.     MVI    M,0
  1161.     LXI    H,CMDBUF+1 ;FIND END OF CMD LINE..
  1162.     MOV    C,M    ;..AND PUT SPACE THERE.
  1163.     MVI    B,0
  1164.     LXI    H,CMDBUF+2
  1165.     DAD    B
  1166.     MVI    M,20H
  1167.     LXI    H,CMDBUF+1
  1168.     MOV    B,M
  1169.     INR    B
  1170.     INR    B
  1171. SCANLP1:
  1172.     INX    H
  1173.     DCR    B
  1174.     JZ    DNSCAN
  1175.     MOV    A,M
  1176.     CPI    20H
  1177.     JNZ    SCANLP1
  1178. SCANLP2:
  1179.     INX    H    ;EAT EXTRA SPACES
  1180.     DCR    B
  1181.     JZ    DNSCAN
  1182.     MOV    A,M
  1183.     CPI    20H
  1184.     JZ    SCANLP2
  1185.     SHLD    BGNMS    ;SAVE START OF NAMES IN CMDBUF
  1186.     INR    B
  1187.     DCX    H
  1188. SCANLP3:
  1189.     INX    H
  1190.     DCR    B
  1191.     JZ    DNSCAN
  1192.     MOV    A,M
  1193.     CPI    20H
  1194.     JNZ    SCANLP3
  1195.     LDA    NAMECT    ;COUNTS NAMES
  1196.     INR    A
  1197.     STA    NAMECT
  1198. SCANLP4:
  1199.     INX    H    ;EAT SPACES
  1200.     DCR    B
  1201.     JZ    DNSCAN
  1202.     MOV    A,M
  1203.     CPI    20H
  1204.     JZ    SCANLP4
  1205.     JMP    SCANLP3
  1206. ;
  1207. DNSCAN:    MVI    M,20H    ;SPACE AFTER LAST CHAR
  1208.     POP    H
  1209.     RET
  1210.  
  1211. ;PLACES NEXT NAME IN BUFFER SO CPMLINE MAY PARSE IT
  1212. TRTOBUF:
  1213.     LHLD    BGNMS
  1214.     MVI    B,0
  1215.     LXI    D,FCBBUF+2
  1216. TBLP:    MOV    A,M
  1217.     CPI    20H
  1218.     JZ    TRBFEND
  1219.     STAX    D
  1220.     INX    H
  1221.     INX    D
  1222.     INR    B    ;COUNT CHARS IN NAME
  1223.     JMP    TBLP
  1224. ;
  1225. TRBFEND:
  1226.     INX    H
  1227.     MOV    A,M    ;EAT EXTRA SPACES
  1228.     CPI    20H
  1229.     JZ    TRBFEND
  1230.     SHLD    BGNMS
  1231.     LXI    H,FCBBUF+1 ;PUT # CHARS BEFORE NAME
  1232.     MOV    M,B
  1233.     RET
  1234.  
  1235. ;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'.
  1236. CKCPM2:    MVI    C,12
  1237.     CALL    BDOS
  1238.     ORA    A    ;RETURN 0 MEANS CP/M 1
  1239.     RZ
  1240.     MVI    C,STDMA
  1241.     LXI    D,80H
  1242.     CALL    BDOS
  1243.     MVI    C,SRCHF    ;SEARCH FOR FILE
  1244.     LXI    D,FCB
  1245.     CALL    BDOS
  1246.     CPI    0FFH
  1247.     RZ
  1248.     ADD A ! ADD A    ;MULT A-REG BY..
  1249.     ADD A ! ADD A    ;..32 TO FIND..
  1250.     ADD    A    ;..NAME IN DMA.
  1251.     LXI    H,80H
  1252.     ADD    L
  1253.     MOV    L,A    ;HL POINTS TO DIR NAME
  1254.     LXI    D,9
  1255.     DAD    D    ;POINT TO R/O ATTRIB BYTE
  1256.     MOV    A,M
  1257.     ANI    80H    ;TEST MSB
  1258.     JNZ    MKCHG    ;IF SET, MAKE CHANGE
  1259.     INX    H    ;CHECK SYSTEM ATTRIB BYTE
  1260.     MOV    A,M
  1261.     ANI    80H
  1262.     RZ        ;NOT $SYS OR $R/O
  1263.     DCX    H
  1264. MKCHG:    LXI    D,-8
  1265.     DAD    D    ;POINT HL TO FILENAME + 1
  1266.     LXI    D,FCB+1    ;MOVE DIR NAME TO FCB..
  1267.     MVI    B,11    ;..WITHOUT CHANGING DRIVE.
  1268.     CALL    MOVE
  1269.     LXI    H,FCB+9    ;R/O ATTRIB
  1270.     MOV    A,M
  1271.     ANI    7FH    ;STRIP R/O ATTRIB
  1272.     MOV    M,A
  1273.     INX    H    ;SYS ATTRIB
  1274.     MOV    A,M
  1275.     ANI    7FH
  1276.     MOV    M,A
  1277.     LXI    D,FCB
  1278.     MVI    C,30    ;SET NEW ATTRIBS IN DIR
  1279.     CALL    BDOS
  1280.  
  1281. ;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE
  1282. PLANCHG:
  1283.     LXI    H,FCB    ;CHANGE NAME TO TYPE "BAK"
  1284.     LXI    D,6CH
  1285.     MVI    B,9    ;MOVE DRIVE AND NAME (NOT TYPE)
  1286.     CALL    MOVE
  1287.     LXI    H,75H    ;START OF TYPE IN FCB2
  1288.     MVI    M,'B'
  1289.     INX    H
  1290.     MVI    M,'A'
  1291.     INX    H
  1292.     MVI    M,'K'
  1293.     LXI    D,6CH
  1294.     MVI    C,ERASE    ;ERASE ANY PREV BACKUPS
  1295.     CALL    BDOS
  1296.     LXI    H,6CH    ;FCB2 DR FIELD SHOULD..
  1297.     MVI    M,0    ;..0 FOR RENAME.
  1298.     LXI    D,FCB
  1299.     MVI    C,23    ;RENAME
  1300.     CALL    BDOS
  1301.     RET
  1302.  
  1303. CKBAKUP:
  1304.     LDA    BAKUPBYTE
  1305.     ORA    A
  1306.     RZ
  1307.     MVI    C,SRCHF
  1308.     LXI    D,FCB
  1309.     CALL    BDOS
  1310.     INR    A
  1311.     RZ    ;FILE NOT FOUND
  1312.     JMP    PLANCHG    ;IN "CKCPM2" - RET DONE THERE
  1313.  
  1314. ;MULTI-FILE ACCESS SUBROUTINE FROM CP/M USER'S GROUP
  1315. ;FIXED BY MARK ZEIGER 8/17/80
  1316. ;CARRY IS SET IF NO MORE NAMES CAN BE FOUND
  1317.  
  1318. MFNAME:    MFACCESS    ;A MACRO IN MACROS.LIB
  1319.  
  1320. RCVSECT:
  1321.     XRA    A
  1322.     STA    ERRCT
  1323. RCVRPT:    XRA    A    ;ZERO ACCUM
  1324.     STA    ERRCDE    ;CLEAR RECEIVE ERROR CODE
  1325.     LDA    QFLG
  1326.     ORA    A
  1327.     JZ    RCVSQ
  1328.     CALL    ILPRT
  1329. DB    CR,'Awaiting # ',0
  1330.     PUSH    H    ;SAVE IT
  1331.     LHLD    SECTNO    ;GET SECTOR NUMBER
  1332.     INX    H    ;BUMP IT
  1333.     CALL    DECOUT    ;PRINT SECTOR NUMBER IN DECIMAL
  1334.     CALL    ILPRT
  1335.     DB    ' (', 0
  1336.     CALL    DHXOUT    ;16 BIT HEX CONVERSION & OUTPUT
  1337.     CALL    ILPRT
  1338.     DB    'H)',0
  1339.     MOV    A,L    ;ONLY LOW BYTE USED BY PROGRAM
  1340.     POP    H    ;RESTORE IT
  1341. ;
  1342. ;---->    RCVSQ:
  1343. ;    If CRC is in effect, there is only a 3 second wait
  1344. ;    for the first SOH.  If the SOH is not received within
  1345. ;    3 seconds, then a NAK is sent which tells the sender
  1346. ;    to use checksum checking instead of CRC.  This allows
  1347. ;    automatic compatability with versions of XMODEM that
  1348. ;    do not implement Cyclic Redundancy Checking(CRC).
  1349. ;
  1350. RCVSQ:    LDA    FIRSTME    ;first SOH...
  1351.     ORA    A    ;...been received?
  1352.     JZ    RCVSQ2    ;yes, go get next SOH
  1353.     XRA    A    ;turn off...
  1354.     STA    FIRSTME    ;...first soh recvd switch
  1355.     LDA    CRCFLG    ;CRC in...
  1356.     ORA    A    ;...effect?
  1357.     JNZ    RCVSQ2    ;no, do long wait for first SOH
  1358.     MVI    B,3    ;wait for upto 3 seconds
  1359.     CALL    RECV    ;get a character from modem
  1360.     JNC    RCVSQ3    ;got a char, go see if SOH
  1361.     CALL    ILPRT
  1362. DB    CR,LF,'++Switching to CHECKSUM MODE++',CR,LF,0
  1363.     MVI    A,'C'    ;turn off...
  1364.     STA    CRCFLG    ;...CRC mode.
  1365.     MVI    A,NAK    ;send NAK to tell sender checksum
  1366.     CALL    SEND    ;...is in effect & to start sending.
  1367.     JMP    RCVSECT    ;go start receiving sector
  1368. ;
  1369. RCVSQ2:    MVI    B,7    ;10 IN ORIG PROG
  1370.     CALL    RECV
  1371.     JC    RCVSTOT
  1372. ;
  1373. RCVSQ3:    CALL    RCVERR    ;CHECK FOR ERRORS
  1374.     JC    RCVDERR    ;JUMP IF THERE WAS AN ERROR
  1375.     CPI    SOH
  1376.     JZ    RCVSOH
  1377.     ORA    A
  1378.     JZ    RCVSQ
  1379.     CPI    EOT
  1380.     STC
  1381.     RZ
  1382.     MOV    B,A
  1383.     LDA    VSEEFLG
  1384.     ORA    A
  1385.     JZ    RCVSEH
  1386.     LDA    QFLG
  1387.     ORA    A
  1388.     JZ    RCVSERR
  1389.  
  1390. RCVSEH:    MOV    A,B
  1391.     CALL    CRLF
  1392.     CALL    HEXO
  1393.     CALL    ILPRT
  1394. DB    'H recv''d, not SOH',CR,LF,0
  1395.  
  1396. RCVSERR: MVI    B,1
  1397.     CALL    RECV
  1398.     JNC    RCVSERR
  1399.     MVI    A,NAK
  1400.     CALL    SEND
  1401.     LDA    ERRCT
  1402.     INR    A
  1403.     STA    ERRCT
  1404.     CPI    ERRLIM
  1405.     JC    RCVRPT
  1406.     LDA    VSEEFLG
  1407.     ORA    A
  1408.     JZ    RCVCKQ
  1409.     LDA    QFLG
  1410.     ORA    A
  1411.     JZ    RCVSABT
  1412. RCVCKQ:    CALL    CKQUIT
  1413.     JZ    RCVSECT
  1414. RCVSABT:
  1415.     CALL    CLOSFIL
  1416.     CALL    ERXIT
  1417. DB    CR,LF,'++Unable to receive block - Aborting++',CR,LF,'$'
  1418.  
  1419. RCVSTOT:
  1420.     LDA    VSEEFLG
  1421.     ORA    A
  1422.     JZ    RCVSPT
  1423.     LDA    QFLG
  1424.     ORA    A
  1425.     JZ    RCVSERR
  1426. RCVSPT:    CALL    ILPRT
  1427. DB    CR,LF,'++  Timeout ++ ',0
  1428. RCVPRN:    LDA    ERRCT
  1429.     CALL    HEXO
  1430.     CALL    CRLF
  1431.     JMP    RCVSERR
  1432.  
  1433. ;---->    RCVERR:
  1434. ;    Checks for framing, overrun, and parity errors. Parity errors
  1435. ;    cannot be detected unless the parity option has been selected.
  1436. ;    1.Error code (ERRCDE) was set in RECV routine.
  1437. ;    2.ERRCDE=0 for no errors, ERRCDE<>0 for errors.
  1438. ;    3.If there is an error, routine returns with carry flag set.
  1439.  
  1440. RCVERR:    PUSH    PSW    ;SAVE CHAR TRANSMITTED
  1441.     LDA    ERRCDE    ;GET RECEIVE ERROR CODE
  1442.     ANA    A    ;IS IT ZERO?
  1443.     JZ    RCVERR2    ;YES, NO RECEIVE ERROR
  1444.     POP    PSW    ;RESTORE CHAR TRANSMITTED
  1445.     STC        ;SET CARRY ON TO INDICATE AN ERROR
  1446.     RET
  1447.  
  1448. RCVERR2:
  1449.     POP    PSW    ;RESTORE CHAR TRANSMITTED
  1450.     RET
  1451.  
  1452. ;---->    RCVDERR: Checks for a receive error and displays appropriate error
  1453. ;    message. Then goes to RCVSERR to purge the line and send a NAK.
  1454.  
  1455. RCVDERR:
  1456.     LDA    VSEEFLG    ;VIEWING
  1457.     ORA    A    ;...MODE?
  1458.     JZ    RCVDERRP ;YES,..PRT MSG
  1459.     LDA    QFLG    ;QUIET...
  1460.     ORA    A    ;...MODE?
  1461.     JZ    RCVSERR    ;YES, NO MSG
  1462.  
  1463. RCVDERRP: CALL ILPRT
  1464.     DB    CR,LF,0
  1465.     LDA    ERRCDE    ;GET RECEIVE ERR CODE
  1466.     ANI    FRMER    ;WAS THERE A FRAMING ERROR?
  1467.     JZ    RCVDERR2 ;NO, GO CHECK FOR OVERRUN
  1468.     CALL    ILPRT
  1469. DB    '++Framing error++ ',0
  1470.     CALL    RCVDERR5 ;PRINT # OF ERROR
  1471.  
  1472. RCVDERR2:
  1473.     LDA    ERRCDE    ;GET RECEIVE ERR CODE
  1474.     ANI    ORUNER    ;WAS THERE AN OVERRUN
  1475.     JZ    RCVDERR3 ;NO, GO CHECK FOR PARITY ERROR
  1476.     CALL    ILPRT
  1477. DB    '++Overrun error++ ',0
  1478.     CALL    RCVDERR5
  1479.  
  1480. RCVDERR3:
  1481.     LDA    ERRCDE    ;GET RECEIVE ERR CODE
  1482.     ANI    PARER    ;WAS THERE A PARITY ERROR?
  1483.     JZ    RCVDERR4 ;NO, GO PURGE LINE
  1484.     CALL    ILPRT
  1485. DB    '++Parity error++ ',0
  1486.     CALL    RCVDERR5
  1487.  
  1488. RCVDERR4: JMP    RCVSERR    ;GO PURGE LINE, SEND NAK
  1489.  
  1490. ;Display the number of the error, do a carriage return and line feed.
  1491. RCVDERR5:
  1492.     LDA    ERRCT    ;GET ERROR NUMBER
  1493.     CALL    HEXO    ;DISPLAY IT
  1494.     CALL    CRLF    ;DO CR, LF
  1495.     RET
  1496.  
  1497. RCVSOH:    MVI    B,1
  1498.     CALL    RECV
  1499.     JC    RCVSTOT
  1500.     CALL    RCVERR    ;CHECK FOR RECEIVE ERROR
  1501.     JC    RCVDERR
  1502.     MOV    D,A
  1503.     MVI    B,1
  1504.     CALL    RECV
  1505.     JC    RCVSTOT
  1506.     CALL    RCVERR    ;CHECK FOR RECEIVE ERROR
  1507.     JC    RCVDERR
  1508.     CMA
  1509.     CMP    D
  1510.     JZ    RCVDATA
  1511.     LDA    VSEEFLG
  1512.     ORA    A
  1513.     JZ    RCVBSE
  1514.     LDA    QFLG
  1515.     ORA    A
  1516.     JZ    RCVSERR
  1517. RCVBSE:    CALL    ILPRT
  1518. DB    CR,LF,'++  Bad sector # in Hdr',CR,LF,0
  1519.     JMP    RCVSERR
  1520.  
  1521. RCVDATA:
  1522.     MOV    A,D
  1523.     STA    RCVSNO
  1524.     MVI    A,1
  1525.     STA    DATAFLG
  1526.     MVI    C,0
  1527.     CALL    CLRCRC    ;clear crc counter
  1528.     LXI H,80H
  1529. RCVCHR:    MVI    B,1
  1530.     CALL    RECV
  1531.     JC    RCVSTOT
  1532.     CALL    RCVERR    ;CHECK FOR RECEIVE ERROR
  1533.     JC    RCVDERR
  1534.     MOV    M,A
  1535.     INR    L
  1536.     JNZ    RCVCHR
  1537.     LDA    CRCFLG
  1538.     ORA    A
  1539.     JZ    RCVCRC
  1540.     MOV    D,C
  1541.     XRA    A
  1542.     STA    DATAFLG
  1543.     MVI    B,1
  1544.     CALL    RECV
  1545.     JC    RCVSTOT
  1546.     CALL    RCVERR    ;CHECK FOR RECEIVE ERROR
  1547.     JC    RCVDERR
  1548.     CMP    D
  1549.     JNZ    RCVCERR
  1550. CHKSNUM:
  1551.     LDA    RCVSNO
  1552.     MOV    B,A
  1553.     LDA    SECTNO
  1554.     CMP    B
  1555.     JZ    RECVACK
  1556.     INR    A
  1557.     CMP    B
  1558.     JNZ    ABORT
  1559.     RET
  1560. ;
  1561. RCVCRC:    MVI    E,2    ;nr of crc bytes
  1562.     ;
  1563. RCVCRC2:
  1564.     MVI    B,1
  1565.     CALL    RECV
  1566.     JC    RCVSTOT
  1567.     CALL    RCVERR
  1568.     JC    RCVDERR
  1569.     DCR    E
  1570.     JNZ    RCVCRC2
  1571.     CALL    CHKCRC
  1572.     ORA    A
  1573.     JZ    CHKSNUM
  1574.     LDA    VSEEFLG
  1575.     ORA    A
  1576.     JZ    RCVCRER
  1577.     LDA    QFLG
  1578.     ORA    A
  1579.     JZ    RCVSERR
  1580.     ;
  1581. RCVCRER:
  1582.     CALL    ILPRT
  1583. DB    CR,LF,'++CRC error++',0
  1584.     JMP    RCVPRN
  1585.  
  1586. RCVCERR:
  1587.     LDA    VSEEFLG
  1588.     ORA    A
  1589.     JZ    RCVCPR
  1590.     LDA    QFLG
  1591.     ORA    A
  1592.     JZ    RCVSERR
  1593. RCVCPR:    CALL    ILPRT
  1594. DB    '++Cksum error++ ',0
  1595.     JMP    RCVPRN
  1596.  
  1597. RECVACK:
  1598.     CALL    SENDACK
  1599.     JMP    RCVSECT
  1600.  
  1601. SENDACK:
  1602.     MVI    A,ACK
  1603.     CALL    SEND
  1604.     RET
  1605.  
  1606. SENDHDR:
  1607.     LDA    QFLG
  1608.     ORA    A
  1609.     JZ    SENDHNM
  1610.     CALL    ILPRT
  1611. DB    CR,'Send # ',0
  1612.     PUSH    H
  1613.     LHLD    SECTNO    ;GET SECTOR NUMBER
  1614.     CALL    DECOUT    ;PRINT IT IN DECIMAL
  1615.     CALL    ILPRT
  1616.     DB    '  (',0
  1617.     CALL    DHXOUT    ;16 BIT HEX CONVERSION & OUTPUT
  1618.     CALL    ILPRT
  1619.     DB    'H)',0
  1620.     POP    H
  1621. SENDHNM:
  1622.     MVI    A,SOH
  1623.     CALL    SEND
  1624.     LDA    SECTNO
  1625.     CALL    SEND
  1626.     LDA    SECTNO
  1627.     CMA
  1628.     CALL    SEND
  1629.     RET
  1630.  
  1631. SENDSEC:
  1632.     MVI    A,1
  1633.     STA    DATAFLG
  1634.     MVI    C,0
  1635.     CALL    CLRCRC
  1636.     LXI    H,80H
  1637. SENDC:    MOV    A,M
  1638.     CALL    SEND
  1639.     INR    L
  1640.     JNZ    SENDC
  1641.     XRA    A
  1642.     STA    DATAFLG
  1643.     RET
  1644.  
  1645. SENDCKS:
  1646.     MOV    A,C
  1647.     CALL    SEND
  1648.     RET
  1649.  
  1650. SENDCRC:
  1651.     CALL    FINCRC
  1652.     MOV    A,D
  1653.     CALL    SEND
  1654.     MOV    A,E
  1655.     CALL    SEND
  1656.     XRA    A
  1657.     RET
  1658.  
  1659. GETACK:    MVI    B,7    ;10 IN ORIG PROG
  1660.     CALL    RECVDG
  1661.     JC    GETATOT
  1662.     CPI    ACK
  1663.     RZ
  1664.     MOV    B,A
  1665.     LDA    QFLG
  1666.     ORA    A
  1667.     JZ    ACKERR
  1668.     MOV    A,B
  1669.     CALL    CRLF
  1670.     CALL    HEXO
  1671.     CALL    ILPRT
  1672. DB    'H Recv''d, not ACK',CR,LF,0
  1673. ACKERR:    LDA    ERRCT
  1674.     INR    A
  1675.     STA    ERRCT
  1676.     CPI    ERRLIM
  1677.     RC
  1678.     LDA    VSEEFLG
  1679.     ORA    A
  1680.     JZ    GACKV
  1681.     LDA    QFLG
  1682.     ORA    A
  1683.     JZ    CSABORT
  1684. GACKV:    CALL    CKQUIT
  1685.     STC
  1686.     RZ
  1687. CSABORT:
  1688.     CALL    ERXIT
  1689. DB    CR,LF,'Can''t send sector -- Aborting',CR,LF,'$'
  1690.     ;
  1691. GETATOT:
  1692.     LDA    QFLG
  1693.     ORA    A
  1694.     JZ    ACKERR
  1695.     CALL    ILPRT
  1696. DB    CR,LF,'Timeout on ACK',CR,LF,0
  1697.     JMP ACKERR
  1698.  
  1699. CKABORT:
  1700.     LDA    VSEEFLG
  1701.     ORA    A
  1702.     JZ    CKABGO
  1703.     LDA    QFLG
  1704.     ORA    A
  1705.     RZ    
  1706. CKABGO:    CALL    STAT
  1707.     RZ
  1708.     CALL    KEYIN
  1709.     CPI    CAN
  1710.     RNZ
  1711. ABORT:    LXI    SP,STACK
  1712. ABORTL:    MVI    B,1
  1713.     CALL    RECV
  1714.     JNC    ABORTL
  1715.     MVI    A,CAN
  1716.     CALL    SEND
  1717. ABORTW:    MVI    B,1
  1718.     CALL    RECV
  1719.     JNC    ABORTW
  1720.     MVI    A,' '
  1721.     CALL    SEND
  1722.     CALL    ILPRT
  1723. DB    CR,LF,'Routine cancelled',CR,LF,BELL,0
  1724.     MVI    A,'B'    ;TURN MULTI-FILE MODE..
  1725.     STA    BATCHFLG ;..OFF SO ROUTINE ENDS.
  1726.     JMP    DONETCE
  1727.  
  1728. INCRSNO:
  1729.     PUSH    H
  1730.     LHLD    SECTNO    ;GET SECTOR NUMBER
  1731.     INX    H    ;BUMP IT
  1732.     SHLD    SECTNO    ;STORE IT
  1733.     MOV    A,L
  1734.     POP    H
  1735.     RET
  1736.  
  1737. ERASFIL:
  1738.     LDA    BATCHFLG ;DON'T ASK FOR ERASE..
  1739.     ORA    A    ;..IN MULTI-FILE MODE,..
  1740.     JZ    NOASK    ;..JUST DO IT.
  1741.     LXI    D,FCB
  1742.     MVI    C,SRCHF
  1743.     CALL    BDOS
  1744.     INR    A
  1745.     RZ
  1746.     CALL    ILPRT
  1747. DB    'File exists -- Type ''Y'' to erase: ',BELL,0
  1748.     CALL    KEYIN
  1749.     PUSH    PSW
  1750.     CALL    TYPE
  1751.     POP    PSW
  1752.     CALL    UCASE
  1753.     CPI    'Y'
  1754.     JNZ    MENU
  1755.     CALL    CRLF
  1756.     ;
  1757. NOASK:    LXI    D,FCB
  1758.     MVI    C,ERASE
  1759.     CALL    BDOS
  1760.     RET
  1761.  
  1762. BLKFILE:
  1763.     CALL    ILPRT    ;ROUTINE IF NO FILE IS NAMED FOR "SEND" OR "RECEIVE"
  1764. DB    CR,LF,'No file specified',CR,LF,BELL,0
  1765.     JMP    MENU
  1766.  
  1767. MAKEFIL:
  1768.     LXI    D,FCB
  1769.     MVI    C,MAKE
  1770.     CALL    BDOS
  1771.     INR    A
  1772.     RNZ
  1773.     CALL    ERXIT
  1774. DB    'Error - Can''t make file',CR,LF
  1775. DB    'Directory must be full',CR,LF,'$'
  1776.  
  1777.     IF    CPM2X
  1778. CNREC:    MVI    C,FILSIZ ;COMPUTE FILE SIZE FUNCTION IN CP/M 2.x
  1779.     LXI    D,FCB    ;POINT TO FILE CONTROL BLOCK
  1780.     CALL    BDOS
  1781.     LHLD    FCB+33    ;GET RECORD COUNT
  1782.     SHLD    RCNT    ;STORE IT
  1783.     LXI    H,0    ;ZERO HL
  1784.     SHLD    FCB+33    ;RESET RANDOM RECORD IN FCB
  1785.     RET
  1786.     ENDIF
  1787.  
  1788.     IF    NOT CPM2X
  1789. CNREC:    MVI    A,'?'    ;MATCH ALL EXTENTS
  1790.     STA    FCBEXT
  1791.     MVI    A,0FFH
  1792.     STA    MAXEXT    ;INIT MAX EXT NO.
  1793.     MVI    C,SRCHF    ;GET 'SEARCH FIRST' FNC
  1794.     LXI    D,FCB
  1795.     CALL    BDOS    ;READ FIRST
  1796.     INR    A    ;WERE THERE ANY?
  1797.     JNZ    SOME    ;GOT SOME
  1798.     CALL    ERXIT
  1799. DB    '++File not found++$'
  1800.  
  1801. ;READ MORE DIRECTORY ENTRIES
  1802. MOREDIR:
  1803.     MVI    C,SRCHN    ;SEARCH NEXT
  1804.     LXI    D,FCB
  1805.     CALL    BDOS    ;READ DIR ENTRY
  1806.     INR    A    ;CHECK FOR END (0FFH)
  1807.     JNZ    SOME    ;NOT END OF DIR...PROCESS EXTENT
  1808.     LDA    MAXEXT    ;HIT END...GET HIGHEST EXTENT NO. SEEN
  1809.     MOV    L,A    ;WHICH GIVES EXTENT COUNT -1
  1810.     MVI    H,0
  1811.     MOV    D,H
  1812.     LDA    RCNT    ;GET RECORD COUNT OF MAX EXTENT SEEN
  1813.     MOV    E,A    ;SAVE IT IN DE
  1814.     DAD    H
  1815.     DAD    H    ;MULTIPLY # OF EXTENTS -1
  1816.     DAD    H    ; TIMES 128
  1817.     DAD    H
  1818.     DAD    H
  1819.     DAD    H
  1820.     DAD    H
  1821.     DAD    D    ;ADD IN SIZE OF LAST EXTENT
  1822.     SHLD    RCNT    ;SAVE TOTAL RECORD COUNT
  1823.     RET    ;AND EXIT
  1824.  
  1825. ;POINT TO DIRECTORY ENTRY
  1826. SOME:    DCR    A    ;UNDO PREV 'INR A'
  1827.     ANI    3    ;MAKE MODULUS 4
  1828.     ADD    A    ;MULTIPLY...
  1829.     ADD    A    ;..BY 32 BECAUSE
  1830.     ADD    A    ;..EACH DIRECTORY
  1831.     ADD    A    ;..ENTRY IS 32
  1832.     ADD    A    ;..BYTES LONG
  1833.     LXI    H,80H ;POINT TO BUFFER
  1834.     ADD    L    ;POINT TO ENTRY
  1835.     ADI    15    ;OFFSET TO RECORD COUNT
  1836.     MOV    L,A    ;HL NOW POINTS TO REC COUNT
  1837.     MOV    B,M    ;GET RECORD COUNT
  1838.     DCX    H
  1839.     DCX    H    ;BACK DOWN TO EXTENT NUMBER
  1840.     DCX    H
  1841.     LDA    MAXEXT    ;COMPARE WITH CURRENT MAX.
  1842.     ORA    A    ;IF NO MAX YET
  1843.     JM    BIGGER    ;THEN SAVE RECORD COUNT ANYWAY
  1844.     CMP    M
  1845.     JNC    MOREDIR
  1846. BIGGER:    MOV    A,B    ;SAVE NEW RECORD COUNT
  1847.     STA    RCNT
  1848.     MOV    A,M    ;SAVE NEW MAX. EXTENT NO.
  1849.     STA    MAXEXT
  1850.     JMP    MOREDIR    ;GO FIND MORE EXTENTS
  1851.     ENDIF
  1852.  
  1853. OPENFIL:
  1854.     LXI    D,FCB
  1855.     MVI    C,OPEN
  1856.     CALL    BDOS
  1857.     INR    A
  1858.     JNZ    OPENOK
  1859.     CALL    ERXIT
  1860. DB    'Can''t open file$'
  1861.  
  1862. OPENOK:    LDA    BATCHFLG
  1863.     ORA    A
  1864.     JNZ    OPENOK1
  1865.     LDA    QFLG
  1866.     ORA    A
  1867.     RZ
  1868. OPENOK1:
  1869.     CALL    ILPRT
  1870. DB    'File open, size: ',0
  1871.     LHLD    RCNT    ;GET RECORD COUNT
  1872.     CALL    DECOUT    ;PRINT NUMBER OF SECTORS IN DECIMAL
  1873.     CALL    ILPRT    ;PRINT
  1874.     DB    ' (',0
  1875.     CALL    DHXOUT
  1876.     CALL    ILPRT
  1877.     DB    'H) sectors',CR,LF,0
  1878.     RET
  1879.  
  1880. CLOSFIL:
  1881.     LXI    D,FCB
  1882.     MVI    C,CLOSE
  1883.     CALL    BDOS
  1884.     INR    A
  1885.     RNZ
  1886.     CALL    ERXIT
  1887. DB    'Can''t close file$'
  1888.  
  1889. RDSECT:
  1890.     LDA    SECINBF
  1891.     DCR    A
  1892.     STA    SECINBF
  1893.     JM    RDBLOCK
  1894.     LHLD    SECPTR
  1895.     LXI    D,80H
  1896.     CALL    MOVE128
  1897.     SHLD    SECPTR
  1898.     RET
  1899.  
  1900. RDBLOCK:
  1901.     LDA    EOFLG
  1902.     CPI    1
  1903.     STC
  1904.     RZ
  1905.     MVI    C,0
  1906.     LXI    D,DBUF
  1907. RDSECLP:
  1908.     PUSH B
  1909.     PUSH D
  1910.     MVI    C,STDMA
  1911.     CALL    BDOS
  1912.     LXI    D,FCB
  1913.     MVI    C,READ
  1914.     CALL    BDOS
  1915.     POP    D
  1916.     POP    B
  1917.     ORA    A
  1918.     JZ    RDSECOK
  1919.     DCR    A
  1920.     JZ    REOF
  1921.     CALL    ERXIT
  1922. DB    '++    File read error    ++$'
  1923. RDSECOK:
  1924.     LXI    H,80H
  1925.     DAD    D
  1926.     XCHG
  1927.     INR    C
  1928.     MOV    A,C
  1929.     CPI    DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
  1930.     JZ    RDBFULL
  1931.     JMP    RDSECLP
  1932. REOF:    MVI    A,1
  1933.     STA    EOFLG
  1934.     MOV    A,C
  1935. RDBFULL:
  1936.     STA    SECINBF
  1937.     LXI    H,DBUF
  1938.     SHLD    SECPTR
  1939.     LXI    D,80H
  1940.     MVI    C,STDMA
  1941.     CALL    BDOS
  1942.     JMP    RDSECT
  1943. ;
  1944. WRSECT:    LHLD    SECPTR
  1945.     XCHG
  1946.     LXI    H,80H
  1947.     CALL    MOVE128
  1948.     XCHG
  1949.     SHLD    SECPTR
  1950.     LDA    SECINBF
  1951.     INR    A
  1952.     STA    SECINBF
  1953.     CPI    DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
  1954.     RNZ
  1955. ;
  1956. WRBLOCK:
  1957.     LDA    SECINBF
  1958.     ORA    A
  1959.     RZ
  1960.     MOV    C,A
  1961.     LXI    D,DBUF
  1962. DKWRLP:    PUSH    H
  1963.     PUSH    D
  1964.     PUSH    B
  1965.     MVI    C,STDMA
  1966.     CALL    BDOS
  1967.     LXI    D,FCB
  1968.     MVI    C,WRITE
  1969.     CALL    BDOS
  1970.     POP    B
  1971.     POP    D
  1972.     POP    H
  1973.     ORA    A
  1974.     JNZ    WRERR
  1975.     LXI    H,80H
  1976.     DAD    D
  1977.     XCHG
  1978.     DCR    C
  1979.     JNZ    DKWRLP
  1980.     XRA    A
  1981.     STA    SECINBF
  1982.     LXI    H,DBUF
  1983.     SHLD    SECPTR
  1984.     RET
  1985.  
  1986. WRERR:    MVI    C,CAN
  1987.     CALL    SEND
  1988.     CALL    ERXIT
  1989. DB    'Error writing file',CR,LF,'$'
  1990.  
  1991. ;---->    RECV: Receive a character
  1992.  
  1993. ;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage
  1994. ;characters on the line. For example, having just sent a sector, calling
  1995. ;RECVDG will delete any line noise induced characters LONG before the
  1996. ;ACK/NAK would be received.
  1997.  
  1998. RECVDG:    EQU $
  1999.     CALL    IN$MODDATP
  2000.     CALL    IN$MODDATP
  2001. RECV:    PUSH    D
  2002.     LDA    FASTCLK
  2003.     ORA    A
  2004.     JZ    MSEC
  2005.     MOV    A,B
  2006.     ADD    A
  2007.     MOV    B,A
  2008. MSEC:    LXI    D,15000    ;60% OF ORIG 50000
  2009.     CALL    CKABORT
  2010. MWTI:    CALL    IN$MODCTLP
  2011.     CALL    ANI$MODRCVB
  2012.     CALL    CPI$MODRCVR
  2013.     JZ    MCHAR
  2014.     DCR    E
  2015.     JNZ    MWTI
  2016.     DCR    D
  2017.     JNZ    MWTI
  2018.     DCR    B
  2019.     JNZ    MSEC
  2020.     POP    D
  2021.     STC
  2022.     RET
  2023.  
  2024. MCHAR:    LDA    PMMIBYTE ;IS THE MODEM A PMMI?
  2025.     ORA    A    ;SET FLAGS
  2026.     JZ    MCHAR1    ;YES, JUMP
  2027.     CALL    IN$MODCTLP ;GET ERROR-STATUS BYTE
  2028.     ANI    ERRCDMSK ;MASK OUT ALL EXCEPT ERROR BITS (3-5)
  2029.     STA    ERRCDE    ;SAVE THE ERROR CODE
  2030. MCHAR1:    CALL    IN$MODDATP
  2031.     POP    D
  2032.     PUSH    PSW
  2033.     CALL    UPDCRC    ;calc crc
  2034.     ADD    C    
  2035.     MOV    C,A
  2036.     LDA    RSEEFLG
  2037.     ORA    A
  2038.     JZ    MONIN
  2039.     LDA    VSEEFLG
  2040.     ORA    A
  2041.     JNZ    NOMONIN
  2042.     LDA    DATAFLG
  2043.     ORA    A
  2044.     JZ    NOMONIN
  2045. MONIN:    POP    PSW
  2046.     PUSH    PSW
  2047.     CALL    SHOW
  2048. NOMONIN:
  2049.     POP    PSW
  2050.     ORA    A
  2051.     RET
  2052.  
  2053. SEND:    PUSH    PSW
  2054.     LDA    SSEEFLG
  2055.     ORA    A
  2056.     JZ    MONOUT
  2057.     LDA    VSEEFLG
  2058.     ORA    A
  2059.     JNZ    NOMONOT
  2060.     LDA    DATAFLG
  2061.     ORA    A
  2062.     JZ    NOMONOT
  2063. MONOUT:    POP    PSW
  2064.     PUSH    PSW
  2065.     CALL    SHOW
  2066. NOMONOT:
  2067.     POP    PSW
  2068.     PUSH    PSW
  2069.     CALl    UPDCRC    ;calc crc
  2070.     ADD    C
  2071.     MOV    C,A
  2072. SENDW:    CALL    IN$MODCTLP
  2073.     CALL    ANI$MODSNDB
  2074.     CALL    CPI$MODSNDR
  2075.     JNZ    SENDW
  2076.     POP    PSW
  2077.     CALL    OUT$MODDATP
  2078.     RET
  2079.  
  2080. WAITNAK:
  2081.     LDA    VSEEFLG
  2082.     ORA    A
  2083.     JZ    WAITNPR
  2084.     LDA    QFLG
  2085.     ORA    A
  2086.     JZ    WAITNLP
  2087. WAITNPR:
  2088.     CALL    ILPRT
  2089. DB    'Awaiting initial NAK',CR,LF,0
  2090. WAITNLP:
  2091.     CALL    CKABORT
  2092.     MVI    B,1
  2093.     CALL    RECV
  2094.     CPI    NAK
  2095.     RZ
  2096.     CPI    CRC    ;crc request?
  2097.     JZ    WAITCRC    ;yes, go set crc flag
  2098.     DCR    E
  2099.     JZ    ABORT
  2100.     JMP    WAITNLP
  2101. ;
  2102. WAITCRC:
  2103.     CALL    ILPRT
  2104. DB    'CRC request received',CR,LF,0
  2105.     XRA    A
  2106.     STA    CRCFLG
  2107.     RET
  2108. ;
  2109. ;--->PARITY: Routine to setup PMMI for odd/even parity.
  2110.  
  2111. PARITY:    LDA    PMMIBYTE ;IS MODEM A PMMI?
  2112.     ORA    A    ;SET FLAGS
  2113.     RZ        ;NO, RETURN
  2114.     LDA    OPARITY    ;GET ODD PARITY REQUEST BYTE
  2115.     ORA    A    ;SET FLAGS
  2116.     JNZ    EVENPAR    ;IF NOT ODD SEE IF IT IS EVEN
  2117.     LDA    UARTCTLB ;GET UART/MODEM CONTROL BYTE
  2118.     ANI    ODPARMSK
  2119.     JMP    PARITY1
  2120.  
  2121. EVENPAR:
  2122.     LDA    EPARITY    ;GET EVEN PARITY REQUEST BYTE
  2123.     ORA    A    ;SET FLAGS
  2124.     RNZ        ;IF EVEN PARITY NOT SPECIFIED RETURN
  2125.     LDA    UARTCTLB ;GET UART/MODEM CONTROL BYTE
  2126.     ANI    ODPARMSK ;SET FOR PARITY
  2127.     ORI    EVPARMSK ;NOW SET FOR EVEN PARITY
  2128.  
  2129. PARITY1:
  2130.     JMP    OUT$MODCTLP ;SEND TO PMMI -
  2131.             ;WHEN OUT$MODCTLP DOES RET IT
  2132.             ;WILL GO BACK TO CALLING ROUTINE
  2133.  
  2134. NOPARIT:
  2135.     LDA    PMMIBYTE
  2136.     ORA    A
  2137.     RZ
  2138.     LDA    UARTCTLB    ;GET UART/MODEM CONTROL BYTE
  2139.     ORI    NOPARMSK    ;RESET PARITY BIT ON PMMI
  2140.     JMP    OUT$MODCTLP
  2141.  
  2142.  
  2143. INITADR:
  2144.     LHLD    1
  2145.     LXI    D,3
  2146.     DAD    D
  2147.     SHLD    VSTAT+1
  2148.     DAD    D
  2149.     SHLD    VKEYIN+1
  2150.     DAD    D
  2151.     SHLD    VTYPE+1
  2152.     LDA    PMMIBYTE
  2153.     ORA    A
  2154.     JZ    JMP$INITMOD    ;RETURN DONE FROM THIS ROUTINE..
  2155.     LDA    IN$MODCTLP+1    ;..IF NOT PMMI
  2156.     STA    OUT$MODCTLP+1
  2157.     INR    A
  2158.     STA    OUT$MODDATP+1
  2159.     STA    IN$MODDATP+1
  2160.     INR    A
  2161.     STA    IN$BAUDRP+1
  2162.     STA    OUT$BAUDRP+1
  2163.     INR    A
  2164.     STA    OUT$MODCTL2+1
  2165.     RET
  2166.  
  2167. PROCOPT:
  2168.     LXI    D,FCB+1
  2169.     LDAX    D
  2170.     STA    OPTION
  2171. OPTLP:    INX    D
  2172.     LDAX    D
  2173.     CPI    ' '
  2174.     JZ    ENDOPT
  2175.     LXI    H,OPTBL
  2176.     MVI    B,OPTBE-OPTBL
  2177. OPTCK:    CMP    M
  2178.     JNZ    OPTNO
  2179.     MVI    M,0
  2180.     JMP    OPTLP
  2181. OPTNO:    INX    H
  2182.     DCR    B
  2183.     JNZ    OPTCK
  2184.     JMP    BADOPT
  2185.  
  2186. ENDOPT: LDA    CRCFLG
  2187.     ORA    A
  2188.     JNZ    ENDOPT2
  2189.     LDA    OPTION
  2190.     CPI    'R'
  2191.     JNZ    BADOPT    ;crc only allowed for recv
  2192. ;
  2193. ENDOPT2:
  2194.     LDA    VSEEFLG
  2195.     ORA    A
  2196.     RNZ
  2197.     STA    QFLG
  2198.     RET
  2199.  
  2200. DONE:    LDA    BATCHFLG
  2201.     ORA    A
  2202.     JNZ    DONETCC
  2203.     LDA    QFLG
  2204.     ORA    A
  2205.     JZ    NMSTRNS
  2206.     LXI    H,FCB+1    ;PUT FILE NAME IN..
  2207.     LXI    D,FTRNMSG ;..SPACES IN MESSAGE..
  2208.     MVI    B,8    ;..BELOW.
  2209.     CALL    MOVE
  2210.     INX    D    ;PUT FILE TYPE AFTER..
  2211.     MVI    B,3    ;..SKIPPING ONE SPACE..
  2212.     CALL    MOVE    ;..BELOW.    
  2213.     CALL    ILPRT
  2214. FTRNMSG:
  2215. DB    '              transferred',CR,LF,CR,LF,0    ;13 SPACES
  2216.  
  2217. NMSTRNS:
  2218.     LDA    FCB    ;SAVE DRIVE NO.
  2219.     STA    DISKNO
  2220.     LXI    H,FCB    ;BLANK OUT FILE CONTROL BLOCKS
  2221.     CALL    INITFCBS
  2222.     LDA    DISKNO    ;PUT DRIVE NUMBER BACK
  2223.     STA    FCB
  2224.     LXI    H,RESTSN ;RESTORE SECTORE NUMBERS..
  2225.     LXI    D,SECTNOB ;..FOR NEW FILE TRANSFER.
  2226.     MVI    B,SECTNOE-SECTNOB ;ROUTINE ALSO DONE IN MENU.
  2227.     CALL    MOVE
  2228.     LDA    SENDFLG    ;GOES TO EITHER SEND OR..
  2229.     ORA    A    ;..RECEIVE FILE, DEPENDING..
  2230.     JNZ    SENDFIL    ;..UPON WHICH ROUTINE SET..
  2231.     JMP    RCVFIL    ;..THE FLAG IN MULTI-FILE MODE.
  2232.  
  2233. DONETCC:
  2234.     MVI    A,TRUE    ;INDICATE NO FILES BEING..
  2235.     STA    FSTFLG    ;RESET MULTIFILE TRANS
  2236.     STA    NFILFLG    ;..USED IN TERMINAL ROUTINE.
  2237.     CMA
  2238.     OUT    FRONTPAN
  2239.     STA    SAVEFLG    ;STOP MEMORY SAVE IN TERM ROUTINE.
  2240.     LDA    VSEEFLG
  2241.     ORA    A
  2242.     JZ    DONETC
  2243.     LDA    QFLG
  2244.     ORA    A
  2245.     JZ    DONETCA
  2246. DONETC:    CALL    ILPRT
  2247. DB    CR,LF,'All transfers completed'
  2248. DB    CR,LF,BELL,0
  2249. DONETCA:
  2250.     LDA    DISCFLG    ;see if disconnect when thru
  2251.     ORA    A
  2252.     JNZ    DONETCE    ;no, don't disconnect
  2253. DONETCB:
  2254.     CALL    ILPRT
  2255. DB    CR,LF,'++Press RETURN to disconnect++',BELL,CR,LF,0
  2256.     MVI    C,RDCON
  2257.     CALL    BDOS    ;wait for response
  2258.     CPI    0DH    ;carriage return
  2259.     JNZ    DONETCB    ;nope
  2260.     CALL    ILPRT
  2261. DB    CR,LF,'++Disconnected++',CR,LF,0
  2262.     CALL    DISCONNT ;hang-up the pmmi
  2263.     JMP    EXIT    ;go to CP/M
  2264.  
  2265. DONETCE:
  2266.     CALL    NOPARIT    ;RESET TO NO PARITY
  2267.     mvi    a,crc    ;@7.41....................
  2268.     sta    CRCFLG    ;turn off CRC option
  2269.     mvi    a,0FFH
  2270.     sta    FIRSTME    ;set first-time flag
  2271.             ;@7.41....................
  2272.     LDA    TERMFLG    ;SEE IF RETURN TO..
  2273.     ORA    A    ;..TERMINAL MODE..
  2274.     JNZ    MENU    ;..AFTER X'FER.
  2275.     CALL    CRLF
  2276.     JMP    TERM
  2277.  
  2278. INITMOD:
  2279. SETBAUD:
  2280.     LDA    PMMIBYTE
  2281.     ORA    A
  2282.     RZ
  2283.     LDA    ANSWFLG    ;IF ANSWER OR ORIGINATE MODE..
  2284.     ORA    A    ;..IS NOT REQUESTED OR NO..
  2285.     JNZ    SKIPB1    ;..BAUDRATE SPECIFIED, THEN..
  2286.     CALL    GETBAUD    ;..ROUTINE RETURNS WITH CHANGE..
  2287.     JMP    FIXBAUD    ;..OF BAUD. IF OPT REQUESTED,..
  2288. SKIPB1:    LDA    ORIGFLG    ;..A BLANK FORCES 300 BAUD..
  2289.     ORA    A    ;..ELSE A 0 FROM NEWBAUD..
  2290.     RNZ        ;..FORCES 300 BAUD.
  2291.     CALL    GETBAUD
  2292. FIXBAUD:
  2293.     CALL    OUT$BAUDRP
  2294.     CPI    52
  2295.     MVI    A,5FH
  2296.     JC    GT300
  2297.     MVI    A,7FH
  2298. GT300:    CALL    OUT$MODCTL2
  2299.     STA    MODCTLB    ;SAVE MODEM CONTROL BYTE
  2300.     LDA    ORIGFLG
  2301.     ORA    A
  2302.     MVI    A,ORIGMOD
  2303.     JZ    OFFHOOK
  2304.     LDA    ANSWFLG
  2305.     ORA    A
  2306.     MVI    A,ANSWMOD
  2307.     RNZ
  2308.  
  2309. OFFHOOK:
  2310.     LXI    H,4000
  2311. OFFDLY:    DCR    L
  2312.     JNZ    OFFDLY
  2313.     DCR    H
  2314.     JNZ    OFFDLY
  2315.     CALL    OUT$MODCTLP
  2316.     RET
  2317.  
  2318. GETBAUD:
  2319.     LDA    FCB+9
  2320.     CPI    ' '
  2321.     MVI    A,52
  2322.     RZ
  2323.     LDA    FCB+9
  2324.     CPI    0
  2325.     MVI    A,52
  2326.     RZ
  2327.  
  2328.     LXI    D,FCB+9
  2329.     LXI    H,0
  2330. DECLP:    LDAX    D
  2331.     INX    D
  2332.     CPI    ' '
  2333.     JZ    DECLP
  2334.     CPI    '0'
  2335.     JC    BADRATE
  2336.     CPI    '9'+1
  2337.     JNC    BADRATE
  2338.     SUI    '0'
  2339.     MOV    B,H
  2340.     MOV    C,L
  2341.     DAD    H
  2342.     DAD    H
  2343.     DAD    B
  2344.     DAD    H
  2345.     ADD    L
  2346.     MOV    L,A
  2347.     JNZ    DIGNC
  2348.     INR    H
  2349. DIGNC:    MOV    A,E
  2350.     CPI    FCB+12
  2351.     JNZ    DECLP
  2352.     MOV    A,H
  2353.     CMA
  2354.     MOV    D,A
  2355.     MOV    A,L
  2356.     CMA
  2357.     MOV    E,A
  2358.     INX    D
  2359.     LXI    H,15625
  2360.     LXI    B,-1
  2361. DIVLP:    INX    B
  2362.     DAD    D
  2363.     JC    DIVLP
  2364.     MOV    A,B
  2365.     ORA    A
  2366.     MOV    A,C
  2367.     RZ
  2368.  
  2369. BADRATE:
  2370.     CALL    ERXIT
  2371. DB    '++    Invalid baud rate ++$'
  2372.  
  2373. MOVEFCB:
  2374.     LXI    H,FCB+16
  2375.     LXI    D,FCB
  2376.     MVI    B,16
  2377.     CALL    MOVE
  2378.     XRA    A
  2379.     STA    FCBSNO
  2380.     STA    FCBEXT
  2381.     RET
  2382.  
  2383. SHOW:    CPI    LF
  2384.     JZ    CTYPE
  2385.     CPI    CR
  2386.     JZ    CTYPE
  2387.     CPI    9
  2388.     JZ    CTYPE
  2389.     CPI    ' '
  2390.     JC    SHOWHEX
  2391.     CPI    7FH
  2392.     JC    CTYPE
  2393. SHOWHEX:
  2394.     PUSH    PSW
  2395.     MVI    A,'('
  2396.     CALL    CTYPE
  2397.     POP    PSW
  2398.     CALL    HEXO
  2399.     MVI    A,')'
  2400.     JMP    CTYPE
  2401.  
  2402. CTYPE:    PUSH    B
  2403.     PUSH    D
  2404.     PUSH    H
  2405.     MOV    E,A
  2406.     MVI    C,WRCON
  2407.     CALL    BDOS
  2408.     POP    H
  2409.     POP    D
  2410.     POP    B
  2411.     RET
  2412.  
  2413. CRLF:    PUSH    PSW
  2414.     MVI    A,CR
  2415.     CALL    TYPE
  2416.     MVI    A,LF
  2417.     CALL    TYPE
  2418.     POP    PSW
  2419.     RET
  2420.  
  2421. TYPE:    PUSH    PSW
  2422.     PUSH    B
  2423.     PUSH    D
  2424.     PUSH    H
  2425.     MOV    C,A
  2426. VTYPE:    CALL    $-$
  2427.     POP    H
  2428.     POP    D
  2429.     POP    B
  2430.     POP    PSW
  2431.     RET
  2432.  
  2433. STAT:    PUSH    B
  2434.     PUSH    D
  2435.     PUSH    H
  2436. VSTAT:    CALL    $-$
  2437.     POP    H
  2438.     POP    D
  2439.     POP    B
  2440.     ORA    A
  2441.     RET
  2442.  
  2443. KEYIN:    PUSH    B
  2444.     PUSH    D
  2445.     PUSH    H
  2446. VKEYIN:    CALL    $-$
  2447.     POP    H
  2448.     POP    D
  2449.     POP    B
  2450.     RET
  2451.  
  2452. UCASE:    CPI    61H    ;CHANGES LOWER CASE CHARACTER..
  2453.     RC        ;..IN A-REG TO UPPER CASE.
  2454.     CPI    7BH
  2455.     RNC
  2456.     ANI    5FH
  2457.     RET
  2458.  
  2459. DECOUT:    PUSH    PSW
  2460.     PUSH    B
  2461.     PUSH    D
  2462.     PUSH    H
  2463.     LXI    B,-10
  2464.     LXI    D,-1
  2465.  
  2466. DECOU2:    DAD    B
  2467.     INX    D
  2468.     JC    DECOU2
  2469.     LXI    B,10
  2470.     DAD    B
  2471.     XCHG
  2472.     MOV    A,H
  2473.     ORA    L
  2474.     CNZ    DECOUT
  2475.     MOV    A,E
  2476.     ADI    '0'
  2477.     CALL    CTYPE
  2478.     POP    H
  2479.     POP    D
  2480.     POP    B
  2481.     POP    PSW
  2482.     RET
  2483.  
  2484. ;---->    DHXOUT: - double precision hex output routine.
  2485.  
  2486. DHXOUT:    PUSH    H
  2487.     PUSH    PSW
  2488.     MOV    A,H    ;GET MS BYTE
  2489.     CALL    HEXO    ;OUTPUT HIGH ORDER BYTE
  2490.     MOV    A,L    ;GET LS BYTE
  2491.     CALL    HEXO    ;OUTPUT LOW ORDER BYTE
  2492.     POP    PSW
  2493.     POP    H
  2494.     RET
  2495.  
  2496. HEXO:    PUSH    PSW
  2497.     RAR
  2498.     RAR
  2499.     RAR
  2500.     RAR
  2501.     CALL    NIBBL
  2502.     POP    PSW
  2503. NIBBL:    ANI    0FH
  2504.     CPI    10
  2505.     JC    ISNUM
  2506.     ADI    7
  2507. ISNUM:    ADI    '0'
  2508.     JMP    TYPE
  2509.  
  2510. ;RETURNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
  2511. ;NO QUESTIONS ASKED, JUST QUIT
  2512.  
  2513. CKQUIT:    LDA    BATCHFLG
  2514.     ORA    A
  2515.     JNZ    CKQTASK    ;ASK FOR RETRY
  2516.     INR    A    ;RESET ZERO FLG
  2517.     RET
  2518. CKQTASK:
  2519.     XRA    A
  2520.     STA    ERRCT
  2521.     CALL    ILPRT
  2522. DB    'Multiple errors encountered.',CR,LF
  2523. DB    'Type Q to quit, R to retry:  ',BELL,0
  2524.     CALL    KEYIN
  2525.     PUSH    PSW
  2526.     CALL    CRLF
  2527.     POP    PSW
  2528.     CALL    UCASE    ;INSTEAD OF "ANI 5FH"
  2529.     CPI    'R'
  2530.     RZ
  2531.     CPI    'Q'
  2532.     JNZ    CKQUIT
  2533.     ORA    A
  2534.     RET
  2535.  
  2536. ILPRT:    XTHL
  2537. ILPLP:    MOV    A,M
  2538.     ORA    A
  2539.     JZ    ILPRET
  2540.     CALL    CTYPE
  2541.     INX    H
  2542.     JMP    ILPLP
  2543. ILPRET:    XTHL
  2544.     RET
  2545.  
  2546. PRTMSG:    MVI    C,PRINT
  2547.     JMP    BDOS
  2548.  
  2549. ERXIT:    POP    D
  2550.     CALL    PRTMSG
  2551.     CALL    ILPRT
  2552. DB    BELL,0
  2553.     LDA    BATCHFLG
  2554.     ORA    A
  2555.     JNZ    DONETCE
  2556.     MVI    A,'Q'    ;RESET QFLG
  2557.     STA    QFLG
  2558.     JMP    ABORT    ;ABORT OTHER COMPUTER
  2559.  
  2560. EXIT:    LXI    D,80H
  2561.     MVI    C,STDMA
  2562.     CALL    BDOS
  2563.     LHLD    STACK
  2564.     SPHL
  2565.     LDA    SAVCCP
  2566.     ORA    A
  2567.     JZ    0    ;WARM BOOT
  2568.     RET
  2569.  
  2570. MOVE128:
  2571.     MVI    B,128
  2572. MOVE:    MOV    A,M
  2573.     STAX    D
  2574.     INX    H
  2575.     INX    D
  2576.     DCR    B
  2577.     JNZ    MOVE
  2578.     RET
  2579.  
  2580. ;DIALING ROUTINES TAKEN (AND GREATLY MODIFIED) FROM PMMI MANUAL.
  2581.  
  2582. ;MODEM CONTROL COMMAND WORDS
  2583.  
  2584. CLEAR    EQU 3FH    ;IDLE MODE
  2585. MAKEM    EQU 1    ;TELE LINE MAKE (OFF HOOK)
  2586. BRKM    EQU 0    ;TELE LINE ON HOOK (BREAK DURING DIALING)
  2587. DTMSK    EQU 1    ;DIAL TONE MASK
  2588. RBLMT    EQU 70    ;# OF SEC*10 TO WAIT BEFORE GIVING NO RING HEARG MSG
  2589. RBWAIT    EQU 50    ;# OF SEC*10 DELAY BEFORE REDIALING NUMBER
  2590. TMPUL    EQU 80H    ;TIMER PULSES MASK BIT
  2591. TRATE    EQU 250    ;VALUE FOR 0.1 SECOND
  2592.  
  2593.  
  2594. DIALPL:    LDA    PMMIBYTE ;FLAG FOR PMMI OPERATION
  2595.     ORA    A    ;SET FLAGS
  2596.     RZ        ;PMMI FALSE, RETURN
  2597.     XRA    A    ; 0
  2598.     STA    CRFLAG    ;CONTINUOUS REDIAL FLAG
  2599.     CALL    DIALPL0    ; DISCONNECT, RECONNECT, WAIT DIAL TONE
  2600.     JC    DILAGN    ;ASK IF TRY AGAIN
  2601.     LXI    H,CMDBUF+1 ;POINT # OF CHARS IN BUFF
  2602.     MOV    A,M    ;GET # OF CHARS
  2603.     CPI    4    ;4 OR MORE CHARS TYPED BEFORE <CR>?
  2604.     JC    ENTNUM    ;NO, ASK FOR NUMBER
  2605.     LXI    H,CMDBUF+6 ;POINT TO NUMBER TO DIAL
  2606.     JMP    DIAL10    ;CHECK IF LIB #, & DIAL
  2607.  
  2608. DIALPL0:
  2609.     CALL    DISCONNT
  2610.     CALL    ILPRT
  2611. DB    CR,LF,'Waiting for dial tone',CR,LF,0
  2612.  
  2613.     MVI    A,MAKEM    ;MAKE MAKE (OFF-HOOK)
  2614.     CALL    OUT$MODCTLP ;DO IT
  2615.     MVI    D,DTMSK    ;DIAL TONE MASK
  2616.     MVI    C,100    ;10 SECOND WAIT
  2617.     CALL    WAIT    ;WAIT FOR DIAL TONE
  2618.     NOP        ;DELAY
  2619.  
  2620. ; WAIT SUBROUTINE WILL RETURN WITH CARRY SET IF UNABLE TO
  2621. ; GET DIALTONE, ELSE CARRY NOT SET MEANS DIALTONE RECEIVED
  2622.  
  2623.     RNC        ;IF DIAL TONE WITHIN 10 SECONDS
  2624.     CALL    ILPRT    ;ELSE, MESSAGE AND RETURN WITH CARRY SET
  2625. DB    CR,LF
  2626. DB    '++No dial tone after 10 seconds++',CR,LF,0
  2627.     STC
  2628.     RET
  2629.  
  2630. ENTNUM:    ;this is all the set-up for the print at entnum2.
  2631.     MVI    C,13    ;number of lines to move
  2632.     LXI    H,NUMBLIB ;address of source memory
  2633.     LXI    D,DBUF    ;address of target memory
  2634.     CALL    NEWLINE    ;start with CRLF
  2635.     STAX    D    ;+LF
  2636.     INX    D    ;and bump it
  2637.  
  2638. ENTNUM1:
  2639.     MVI    B,30    ;number of bytes to move
  2640.     CALL    MOVE    ;move to buffer
  2641.     CALL    SPACES    ;2 entries + 3 spaces = 63 characters
  2642.     MVI    B,30
  2643.     CALL    MOVE
  2644.     CALL    NEWLINE
  2645.     DCR    C    ;number of lines to print
  2646.     JZ    ENTNUM2
  2647.     JMP    ENTNUM1
  2648.  
  2649. NEWLINE:        ;puts CR-LF at memory pointed by DE
  2650.     MVI    A,CR    ;CR
  2651.     STAX    D    ;store it
  2652.     MVI    A,LF    ;LF
  2653.     INX    D    ;bump pointer
  2654.     STAX    D    ;store LF
  2655.     INX    D    ;bump pointer
  2656.     RET
  2657.  
  2658. SPACES:
  2659.     MVI    A,20H    ;space
  2660.     STAX D ! INX D    ; 1
  2661.     STAX D ! INX D    ; 2
  2662.     STAX D ! INX D    ; 3
  2663.     RET
  2664.  
  2665. ENTNUM2:
  2666.     MVI    A,'$'
  2667.     STAX    D
  2668.     MVI    C,PRINT
  2669.     LXI    D,DBUF    ;point to table of numbers to print
  2670.     CALL    BDOS
  2671.     CALL    CRLF
  2672.  
  2673.     CALL    ILPRT
  2674. DB    'Enter number or library letter - Type C/R when finished,',CR,LF
  2675. DB    'CTRL-X cancels while dialing:        ',0
  2676.  
  2677.     LXI    D,CMDBUF
  2678.     CALL    INBUFF
  2679.  
  2680. DIALLP1:
  2681.     LDA    CMDBUF+1
  2682.     ORA    A    ;NULL MEANS <CR> WAS TYPED
  2683.     JZ    BORTIT    ;ABORT DIALING, RETURN TO MENU
  2684.  
  2685.     LXI    H,CMDBUF+2 ;FIRST TYPED CHAR OF NUMBER TO DIAL
  2686.  ;
  2687.  ; ENTER THIS ROUTINE WITH HL POINTING TO NUMBER TO DIAL
  2688.  ;
  2689. DIAL10:
  2690.     MVI    B,'A'    ;FIRST LETTER OF ALPHABET
  2691.     MVI    E,0    ;COUNTS NUMBER OF LETTERS TO MATCH
  2692.     MVI    C,26    ;NUMBER OF LETTERS IN ALPHABET
  2693.     MOV    A,M    ;GET CHAR BUFFER
  2694. DIAL11:
  2695.     CMP    B    ;NUMBER FROM TABLE?
  2696.     JZ    LIBSET
  2697.     INR    B    ;MAKE NEXT LETTER (A-Z)
  2698.     INR    E    ;COUNT UP
  2699.     DCR    C    ;COUNT DOWN
  2700.     JZ    DIALLPX    ;NOT A LETTER
  2701.     JMP    DIAL11    ;LOOP
  2702.  
  2703. LIBSET:
  2704.     LXI    H,NUMBLIB ;PHONE NUMBER LIBRARY
  2705.     LXI    B,30    ;LENGTH OF LIBRARY ENTRY
  2706.     MOV    A,E    ;NUMBER OF TIMES TO ADD 30 TO HL
  2707.     ORA    A    ;SET FLAGS
  2708.     JZ    DIAL13
  2709.  
  2710. DIAL12:
  2711.     MOV    A,M    ;GET FIRST CHAR OF SELECTED LIB ENTRY
  2712.     ORA    A    ;SET FLAGS
  2713.     JZ    DIALLP2    ;SEND BADLIB MSG
  2714.     DAD    B    ;INCREMENT HL BY 30
  2715.     DCR    E    ;COUNTDOWN
  2716.     JNZ    DIAL12    ;NOT THERE YET, LOOP
  2717.  
  2718. DIAL13:
  2719.     MVI    B,30    ;NUMBER OF CHARACTERS TO GET FROM TABLE
  2720.     LXI    D,CMDBUF+1 ;POINT TO BUFFER
  2721.     XCHG        ;HL POINTS TO CMDBUF+1
  2722.     MOV    M,B    ;STORE # OF BYTES IN A TABLE ENTRY
  2723.     XCHG        ;RESTORE REG.
  2724.     INX    D    ;POINT TO FIRST CHAR POSITION IN BUFFER
  2725.     CALL    MOVE    ;MOVE TABLE ENTRY TO BUFFER
  2726.  
  2727. DIALLPX:
  2728.     LDA    CMDBUF+1
  2729.     MOV    E,A    ;NUMBER OF CHARS IN BUFF
  2730.     LXI    H,CMDBUF+2 ;POINT FIRST CHAR
  2731.  
  2732. DIALLP2:
  2733.     MOV    A,M    ;GET FIRST # FROM BUFFER
  2734.  ;
  2735.  ; ROUTINE TO PRINT 'BADLIB' MESSAGE AND ABORT IF NULL ENCOUNTERED
  2736.  ;
  2737.     ORA    A    ;SET FLAGS
  2738.     PUSH    D    ;SAVE DE REGISTERS
  2739.     LXI    D,BADLIB ;BAD LIBRARY NUMBER IF NULL
  2740.     MVI    C,PRINT    ; 9
  2741.     PUSH    PSW    ;SAVE A AND FLAGS
  2742.     CZ    BDOS
  2743.     POP    PSW    ;RESTORE A AND FLAGS
  2744.     POP    D    ;RESTORE DE REGISTERS
  2745.     JZ    BORTIT    ;ABORT
  2746. ;
  2747. ; DIAL A DIGIT, CHECK KBD FOR ABORT
  2748. ;
  2749.     CALL    DIAL    ;DIAL IT
  2750.     CALL    STAT    ; KEYPRESS?
  2751.     ORA    A    ;SET FLAGS
  2752.     CNZ    KEYIN    ;YES, GO GET IT
  2753.     CPI    CAN    ; ^X?
  2754.     JZ    BORTIT    ;YES, ABORT
  2755.     INX    H    ;BUMP POINTER
  2756.     PUSH    D    ;SAVE DE
  2757.     PUSH    H    ;SAVE HL
  2758.     MVI    B,1    ;WAIT 1 TIME INTERVAL
  2759.     CALL    TIMER
  2760.     POP    H    ;RESTORE HL
  2761.     POP    D    ;RESTORE DE
  2762.     DCR    E    ;COUNT DOWN CHARS IN BUFF
  2763.     JNZ    DIALLP2    ;NOT DONE, LOOP
  2764.     JZ    DIALDN    ;DIALING DONE
  2765.  
  2766. DISCONNT:
  2767.     XRA    A    ;0
  2768.     CALL    OUT$MODCTL2 ;CLEAR DAV, ESD, ETC
  2769.     CALL    OUT$MODCTLP ;HANG-UP
  2770.     PUSH    B
  2771.     MVI    B,8    ;wait for PMMI to disconnect
  2772.     CALL    TIMER
  2773.     POP    B
  2774.     RET
  2775.  
  2776. TIMER:    MVI    A,TRATE    ;TRATE 250, VALUE FOR .1 SEC INTERVAL
  2777.     CALL    OUT$BAUDRP ;B-REG CONTAINS NUMBER OF .1 SEC INTERVALS
  2778. TIMES:    CALL    IN$BAUDRP  ;TO COUNT
  2779.     ANI    TMPUL
  2780.     JZ    TIMES    ;WAIT FOR TIMER TO GO HIGH
  2781. TIMEE:    CALL    IN$BAUDRP
  2782.     ANI    TMPUL
  2783.     JNZ    TIMEE    ;WAIT FOR TIMER TO GO LOW
  2784.     DCR    B
  2785.     JNZ    TIMES
  2786.     RET
  2787.  
  2788. BORTIT:    CALL DISCONNT
  2789.     JMP    MENU
  2790.  
  2791. ;AUTO DIALER
  2792.  
  2793. DIAL:    CALL    TYPE    ;PRINT WHATEVER CHARACTER, DASHES, ETC.
  2794.     CPI    30H
  2795.     RC        ;DIGIT MUST BE AT LEAST 0..
  2796.     CPI    'R'    ;COULD IT BE A RINGBACK CHARACTER
  2797.     JNZ    DIAL1    ;NO? - JUMP
  2798.     PUSH    PSW    ;SAVE ACCUMULATOR & FLAGS
  2799.     MOV    A,E    ;GET # OF CHAR LEFT INTO ACC.
  2800.     CPI    01H    ;IS THIS THE LAST CHARACTER?
  2801.     JZ    RINGBK    ;IF SO, IT MUST BE RINGBACK CHAR - DO RINGBACK
  2802.     POP    PSW    ;EVERYTHING BACK AS IT WAS
  2803. DIAL1:    CPI    3AH
  2804.     RNC        ;..AND NOT MORE THAN 9
  2805.     ANI    0FH    ;STRIP ASCII -- COULD ALSO DO SUI 30H ('0')
  2806.     JNZ    DIALS
  2807.     MVI    A,10    ;CONVERT ZERO TO 10 PULSES
  2808. DIALS:    MOV    C,A
  2809.     LDA    PULSERATE ;CONTAINS VALUE FOR DIAL SPEED
  2810.     CALL    OUT$BAUDRP
  2811. DIALC:    CALL    IN$BAUDRP
  2812.     ANI    TMPUL
  2813.     JNZ    DIALC
  2814. DIALB:    CALL    IN$BAUDRP
  2815.     ANI    TMPUL
  2816.     JZ    DIALB
  2817. MAKEP:    MVI    A,MAKEM
  2818.     CALL    OUT$MODCTLP
  2819. TIMEM:    CALL    IN$BAUDRP
  2820.     ANI    TMPUL
  2821.     JNZ    TIMEM
  2822.     MVI    A,BRKM
  2823.     CALL    OUT$MODCTLP
  2824. TIMEB:    CALL    IN$BAUDRP
  2825.     ANI    TMPUL
  2826.     JZ    TIMEB
  2827.     DCR    C
  2828.     JNZ    MAKEP
  2829.     MVI    A,MAKEM
  2830.     CALL    OUT$MODCTLP
  2831.     MVI    B,2
  2832.     CALL    TIMER
  2833.     RET
  2834.  
  2835. RINGBK:    POP    PSW    ;TO GET IT OFF THE STACK
  2836.     LDA    CMDBUF+1 ;GET # OF CHAR IN BUFFER
  2837.     SUI    01    ;SUBTRACT 1 TO AVOID THE RINGBACK CHAR
  2838.     STA    CMDBUF+1 ;STORE THE NEW VALUE
  2839.     MVI    D,DTMSK    ;LOAD TONE DETECT MASK
  2840.     MVI    C,RBLMT    ;SET TIMER FOR RBLMT NUMBER OF SECONDS
  2841.     CALL    WAIT
  2842.     JC    RBTIME    ;JUMP IF NO RING DETECTED
  2843.     MVI    B,25    ;WAIT 2.5 SEC
  2844.     CALL    TIMER
  2845.     CALL    IN$BAUDRP ;IS TONE STILL PRESENT?
  2846.     ANA    D
  2847.     JNZ    RNGBK1
  2848.     JMP    DILAGN    ;YES, MUST BE BUSY
  2849.  
  2850. RNGBK1:    CALL    HANGP    ;HANG UP THE PHONE
  2851.     MVI    B,RBWAIT ;WAIT X SEC
  2852.     CALL    TIMER
  2853.     CALL    DIALPL0    ;GO OFF HOOK & LISTEN FOR DIAL TONE
  2854.     JNC    DIALLPX    ;GO REDIAL NUMBER
  2855.     JMP    DILAGN    ;NO DIAL TONE HEARD
  2856.  
  2857. RBTIME:    CALL    CRLF
  2858.     JMP    RNGBK1    ;HANGUP, REDIAL, & LISTEN FOR CARRIER
  2859.  
  2860.  
  2861. ;TIME OUT ROUTINE. MUST BE CALLED WITH MASK IN D REG FOR INPUT
  2862. ;AT RELATIVE PORT 2 AND NUMBER OF SECONDS * 10 IN C REG.
  2863.  
  2864. WAIT:    MVI    B,1    
  2865.     CALL    TIMER    ;WAIT FOR TIMER TO GO HIGH THEN LOW
  2866.     CALL    IN$BAUDRP ;PMMIADDR+2 (MODEM STATUS PORT)
  2867.     ANA    D    ;(CTS or DIALTONE MASK)
  2868.     RZ        ;ACTIVE LOW, SO RETURN ON 0
  2869.     PUSH    B    ;SAVE..
  2870.     PUSH    D    ;..ACTIVE REG'S
  2871.     CALL    STAT    ;KEYPRESS?
  2872.     ORA    A    ;SET FLAGS
  2873.     CNZ    KEYIN    ;YES, GET CHAR
  2874.     CPI    CAN    ;^X?
  2875.     JZ    WAIT1    ;YES, DISCONNECT, JMP TO MENU
  2876.     POP D        ;RESTORE..
  2877.     POP B        ;..REGS
  2878.     DCR C        ;COUNT-DOWN
  2879.     JNZ    WAIT
  2880.     STC        ;SET CARRY TO INDICATE MASK NOT SET
  2881.     RET
  2882.  
  2883. WAIT1:
  2884.     POP    D    ;RESET..
  2885.     POP    B    ;..STACK
  2886.     JMP    DISCON1    ;DISCONNECT
  2887.  
  2888. HANGP:    MVI    A,CLEAR
  2889.     CALL    OUT$MODCTL2
  2890.     MVI    A,0
  2891.     CALL    OUT$MODCTLP
  2892.     RET
  2893.  
  2894. DIALDN:    CALL    CRLF
  2895.     MVI    A,07FH        ;TURN ON DTR
  2896.     CALL    OUT$MODCTL2 ;TIMER RATE?
  2897.  
  2898.     MVI    B,1
  2899.     CALL    TIMER    ;WAIT FOR MODEM TO TURN ON DTR
  2900.  
  2901.     MVI    A,5DH    ;2 STOP BITS, NO PARITY, 8 DATA BITS
  2902.             ;+ NO DISCONNECT AFTER 17 SECS
  2903.     CALL    OUT$MODCTLP
  2904.  
  2905.     MVI    D,4      ;CLEAR TO SEND MASK
  2906.     MVI    C,WAITCTS ;wait time for cts (25.5 SEC MAX)
  2907.     CALL    WAIT
  2908.  
  2909.     JNC    CONMADE    ;CONNECTION MADE
  2910.  
  2911.     CALL    DISCONNT
  2912. DILAGN:
  2913.     LDA    CRFLAG    ;CONTINUOUS REDIAL FLAG
  2914.     ORA    A
  2915.     JNZ    DILAGN0
  2916.     CALL    ILPRT
  2917. DB    CR,LF,'No answer after time-out.  Redial? (Y/N/C): ',BELL,0
  2918.     CALL    KEYIN    ;GET RESPONSE
  2919.     CALL    TYPE    ;ECHO IT
  2920.     CALL    UCASE    ;ANI 5FH
  2921.     CALL    CRLF    ;NEW LINE
  2922.     CPI    'N'    ;REDIAL?
  2923.     JZ    MENU    ;NO, GO MENU
  2924.     CPI    'Y'    ;REDIAL?
  2925.     JZ    DILAGN0    ;YES, REDIAL
  2926.     CPI    'C'    ;CONTINUOUS REDIAL?
  2927.     JNZ    DILAGN    ;INVALID RESPONSE, ASK AGAIN
  2928.     XRA A ! CMA    ;0FFH
  2929.     STA    CRFLAG    ;CONTINUOUS REDIAL FLAG
  2930.  DILAGN0:
  2931.     MVI    B,50    ;5 seconds wait for pmmi reset
  2932.     CALL    TIMER    ;else busy tone may be sensed as dialtone
  2933.     CALL    DIALPL0    ;WAIT FOR DIAL TONE
  2934.     JNC    DIALLP1    ;DIAL NUMBER
  2935.     JMP    DILAGN    ;NO DIAL TONE AFTER 10 SECS
  2936.  
  2937. CONMADE:
  2938.     CALL    ILPRT
  2939. DB    CR,LF,'Connection established - Select options: ',BELL,0
  2940. DILAGN1:
  2941.     CALL    STAT    ;KEYPRESS?
  2942.     ORA    A    ;SET FLAGS
  2943.     JNZ    GETCMD    ;KEY PRESSED, GO GET OPTIONS
  2944.     MVI    A,BELL
  2945.     CALL    TYPE    ;RING BELL
  2946.     LXI    B,2000H
  2947. DILAGN2:        ;@7.32.........
  2948.     DCR    C
  2949.     JNZ    DILAGN2    ;KILL SOME TIME FOR TERMINAL TO PROCESS BELL
  2950.     DCR    B
  2951.     JNZ    DILAGN2    ;@7.32.........
  2952.     JMP    DILAGN1    ;LOOP
  2953.  
  2954.  
  2955. ;INITIALIZES CP/M FILE CONTROL BLOCKS AT 5CH AND 6CH
  2956. SETFCB:    LXI    D,CMDBUF
  2957.     LXI    H,FCB
  2958.     CALL    CPMLINE
  2959.     CALL    PROCOPT
  2960.  
  2961. CHECKNM:
  2962.     LDA    FCB+1    ;CHECK ON THE PRIMARY OPTION
  2963.     CPI    'E'    ;RETURN IF ECHO OPTION
  2964.     RZ
  2965.     CPI    'M'    ;RETURN TO MENU
  2966.     RZ
  2967.     MOV    B,A
  2968.     LDA    PMMIBYTE
  2969.     ORA    A
  2970.     MOV    A,B
  2971.     JZ    S4
  2972.     CPI    'C'
  2973.     RZ
  2974. S4:    CPI    'T'
  2975.     JZ    TERMSEL
  2976.     CPI    'S'
  2977.     JZ    CKFILE
  2978.     CPI    'R'
  2979.     JNZ    BDOPT
  2980.     LDA    BATCHFLG ;IF MULT FILE MODE, THEN..
  2981.     ORA    A     ;..RECV OPT DOES NOT NEED..
  2982.     RZ         ;..NAME.
  2983.     JMP    CKFILE
  2984. BDOPT:    CALL    ILPRT
  2985. DB    CR,LF,'++Bad Option++',CR,LF,0
  2986.     JMP    REENT
  2987. CKFILE:    LDA    FCB+17    ;IF OPTION THAT NEEDS FILE NAME,..
  2988.     CPI    ' '    ;..THEN CHECK TO SEE IF NAME..
  2989.     RNZ        ;..EXISTS. IF NOT..
  2990. REENT:    CALL    ILPRT    ;..DO EVERYTHING OVER.
  2991. DB    CR,LF,'Re-enter PRIMARY option and file name only: ',BELL,0
  2992.     LXI    D,CMDBUF
  2993.     CALL    INBUFF
  2994.     JMP    SETFCB
  2995.  
  2996. TERMSEL:
  2997.     LDA    FCB+17
  2998.     CPI    ' '
  2999.     JNZ    SAVAGN
  3000.     MVI    A,FALSE
  3001.     STA    SAVEFLG
  3002.     MVI    A,TRUE
  3003.     STA    NFILFLG
  3004.     CMA
  3005.     OUT    FRONTPAN
  3006.     RET
  3007. SAVAGN:
  3008.     MVI    A,FALSE
  3009.     STA    NFILFLG
  3010.     RET
  3011.  
  3012. NEWBAUD:
  3013.     LDA    PMMIBYTE
  3014.     ORA    A
  3015.     RZ
  3016.     CALL    ILPRT
  3017. DB    'Enter New Baudrate: ',0
  3018.     LXI    H,FCB+9
  3019.     MVI    M,0    ;PUTS A ZERO IN FIRST POSITION SO AS TO
  3020. LOOP5:    CALL    KEYIN    ;FORCE THE DEFAULT OPTION OF 300 BAUD.
  3021.     CPI    CR    ;CARRIAGE RET ENTERS BAUD RATE
  3022.     JNZ    CONNEWB    ;GOES TO THE ESTABLISHED ROUTINE - RETURN TO MAIN
  3023.     CALL    CRLF    ;PROGRAM IS DONE THERE.
  3024.     JMP    SETBAUD
  3025. CONNEWB:
  3026.     CPI    30H    ;MAKE SURE IT'S..
  3027.     JC    LOOP5    ;..A DIGIT, ELSE..
  3028.     CPI    3AH    ;..DON'T ACCEPT IT.
  3029.     JNC    LOOP5
  3030.     MOV    M,A
  3031.     MOV    C,A
  3032.     CALL    TYPE    ;ECHO THE CHARACTER ENTERED
  3033.     INX    H
  3034.     JMP    LOOP5
  3035. ;
  3036. ;****************************************************************
  3037. ;* CRCSUBS (Cyclic Redundancy Code Subroutines) version 1.20    *
  3038. ;* 8080 Mnemonics                        *
  3039. ;*                                *
  3040. ;*   These subroutines will compute and check a true 16-bit    *
  3041. ;* Cyclic Redundancy Code for a message of arbitrary length.    *
  3042. ;*                                *
  3043. ;* The  use  of this scheme will guarantee detection of all    *
  3044. ;* single and double bit errors, all  errors  with  an  odd    *
  3045. ;* number  of  error bits, all burst errors of length 16 or    *
  3046. ;* less, 99.9969% of all 17-bit error bursts, and  99.9984%    *
  3047. ;* of  all  possible  longer  error bursts.  (Ref: Computer    *
  3048. ;* Networks, Andrew S.  Tanenbaum, Prentiss-Hall, 1981)        *
  3049. ;*                                *
  3050. ;* Designed & coded by Paul Hansknecht, June 13, 1981        *
  3051. ;*                                *
  3052. ;* Copyright (c) 1981, Carpenter Associates            *
  3053. ;*            Box 451                    *
  3054. ;*            Bloomfield Hills, MI 48013            *
  3055. ;*            313/855-3074                *
  3056. ;*                                *
  3057. ;* This program may be freely reproduced for non-profit use.    *
  3058. ;*                                *
  3059. ;****************************************************************
  3060. ;
  3061. ;    ENTRY    CLRCRC,UPDCRC,FINCRC,CHKCRC
  3062. ;
  3063. CLRCRC:    EQU    $    ;Reset CRC Accumulator for a new message.
  3064.     PUSH    H
  3065.     LXI    H,0
  3066.     SHLD    CRCVAL
  3067.     POP    H
  3068.     RET
  3069. ;
  3070. UPDCRC:    EQU    $    ;Update CRC Accumulator using byte in (A).
  3071.     PUSH    PSW
  3072.     PUSH    B
  3073.     PUSH    H
  3074.     MVI    B,8
  3075.     MOV    C,A
  3076.     LHLD    CRCVAL
  3077. ;
  3078. UPDLOOP: MOV    A,C
  3079.     RLC
  3080.     MOV    C,A
  3081.     MOV    A,L
  3082.     RAL
  3083.     MOV    L,A
  3084.     MOV    A,H
  3085.     RAL
  3086.     MOV    H,A
  3087.     JNC    SKIPIT
  3088.     MOV    A,H ;The generator is X^16 + X^12 + X^5 + 1
  3089.     XRI    10H ;as recommended by CCITT.
  3090.     MOV    H,A ;An alternate generator which is often
  3091.     MOV    A,L ;used in synchronous transmission protocols
  3092.     XRI    21H ;is X^16 + X^15 + X^2 + 1. This may be
  3093.     MOV    L,A ;used by substituting XOR 80H for XOR 10H
  3094. SKIPIT:    DCR    B   ;and XOR 05H for XOR 21H in the adjacent code.
  3095.     JNZ    UPDLOOP
  3096.     SHLD    CRCVAL
  3097.     POP    H
  3098.     POP    B
  3099.     POP    PSW
  3100.     RET
  3101. ;
  3102. FINCRC:    EQU    $    ; Finish CRC calc for outbound message.
  3103.     PUSH    PSW
  3104.     XRA    A
  3105.     CALL    UPDCRC
  3106.     CALL    UPDCRC
  3107.     PUSH    H
  3108.     LHLD    CRCVAL
  3109.     MOV    D,H
  3110.     MOV    E,L
  3111.     POP    H
  3112.     POP    PSW
  3113.     RET
  3114. ;
  3115. CHKCRC:    EQU    $    ; Check CRC bytes of received message.
  3116.     PUSH    H
  3117.     LHLD    CRCVAL
  3118.     MOV    A,H
  3119.     ORA    L
  3120.     POP    H
  3121.     RZ
  3122.     MVI    A,0FFH
  3123.     RET
  3124. ;
  3125. CRCVAL:    DW    0
  3126. ;
  3127. MENU:    LXI    H,RESTSN  ;RESTORE SECTORE NUMBERS..
  3128.     LXI    D,SECTNOB ;..FOR NEW FILE TRANSFER.
  3129.     MVI    B,SECTNOE-SECTNOB
  3130.     CALL    MOVE
  3131.     LXI    H,RESTROPT ;RESTORE OPTION TABLE
  3132.     LXI    D,OPTBL
  3133.     MVI    B,OPTBE-OPTBL
  3134.     CALL    MOVE
  3135.     MVI    A,0
  3136.     STA    MFFLG1    ;RESET MFACCESS ROUTINE..
  3137.     CMA        ;..AND MULTI TRANS IN CASE..
  3138.     STA    FSTFLG    ;..OF ABORT.
  3139.  
  3140. MENU1:    LDA    XPRFLG    ;TEST IF MENU SHOULD BE SHOWN
  3141.     ORA    A
  3142.     JNZ    XPRT
  3143. MENU2:    CALL    ILPRT
  3144. DB    CR,LF,CR,LF
  3145. DB    'WRT   - Write file to disk (from terminal mode)',CR,LF
  3146. DB    'DEL   - Erase present file (from terminal mode)',CR,LF
  3147. DB    'RET   - Return to terminal mode with no loss of data',CR,LF,0
  3148.     LDA    PMMIBYTE
  3149.     ORA    A
  3150.     JZ    S5
  3151.     CALL    ILPRT
  3152. DB    'DSC   - Disconnect',CR,LF
  3153. DB    'CAL   - Dial number',CR,LF,0
  3154. S5:    CALL    ILPRT
  3155. DB    'XPR   - Toggle expert mode (Menu on/off)',CR,LF
  3156. DB    'DIR   - List directory (may specify drive)',CR,LF
  3157. DB    'CPM   - Exit to CP/M',CR,LF
  3158. DB    'S     - Send CP/M file',CR,LF
  3159. DB    'R     - Receive CP/M file',CR,LF
  3160. DB    'T     - Terminal mode (optional file name)',CR,LF
  3161. DB    'E     - Terminal mode with echo',CR,LF,0
  3162. XPRT:    CALL    ILPRT
  3163. DB    CR,LF,CR,LF,'DEFAULT DRIVE: ',0
  3164.     MVI    C,25    ;CURRENT DISK FUNCTION
  3165.     CALL    BDOS
  3166.     ADI    41H    ;MAKE ASCII
  3167.     CALL    TYPE
  3168.     CALL    ILPRT
  3169. DB    CR,LF,CR,LF,'Command: '
  3170. DB    0
  3171.  
  3172. GETCMD:    LXI    D,CMDBUF ;ENTER COMMAND
  3173.     CALL    INBUFF
  3174.     CALL    CRLF
  3175.     LXI    D,CMDBUF+2 ;POINT TO COMMAND
  3176.     CALL    ILCOMP
  3177. DB    'CPM',0
  3178.     JNC    EXIT
  3179.     CALL    ILCOMP
  3180. DB    'DIR',0
  3181.     JNC    DIR
  3182.     CALL    ILCOMP
  3183. DB    'RET',0
  3184.     JC    NXTOPT1    ;CARRY SET = NO MATCH
  3185.     lda    origsav    ;@MODEM75.FIX
  3186.     sta    origflg    ;@MODEM75.FIX
  3187.     LHLD    HLSAVE    ;RETURN TO TERMINAL..
  3188.     JMP    TERM    ;..MODE WITH SAVE OPTION..
  3189.             ;..IF PREVIOUSLY ENABLED.
  3190. NXTOPT1:
  3191.     LDA    PMMIBYTE
  3192.     ORA    A
  3193.     JZ    S6
  3194.     CALL    ILCOMP    ;DE SET FROM 1ST ILCOMP CALL
  3195. DB    'DSC',0
  3196.     JNC    DISCON1
  3197. S6:    CALL    ILCOMP
  3198. DB    'WRT',0
  3199.     JNC    WRTFIL
  3200.     CALL    ILCOMP
  3201. DB    'XPR',0
  3202.     JNC    XPRMODE
  3203.     CALL    ILCOMP
  3204. DB    'DEL',0
  3205.     JNC    NEWFILE
  3206.     LDA    PMMIBYTE
  3207.     ORA    A
  3208.     JZ    NXTOPT2
  3209.     CALL    ILCOMP
  3210. DB    'CAL',0
  3211.     JC    NXTOPT2
  3212.     MVI    A,20H        ;FOOL THE SYSTEM'''
  3213.     STA    CMDBUF+4    ;..CMDBUF SO THAT IT..
  3214.     JMP    DOOPT        ;..LOOKS AT OPTION FOR DIAL
  3215.  
  3216. NXTOPT2:
  3217.     PUSH    H
  3218.     LDA    CMDBUF+2
  3219.     LXI    H,COMPLIST
  3220.     CALL    COMPARE    ;COMPARES LIST POINTED TO BY HL..
  3221.     POP    H    ;..TO CHAR IN A-REG.
  3222.     JC    MENU1    ;CARRY SET = NO MATCH
  3223.  
  3224. DOOPT:    PUSH    H    ;LOAD ORIGINAL FCB WITH TRANSFER..
  3225.     CALL    SETFCB    ;..CMDS AND GO TO BEGINNING OF..
  3226.     POP    H    ;..PROGRAM. WILL FOLLOW SAME LOGIC..
  3227.     JMP    RESTART    ;..AS IF PROGRAM WERE CALLED WITH..
  3228.             ;..CP/M COMMAND LINE.
  3229.  
  3230. DISCON1:
  3231.     LDA    PMMIBYTE
  3232.     ORA    A
  3233.     JZ    MENU
  3234.     CALL    DISCONNT
  3235.     CALL    ILPRT
  3236. DB    CR,LF,'++Disconnected++',CR,LF,BELL,0
  3237.     JMP    MENU    ;@MODEM75.FIX (was MENU1) - restore option tables
  3238.  
  3239. DIR:    CALL    DIRLST
  3240.     JMP    XPRT
  3241.  
  3242. NEWFILE:
  3243.     LDA    FCB3+1
  3244.     CPI    ' '
  3245.     JZ    MENU1    ;IF NO FILE, DON'T ERASE
  3246.     LXI    D,FCB3
  3247.     MVI    C,ERASE
  3248.     CALL    BDOSRT
  3249.     MVI    A,TRUE    ;DO NOT ALLOW TERMINAL..
  3250.     STA    NFILFLG    ;..SAVE SINCE NO FILE..
  3251.     CMA        ;..SPECIFIED.
  3252.     STA    SAVEFLG
  3253.     OUT    FRONTPAN
  3254.     LXI    H,FCB3
  3255.     CALL    INITFCBS
  3256.     JMP    MENU1
  3257.  
  3258. WRTFIL:
  3259.     LDA    NFILFLG
  3260.     CPI    TRUE
  3261.     JZ    MENU1
  3262.     LDA    FCB3+1    ;CHECK THAT FILE WAS REQUESTED
  3263.     CPI    ' '
  3264.     JZ    MENU1
  3265.     LHLD    HLSAVE
  3266.     CALL    NUMRECS    ;DISK WRITE ROUTINE AS USED IN..
  3267.     CALL    WRTDSK    ;..IN THE INTDSKSV ROUTINE.
  3268.     CALL    CLOSE3
  3269.     MVI    A,TRUE
  3270.     STA    NFILFLG
  3271.     CMA
  3272.     STA    SAVEFLG
  3273.     OUT    FRONTPAN
  3274.     LXI    H,FCB3
  3275.     CALL    INITFCBS ;BLANK OUT FCB SO WRITTEN FILE..
  3276.     JMP    MENU1     ;..CAN'T BE ERASED.
  3277.  
  3278. XPRMODE:
  3279.     LDA    XPRFLG
  3280.     CMA
  3281.     STA    XPRFLG
  3282.     JMP    MENU1
  3283.  
  3284.  
  3285. COMPARE:
  3286.     MOV    B,M    ;COMPARES A-REG WITH LIST..
  3287. COMPLP:    INX    H    ;..ADDRESSED BY HL. FIRST ELEMENT..
  3288.     CMP    M    ;..OF LIST MUST BE NUMBER OF ELEMENTS..
  3289.     JZ    VALID    ;..BEING COMPARED. RETURNS WITH..
  3290.     DCR    B    ;..CARRY SET IF A-REG DOES NOT..
  3291.     JNZ    COMPLP    ;.. CONTAIN AN ELEMENT IN LIST.
  3292.     STC
  3293. VALID:    RET
  3294.  
  3295. COMPLIST: DB 5, 'S', 'R', 'T', 'E', 'M'
  3296.  
  3297. ILCOMP:    INLNCOMP    ;A MACRO IN MACROS.LIB
  3298.  
  3299.  
  3300. INBUFF:    INBUF    ;A MACRO IN "MACROS.LIB"
  3301.  
  3302. ;IF ABOVE ROUTINE DOES NOT LET YOU EDIT IN A PROPER MANNER,
  3303. ;THEN THE MACRO MAY BE SUBSTITUTED FOR THE FOLLOWING ROUTINE:
  3304.  
  3305. ;INBUFF:
  3306. ;    MVI    C,RDBUF
  3307. ;    CALL    BDOSRT
  3308. ;    RET    ;BUT BE CAREFUL OF CONTROL-C
  3309.  
  3310.  
  3311. CPMLINE:
  3312.     CMDLINE    ;A MACRO IN "MACROS.LIB"
  3313.  
  3314. DIRLST:    DIRLIST    ;A MACRO IN "MACROS.LIB"
  3315.  
  3316. NFILFLG:
  3317.     DB FALSE    ;NORMALLY SET TO FALSE. ALLOWS WRITE TO..
  3318.         ;..MEMORY IN TERMINAL MODE.
  3319.  
  3320. OPTION:    DB 0
  3321.  
  3322. OPTBL:    EQU $
  3323. ANSWFLG:
  3324.     DB 'A'
  3325. DISCFLG:
  3326.     DB 'D'
  3327. ORIGFLG:
  3328.     DB 'O'
  3329. QFLG:    DB 'Q'
  3330. RSEEFLG:
  3331.     DB 'R'
  3332. SSEEFLG:
  3333.     DB 'S'
  3334. VSEEFLG:
  3335.     DB 'V'
  3336. TERMFLG:
  3337.     DB 'T'
  3338. EPARITY:
  3339.     DB '0'    ;EVEN PARITY SUB-OPTION - ONLY AVAILABLE IN 'S' AND 'R' MODES
  3340. OPARITY:
  3341.     DB '1'    ;ODD PARITY SUB-OPTION - ONLY AVAILABLE IN 'S' AND 'R' MODES
  3342. BATCHFLG:
  3343.     DS 1    ;SET TO 'B' BY MENU. DOES NOT ALLOW MULTI-..
  3344. OPTBE:    EQU $    ;..FILE XFER WHEN PROGRAM INITIALLY CALLED.
  3345.  
  3346. RESTROPT:    ;MUST BE IN SAME ORDER AS TABLE ABOVE
  3347.  
  3348.     DB 'A','D','O','Q','R','S','V','T'
  3349. ;    DB 'C'        ;@7.41
  3350.     DB '0','1','B'
  3351.  
  3352. CRCFLG: DB 'C'    ;use CRC instead of cksum    ;@7.41 (moved)
  3353.  
  3354. RESTSN:    DB 0,0,0,0,0,0
  3355.     DW DBUF
  3356.     DB 0,0,0,0,0
  3357.  
  3358. SECTNOB:    EQU $
  3359. RCVSNO:        DB 0
  3360. SECTNO:        DW 0
  3361. ERRCT:        DB 0
  3362. ERRCDE:        DB 0
  3363. EOFLG:        DB 0
  3364. SECPTR:        DW DBUF
  3365. SECINBF:    DB 0
  3366. MAXEXT:        DB 0
  3367. RCNT:        DW 0
  3368. DATAFLG:    DB 0
  3369. EXACFL:        DB 0
  3370. SECTNOE:    EQU $
  3371.  
  3372. BADOPT:    CALL    ILPRT
  3373. DB    'Invalid option',CR,LF,BELL,0
  3374.     JMP    MENU
  3375.  
  3376. FSTFLG:    DB TRUE
  3377. FIRSTME:
  3378.     DB    0FFH
  3379.         ;first SOH received switch(it is zero after 1rst SOH)
  3380.  
  3381. CMDBUF:    DB    80H,0
  3382.     DS    80H
  3383. BADLIB:    DB    CR,LF,'++Bad library number called++',CR,LF,'$'
  3384. HLSAVE:    DS    2
  3385. DISKNO:    DS    1
  3386. SENDFLG:
  3387.     DS    1
  3388. NBSAVE:    DS    2
  3389. BGNMS:    DS    2
  3390. FILECT:    DS    1
  3391. NAMECT:    DS    1
  3392. origsav: ds    1    ;@MODEM75.FIX
  3393. MODCTLB:
  3394.     DB    07FH
  3395. UARTCTLB:
  3396.     DB    ANSWMOD    ; @7.5  (was previously ORIGMOD)
  3397.  
  3398.     DS    100
  3399. STACK:    DS    2
  3400. FCB3:    DS    33
  3401. FCBBUF:    DS    15
  3402. DBUF:        EQU    $    
  3403. NAMEBUF:    EQU    DBUF+(DBUFSIZ*1024)
  3404.         ;BUFFER FOR NAMES IN BATCH MODE. OVERFLOWS..
  3405.         ;..ABOVE PROGRAM CODE.
  3406.  
  3407. ;    BDOS EQUATES
  3408. RDCON        EQU    1
  3409. WRCON        EQU    2
  3410. PRINT        EQU    9
  3411. RDBUF        EQU    10
  3412. CONST        EQU    11
  3413. OPEN        EQU    15
  3414. CLOSE        EQU    16
  3415. SRCHF        EQU    17
  3416. SRCHN        EQU    18
  3417. ERASE        EQU    19
  3418. READ        EQU    20
  3419. WRITE        EQU    21
  3420. MAKE        EQU    22
  3421. REN        EQU    23
  3422. STDMA        EQU    26
  3423. FILSIZ        EQU    35
  3424. BDOS        EQU    5
  3425. REIPL        EQU    0
  3426. FCB        EQU    5CH
  3427. FCBEXT        EQU    FCB+12
  3428. FCBSNO        EQU    FCB+32
  3429. FCBRNO        EQU    FCB+32
  3430. FCB2        EQU    6CH
  3431.  
  3432. LAST        END    100H
  3433.  
  3434.