home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / cpmug / cpmug079.ark / MODEM741.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  65.9 KB  |  3,296 lines

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