home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / MODEMS / MODEM2 / UKM7.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  61KB  |  3,112 lines

  1. ;
  2. ;            UKM7
  3. ;This program was originally written in 1977 by Ward Christensen.
  4. ;Ward's comments were removed, Terminal File and Batch Mode were
  5. ;added in 1980 by Mark Zeiger and James Mills. The original CRC
  6. ;checks were added by Paul Hansknecht in June 1981.
  7. ;Improved terminal file facilities, menus and a general tidy
  8. ;up of a very untidy program, removal of all modem dependent
  9. ;features, many bugs and adaptation for the UK CP/M Users
  10. ;Group Library by David Back. 4 May 1983.
  11. ;Version 1.5 includes many additional facilities, including a
  12. ;printer buffer, active toggling of terminal and secondary
  13. ;options, faster CRC's etc. David Back. 21 February 1984
  14. ;
  15. ;The file exchange protocols are compatible with the MODEMX
  16. ;series of programs in the US CP/M UG Library.
  17. ;UKM7 is compatible with CP/M 1.4 and CP/M 2.2.
  18. ;
  19. FALSE    EQU    0
  20. TRUE    EQU    0FFH
  21.  
  22.     ORG 100H
  23. ;********* SYSTEM DEPENDENT OVERLAY **************
  24. ;**** This is a general purpose overlay applicable to many systems ****
  25.     JMP    300H    ;absolute start of program
  26.  
  27. MODCTLP    EQU    0ECH    ;MODEM CONTROL PORT
  28. MODDATP    EQU    0EDH    ;MODEM DATA PORT FOR SEND
  29. MODDRCV    EQU    0EDH    ;MODEM DATA PORT FOR RECEIVE
  30. MSNDB    EQU    1    ;MODEM SEND BIT (XMIT BUFF EMPTY)
  31. MSNDR    EQU    1    ;MODEM SEND READY
  32. MRCVB    EQU    2    ;MODEM RECEIVE BIT (DAV)
  33. MRCVR    EQU    2    ;MODEM RECEIVE READY
  34. BAUD    EQU    2    ;enter 1 for 1X, or 2 for 16X, or 3 for 64X
  35. ;It is important not to alter the addresses of labels below
  36. OLID:        DB 1        ;overlay identifier
  37. TWIDTH:        DB 70        ;max. terminal columns
  38. FASTCLK:    DB  TRUE    ;4 MHz or greater processor speed
  39. BAKUPBYTE:    DB  TRUE    ;true=make .BAK file
  40. XPRFLG:        DB  TRUE    ;true=menu initially off
  41. SAVCCP:        DB  TRUE    ;true=do not overwrite CCP
  42. SAVEFLG:    DB TRUE        ;true=terminal filesave initially on
  43. ECHOFLG:    DB FALSE    ;true=terminal echo initially on
  44. INITFLG:    DB FALSE    ;true=modem port already initialised
  45. ANSBAK:        DB TRUE        ;true=answerback on ^E
  46. INMODCTLP:    IN    MODCTLP    ;get port status
  47.         RET
  48.         DB    0    ;space for memory mapped I/O's
  49. OUTCTLP:    OUT    MODCTLP    ;control
  50.         RET
  51.         DB    0
  52. OUTMODDATP:    OUT    MODDATP    ;send data
  53.         RET
  54.         DB    0
  55. ANISND:        ANI    MSNDB    ;bit to test for send ready
  56.         RET
  57. CPISND:        CPI    MSNDR    ;value of send bit when ready
  58.         RET
  59. INMODDATP:    IN    MODDRCV    ;get data
  60.         RET
  61.         DB    0
  62. ANIRCV:        ANI    MRCVB    ;bit to test for receive ready
  63.         RET
  64. CPIRCV:        CPI    MRCVR    ;value of receive bit when ready
  65.         RET
  66. LOGMSSG:    DB 'David;Back;Shepperton Middx',CR,LF,0
  67.     ORG 150H    ;do not alter this org
  68. ;The routine below should work in most systems which use an 8251 USART
  69. ;Modem port must be initialised for 8 data bits and no parity
  70. INITMOD:LXI    D,CPMS    ;finish signon message
  71.     MVI    C,9
  72.     CALL    BDOS
  73.     LDA    INMODCTLP+1
  74.     CALL    HEXPRT
  75.     LXI    D,DPMS
  76.     MVI    C,9
  77.     CALL    BDOS
  78.     LDA    OUTMODDATP+1
  79.     CALL    HEXPRT
  80.     LXI    D,HMS
  81.     MVI    C,9
  82.     CALL    BDOS
  83.     LDA    INITFLG
  84.     ORA    A    ;return if already initialsed
  85.     RNZ
  86.     MVI    A,0EH
  87.     CALL    OUTCTLP    ;force command instruction
  88.     PUSH    PSW
  89.     POP    PSW
  90.     MVI    A,40H
  91.     CALL    OUTCTLP    ;internal reset
  92.     PUSH    PSW
  93.     POP    PSW
  94.     MVI    A,6CH OR (BAUD AND 3)
  95.     CALL    OUTCTLP    ;8 bits no parity
  96.     PUSH    PSW
  97.     POP    PSW
  98.     MVI    A,37H    ;modem connected
  99.     CALL    OUTCTLP
  100.     CALL    INMODDATP
  101.     CALL    INMODDATP ;clear buffers
  102.     RET
  103. ;necessary because location of HEXO is not fixed
  104. HEXPRT:    PUSH    PSW
  105.     RAR
  106.     RAR
  107.     RAR
  108.     RAR
  109.     CALL    NIB
  110.     POP    PSW
  111. NIB:    ANI    0FH
  112.     CPI    10
  113.     JC    NU
  114.     ADI    7
  115. NU:    ADI    '0'
  116.     MOV    E,A
  117.     MVI    C,2
  118.     CALL    BDOS
  119.     RET
  120. CPMS:    DB 'Control port=0$'
  121. DPMS:    DB 'H  Data port=0$'
  122. HMS:    DB 'H',CR,LF,'$'
  123. ;********** END OF OVERLAY AREA ************
  124.  
  125. DBUFSIZ    EQU    2    ;S & R BUFFER SIZE IN KBYTES
  126.             ;2K is the normally accepted optimum
  127. RING    EQU    8    ;print ring buffer size, K bytes
  128. ERRLIM    EQU 10        ;NUMBER OF TIMES TO RETRY
  129.             ;SEND/RECEIVE ERRORS BEFORE QUIT
  130. COMPUT EQU 'C'-40H    ; ^C = Computer mode
  131. DMENU EQU 'D'-40H    ; ^D = display terminal menu
  132. EXITCHR    EQU 'E'-40H    ; ^E = exit terminal mode
  133. TRANCHR    EQU 'T'-40H    ; ^T = TRANSFER FILE
  134. SAVECHR    EQU 'Y'-40H    ; ^Y = memory save toggle
  135. PRNCHR    EQU 'P'-40H    ; ^P = printer toggle
  136. EXTCHR    EQU '^'-40H    ;SEND NEXT CHAR LITERALLY
  137. SAVON    EQU 12H        ;^R Terminal filesave on
  138. SAVOFF    EQU 14H        ;^T Terminal filesave off
  139. ;
  140. ;PROGRAM FOLLOWING IS NOT SYSTEM DEPENDENT,
  141. ;PLEASE DO NOT INTRODUCE ANY SYSTEM DEPENDENT FEATURES BELOW
  142. ;
  143. XOFF    EQU 'S'-40H    ; ^S = XOFF CHARACTER
  144. XON    EQU 'Q'-40H    ; ^Q = XON CHARACTER
  145. CAN    EQU 'X'-40H    ; ^X = CANCEL SEND/RECEIVE
  146. EOFCHAR    EQU 'Z'-40H    ; ^Z = END OF FILE
  147. ENQ    EQU 5        ; ^E Auto ID
  148. SOH    EQU 1        ; START OF HEADER
  149. EOT    EQU 4        ; END OF TEXT
  150. ACK    EQU 6        ; ACKNOWLEDGE
  151. NAK    EQU 15H        ; NOT ACKNOWLEDGE
  152. CRC    EQU 'C'        ;USED TO RQST CRC INSTEAD OF CKSUM
  153. BDNMCH    EQU 75H        ; BAD NAME MATCH
  154. LF    EQU 10        ; LINEFEED
  155. CR    EQU 13        ; CARRIAGE RETURN
  156. BELL    EQU 7        ; BELL CHARACTER
  157. WRCON    EQU 2
  158. LIST    EQU 5        ;printer o/p
  159. PRINT    EQU 9        ;string o/p to console
  160. OPEN    EQU 15
  161. CLOSE    EQU 16
  162. SRCHF    EQU 17
  163. SRCHN    EQU 18
  164. ERASE    EQU 19
  165. READ    EQU 20
  166. WRITE    EQU 21
  167. MAKE    EQU 22
  168. REN    EQU 23
  169. STDMA    EQU 26
  170. FILSIZ    EQU 35
  171. BDOS    EQU 5
  172. FCB    EQU 5CH
  173. FCBEXT    EQU FCB+12
  174. FCBRNO    EQU FCB+32
  175.  
  176.     ORG 300H    ;do not alter this org
  177.     LXI    H,0
  178.     DAD    SP    ;GET CP/M'S STACK
  179.     SHLD    STAK    ;SAVE IT
  180.     LXI    SP,STAK ;LOCAL STACK
  181.     CALL    INITADR    ;INITIALIZE BIOS ADDRESSES
  182.     CALL    INITCRC    ;initialise crc table
  183.     CALL    ILPRT
  184.     DB 'UK MODEM7 D.R. Back Version 1.5',CR,LF,0
  185.     CALL    INITMOD    ;INITIALISE MODEM PORTS
  186.     LXI    H,80H
  187.     LXI    D,CMDBUF+1
  188.     MVI    B,80H
  189.     CALL    MOVE    ;default buffer to cmdbuf
  190.     MVI    A,TRUE
  191.     STA    NFILFLG
  192.     CALL    PROCOPT    ;PROCESS CONTROL OPTIONS
  193. RESTART:LDA    OPTION    ;GET MAIN OPTION
  194.     CPI    ' '    ;NO OPTION SPEC'D?
  195.     JZ    MENU
  196.     CPI    'M'    ;MENU
  197.     JZ    MENU2
  198.     CALL    MOVEFCB    ;MOVE 2ND HALF FCB TO FIRST HALF
  199.     CALL    INMODDATP ;GOBBLE UP GARBAGE..
  200.     CALL    INMODDATP ;..CHARACTERS ON LINE
  201.     LDA    OPTION    ;PROCESS MAIN OPTION
  202.     CPI    'T'    ;TERMINAL MODE?
  203.     JZ    DSKSAVE
  204.     CPI    'S'    ;SEND A FILE?
  205.     JZ    SENDFIL
  206.     CPI    'R'    ;RECEIVE A FILE?
  207.     JZ    RCVFIL
  208. MENU:    LXI    SP,STAK    ;RESTORE STACK
  209.     LXI    H,RESTSN  ;RESTORE SECTOR NUMBERS..
  210.     LXI    D,SECNOB ;..FOR NEW FILE TRANSFER.
  211.     MVI    B,SECNOE-SECNOB
  212.     CALL    MOVE
  213.     LXI    H,RESTROPT ;RESTORE OPTION TABLE
  214.     LXI    D,OPTBL
  215.     MVI    B,OPTBE-OPTBL
  216.     CALL    MOVE
  217.     LDA    LSTFLG
  218.     STA    LSTRET    ;save print toggle
  219.     MVI    A,0
  220.     STA    LSTFLG    ;printer off
  221.     STA    MFFLG1    ;RESET MFACCESS ROUTINE..
  222.     CMA        ;..AND MULTI TRANS IN CASE..
  223.     STA    FSTFLG    ;..OF ABORT.
  224. MENU1:    LDA    XPRFLG    ;TEST IF MENU SHOULD BE SHOWN
  225.     ORA    A
  226.     JNZ    XPRT
  227. MENU2:    CALL    ILPRT
  228.     DB CR,LF
  229.     DB 'SYNTAX: primaryoption[secondaryoptions] [d:][filename] [ afn]'
  230.     DB CR,LF,CR,LF
  231.     DB '            PRIMARY OPTIONS:',CR,LF
  232.     DB ' S     Send binary files, afn list',CR,LF
  233.     DB ' R     Receive binary files, drive:',CR,LF
  234.     DB ' T     Terminal mode. Terminal filename optional',CR,LF
  235.     DB ' DEL   Delete Terminal file',CR,LF
  236.     DB ' DIR   Directory list, afn optional',CR,LF
  237.     DB ' CPM   Exit to CP/M.',CR,LF
  238.     DB ' X     Expert, toggle menus on/off',CR,LF
  239.     DB ' M     Menu display',CR,LF,CR,LF
  240.     DB '            SECONDARY OPTIONS: (for primary options S and R)'
  241.     DB CR,LF
  242.     DB ' N     Non batch mode, send or receive file'
  243.     DB CR,LF
  244.     DB ' Q     Quiet mode, remote system Send/Receive',CR,LF
  245.     DB 'S,R,V  Monitor data Sent, Received or View file',CR,LF
  246.     DB ' T     Go to Terminal mode after file transfers',CR,LF,0
  247. XPRT:    CALL    ILPRT
  248.     DB CR,LF,0
  249.     MVI    C,25    ;CURRENT DISK FUNCTION
  250.     CALL    BDOS
  251.     ADI    41H    ;MAKE ASCII
  252.     CALL    CTYPE
  253.     CALL    ILPRT
  254.     DB ' ==>>',0
  255.     LXI    D,CMDBUF ;ENTER COMMAND
  256.     CALL    INBUFF
  257.     CALL    CRLF
  258.     LXI    D,CMDBUF+2 ;POINT TO COMMAND
  259.     CALL    ILCOMP
  260.     DB 'CPM',0
  261.     JNC    EXIT
  262.     CALL    ILCOMP
  263.     DB 'DIR',0
  264.     JNC    DIR
  265.     CALL    ILCOMP
  266.     DB 'DEL',0
  267.     JNC    NEWFILE
  268.     LXI    D,CMDBUF
  269.     LXI    H,FCB
  270.     CALL    CPMLINE    ;LOAD FCB
  271.     CALL    PROCOPT
  272.     JMP    RESTART
  273.  
  274. DIR:    CALL    DIRLST
  275.     JMP    XPRT
  276.  
  277. EXIT:    LDA    NFILFLG
  278.     CPI    TRUE
  279.     CNZ    TFILWR    ;write and close terminal file
  280.     LXI    D,80H
  281.     MVI    C,STDMA
  282.     CALL    BDOS
  283.     LHLD    STAK
  284.     SPHL
  285.     LDA    SAVCCP
  286.     ORA    A
  287.     JZ    0    ;WARM BOOT
  288.     RET        ;to CCP
  289.  
  290. NEWFILE:LDA    NFILFLG
  291.     CPI    TRUE
  292.     JZ    MENU1    ;IF NO FILE, DON'T ERASE
  293.     LXI    D,FCB3
  294.     MVI    C,ERASE
  295.     CALL    BDOSRT
  296.     MVI    A,TRUE    ;DO NOT ALLOW TERMINAL..
  297.     STA    NFILFLG    ;..SAVE SINCE NO FILE..
  298.     JMP    MENU1
  299. ;======================================
  300. ;TERMINAL ROUTINE ALLOWING MEMORY SAVE
  301. DSKSAVE:LDA    FCB+1    ;FIRST CHAR OF FILENAME
  302.     CPI    ' '    ;FILE SPEC'D
  303.     LHLD    HLSAVE
  304.     JZ    TERM1
  305.     LDA    NFILFLG
  306.     CPI    TRUE
  307.     CNZ    TFILWR    ;write & close existing file
  308.     CALL    TFLERAS
  309.     CALL    MOVE2    ;move FCB to FCB3
  310.     LXI    D,FCB3
  311.     MVI    C,MAKE
  312.     CALL    BDOS
  313.     INR    A
  314.     JNZ    TERM0
  315.     CALL    ILPRT
  316.     DB 'Can''t make file',CR,LF,0
  317.     JMP    TERM1
  318. TERM0:    LXI    H,BOTTRAM
  319.     SHLD    HLSAVE
  320.     MVI    A,FALSE
  321.     STA    NFILFLG
  322.     STA    CTRLR    ;cancel any previous ^R
  323. TERM1:    LDA    LSTRET
  324.     STA    LSTFLG    ;restore printer toggle
  325.     LDA    XPRFLG
  326.     ORA    A
  327.     JNZ    TERM3
  328. TERM2:    LDA    NFILFLG
  329.     CPI    TRUE
  330.     JZ    NOTFIL
  331.     PUSH    H
  332.     LXI    H,FCB3
  333.     LXI    D,TFILE
  334.     MOV    A,M
  335.     ORA    A
  336.     JNZ    PUTDRV
  337.     MVI    A,' '
  338.     STAX    D
  339.     INX    D
  340.     JMP    NAME1
  341. PUTDRV:    ADI    40H
  342.     STAX    D
  343.     INX    D
  344.     MVI    A,':'
  345. NAME1:    STAX    D
  346.     INX    D
  347.     INX    H
  348.     MVI    B,8
  349.     CALL    MOVE
  350.     INX    D
  351.     MVI    B,3
  352.     CALL    MOVE
  353.     POP    H
  354.     CALL    ILPRT
  355.     DB CR,LF,' ^Y    Terminal file '
  356. TFILE:    DB '               toggle save on/off  '':'' =on',0
  357. NOTFIL:    CALL    ILPRT
  358.     DB CR,LF
  359.     DB ' ^P    Printer, toggle on/off',CR,LF
  360.     DB ' ^T    Transfer (Send) ASCII file without checks',CR,LF
  361.     DB ' ^X    Abort transfer initiated above',CR,LF
  362.     DB ' ^C    Computer mode, toggle echo on/off',CR,LF
  363.     DB ' ^^    Send following character literally',CR,LF
  364.     DB ' ^E    Exit to command menu',CR,LF
  365.     DB ' ^D    Display terminal menu',CR,LF,0
  366. TERM3:    LDA    NFILFLG
  367.     ORA    A
  368.     JNZ    TERM
  369.     LDA    SAVEFLG
  370.     ORA    A
  371.     JZ    TERM
  372.     MVI    A,':'    ;indicate filesave is on
  373.     CALL    TYPE    ;dont print or inc col count
  374. TERM:    CALL    STAT    ;o/p to print & check keypress
  375.     JZ    TERML    ;NO, CHECK LINE
  376.     CALL    KEYIN    ;GET CHAR FROM KBD
  377.     MOV    B,A
  378.     LDA    EXACFL
  379.     ORA    A
  380.     MVI    A,FALSE
  381.     STA    EXACFL
  382.     MOV    A,B
  383.     JNZ    NOTOG
  384.     CPI    EXITCHR    ;^E?
  385.     JZ    MENU    ;YES, RETURN TO MENU
  386.     CPI    COMPUT    ;^C Computer mode with echo
  387.     JNZ    NOECH
  388.     LDA    ECHOFLG
  389.     CMA
  390.     STA    ECHOFLG
  391.     JMP    TERML
  392. NOECH:    CPI    DMENU    ;^D display terminal menu
  393.     JZ    TERM2
  394.     CPI    EXTCHR    ;literal
  395.     JZ    EXTFLG
  396.     CPI    TRANCHR    ;TEST FOR TRANSFER REQUEST (^T)
  397.     CZ    TRANSFER ;SEND-A-FILE
  398.     JZ    TERM3    ;LOOP
  399.     CPI    PRNCHR
  400.     JNZ    NOTLST
  401.     LDA    LSTFLG
  402.     CMA
  403.     STA    LSTFLG
  404.     JMP    TERML
  405. NOTLST:    CPI    SAVECHR
  406.     JNZ    NOTOG
  407.     LDA    NFILFLG    ;DO NOT ALLOW SAVE IF..
  408.     CPI    TRUE    ;..THIS FLAG IS SET.
  409.     JZ    TERML
  410.     LDA    SAVEFLG
  411.     CMA
  412.     STA    SAVEFLG
  413.     JMP    TERM3
  414. EXTFLG:    MVI    A,TRUE
  415.     STA    EXACFL
  416.     JMP    TERML
  417. NOTOG:    MOV    B,A
  418.     LDA    ECHOFLG
  419.     ORA    A
  420.     MOV    A,B
  421.     JZ    TSEND
  422.     CPI    LF
  423.     JZ    TERML    ;ignore LF
  424.     CALL    OUTMODDATP
  425.     CALL    CTYPE    ;local echo
  426.     PUSH    PSW
  427.     CALL    MSAVE    ;local save in terminal file
  428.     POP    PSW
  429.     CPI    CR
  430.     JNZ    TERML
  431.     MVI    A,LF
  432.     CALL    CHRSND    ;send to remote
  433.     CALL    CTYPE    ;append LF
  434.     CALL    MSAVE
  435.     JMP    TERML
  436. TSEND:    CALL    OUTMODDATP
  437. TERML:    CALL    INMODCTLP
  438.     CALL    ANIRCV
  439.     CALL    CPIRCV
  440.     JNZ    TERM
  441.     CALL    INMODDATP
  442.     ANI    7FH    ;strip parity
  443.     JZ    TERM    ;ignore null
  444.     CPI    ENQ    ;auto logon
  445.     JNZ    NOLOG
  446.     LDA    ANSBAK
  447.     ORA    A
  448.     JZ    TERM
  449.     LXI    D,LOGMSSG
  450. NXCHAR:    LDAX    D
  451.     INX    D
  452.     ORA    A
  453.     JZ    TERM
  454.     CALL    CHRSND    ;send to remote
  455.     MOV    B,A
  456.     LDA    ECHOFLG
  457.     ORA    A
  458.     MOV    A,B
  459.     JNZ    CHRSAV
  460.     PUSH    D
  461.     MVI    D,0    ;init count
  462.     CALL    INMODEM    ;wait 100ms for echo
  463.     DCR    D
  464.     POP    D
  465.     JNZ    NXCHAR
  466. CHRSAV:    CALL    CTYPE
  467.     CALL    MSAVE
  468.     JMP    NXCHAR
  469. NOLOG:    CPI    SAVON    ;auto filesave on
  470.     JNZ    TRYT
  471.     LDA    SAVEFLG
  472.     ORA    A
  473.     JNZ    TERM    ;save already on
  474.     MVI    A,TRUE
  475.     STA    SAVEFLG    ;turn on save
  476.     STA    CTRLR    ;remember
  477.     JMP    TERM3
  478. TRYT:    CPI    SAVOFF    ;auto save off
  479.     JNZ    ONWRD
  480.     LDA    CTRLR
  481.     ORA    A
  482.     JZ    TERM    ;turn save off only
  483.     MVI    A,FALSE    ;if it was turned on
  484.     STA    SAVEFLG    ;by ^R from remote
  485.     STA    CTRLR
  486.     JMP    TERM
  487. ONWRD:    MOV    B,A
  488.     LDA    ECHOFLG
  489.     ORA    A
  490.     MOV    A,B
  491.     JZ    TERM5
  492.     CPI    LF
  493.     JZ    TERM    ;ignore LF
  494.     CALL    OUTMODDATP    ;echo to distant terminal
  495.     CPI    CR
  496.     JNZ    TERM5
  497.     CALL    CTYPE
  498.     CALL    MSAVE    ;save in terminal file
  499.     MVI    A,LF
  500.     CALL    CHRSND    ;send LF
  501. TERM5:    CALL    CTYPE
  502.     CALL    MSAVE    ;save in terminal file
  503.     JMP    TERM
  504. CTRLR:    DB FALSE
  505. LASTB1:    DB 0
  506. LASTB2:    DB 0
  507. ;=========================================
  508. ;SEND A CP/M FILE
  509. SENDFIL:LDA    BATCHFLG ;CHECK IF MULTIPLE FILE..
  510.     ORA    A    ;..MODE IS SET.
  511.     JZ    SENDC1
  512.     MVI    A,TRUE    ;INDICATE BATCH SEND
  513.     STA    SENDFLG
  514.     LDA    FSTFLG    ;IF FIRST TIME THRU..
  515.     ORA    A    ;..SCAN THE COMMAND LINE..
  516.     CNZ    TNMBUF    ;..FOR MULTIPLE NAMES.
  517.     CALL    SENDFN    ;SENDS FILE NAME TO RECEIVER
  518.     JNC    SENDC2    ;CARRY SET MEANS NO MORE FILES.
  519.     MVI    A,0    ;STOP BATCH..
  520.     STA    BATCHFLG ;..MODE OPTION.
  521.     MVI    A,EOT    ;FINAL XFER END
  522.     CALL    SEND
  523.     JMP    DONE
  524. SENDC1:    LDA    FCB+1
  525.     CPI    ' '
  526.     JZ    BLKFILE
  527.     CALL    AMBGTS    ;test for ambiguous filename
  528. SENDC2:    CALL    CNREC    ;GET NUMBER OF RECORDS
  529.     CALL    OPENFIL
  530.     MVI    E,80
  531.     CALL    WAITNAK    ;if a 'C' is received instead of NAK
  532. SENDLP:    CALL    RDSECT    ;then CRC mode is enabled
  533.     JC    SENDEOF
  534.     CALL    INCRSNO
  535.     XRA    A
  536.     STA    ERRCT
  537. SENDRPT:CALL    SENDHDR
  538.     CALL    SENDSEC
  539.     LDA    CRCFLG
  540.     ORA    A
  541.     CZ    SENDCRC
  542.     CNZ    SENDCKS
  543.     CALL    GETACK
  544.     JC    SENDRPT
  545.     JMP    SENDLP
  546. SENDEOF:MVI    A,EOT
  547.     CALL    SEND
  548.     CALL    GETACK
  549.     JC    SENDEOF
  550.     JMP    DONE
  551. ;===============================
  552. ;RECEIVE A FILE
  553. RCVFIL:    XRA    A    ;default to CRC mode
  554.     STA    CRCFLG
  555. RCV1FIL:LDA    BATCHFLG ;CHECK IF MULT..
  556.     ORA    A    ;..FILE MODE.
  557.     JZ    RCVC1
  558.     MVI    A,FALSE    ;FLAG WHERE TO RETURN..
  559.     STA    SENDFLG    ;..FOR NEXT FILE TRANS.
  560.     CALL    GETFN    ;GET THE FILE NAME.
  561.     JNC    RCVC2    ;CARRY SET MEANS NO MORE FILES.
  562.     MVI    A,0    ;STOP BATCH..
  563.     STA    BATCHFLG ;..MODE OPTION.
  564.     JMP    DONE
  565. RCVC1:    LDA    FCB+1    ;MAKE SURE FILE IS NAMED
  566.     CPI    ' '
  567.     JZ    BLKFILE
  568.     JMP    RCVC3
  569. RCVC2:    CALL    CKCPM2
  570.     CALL    CKBAKUP
  571. RCVC3:    CALL    ERASFIL
  572.     CALL    MAKEFIL
  573.     LDA    QFLG
  574.     ORA    A
  575.     JZ    RCVFST
  576. RCVC4:    CALL    ILPRT    ;first comment
  577.     DB 'File open, ready to receive',CR,LF,0
  578. RCVFST:    LDA    CRCFLG
  579.     ORA    A
  580.     MVI    A,NAK
  581.     JNZ    RCV2FIL
  582.     MVI    A,CRC    ;indicate to Tx that CRC is wanted
  583. RCV2FIL:CALL    SEND    ;by sending a 'C' instead of NAK
  584.     LDA    QFLG
  585.     ORA    A
  586.     JZ    RCVLP
  587.     LDA    CRCFLG
  588.     ORA    A
  589.     JNZ    RCVNAKM        ;if in CRC mode
  590.     CALL    ILPRT        ;then say so
  591.     DB    'CRC in effect',cr,lf,0
  592.     JMP    RCVLP
  593. RCVNAKM:CALL    ILPRT        ;else say checksum mode
  594.     DB    'Checksum in effect',cr,lf,0
  595. RCVLP:    CALL    RCVSECT
  596.     JC    RCVEOT
  597.     CALL    WRSECT    ;sends CAN if error
  598.     CALL    INCRSNO
  599.     CALL    SENDACK
  600.     JMP    RCVLP
  601. RCVEOT:    CALL    WRBLOCK    ;sends CAN if error
  602.     CALL    SENDACK
  603.     CALL    CLOSFIL
  604.     JMP    DONE
  605. ;===================================
  606. BLKFILE:CALL    ILPRT    ;fatal error
  607.     DB CR,LF,'No file specified',CR,LF,BELL,0
  608.     JMP    MENU
  609. ;===============================
  610. DONE:    LDA    BATCHFLG
  611.     ORA    A
  612.     JZ    DONETB
  613.     LDA    QFLG
  614.     ORA    A
  615.     JZ    NMSTRNS
  616.     LXI    H,FCB+1    ;PUT FILE NAME IN..
  617.     LXI    D,FTRNMSG ;..SPACES IN MESSAGE..
  618.     MVI    B,8    ;..BELOW.
  619.     CALL    MOVE
  620.     INX    D    ;PUT FILE TYPE AFTER..
  621.     MVI    B,3    ;..SKIPPING ONE SPACE..
  622.     CALL    MOVE    ;..BELOW.    
  623.     CALL    ILPRT    ;final comment
  624.     DB CR,LF
  625. FTRNMSG:DB '              transferred',CR,LF,CR,LF,0    ;13 SPACES
  626. NMSTRNS:LDA    FCB    ;SAVE DRIVE NO.
  627.     STA    DISKNO
  628.     LXI    H,FCB    ;BLANK OUT FILE CONTROL BLOCKS
  629.     CALL    INITFCBS
  630.     LDA    DISKNO    ;PUT DRIVE NUMBER BACK
  631.     STA    FCB
  632.     LXI    H,RESTSN ;RESTORE SECTOR NUMBERS..
  633.     LXI    D,SECNOB ;..FOR NEW FILE TRANSFER.
  634.     MVI    B,SECNOE-SECNOB ;ROUTINE ALSO DONE IN MENU.
  635.     CALL    MOVE
  636.     LDA    SENDFLG    ;GOES TO EITHER SEND OR..
  637.     ORA    A    ;..RECEIVE FILE, DEPENDING..
  638.     JNZ    SENDFIL    ;..UPON WHICH ROUTINE SET..
  639.     JMP    RCV1FIL    ;..THE FLAG IN MULTI-FILE MODE.
  640.  
  641. DONETB:    MVI    A,TRUE    ;INDICATE NO FILES BEING..
  642.     STA    FSTFLG    ;RESET MULTIFILE TRANS
  643.     LDA    QFLG
  644.     ORA    A
  645.     JZ    DONETA
  646.     CALL    ILPRT    ;final comment
  647.     DB CR,LF,'All transfers completed'
  648.     DB CR,LF,BELL,0
  649. DONETA:    LXI    SP,STAK    ;restore stack
  650.     MVI    A,CRC
  651.     STA    CRCFLG    ;turn off CRC option
  652.     MVI    A,0FFH
  653.     STA    FIRSTME    ;set first-time flag
  654.     LDA    TERMFLG    ;SEE IF RETURN TO..
  655.     ORA    A    ;..TERMINAL MODE..
  656.     JNZ    MENU    ;..AFTER X'FER.
  657.     CALL    CRLF
  658.     MVI    A,'T'
  659.     STA    OPTION
  660.     MVI    A,' '
  661.     STA    FCB+1    ;too late to specify filename
  662.     CALL    INMODDATP
  663.     CALL    INMODDATP;clear usart
  664.     JMP    DSKSAVE
  665. ;============================= SUBROUTINES ===============
  666. MSAVE:    PUSH    PSW
  667.     LDA    NFILFLG
  668.     CPI    TRUE
  669.     JZ    NOSAVE    ;CANT SAVE IF NO FILE
  670.     LDA    SAVEFLG
  671.     CPI    FALSE
  672.     JZ    NOSAVE
  673.     POP    PSW
  674.     CPI    EOFCHAR    ;dont save EOF's in file
  675.     RZ        ;CP/M doesn't like them
  676.     LHLD    HLSAVE
  677.     MOV    M,A
  678.     INX    H
  679.     SHLD    HLSAVE    ;MENU COMMAND DESTROYS HL-REG..
  680.     CPI    LF
  681.     JNZ    NOCOLON    ;TYPE ":" AFTER EACH LINE FEED..
  682.     MVI    A,':'    ;..WHEN MEMORY SAVE ACTIVE.
  683.     CALL    TYPE    ;dont increment col count
  684. NOCOLON:LDA    SAVCCP
  685.     ORA    A
  686.     JZ    SUB1
  687.     LDA    7
  688.     SBI    8    ;..PAGE BELOW CCP ..
  689.     JMP    SUB1A
  690. SUB1:    LDA    7
  691. SUB1A:    DCR    A    ;..OR BDOS HAS BEEN..
  692.     CMP    H    ;..REACHED AND DISKSAVE IS NEEDED.
  693.     CZ    INTDSKSV
  694.     RET
  695. NOSAVE:    POP    PSW
  696.     RET
  697. ;==================================
  698. PROCOPT:LXI    D,FCB+1
  699.     LDAX    D
  700.     STA    OPTION    ;primary option
  701. OPTLP:    INX    D
  702.     LDAX    D
  703.     CPI    ' '
  704.     JZ    CKPRI
  705.     LXI    H,OPTBL
  706.     MVI    B,OPTBE-OPTBL
  707. OPTCK:    CMP    M
  708.     JNZ    OPTNO
  709.     MVI    M,0    ;INSERT SECONDARY OPTION
  710.     JMP    OPTLP
  711. OPTNO:    INX    H
  712.     DCR    B
  713.     JNZ    OPTCK
  714.     JMP    BDOPT
  715. CKPRI:    LDA    FCB+1    ;CHECK ON THE PRIMARY OPTION
  716.     CPI    'X'
  717.     JZ    EXPRT
  718.     CPI    ' '
  719.     RZ
  720.     CPI    'M'
  721.     RZ
  722.     CPI    'T'
  723.     RZ
  724.     CPI    'S'
  725.     JZ    CKFILE
  726.     CPI    'R'
  727.     JNZ    BDOPT
  728.     LDA    BATCHFLG ;IF MULT FILE MODE, THEN..
  729.     ORA    A     ;..RECV OPT MUST NOT BE NAMED
  730.     JZ    CKFILE
  731.     LDA    FCB+17
  732.     CPI    ' '
  733.     RZ
  734. BDOPT:    CALL    ILPRT    ;fatal error
  735.     DB '++Bad Syntax++',CR,LF,0
  736.     JMP    MENU
  737. EXPRT:    LDA    XPRFLG
  738.     CMA
  739.     STA    XPRFLG
  740.     JMP    MENU
  741. CKFILE:    LDA    FCB+17    ;IF OPTION THAT NEEDS FILE NAME,..
  742.     CPI    ' '    ;..THEN CHECK TO SEE IF NAME..
  743.     RNZ        ;..EXISTS.
  744.     JMP    BDOPT
  745. ;==================================
  746. TFILWR:    LHLD    HLSAVE
  747.     CALL    NUMRECS    ;DISK WRITE ROUTINE AS USED IN..
  748.     CALL    WRTDSK    ;..IN THE INTDSKSV ROUTINE.
  749.     LXI    D,FCB3
  750.     MVI    C,CLOSE
  751.     CALL    BDOS
  752.     MVI    A,TRUE
  753.     STA    NFILFLG
  754.     RET
  755. ;================================
  756. INTDSKSV:
  757.     MVI    A,XOFF    ;SEND A CTRL-S TO STOP..
  758.     CALL    OUTMODDATP ;..REMOTE COMPUTER OUTPUT.
  759.     MVI    D,0    ;D IS THE BUFFER COUNT
  760.     CALL    INMODEM    ;GET LAST BYTES SENT..
  761.     STA    LASTB1 ;..AFTER CTRL-S.
  762.     CALL    INMODEM    ;ADD MORE CALLS TO INMODEM..
  763.     STA    LASTB2 ;..AND STA LASTBYT# IF YOU ARE..
  764.             ;..LOSING BYTES WHEN MEMORY IS FULL.
  765.     PUSH    D
  766.     CALL    NUM1REC
  767.     CALL    WRTDSK    ;WRITE THE RECORDS
  768.     POP    D
  769.     LXI    H,BOTTRAM
  770.     INR    D
  771.     DCR    D    ;TEST BUFFER COUNT FOR ZERO
  772.     JZ    CTRLQ
  773.     LDA    LASTB1 ;GET THE LAST BYTES THAT WERE..
  774.     MOV    M,A    ;..SAVED AND PUT THEM IN..
  775.     INX    H    ;..BOTTRAM.
  776.     CALL    CTYPE
  777.     DCR    D
  778.     JZ    CTRLQ
  779.     LDA    LASTB2
  780.     MOV    M,A
  781.     INX    H
  782.     CALL    CTYPE
  783. CTRLQ:    SHLD    HLSAVE
  784.     MVI    A,XON    ;SEND START CHARACTER..
  785.     CALL    OUTMODDATP ;..TO REMOTE COMPUTER.
  786.     RET
  787. ;======================================
  788. ;SUBROUTINE LOOPS UNTIL THE MODEM RECEIVES A CHARACTER OR 100ms
  789. ;RETURNS BYTE COUNT IN D OR ZERO FOR TIMEOUT
  790. ;if ^S is received it waits until ^Q is received
  791. INMODEM:LDA    FASTCLK
  792.     ORA    A
  793.     LXI    B,1250
  794.     JZ    CHKMOD
  795.     LXI    B,2500
  796. CHKMOD:    CALL    INMODCTLP
  797.     CALL    ANIRCV
  798.     CALL    CPIRCV
  799.     JZ    GETBYTE
  800.     DCX    B
  801.     MOV    A,B
  802.     ORA    C
  803.     JNZ    CHKMOD
  804.     RET
  805. GETBYTE:CALL    INMODDATP
  806.     ANI    7FH    ;clear parity
  807.     CPI    XOFF
  808.     JNZ    TWAIT4
  809.     PUSH    H
  810.     CALL    ILPRT
  811.     DB CR,LF,'XOFF received, type ^Q to force continuation',CR,LF,0
  812. TWAIT1:    CALL    INMODCTLP
  813.     CALL    ANIRCV
  814.     CALL    CPIRCV
  815.     JZ    TWAIT2
  816.     CALL    STAT    ;local key?
  817.     JZ    TWAIT1
  818.     CALL    KEYIN    ;get char
  819.     CPI    XON
  820.     JZ    TWAIT3
  821.     JMP    TWAIT1
  822. TWAIT2:    CALL    INMODDATP
  823.     ANI    7FH
  824.     CPI    XON    ;remote XON?
  825.     JNZ    TWAIT1
  826.     CALL    ILPRT
  827.     DB 'XON received',CR,LF,0
  828. TWAIT3:    POP    H
  829.     JMP    INMODEM
  830. TWAIT4:    INR    D
  831.     RET
  832. ;================================
  833. NUMRECS:MVI    M,EOFCHAR
  834.     INX    H
  835.     LXI    D,127
  836.     DAD    D
  837. NUM1REC:LXI    D,-(BOTTRAM)
  838.     DAD    D
  839.     MOV    A,L    ;DIVIDE HL BY 128..
  840.     ORA    A
  841.     RAL        ;..TO GET THE..
  842.     MOV    L,H    ;..NUMBER OF SECTORS
  843.     MVI    H,0
  844.     PUSH    PSW
  845.     DAD    H
  846.     POP    PSW
  847.     MVI    A,0
  848.     ADC    L
  849.     MOV    L,A    ;RETNS WITH NUMBER OF..
  850.     RET        ;..128 BYTE RECORDS IN HL.
  851. ;======================================
  852. WRTDSK:    LXI    D,BOTTRAM
  853. NEXTWRT:MVI    C,STDMA
  854.     CALL    BDOSRT
  855.     PUSH    D
  856.     LXI    D,FCB3
  857.     MVI    C,WRITE
  858.     CALL    BDOSRT
  859.     POP    D
  860.     INR    A
  861.     JZ    WRTERR
  862.     XCHG
  863.     PUSH    D
  864.     LXI    D,128
  865.     DAD    D
  866.     POP    D
  867.     XCHG
  868.     DCX    H
  869.     MOV    A,H
  870.     ORA    L
  871.     JNZ    NEXTWRT
  872.     CALL    RSDMA    ;for CP/M 1.4
  873.     RET
  874. WRTERR:    CALL    ILPRT
  875.     DB 'Terminal file write error',CR,LF,0
  876.     RET
  877. ;==========================
  878. BDOSRT:    PUSH    B
  879.     PUSH    D
  880.     PUSH    H
  881.     CALL    BDOS
  882.     POP    H
  883.     POP    D
  884.     POP    B
  885.     RET
  886. ;============================
  887. MOVE2:    LXI    H,FCB3
  888.     CALL    INITFCBS
  889.     LXI    H,FCB
  890.     LXI    D,FCB3
  891.     MVI    B,12
  892.     CALL    MOVE
  893.     RET
  894. ;=============================
  895. ;FILE TRANSFER ROUTINE - CALLED WITH 
  896. ;CONTROL-T FROM TERMINAL ROUTINE.
  897. ;TRANSFER MAY BE CANCELLED WHILE SENDING BY USING CONTROL-X.
  898. TRANSFER:
  899.     SHLD    HLSAVE
  900.     PUSH    D
  901.     PUSH    B
  902.     PUSH    PSW
  903.     LXI    H,FCB4
  904.     CALL    INITFCBS ;INITIALIZES FCBS POINTED..
  905.     LXI    H,FCB+16 ;..TO BY HL REG.
  906.     CALL    INITFCBS
  907. GET:    CALL    ILPRT
  908.     DB CR,LF,'Enter file name to be transferred -  C/R TO QUIT: ',0
  909.     LXI    D,CMDBUF
  910.     CALL    INBUFF
  911.     CALL    CRLF
  912.     LDA    CMDBUF+2 ;WAS FILE ENTERED
  913.     CPI    20H
  914.     JZ    TRANCAN
  915.     LXI    D,CMDBUF
  916.     LXI    H,FCB4
  917.     CALL    CPMLINE
  918.     LXI    D,FCB4
  919.     MVI    C,OPEN
  920.     CALL    BDOS
  921.     CPI    0FFH    ;RETURN WITH 0FFH MEANS
  922.     JNZ    CONTIN    ;FILE DOES NOT EXIST
  923.     CALL    ILPRT
  924.     DB '++File does not exist++',CR,LF,0
  925. TRANS2L:CALL ILPRT
  926.     DB 'Type "^X" to cancel transfer',CR,LF
  927.     DB 'Type "A" to re-enter name: ',BELL,0
  928.     CALL    KEYIN
  929.     CALL    UCASE
  930.     CALL    CTYPE    ;ECHO RESPONSE
  931.     CALL    CRLF
  932.     CPI    'A'
  933.     JZ    GET
  934.     CPI    CAN
  935.     JZ    TRANCAN
  936.     JMP    TRANS2L
  937. CONTIN:    LXI    D,80H
  938.     MVI    C,STDMA
  939.     CALL    BDOS
  940.     LDA    ECHOFLG    ;computer mode ?
  941.     ORA    A
  942.     JZ    READMR
  943.     MVI    A,SAVON    ;activate remote save
  944.     CALL    CHRSND    ;computer mode only
  945. READMR:    LXI    D,FCB4
  946.     MVI    C,READ
  947.     CALL    BDOS
  948.     ORA    A
  949.     JNZ    RETNS
  950.     CALL    SEND80C
  951.     CPI    EOFCHAR    ;END OF FILE
  952.     JZ    RETNS
  953.     CPI    CAN    ;CANCELLATION?
  954.     JZ    TRANC1
  955.     JMP    READMR
  956. RETNS:    LDA    ECHOFLG
  957.     ORA    A
  958.     JZ    RETN1
  959.     MVI    A,SAVOFF
  960.     CALL    CHRSND    ;deactivate remote save
  961. RETN1:    CALL    ILPRT
  962.     DB CR,LF,'++File transfer completed++',CR,LF,BELL,0
  963.     JMP    RETURN
  964. TRANC1:    LDA    ECHOFLG
  965.     ORA    A
  966.     JZ    TRANCAN
  967.     MVI    A,SAVOFF
  968.     CALL    CHRSND    ;deactivate remote save
  969. TRANCAN:CALL    ILPRT
  970.     DB CR,LF,'++ Transfer cancelled ++',CR,LF,BELL,0
  971. RETURN:    POP    PSW
  972.     POP    B
  973.     POP    D
  974.     LHLD    HLSAVE
  975.     RET
  976. ;=============================
  977. INITFCBS:        ;ENTRY AT +2 WILL LEAVE..
  978.     MVI    M,0    ;..DRIVE NO. INTACT.
  979.     INX    H    ;WILL INITIALIZE AN FCB..
  980.     MVI    B,11    ;..POINTED TO BY HL-REG. FILLS 1ST POS
  981. LOOP10:    MVI    M,' '    ;..WITH 0, NEXT 11 WITH..
  982.     INX    H    ;..WITH BLANKS, AND LAST..
  983.     DCR    B    ;..21 WITH NULLS.
  984.     JNZ    LOOP10
  985.     MVI    B,21
  986. LOOP11:    MVI    M,0
  987.     INX    H
  988.     DCR    B
  989.     JNZ    LOOP11
  990.     RET
  991. ;===========================
  992. CHRSND:    PUSH    PSW
  993. REDY:    CALL    INMODCTLP
  994.     CALL    ANISND
  995.     CALL    CPISND
  996.     JNZ    REDY
  997.     POP    PSW
  998.     CALL    OUTMODDATP
  999.     RET
  1000. ;===============================
  1001. ;used by ^T transfer
  1002. SEND80C:MVI    B,80H
  1003.     LXI    H,80H
  1004. SEND81:    MOV    A,M    ;get next char
  1005.     ANI    7FH    ;remove top bit
  1006.     CPI    EOFCHAR    ;end of file?
  1007.     RZ
  1008.     CALL    FILTER    ;ignore non printing ASCII
  1009.     JC    SEND85
  1010.     MOV    C,A
  1011.     LDA    ECHOFLG
  1012.     ORA    A
  1013.     MOV    A,C
  1014.     JNZ    SEND83
  1015.     CPI    LF    ;ignore lf's in terminal mode
  1016.     JZ    SEND85
  1017.     MOV    A,C
  1018.     CALL    CHRSND    ;send to remote
  1019.     CPI    CR
  1020.     JZ    SEND82
  1021.     PUSH    B
  1022.     MVI    D,0
  1023.     CALL    INMODEM    ;wait 100ms for echo
  1024.     POP    B
  1025.     JZ    SEND85    ;zero indicates no echo
  1026.     JMP    SEND84
  1027. SEND83:    CALL    CHRSND
  1028.     PUSH    PSW
  1029.     PUSH    B
  1030.     LXI    B,1    ;zero delay
  1031.     CALL    CHKMOD    ;check for XOFF from remote
  1032.     POP    B
  1033.     POP    PSW
  1034. SEND84:    CALL    CTYPE    ;local console
  1035.     PUSH    B
  1036.     PUSH    H
  1037.     CALL    MSAVE    ;save to memory
  1038.     POP    H
  1039.     POP    B
  1040.     JMP    SEND85
  1041. SEND82:    PUSH    B
  1042.     MVI    D,0
  1043.     CALL    INMODEM    ;wait 100ms for echo
  1044.     POP    B
  1045.     JZ    SEND85    ;loop until timeout
  1046.     PUSH    B
  1047.     CALL    CTYPE
  1048.     PUSH    PSW    ;save inmodem flag
  1049.     PUSH    H
  1050.     CALL    MSAVE
  1051.     POP    H
  1052.     POP    PSW
  1053.     POP    B
  1054.     JMP    SEND82
  1055. SEND85:    CALL    STAT    ;TEST TO SEE IF
  1056.     ORA    A    ;CANCELLATION REQUESTED
  1057.     JZ    SKIP12
  1058.     CALL    KEYIN
  1059.     CPI    CAN    ;cancel?
  1060.     RZ
  1061.     CPI    SAVECHR    ;memory save toggle
  1062.     JNZ    SEND86
  1063.     LDA    NFILFLG
  1064.     CPI    TRUE    ;cant save if no file
  1065.     JZ    SEND86
  1066.     LDA    SAVEFLG
  1067.     CMA
  1068.     STA    SAVEFLG
  1069. SEND86:    CPI    PRNCHR
  1070.     JNZ    SKIP12
  1071.     LDA    LSTFLG
  1072.     CMA
  1073.     STA    LSTFLG    ;print toggle
  1074. SKIP12:    INX    H
  1075.     DCR    B
  1076.     JNZ    SEND81
  1077.     RET
  1078. ;=================================-
  1079. ;send filename
  1080. SENDFN:    LDA    QFLG
  1081.     ORA    A
  1082.     JZ    SWNAK
  1083.     CALL    ILPRT    ;first comment
  1084.     DB 'Awaiting name NAK',CR,LF,0
  1085. SWNAK:    MVI    E,80    ;80 second timeout
  1086.     CALL    WAITNLP
  1087.     MVI    A,ACK    ;GOT NAK, SEND ACK
  1088.     CALL    SEND
  1089.     LXI    H,FILECT
  1090.     DCR    M
  1091.     JM    NOMRNM
  1092.     LHLD    NBSAVE    ;GET FILE NAME..
  1093.     LXI    D,FCB    ;..IN FCB
  1094.     MVI    B,12
  1095.     CALL    MOVE
  1096.     SHLD    NBSAVE
  1097.     CALL    SENDNM    ;SEND IT
  1098.     ORA    A    ;CLEAR CARRY
  1099.     RET
  1100. NOMRNM:    MVI    A,EOT
  1101.     CALL    SEND
  1102.     STC
  1103.     RET
  1104. ;======================================
  1105. SENDNM:    PUSH    H
  1106. SEND1NM:MVI    D,11    ;COUNT CHARS IN NAME
  1107.     MVI    C,0    ;INIT CHECKSUM
  1108.     LXI    H,FCB+1    ;ADDRESS NAME
  1109. NAMLPS:    MOV    A,M    ;SEND NAME
  1110.     ANI    7FH    ;STRIP HIGH ORDER BIT SO CP/M 2..
  1111.     CALL    SEND    ;..WON'T SEND R/O FILE DESIGNATION.
  1112.     LDA    SSEEFLG
  1113.     ORA    A
  1114.     JZ    ACKLP    ;already typed by SEND
  1115.     LDA    QFLG    ;SHOW NAME IF..
  1116.     ORA    A    ;..QFLG NOT SET.
  1117.     MOV    A,M
  1118.     CNZ    TYPE    ;first comment
  1119. ACKLP:    PUSH    B    ;SAVE CKSUM
  1120.     MVI    B,1    ;WAIT FOR RECEIVER..
  1121.     CALL    RECV    ;..TO ACKNOWLEDGE..
  1122.     POP    B    ;..GETTING LETTER.
  1123.     JC    SCKSER
  1124.     CPI    ACK
  1125.     JNZ    ACKLP
  1126.     INX    H    ;NEXT CHAR
  1127.     DCR    D
  1128.     JNZ    NAMLPS
  1129.     MVI    A,EOFCHAR ;TELL RECEIVER END OF NAME
  1130.     CALL    SEND
  1131.     LDA    QFLG
  1132.     ORA    A
  1133.     CNZ    CRLF    ;first comment
  1134.     MOV    D,C    ;SAVE CHECKSUM
  1135.     MVI    B,1
  1136.     CALL    RECV    ;GET CHECKSUM..
  1137.     CMP    D    ;..FROM RECEIVER.
  1138.     JZ    NAMEOK
  1139. SCKSER:    MVI    A,BDNMCH ;BAD NAME-TELL RECEIVER
  1140.     CALL    SEND
  1141.     LDA    QFLG
  1142.     ORA    A
  1143.     JZ    SKCSER1
  1144.     CALL    ILPRT    ;error message
  1145.     DB 'Checksum error',CR,LF,0
  1146. SKCSER1:MVI    E,80    ;DO HANDSHAKING OVER
  1147.     CALL    WAITNLP    ;DON'T PRINT "AWAITING NAK" MSG
  1148.     MVI    A,ACK
  1149.     CALL    SEND
  1150.     JMP    SEND1NM
  1151. NAMEOK:    MVI    A,ACK    ;GOOD NAME-TELL RECEIVER
  1152.     CALL    SEND
  1153.     POP    H
  1154.     RET    
  1155. ;============================
  1156. ;get filename
  1157. GETFN:    LXI    H,FCB
  1158.     CALL    INITFCBS+2 ;DOES NOT INITIALIZE DRIVE
  1159.     LDA    QFLG
  1160.     ORA    A
  1161.     JZ    GNAMELP
  1162.     CALL    ILPRT    ;first comment
  1163.     DB 'Awaiting file name',CR,LF,0
  1164. GNAMELP:CALL    HSNAK
  1165.     JC    GNAMELP
  1166.     CALL    GETNM    ;GET THE NAME
  1167.     CPI    EOT    ;IF EOT, THEN NO MORE FILES
  1168.     JZ    NOMRNG
  1169.     ORA    A    ;CLEAR CARRY
  1170.     RET
  1171. NOMRNG:    STC
  1172.     RET
  1173. ;================================
  1174. GETNM:    PUSH    H
  1175. GETNM1:    MVI    C,0    ;INIT CHECKSUM
  1176.     LXI    H,FCB+1
  1177. NAMELPG:MVI    B,5
  1178.     CALL    RECV    ;GET CHAR
  1179.     JNC    GETNM3
  1180.     LDA    QFLG
  1181.     ORA    A
  1182.     JZ    GETNM2
  1183.     CALL    ILPRT    ;error message
  1184.     DB 'Time out receiving filename',CR,LF,0
  1185. GETNM2:    JMP    GCKSER
  1186. GETNM3:    CPI    EOT    ;IF EOT, THEN NO MORE FILES
  1187.     JZ    GNRET
  1188.     CPI    EOFCHAR    ;GOT END OF NAME
  1189.     JZ    ENDNAME
  1190.     MOV    M,A    ;PUT NAME IN FCB
  1191.     LDA    RSEEFLG
  1192.     ORA    A
  1193.     JZ    GETNM4    ;already typed by RECV
  1194.     LDA    QFLG    ;TYPE IT IF NO QFLG
  1195.     ORA    A
  1196.     MOV    A,M
  1197.     CNZ    CTYPE    ;first comment
  1198. GETNM4:    PUSH    B    ;SAVE CKSUM
  1199.     MVI    A,ACK    ;ACK GETTING LETTER
  1200.     CALL    SEND
  1201.     POP    B
  1202.     INX    H    ;GET NEXT CHAR
  1203.     MOV    A,L    ;DON'T LET NOISE...
  1204.     CPI    7FH    ;..CAUSE OVERFLOW..
  1205.     JZ    GCKSER    ;..INTO PROGRAM AREA.
  1206.     JMP    NAMELPG
  1207. ENDNAME:LDA    QFLG
  1208.     ORA    A
  1209.     CNZ    CRLF    ;first comment
  1210.     MOV    A,C    ;SEND CHECKSUM
  1211.     CALL    SEND
  1212.     MVI    B,1
  1213.     CALL    RECV    ;CHECKSUM GOOD?
  1214.     CPI    ACK    ;YES IF ACK SENT..
  1215.     JZ    GNRET    ;..ELSE DO OVER.
  1216. GCKSER:    LXI    H,FCB    ;CLEAR FCB (EXCEPT DRIVE)..
  1217.     CALL    INITFCBS+2 ;..SINCE IT MIGHT BE DAMAGED..
  1218.     LDA    QFLG    ;..BY TOO MANY CHARS.
  1219.     ORA    A
  1220.     JZ    GCK1SER
  1221.     CALL    ILPRT    ;error message
  1222.     DB 'Checksum error',CR,LF,0
  1223. GCK1SER:CALL    HSNAK    ;DO HANDSHAKING OVER
  1224.     JC    GCK1SER
  1225.     JMP    GETNM1
  1226. GNRET:    POP    H
  1227.     RET
  1228. ;==============================
  1229. HSNAK:    MVI    A,NAK    ;SEND NAK UNTIL..
  1230.     CALL    SEND    ;..RECEIVING ACK.
  1231.     CALL    CKABORT    ;DON'T GET HUNG UP HERE
  1232.     MVI    B,2    ;WAIT 2 SECONDS..
  1233.     CALL    RECV    ;..IN RECEIVE.
  1234.     CPI    ACK    ;IF ACK,RETURN WITH..
  1235.     RZ        ;..CARRY CLEAR.
  1236.     STC
  1237.     RET
  1238. ;============================
  1239. TNMBUF:    MVI    A,FALSE    ;CALL FROM SENDFIL ONLY ONCE.
  1240.     STA    FSTFLG
  1241.     STA    FILECT
  1242.     CALL    SCAN
  1243.     LXI    H,NAMEBUF
  1244.     SHLD    NBSAVE    ;SAVE ADDR OF 1ST NAME
  1245. TNLP1:    CALL    TRTOBUF
  1246.     LXI    H,FCB
  1247.     LXI    D,FCBBUF
  1248.     CALL    CPMLINE    ;PARSE NAME TO CP/M FORMAT
  1249. TNLP2:    CALL    MFNAME    ;SEARCH FOR NAMES (* FORMAT)
  1250.     JC    NEXTNM
  1251.     LDA    FCB+10    ;IF CP/M 2 $SYS FILE..
  1252.     ANI    80H    ;..DON'T SEND
  1253.     JNZ    TNLP2
  1254.     LHLD    NBSAVE    ;GET NAME
  1255.     LXI    D,FCB    ;MOVE IT TO FCB
  1256.     XCHG
  1257.     MVI    B,12
  1258.     CALL    MOVE
  1259.     XCHG
  1260.     SHLD    NBSAVE    ;ADDR OF NEXT NAME
  1261.     LXI    H,FILECT    ;COUNT FILES FOUND
  1262.     INR    M
  1263.     JMP    TNLP2
  1264. ;
  1265. NEXTNM:    LXI    H,NAMECT ;COUNT NAMES FOUND
  1266.     DCR    M
  1267.     JNZ    TNLP1
  1268.     LXI    H,NAMEBUF ;SAVE START OF BUFFER
  1269.     SHLD    NBSAVE
  1270.     LDA    FILECT
  1271.     ORA    A
  1272.     JZ    NOBFILE
  1273.     CPI    65    ;NO MORE THAN 64 TRANSFERS
  1274.     RC
  1275.     MVI    A,64    ;ONLY X'FER FIRST 64
  1276.     STA    FILECT
  1277.     RET
  1278. NOBFILE:CALL    ILPRT    ;fatal error
  1279.     DB 'No file',CR,LF,0
  1280.     JMP    MENU
  1281. ;==============================================-
  1282. ;SCANS CMDBUF COUNTING NAMES AND PUTTING DELIMITER (SPACE)
  1283. ;AFTER LAST NAME
  1284. SCAN:    PUSH    H
  1285.     LXI    H,NAMECT
  1286.     MVI    M,0
  1287.     LXI    H,CMDBUF+1 ;FIND END OF CMD LINE..
  1288.     MOV    C,M    ;..AND PUT SPACE THERE.
  1289.     MVI    B,0
  1290.     LXI    H,CMDBUF+2
  1291.     DAD    B
  1292.     MVI    M,20H
  1293.     LXI    H,CMDBUF+1
  1294.     MOV    B,M
  1295.     INR    B
  1296.     INR    B
  1297.     CALL    EAT    ;eat spaces
  1298.     JZ    DNSCAN
  1299. SCAN1LP:INX    H
  1300.     DCR    B
  1301.     JZ    DNSCAN
  1302.     MOV    A,M
  1303.     CPI    20H
  1304.     JNZ    SCAN1LP
  1305.     CALL    EAT
  1306.     JZ    DNSCAN
  1307.     SHLD    BGNMS    ;SAVE START OF NAMES IN CMDBUF
  1308.     INR    B
  1309.     DCX    H
  1310. SCAN3LP:INX    H
  1311.     DCR    B
  1312.     JZ    DNSCAN
  1313.     MOV    A,M
  1314.     CPI    20H
  1315.     JNZ    SCAN3LP
  1316.     LDA    NAMECT    ;COUNTS NAMES
  1317.     INR    A
  1318.     STA    NAMECT
  1319.     CALL    EAT
  1320.     JZ    DNSCAN
  1321.     JMP    SCAN3LP
  1322. ;
  1323. DNSCAN:    MVI    M,20H    ;SPACE AFTER LAST CHAR
  1324.     POP    H
  1325.     RET
  1326. ;==================================
  1327. ;Space eater
  1328. EAT:    INX    H
  1329.     DCR    B
  1330.     RZ
  1331.     MOV    A,M
  1332.     CPI    ' '
  1333.     JZ    EAT
  1334.     RET
  1335. ;==========================================
  1336. ;PLACES NEXT NAME IN BUFFER SO CPMLINE MAY PARSE IT
  1337. TRTOBUF:LHLD    BGNMS
  1338.     MVI    B,0
  1339.     LXI    D,FCBBUF+2
  1340. TBLP:    MOV    A,M
  1341.     CPI    20H
  1342.     JZ    TRBFEND
  1343.     STAX    D
  1344.     INX    H
  1345.     INX    D
  1346.     INR    B    ;COUNT CHARS IN NAME
  1347.     JMP    TBLP
  1348. ;
  1349. TRBFEND:INX    H
  1350.     MOV    A,M    ;EAT EXTRA SPACES
  1351.     CPI    20H
  1352.     JZ    TRBFEND
  1353.     SHLD    BGNMS
  1354.     LXI    H,FCBBUF+1 ;PUT # CHARS BEFORE NAME
  1355.     MOV    M,B
  1356.     RET
  1357. ;====================================
  1358. ;IN CP/M V.2, IF FILE IS R/O OR SYS, IT IS CHANGED TO 'BAK'.
  1359. CKCPM2:    MVI    C,12
  1360.     CALL    BDOS
  1361.     ORA    A    ;RETURN 0 MEANS CP/M 1
  1362.     RZ
  1363.     MVI    C,STDMA
  1364.     LXI    D,80H
  1365.     CALL    BDOS
  1366.     MVI    C,SRCHF    ;SEARCH FOR FILE
  1367.     LXI    D,FCB
  1368.     CALL    BDOS
  1369.     CPI    0FFH
  1370.     RZ
  1371.     ADD    A
  1372.     ADD    A    ;MULT A-REG BY..
  1373.     ADD    A
  1374.     ADD    A    ;..32 TO FIND..
  1375.     ADD    A    ;..NAME IN DMA.
  1376.     LXI    H,80H
  1377.     ADD    L
  1378.     MOV    L,A    ;HL POINTS TO DIR NAME
  1379.     LXI    D,9
  1380.     DAD    D    ;POINT TO R/O ATTRIB BYTE
  1381.     MOV    A,M
  1382.     ANI    80H    ;TEST MSB
  1383.     JNZ    MKCHG    ;IF SET, MAKE CHANGE
  1384.     INX    H    ;CHECK SYSTEM ATTRIB BYTE
  1385.     MOV    A,M
  1386.     ANI    80H
  1387.     RZ        ;NOT $SYS OR $R/O
  1388.     DCX    H
  1389. MKCHG:    LXI    D,-8
  1390.     DAD    D    ;POINT HL TO FILENAME + 1
  1391.     LXI    D,FCB+1    ;MOVE DIR NAME TO FCB..
  1392.     MVI    B,11    ;..WITHOUT CHANGING DRIVE.
  1393.     CALL    MOVE
  1394.     LXI    H,FCB+9    ;R/O ATTRIB
  1395.     MOV    A,M
  1396.     ANI    7FH    ;STRIP R/O ATTRIB
  1397.     MOV    M,A
  1398.     INX    H    ;SYS ATTRIB
  1399.     MOV    A,M
  1400.     ANI    7FH
  1401.     MOV    M,A
  1402.     LXI    D,FCB
  1403.     MVI    C,30    ;SET NEW ATTRIBS IN DIR
  1404.     CALL    BDOS
  1405.  
  1406. ;MAY BE CALLED BY CKBAKUP BELOW. ITS RETURN DONE HERE
  1407. PLANCHG:LXI    H,FCB    ;CHANGE NAME TO TYPE "BAK"
  1408.     LXI    D,6CH
  1409.     MVI    B,9    ;MOVE DRIVE AND NAME (NOT TYPE)
  1410.     CALL    MOVE
  1411.     LXI    H,75H    ;START OF TYPE IN FCB2
  1412.     MVI    M,'B'
  1413.     INX    H
  1414.     MVI    M,'A'
  1415.     INX    H
  1416.     MVI    M,'K'
  1417.     LXI    D,6CH
  1418.     MVI    C,ERASE    ;ERASE ANY PREV BACKUPS
  1419.     CALL    BDOS
  1420.     LXI    H,6CH    ;FCB2 DR FIELD SHOULD..
  1421.     MVI    M,0    ;..0 FOR RENAME.
  1422.     LXI    D,FCB
  1423.     MVI    C,REN
  1424.     CALL    BDOS
  1425.     RET
  1426.  
  1427. CKBAKUP:LDA    BAKUPBYTE
  1428.     ORA    A
  1429.     RZ
  1430.     MVI    C,SRCHF
  1431.     LXI    D,FCB
  1432.     CALL    BDOS
  1433.     INR    A
  1434.     RZ    ;FILE NOT FOUND
  1435.     JMP    PLANCHG    ;IN "CKCPM2" - RET DONE THERE
  1436. ;====================================
  1437. ;receive a sector
  1438. RCVSECT:XRA    A
  1439.     STA    ERRCT
  1440. RCVRPT:    CALL    VORQ
  1441.     JZ    RCVSQ
  1442.     CALL    CRLF    ;clear col count
  1443.     CALL    ILPRT    ;comment message
  1444.     DB 'Awaiting # ',0
  1445.     PUSH    H    ;SAVE IT
  1446.     LHLD    SECNO    ;GET SECTOR NUMBER
  1447.     INX    H    ;BUMP IT
  1448.     CALL    DECOUT    ;PRINT SECTOR NUMBER IN DECIMAL
  1449.     CALL    ILPRT
  1450.     DB    ' (', 0
  1451.     CALL    DHXOUT    ;16 BIT HEX CONVERSION & OUTPUT
  1452.     CALL    ILPRT
  1453.     DB    'H)',0
  1454.     POP    H    ;RESTORE IT
  1455. ;    If CRC is in effect, there is only a 7 second wait
  1456. ;    for the first SOH.  If the SOH is not received within
  1457. ;    this time, then a NAK is sent which tells the sender
  1458. ;    to use checksum checking instead of CRC.  This allows
  1459. ;    automatic compatability with versions of MODEM that
  1460. ;    do not implement Cyclic Redundancy Checking(CRC).
  1461. RCVSQ:    LDA    FIRSTME    ;first SOH...
  1462.     ORA    A    ;...been received?
  1463.     JZ    RCVSQ2    ;yes, go get next SOH
  1464.     XRA    A    ;turn off...
  1465.     STA    FIRSTME    ;...first soh recvd switch
  1466.     LDA    CRCFLG    ;CRC in...
  1467.     ORA    A    ;...effect?
  1468.     JNZ    RCVSQ2    ;no, do long wait for first SOH
  1469.     MVI    B,7    ;wait for upto 7 seconds
  1470.     CALL    RECV    ;get a character from modem
  1471.     JNC    RCVSQ3    ;got a char, go see if SOH
  1472.     LDA    QFLG
  1473.     ORA    A
  1474.     JZ    CRCM
  1475.     CALL    ILPRT    ;first comment
  1476.     DB CR,LF,'++Switching to CHECKSUM MODE++',CR,LF,0
  1477. CRCM:    MVI    A,'C'    ;turn off...
  1478.     STA    CRCFLG    ;...CRC mode.
  1479.     MVI    A,NAK    ;send NAK to tell sender checksum
  1480.     CALL    SEND    ;...is in effect & to start sending.
  1481.     JMP    RCVSECT    ;go start receiving sector
  1482. ;
  1483. RCVSQ2:    MVI    B,7    ;10 IN ORIG PROG
  1484.     CALL    RECV
  1485.     JC    RCVSTOT
  1486. RCVSQ3:    CPI    SOH
  1487.     JZ    RCVSOH
  1488.     ORA    A    ;IGNORE NULLS
  1489.     JZ    RCVSQ
  1490.     CPI    EOT
  1491.     STC
  1492.     RZ
  1493.     MOV    B,A
  1494.     LDA    QFLG
  1495.     ORA    A
  1496.     JZ    RCVSERR
  1497.     MOV    A,B
  1498.     CALL    CRLF
  1499.     CALL    HEXO
  1500.     CALL    ILPRT    ;error message
  1501.     DB 'H recv''d, not SOH',CR,LF,0
  1502. RCVSERR: MVI    B,1
  1503.     CALL    RECV
  1504.     JNC    RCVSERR
  1505.     MVI    A,NAK
  1506.     CALL    SEND
  1507.     LDA    ERRCT
  1508.     INR    A
  1509.     STA    ERRCT
  1510.     CPI    ERRLIM
  1511.     JC    RCVRPT
  1512.     LDA    QFLG
  1513.     ORA    A
  1514.     JZ    RCVSABT
  1515.     CALL    CKQUIT
  1516.     JZ    RCVSECT
  1517. RCVSABT:CALL    CLOSFIL
  1518.     CALL    ERXIT    ;fatal error
  1519.     DB CR,LF,'++Unable to receive block - Aborting++$'
  1520. RCVSTOT:LDA    QFLG
  1521.     ORA    A
  1522.     JZ    RCVSERR
  1523.     CALL    ILPRT    ;error message
  1524.     DB CR,LF,'++  Timeout ++ ',0
  1525. RCVPRN:    LDA    ERRCT
  1526.     CALL    HEXO
  1527.     CALL    CRLF
  1528.     JMP    RCVSERR
  1529. RCVSOH:    MVI    B,1
  1530.     CALL    RECV
  1531.     JC    RCVSTOT
  1532.     MOV    D,A
  1533.     MVI    B,1
  1534.     CALL    RECV
  1535.     JC    RCVSTOT
  1536.     CMA
  1537.     CMP    D
  1538.     JZ    RCVDATA
  1539.     LDA    QFLG
  1540.     ORA    A
  1541.     JZ    RCVSERR
  1542.     CALL    ILPRT    ;error message
  1543.     DB CR,LF,'++  Bad sector # in Hdr',CR,LF,0
  1544.     JMP    RCVSERR
  1545. RCVDATA:MOV    A,D
  1546.     STA    RCVSNO
  1547.     MVI    A,1
  1548.     STA    DATAFLG
  1549.     MVI    C,0    ;clear checksum
  1550.     CALL    CLRCRC    ;clear crc counter
  1551.     LXI    H,80H
  1552. RCVCHR:    MVI    B,1
  1553.     CALL    RECV
  1554.     JC    RCVSTOT
  1555.     MOV    M,A
  1556.     INR    L
  1557.     JNZ    RCVCHR
  1558.     XRA    A
  1559.     STA    DATAFLG
  1560.     LDA    CRCFLG
  1561.     ORA    A
  1562.     JZ    RCVCRC
  1563.     MOV    D,C
  1564.     MVI    B,1
  1565.     CALL    RECV
  1566.     JC    RCVSTOT
  1567.     CMP    D
  1568.     JNZ    RCVCERR
  1569. CHKSNUM:LDA    RCVSNO
  1570.     MOV    B,A
  1571.     LDA    SECNO
  1572.     CMP    B
  1573.     JZ    RECVACK
  1574.     INR    A
  1575.     CMP    B
  1576.     JNZ    ABORT
  1577.     RET
  1578. RCVCRC:    MVI    E,2    ;nr of crc bytes
  1579. RCV2CRC:MVI    B,1
  1580.     CALL    RECV
  1581.     JC    RCVSTOT
  1582.     DCR    E
  1583.     JNZ    RCV2CRC
  1584.     CALL    CHKCRC
  1585.     ORA    A
  1586.     JZ    CHKSNUM
  1587.     LDA    QFLG
  1588.     ORA    A
  1589.     JZ    RCVSERR
  1590.     CALL    ILPRT    ;error message
  1591.     DB CR,LF,'++CRC error++',0
  1592.     JMP    RCVPRN
  1593. RCVCERR:LDA    QFLG
  1594.     ORA    A
  1595.     JZ    RCVSERR
  1596.     CALL    ILPRT    ;error message
  1597.     DB '++Cksum error++ ',0
  1598.     JMP    RCVPRN
  1599. RECVACK:CALL    SENDACK
  1600.     JMP    RCVSECT
  1601. ;===============================
  1602. SENDACK:MVI    A,ACK
  1603.     CALL    SEND
  1604.     RET
  1605. ;===========================
  1606. ;send header
  1607. SENDHDR:CALL    VORQ
  1608.     JZ    SENDHNM
  1609.     CALL    CRLF    ;clear col count
  1610.     CALL    ILPRT    ;comment message
  1611.     DB 'Send # ',0
  1612.     PUSH    H
  1613.     LHLD    SECNO    ;GET SECTOR NUMBER
  1614.     CALL    DECOUT    ;PRINT IT IN DECIMAL
  1615.     CALL    ILPRT
  1616.     DB    '  (',0
  1617.     CALL    DHXOUT    ;16 BIT HEX CONVERSION & OUTPUT
  1618.     CALL    ILPRT
  1619.     DB    'H)',0
  1620.     POP    H
  1621. SENDHNM:MVI    A,SOH
  1622.     CALL    SEND
  1623.     LDA    SECNO
  1624.     CALL    SEND
  1625.     LDA    SECNO
  1626.     CMA
  1627.     CALL    SEND
  1628.     RET
  1629. ;========================
  1630. SENDSEC:MVI    A,1
  1631.     STA    DATAFLG
  1632.     MVI    C,0
  1633.     CALL    CLRCRC
  1634.     LXI    H,80H
  1635. SENDC:    MOV    A,M
  1636.     CALL    SEND
  1637.     INR    L
  1638.     JNZ    SENDC
  1639.     XRA    A
  1640.     STA    DATAFLG
  1641.     RET
  1642. ;===============================
  1643. SENDCKS:MOV    A,C
  1644.     CALL    SEND
  1645.     RET
  1646. ;==============================
  1647. SENDCRC:PUSH    H
  1648.     LHLD    CRCVAL
  1649.     MOV    A,H
  1650.     CALL    SEND
  1651.     MOV    A,L
  1652.     CALL    SEND
  1653.     POP    H
  1654.     XRA    A
  1655.     RET
  1656. ;===============================
  1657. GETACK:    MVI    B,7    ;10 IN ORIG PROG
  1658.     CALL    RECVDG
  1659.     JC    GETATOT
  1660.     CPI    ACK
  1661.     RZ
  1662.     MOV    B,A
  1663.     LDA    QFLG
  1664.     ORA    A
  1665.     JZ    ACKERR
  1666.     MOV    A,B
  1667.     CALL    CRLF
  1668.     CALL    HEXO
  1669.     CALL    ILPRT    ;error message
  1670.     DB 'H Recv''d, not ACK',CR,LF,0
  1671. ACKERR:    LDA    ERRCT
  1672.     INR    A
  1673.     STA    ERRCT
  1674.     CPI    ERRLIM
  1675.     RC
  1676.     LDA    QFLG
  1677.     ORA    A
  1678.     JZ    CSABORT
  1679.     CALL    CKQUIT
  1680.     STC
  1681.     RZ
  1682. CSABORT:CALL    ERXIT    ;fatal error
  1683.     DB CR,LF,'Can''t send sector -- Aborting$'
  1684. GETATOT:LDA    QFLG
  1685.     ORA    A
  1686.     JZ    ACKERR
  1687.     CALL    ILPRT    ;error message
  1688.     DB CR,LF,'Timeout on ACK',CR,LF,0
  1689.     JMP    ACKERR
  1690. ;================================
  1691. CKABORT:LDA    QFLG
  1692.     ORA    A
  1693.     RZ    
  1694.     CALL    STAT
  1695.     RZ
  1696.     CALL    KEYIN
  1697.     CPI    CAN
  1698.     JZ    ABORT    ;local abort
  1699.     RET
  1700. ERXIT:    POP    D    ;print message and abort
  1701.     MVI    C,PRINT
  1702.     CALL    BDOS    ;does not update col count
  1703.     CALL    CRLF    ;reset col count
  1704. ABORT:    LXI    SP,STAK
  1705. ABORTL:    MVI    B,1
  1706.     CALL    RECV    ;wait until sender finishes
  1707.     JNC    ABORTL
  1708.     MVI    A,CAN
  1709.     CALL    SEND
  1710. ABORTW:    MVI    B,1
  1711.     CALL    RECV    ;wait until sender finishes
  1712.     JNC    ABORTW
  1713.     MVI    A,' '    ;send a space to clear out ^X
  1714.     CALL    SEND
  1715.     CALL    ILPRT
  1716.     DB CR,LF,'Routine cancelled',CR,LF,BELL,0
  1717.     LXI    H,RESTROPT
  1718.     LXI    D,OPTBL
  1719.     MVI    B,OPTBE-OPTBL-2
  1720.     CALL    MOVE    ;clear options except T
  1721.     XRA    A
  1722.     STA    BATCHFLG;clear N option
  1723.     JMP    DONETA
  1724. ;===================================
  1725. INCRSNO:PUSH    H
  1726.     LHLD    SECNO    ;GET SECTOR NUMBER
  1727.     INX    H    ;BUMP IT
  1728.     SHLD    SECNO    ;STORE IT
  1729.     POP    H
  1730.     RET
  1731. ;===============================
  1732. AMBGTS:    LXI    H,FCB+1
  1733.     MVI    C,11
  1734. AMBIG:    MOV    A,M
  1735.     INX    H
  1736.     CPI    '?'    ;test for ambiguous name
  1737.     JNZ    NOTAMB
  1738.     CALL    ILPRT    ;fatal error
  1739.     DB 'Ambiguous filename not allowed',CR,LF,0
  1740.     JMP    MENU
  1741. NOTAMB:    DCR    C
  1742.     JNZ    AMBIG
  1743.     RET
  1744. ;=============================
  1745. ERASFIL:LDA    BATCHFLG ;DON'T ASK FOR ERASE..
  1746.     ORA    A    ;..IN MULTI-FILE MODE,..
  1747.     JNZ    NOASK
  1748.     LDA    QFLG
  1749.     ORA    A
  1750.     JZ    NOASK    ;dont hang up in Q mode
  1751. TFLERAS:CALL    AMBGTS    ;ambiguous name ?
  1752.     LXI    D,FCB
  1753.     MVI    C,SRCHF    ;see if file exists already
  1754.     CALL    BDOS
  1755.     INR    A
  1756.     RZ
  1757.     CALL    ILPRT
  1758.     DB 'File exists -- Type ''Y'' to erase: ',BELL,0
  1759.     CALL    KEYIN
  1760.     PUSH    PSW
  1761.     CALL    CTYPE
  1762.     POP    PSW
  1763.     CALL    UCASE
  1764.     CPI    'Y'
  1765.     CALL    CRLF
  1766.     JNZ    MENU
  1767. NOASK:    LXI    D,FCB
  1768.     MVI    C,ERASE
  1769.     CALL    BDOS
  1770.     RET
  1771. ;===========================
  1772. MAKEFIL:LXI    D,FCB
  1773.     MVI    C,MAKE
  1774.     CALL    BDOS
  1775.     INR    A
  1776.     RNZ
  1777.     CALL    ERXIT    ;fatal error
  1778.     DB 'Error - Can''t make file',CR,LF
  1779.     DB 'Directory must be full$'
  1780. ;==================================
  1781. CNREC:    MVI    C,12
  1782.     CALL    BDOS
  1783.     ORA    A    ;0 means CP/M 1
  1784.     JZ    CNREC14
  1785.     MVI    C,FILSIZ ;COMPUTE FILE SIZE FUNCTION IN CP/M 2.x
  1786.     LXI    D,FCB    ;POINT TO FILE CONTROL BLOCK
  1787.     CALL    BDOS
  1788.     LHLD    FCB+33    ;GET RECORD COUNT
  1789.     SHLD    RCNT    ;STORE IT
  1790.     LXI    H,0    ;ZERO HL
  1791.     SHLD    FCB+33    ;RESET RANDOM RECORD IN FCB
  1792.     RET
  1793. CNREC14:MVI    A,'?'    ;MATCH ALL EXTENTS
  1794.     STA    FCBEXT
  1795.     MVI    A,0FFH
  1796.     STA    MAXEXT    ;INIT MAX EXT NO.
  1797.     MVI    C,SRCHF    ;GET 'SEARCH FIRST' FNC
  1798.     LXI    D,FCB
  1799.     CALL    BDOS    ;READ FIRST
  1800.     INR    A    ;WERE THERE ANY?
  1801.     JNZ    SOME    ;GOT SOME
  1802.     CALL    ERXIT    ;fatal error
  1803.     DB '++File not found++$'
  1804. ;POINT TO DIRECTORY ENTRY
  1805. SOME:    DCR    A    ;UNDO PREV 'INR A'
  1806.     ANI    3    ;MAKE MODULUS 4
  1807.     ADD    A    ;MULTIPLY...
  1808.     ADD    A    ;..BY 32 BECAUSE
  1809.     ADD    A    ;..EACH DIRECTORY
  1810.     ADD    A    ;..ENTRY IS 32
  1811.     ADD    A    ;..BYTES LONG
  1812.     LXI    H,80H ;POINT TO BUFFER
  1813.     ADD    L    ;POINT TO ENTRY
  1814.     ADI    15    ;OFFSET TO RECORD COUNT
  1815.     MOV    L,A    ;HL NOW POINTS TO REC COUNT
  1816.     MOV    B,M    ;GET RECORD COUNT
  1817.     DCX    H
  1818.     DCX    H    ;BACK DOWN TO EXTENT NUMBER
  1819.     DCX    H
  1820.     LDA    MAXEXT    ;COMPARE WITH CURRENT MAX.
  1821.     ORA    A    ;IF NO MAX YET
  1822.     JM    BIGGER    ;THEN SAVE RECORD COUNT ANYWAY
  1823.     CMP    M
  1824.     JNC    MOREDIR
  1825. BIGGER:    MOV    A,B    ;SAVE NEW RECORD COUNT
  1826.     STA    RCNT
  1827.     MOV    A,M    ;SAVE NEW MAX. EXTENT NO.
  1828.     STA    MAXEXT
  1829. MOREDIR:MVI    C,SRCHN    ;SEARCH NEXT
  1830.     LXI    D,FCB
  1831.     CALL    BDOS    ;READ DIR ENTRY
  1832.     INR    A    ;CHECK FOR END (0FFH)
  1833.     JNZ    SOME    ;NOT END OF DIR...PROCESS EXTENT
  1834.     LDA    MAXEXT    ;HIT END...GET HIGHEST EXTENT NO. SEEN
  1835.     MOV    L,A    ;WHICH GIVES EXTENT COUNT -1
  1836.     MVI    H,0
  1837.     MOV    D,H
  1838.     LDA    RCNT    ;GET RECORD COUNT OF MAX EXTENT SEEN
  1839.     MOV    E,A    ;SAVE IT IN DE
  1840.     DAD    H
  1841.     DAD    H    ;MULTIPLY # OF EXTENTS -1
  1842.     DAD    H    ; TIMES 128
  1843.     DAD    H
  1844.     DAD    H
  1845.     DAD    H
  1846.     DAD    H
  1847.     DAD    D    ;ADD IN SIZE OF LAST EXTENT
  1848.     SHLD    RCNT    ;SAVE TOTAL RECORD COUNT
  1849.     RET
  1850. ;==================================
  1851. OPENFIL:XRA    A
  1852.     STA    FCBEXT
  1853.     LXI    D,FCB
  1854.     MVI    C,OPEN
  1855.     CALL    BDOS
  1856.     INR    A
  1857.     JNZ    OPENOK
  1858.     CALL    ERXIT    ;fatal error
  1859.     DB 'Can''t open file$'
  1860. OPENOK:    CALL    VORQ
  1861.     RZ
  1862.     CALL    ILPRT    ;comment message
  1863.     DB 'File open, size: ',0
  1864.     LHLD    RCNT    ;GET RECORD COUNT
  1865.     CALL    DECOUT    ;PRINT NUMBER OF SECTORS IN DECIMAL
  1866.     CALL    ILPRT    ;PRINT
  1867.     DB    ' (',0
  1868.     CALL    DHXOUT
  1869.     CALL    ILPRT
  1870.     DB    'H) sectors',CR,LF,0
  1871.     RET
  1872. ;=============================
  1873. CLOSFIL:LXI    D,FCB
  1874.     MVI    C,CLOSE
  1875.     CALL    BDOS
  1876.     INR    A
  1877.     RNZ
  1878.     CALL    ERXIT    ;fatal error
  1879.     DB 'Can''t close file$'
  1880. ;================================
  1881. RDSECT:    LDA    SECINBF
  1882.     DCR    A
  1883.     STA    SECINBF
  1884.     JM    RDBLOCK
  1885.     LHLD    SECPTR
  1886.     LXI    D,80H
  1887.     CALL    MOVE128
  1888.     SHLD    SECPTR
  1889.     RET
  1890. RDBLOCK:LDA    EOFLG
  1891.     CPI    1
  1892.     STC
  1893.     RZ
  1894.     MVI    C,0
  1895.     LXI    D,DBUF
  1896. RDSECLP:PUSH    B
  1897.     PUSH    D
  1898.     MVI    C,STDMA
  1899.     CALL    BDOS
  1900.     LXI    D,FCB
  1901.     MVI    C,READ
  1902.     CALL    BDOS
  1903.     POP    D
  1904.     POP    B
  1905.     ORA    A
  1906.     JNZ    REOF
  1907.     LXI    H,80H
  1908.     DAD    D
  1909.     XCHG
  1910.     INR    C
  1911.     MOV    A,C
  1912.     CPI    DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
  1913.     JZ    RDBFULL
  1914.     JMP    RDSECLP
  1915. REOF:    MVI    A,1
  1916.     STA    EOFLG
  1917.     MOV    A,C
  1918. RDBFULL:STA    SECINBF
  1919.     LXI    H,DBUF
  1920.     SHLD    SECPTR
  1921.     LXI    D,80H
  1922.     MVI    C,STDMA
  1923.     CALL    BDOS
  1924.     JMP    RDSECT
  1925. ;==================================
  1926. WRSECT:    LHLD    SECPTR
  1927.     XCHG
  1928.     LXI    H,80H
  1929.     CALL    MOVE128
  1930.     XCHG
  1931.     SHLD    SECPTR
  1932.     LDA    SECINBF
  1933.     INR    A
  1934.     STA    SECINBF
  1935.     CPI    DBUFSIZ*8 ;BUFFER SIZE IN 128 BYTE SECTORS
  1936.     RNZ
  1937. WRBLOCK:LDA    SECINBF
  1938.     ORA    A
  1939.     RZ
  1940.     MOV    C,A
  1941.     LXI    D,DBUF
  1942. DKWRLP:    PUSH    H
  1943.     PUSH    D
  1944.     PUSH    B
  1945.     MVI    C,STDMA
  1946.     CALL    BDOS
  1947.     LXI    D,FCB
  1948.     MVI    C,WRITE
  1949.     CALL    BDOS
  1950.     POP    B
  1951.     POP    D
  1952.     POP    H
  1953.     ORA    A
  1954.     JNZ    WRERR
  1955.     LXI    H,80H
  1956.     DAD    D
  1957.     XCHG
  1958.     DCR    C
  1959.     JNZ    DKWRLP
  1960.     XRA    A
  1961.     STA    SECINBF
  1962.     LXI    H,DBUF
  1963.     SHLD    SECPTR
  1964. RSDMA:    LXI    D,80H    ;required by CP/M 1.4
  1965.     MVI    C,STDMA
  1966.     CALL    BDOS
  1967.     RET
  1968. WRERR:    CALL    RSDMA
  1969.     MVI    A,CAN
  1970.     CALL    SEND
  1971.     CALL    ERXIT    ;fatal error
  1972.     DB 'Error writing file$'
  1973. ;===========================================
  1974. ;RECV: Receive a character
  1975. ;Timeout time is in B, in seconds. Entry via 'RECVDG' deletes garbage
  1976. ;characters on the line. For example, having just sent a sector, calling
  1977. ;RECVDG will delete any line noise induced characters LONG before the
  1978. ;ACK/NAK would be received.
  1979. RECVDG:    CALL    INMODDATP
  1980.     CALL    INMODDATP
  1981. RECV:    PUSH    D
  1982.     LDA    FASTCLK
  1983.     ORA    A
  1984.     JZ    MSEC
  1985.     MOV    A,B
  1986.     ADD    A
  1987.     MOV    B,A
  1988. MSEC:    LXI    D,15000    ;60% OF ORIG 50000
  1989.     CALL    CKABORT
  1990. MWTI:    CALL    STAT    ;check keyboard
  1991.     ORA    A
  1992.     JZ    MWTJ
  1993.     CALL    KEYIN    ;get char
  1994.     CALL    UCASE
  1995.     CALL    FLGTGL    ;toggle appropriate flag
  1996. MWTJ:    CALL    INMODCTLP
  1997.     CALL    ANIRCV
  1998.     CALL    CPIRCV    ;wait for modem char
  1999.     JZ    MCHAR
  2000.     DCR    E
  2001.     JNZ    MWTI
  2002.     DCR    D
  2003.     JNZ    MWTI
  2004.     DCR    B
  2005.     JNZ    MSEC
  2006.     POP    D
  2007.     STC
  2008.     RET
  2009. MCHAR:    CALL    INMODDATP
  2010.     POP    D
  2011.     PUSH    PSW
  2012.     CALL    UPDCRC    ;calc crc
  2013.     ADD    C    
  2014.     MOV    C,A
  2015.     LDA    RSEEFLG
  2016.     ORA    A
  2017.     JZ    MONIN
  2018.     LDA    VSEEFLG
  2019.     ORA    A
  2020.     JNZ    NOMONIN
  2021.     LDA    DATAFLG
  2022.     ORA    A
  2023.     JZ    NOMONIN
  2024. MONIN:    POP    PSW
  2025.     PUSH    PSW
  2026.     CALL    SHOW
  2027. NOMONIN:POP    PSW
  2028.     ORA    A
  2029.     RET
  2030. ;==============================
  2031. ;set/reset secondary options
  2032. FLGTGL:    PUSH    B
  2033.     PUSH    D
  2034.     PUSH    H
  2035.     LXI    H,OPTBL    ;flag
  2036.     LXI    D,RESTROPT
  2037.     MVI    C,5    ;do Q,R,S,V,T but NOT N
  2038.     MOV    B,A
  2039. DOCMP:    LDAX    D    ;get reference
  2040.     CMP    B
  2041.     JNZ    DOCMP1
  2042.     MOV    A,B
  2043.     CMP    M    ;current setting
  2044.     MOV    M,A    ;clear flag
  2045.     JNZ    DOCMP1
  2046.     XRA    A
  2047.     MOV    M,A    ;set flag
  2048. DOCMP1:    INX    D
  2049.     INX    H
  2050.     DCR    C
  2051.     JNZ    DOCMP
  2052.     POP    H
  2053.     POP    D
  2054.     POP    B
  2055.     RET
  2056. ;=================================
  2057. SEND:    PUSH    PSW
  2058.     LDA    SSEEFLG
  2059.     ORA    A
  2060.     JZ    MONOUT
  2061.     LDA    VSEEFLG
  2062.     ORA    A
  2063.     JNZ    NOMONOT
  2064.     LDA    DATAFLG
  2065.     ORA    A
  2066.     JZ    NOMONOT
  2067. MONOUT:    POP    PSW
  2068.     PUSH    PSW
  2069.     CALL    SHOW
  2070. NOMONOT:POP    PSW
  2071.     PUSH    PSW
  2072.     CALL    UPDCRC    ;calc crc
  2073.     ADD    C
  2074.     MOV    C,A
  2075.     POP    PSW
  2076.     CALL    CHRSND    ;send to remote
  2077.     CALL    STAT    ;check for keypress
  2078.     ORA    A
  2079.     RZ
  2080.     CALL    KEYIN    ;get char
  2081.     CALL    UCASE
  2082.     CALL    FLGTGL    ;toggle appropriate flag
  2083.     RET
  2084. ;==================================
  2085. WAITNAK:LDA    QFLG
  2086.     ORA    A
  2087.     JZ    WAITNLP
  2088.     CALL    ILPRT    ;first comment
  2089.     DB 'Awaiting initial NAK',CR,LF,0
  2090. WAITNLP:CALL    CKABORT
  2091.     MVI    B,1
  2092.     CALL    RECV
  2093.     CPI    NAK
  2094.     RZ
  2095.     CPI    CRC    ;crc request?
  2096.     JZ    WAITCRC    ;yes, go set crc flag
  2097.     DCR    E
  2098.     JZ    ABORT
  2099.     JMP    WAITNLP
  2100. WAITCRC:XRA    A
  2101.     STA    CRCFLG
  2102.     LDA    QFLG
  2103.     ORA    A
  2104.     RZ
  2105.     CALL    ILPRT    ;first comment
  2106.     DB 'CRC request received',CR,LF,0
  2107.     RET
  2108. ;===============================
  2109. ;return zero = no message display
  2110. ;use ahead of comment messages except first and final
  2111. VORQ:    LDA    VSEEFLG
  2112.     ORA    A
  2113.     RZ
  2114.     LDA    QFLG
  2115.     ORA    A
  2116.     RET
  2117. ;==================================
  2118. INITADR:LHLD    1
  2119.     LXI    D,3
  2120.     DAD    D
  2121.     SHLD    VSTAT+1
  2122.     DAD    D
  2123.     SHLD    VKEYIN+1
  2124.     DAD    D
  2125.     SHLD    VTYPE+1
  2126.     LXI    D,33
  2127.     DAD    D
  2128.     SHLD    LISTST+1
  2129.     RET
  2130. ;=================================
  2131. MOVEFCB:LXI    H,FCB+16
  2132.     LXI    D,FCB
  2133.     MVI    B,16
  2134.     CALL    MOVE
  2135.     XRA    A
  2136.     STA    FCBRNO
  2137.     STA    FCBEXT
  2138.     RET
  2139. ;=========================
  2140. CMPDEHL:MOV    A,E
  2141.     CMP    L
  2142.     RNZ
  2143.     MOV    A,D
  2144.     CMP    H
  2145.     RET
  2146. ;=============================
  2147. ;carry set for non printing ASCII chars + VT & FF
  2148. FILTER:    CPI    8    ;BS
  2149.     RC        ;Byte is less than 08H
  2150.     CPI    LF+1    ;
  2151.     CMC        ;invert carry flag
  2152.     RNC        ;get rid of VT & HT, invert BS & LF carry flag
  2153.     CPI    CR    ;
  2154.     RC        ;Byte is less than 0D
  2155.     RZ        ;byte = LF,CR or BS, no carry
  2156.     CPI    ' '    ;CPI space
  2157.     RC        ;Byte is between 0E & 0F, reject
  2158.     CPI    7FH    ;Del char
  2159.     CMC        ;printable chars to no carry, DEL to carry
  2160.     RET
  2161. ;==============================
  2162. ;put C into print buffer, if buffer full byte is lost
  2163. LISTOUT:MOV    A,C
  2164.     ANI    7FH    ;remove top bit
  2165.     CALL    FILTER    ;ignore non printing chars
  2166.     RC
  2167. LSTBUF:    LHLD    BUFEND
  2168.     XCHG
  2169.     LHLD    BUFRIN
  2170.     INX    H
  2171.     CALL    CMPDEHL
  2172.     JNZ    LBUFF1    ;test for end of buffer
  2173.     LHLD    BUFBEG    ;reset to start
  2174. LBUFF1:    XCHG
  2175.     LHLD    BUFROUT
  2176.     CALL    CMPDEHL
  2177.     RZ        ;buffer full
  2178.     XCHG
  2179.     SHLD    BUFRIN
  2180.     MOV    M,C    ;save byte in buffer
  2181.     RET
  2182. ;==========================
  2183. ;Check printer status, if busy return, else print one char
  2184. LISTST:    CALL    $-$
  2185.     ORA    A
  2186.     RZ        ;see if printer is busy
  2187.     LHLD    BUFRIN
  2188.     XCHG
  2189.     LHLD    BUFROUT
  2190.     CALL    CMPDEHL
  2191.     RZ        ;return if buffer empty
  2192.     INX    H
  2193.     PUSH    H
  2194.     LHLD    BUFEND
  2195.     XCHG
  2196.     POP    H
  2197.     CALL    CMPDEHL
  2198.     JNZ    PRBUF2
  2199.     LHLD    BUFBEG    ;reset to start
  2200. PRBUF2:    SHLD    BUFROUT
  2201.     MOV    E,M
  2202.     MVI    C,LIST    ;CP/M print function
  2203.     CALL    BDOS
  2204.     RET
  2205. ;=============================
  2206. CONO:    MOV    C,A
  2207.     CPI    9
  2208.     JNZ    CONSOP
  2209. TAB:    MVI    A,' '
  2210.     CALL    CONSOP    ;expand tabs
  2211.     LDA    COLCNT
  2212.     ANI    7
  2213.     JNZ    TAB
  2214.     RET
  2215. CONSOP:    MOV    C,A
  2216.     LDA    LSTFLG
  2217.     ORA    A
  2218.     CNZ    LISTOUT    ;no tabs left by now
  2219.     MOV    A,C
  2220.     CALL    TYPE
  2221.     MOV    C,A
  2222.     LXI    H,COLCNT
  2223.     CPI    7FH
  2224.     RZ
  2225.     INR    M
  2226.     CPI    ' '
  2227.     RNC
  2228.     DCR    M
  2229.     MOV    A,M
  2230.     ORA    A
  2231.     RZ
  2232.     MOV    A,C
  2233.     CPI    8
  2234.     JNZ    TRYCR
  2235.     DCR    M
  2236.     RET
  2237. TRYCR:    CPI    CR
  2238.     RNZ
  2239.     MVI    M,0
  2240.     RET
  2241. ;=============================
  2242. SHOW:    CPI    LF
  2243.     JZ    CTYPE
  2244.     CPI    CR
  2245.     JZ    CTYPE
  2246.     PUSH    PSW
  2247.     PUSH    H
  2248.     LXI    H,TWIDTH
  2249.     LDA    COLCNT    ;check terminal width
  2250.     CMP    M
  2251.     CNC    CRLF    ;force CR,LF
  2252.     POP    H
  2253.     POP    PSW
  2254.     CPI    9
  2255.     JZ    CTYPE
  2256.     CPI    ' '
  2257.     JC    SHOWHEX
  2258.     CPI    7FH
  2259.     JC    CTYPE
  2260. SHOWHEX:PUSH    PSW
  2261.     MVI    A,'('
  2262.     CALL    CTYPE
  2263.     POP    PSW
  2264.     CALL    HEXO
  2265.     MVI    A,')'
  2266. CTYPE:    PUSH    PSW
  2267.     PUSH    B
  2268.     PUSH    D
  2269.     PUSH    H
  2270.     ANI    7FH    ;ensure parity bits are suppressed
  2271.     CALL    CONO    ;type with tabs expanded
  2272.     POP    H
  2273.     POP    D
  2274.     POP    B
  2275.     POP    PSW
  2276.     RET
  2277. ;=============================
  2278. CRLF:    PUSH    PSW
  2279.     MVI    A,CR
  2280.     CALL    CTYPE
  2281.     MVI    A,LF
  2282.     CALL    CTYPE
  2283.     POP    PSW
  2284.     RET
  2285. ;==========================
  2286. TYPE:    PUSH    PSW
  2287.     PUSH    B
  2288.     PUSH    D
  2289.     PUSH    H
  2290.     ANI    7FH    ;ensure parity bits are suppressed
  2291.     MOV    C,A
  2292. VTYPE:    CALL    $-$
  2293.     POP    H
  2294.     POP    D
  2295.     POP    B
  2296.     POP    PSW
  2297.     RET
  2298. ;=========================
  2299. STAT:    PUSH    B
  2300.     PUSH    D
  2301.     PUSH    H
  2302.     CALL    LISTST    ;o/p next char to printer
  2303. VSTAT:    CALL    $-$    ;get keyboard status
  2304.     POP    H
  2305.     POP    D
  2306.     POP    B
  2307.     ORA    A
  2308.     RET
  2309. ;===============================
  2310. KEYIN:    PUSH    B
  2311.     PUSH    D
  2312.     PUSH    H
  2313. VKEYIN:    CALL    $-$
  2314.     POP    H
  2315.     POP    D
  2316.     POP    B
  2317.     RET
  2318. ;===========================
  2319. UCASE:    CPI    61H    ;CHANGES LOWER CASE CHARACTER..
  2320.     RC        ;..IN A-REG TO UPPER CASE.
  2321.     CPI    7BH
  2322.     RNC
  2323.     ANI    5FH
  2324.     RET
  2325. ;============================
  2326. DECOUT:    PUSH    PSW
  2327.     PUSH    B
  2328.     PUSH    D
  2329.     PUSH    H
  2330.     LXI    B,-10
  2331.     LXI    D,-1
  2332. DECOU2:    DAD    B
  2333.     INX    D
  2334.     JC    DECOU2
  2335.     LXI    B,10
  2336.     DAD    B
  2337.     XCHG
  2338.     MOV    A,H
  2339.     ORA    L
  2340.     CNZ    DECOUT
  2341.     MOV    A,E
  2342.     ADI    '0'
  2343.     CALL    CTYPE
  2344.     POP    H
  2345.     POP    D
  2346.     POP    B
  2347.     POP    PSW
  2348.     RET
  2349. ;======================================
  2350. ; - double precision hex output routine.
  2351. DHXOUT:    PUSH    H
  2352.     PUSH    PSW
  2353.     MOV    A,H    ;GET MS BYTE
  2354.     ORA    A
  2355.     CNZ    HEXO    ;suppress high order if zero
  2356.     MOV    A,L    ;GET LS BYTE
  2357.     CALL    HEXO    ;OUTPUT LOW ORDER BYTE
  2358.     POP    PSW
  2359.     POP    H
  2360.     RET
  2361. ;===============================
  2362. HEXO:    PUSH    PSW
  2363.     RAR
  2364.     RAR
  2365.     RAR
  2366.     RAR
  2367.     CALL    NIBBL
  2368.     POP    PSW
  2369. NIBBL:    ANI    0FH
  2370.     CPI    10
  2371.     JC    ISNUM
  2372.     ADI    7
  2373. ISNUM:    ADI    '0'
  2374.     JMP    CTYPE
  2375. ;=====================================
  2376. ;RETNS W/ ZERO SET IF RETRY ASKED. IF MULTI-FILE MODE, THEN
  2377. ;NO QUESTIONS ASKED, JUST QUIT
  2378. CKQUIT:    LDA    BATCHFLG
  2379.     ORA    A
  2380.     JZ    CKQTASK    ;ASK FOR RETRY
  2381.     INR    A    ;RESET ZERO FLG
  2382.     RET
  2383. CKQTASK:XRA    A
  2384.     STA    ERRCT
  2385.     CALL    ILPRT
  2386.     DB 'Multiple errors encountered.',CR,LF
  2387.     DB 'Type Q to quit, R to retry:  ',BELL,0
  2388.     CALL    KEYIN
  2389.     PUSH    PSW
  2390.     CALL    CTYPE
  2391.     CALL    CRLF
  2392.     POP    PSW
  2393.     CALL    UCASE
  2394.     CPI    'R'
  2395.     RZ
  2396.     CPI    'Q'
  2397.     JNZ    CKQUIT
  2398.     ORA    A
  2399.     RET
  2400. ;==============================
  2401. ILPRT:    XTHL
  2402. ILPLP:    MOV    A,M
  2403.     ORA    A
  2404.     JZ    ILPRET
  2405.     CALL    TYPE
  2406.     INX    H
  2407.     JMP    ILPLP
  2408. ILPRET:    XTHL
  2409.     RET
  2410. ;=========================
  2411. MOVE128:MVI    B,128
  2412. MOVE:    MOV    A,M
  2413.     STAX    D
  2414.     INX    H
  2415.     INX    D
  2416.     DCR    B
  2417.     JNZ    MOVE
  2418.     RET
  2419. ;==================================
  2420. ;Cyclic Redundancy Check Subroutines.
  2421. ;The generator is X^16 + X^12 + X^5 +1 as
  2422. ;recommended by CCITT
  2423. ;Generate table for fast CRC calculation
  2424. INITCRC:LXI    H,CRCTBL
  2425.     MVI    C,0
  2426. GLOOP:    XCHG
  2427.     LXI    H,0
  2428.     MOV    A,C
  2429.     PUSH    B
  2430.     MVI    B,8
  2431.     XRA    H
  2432.     MOV    H,A
  2433. LLOOP:    DAD    H
  2434.     JNC    LSKIP
  2435.     MVI    A,10H
  2436.     XRA    H
  2437.     MOV    H,A
  2438.     MVI    A,21H
  2439.     XRA    L
  2440.     MOV    L,A
  2441. LSKIP:    DCR    B
  2442.     JNZ    LLOOP
  2443.     POP    B
  2444.     XCHG
  2445.     MOV    M,D
  2446.     INR    H
  2447.     MOV    M,E
  2448.     DCR    H
  2449.     INX    H
  2450.     INR    C
  2451.     JNZ    GLOOP
  2452.     RET
  2453. ;=================================
  2454. ;Reset CRC Accumulator for a new message.
  2455. CLRCRC:    PUSH    H
  2456.     LXI    H,0
  2457.     SHLD    CRCVAL
  2458.     POP    H
  2459.     RET
  2460. ;====================================
  2461. ;Update CRC Accumulator using byte in (A).
  2462. UPDCRC:    PUSH    PSW
  2463.     PUSH    B
  2464.     PUSH    D
  2465.     PUSH    H
  2466.     LHLD    CRCVAL
  2467.     XCHG
  2468.     MVI    B,0
  2469.     XRA    D
  2470.     MOV    C,A
  2471.     LXI    H,CRCTBL
  2472.     DAD    B
  2473.     MOV    A,M
  2474.     XRA    E
  2475.     MOV    D,A
  2476.     INR    H
  2477.     MOV    E,M
  2478.     XCHG
  2479.     SHLD    CRCVAL
  2480.     POP    H
  2481.     POP    D
  2482.     POP    B
  2483.     POP    PSW
  2484.     RET
  2485. ;==================================
  2486. ; Check CRC bytes of received message.
  2487. CHKCRC:    PUSH    H
  2488.     LHLD    CRCVAL
  2489.     MOV    A,H
  2490.     ORA    L
  2491.     POP    H
  2492.     RZ
  2493.     MVI    A,0FFH
  2494.     RET
  2495. ;
  2496. CRCVAL:    DW    0
  2497. ;======================================
  2498. ;INBUFF    - DUPLICATES READ BUFFER ROUTINE
  2499. ;SAME AS CP/M FUNCTION 10, BUT DOES
  2500. ;NOT USE CTRL-C (REASON FOR ROUTINE).
  2501. ;DOES ALLOW CONTROLS U, R, E, AND H (BACKSPACE).
  2502. INBUFF:    PUSH PSW
  2503.     PUSH H
  2504.     PUSH B
  2505.     PUSH D        ;DE REGISTERS MUST BE PUSHED LAST
  2506. ISTART:    CALL ICLEAR    ;CLEAR THE BUFFER AREA
  2507.     POP D        ;GET ADDRESS OF BUFFER ON RETRIES
  2508.     PUSH D        ;RESTORE STACK
  2509.     XRA A
  2510.     INX D        ;ADDRESS COUNT FIELD
  2511.     STAX D        ;INITIALIZE WITH A ZERO IN COUNT BYTE
  2512.     INX D
  2513.     XCHG        ;ADDRESS FIRST BUFFER BYTE WITH HL
  2514. INBUFA:    CALL CONIN
  2515.     CPI 0DH        ;IS IT A RETURN?
  2516.     JZ INBUFR    ;IF SO, THEN RETURN
  2517.     CPI 7FH        ;IS IT A DELETE?
  2518.     JZ DELETE
  2519.     CPI 8        ;CTRL-H WILL BACKSPACE..
  2520.     JZ DELETE    ;..OVER DELETED CHAR.
  2521.     CPI 'U'-40H    ;IS IT A CTRL-U
  2522.     JZ INBUFO    ;OUTPUT # CR LF AND START OVER
  2523.     CPI 'R'-40H    ;CTRL-R RETYPES LINE
  2524.     JZ RETYPE
  2525.     CPI 'E'-40H
  2526.     JZ PCRLF
  2527.     CPI 20H        ;NO CONTROL CHARACTERS OTHER..
  2528.     JC INBUFA    ;..THAN ABOVE ALLOWED.
  2529.     MOV B,A        ;SAVE INPUTTED CHARACTER
  2530.     XCHG        ;SAVE HL IN DE
  2531.     POP H        ;GET ADDRESS OF BUFFER IN HL
  2532.     PUSH H        ;RESTORE STACK
  2533.     INX H        ;ADDRESS COUNT BYTE
  2534.     INR M        ;INCREASE COUNT BYTE
  2535.     DCX H        ;ADDRESS MAXIMUM
  2536.     MOV A,M        ;PUT MAXIMUM IN A
  2537.     INX H        ;ADDRESS COUNT
  2538.     CMP M        ;COMPARE COUNT TO MAXIMUM
  2539.     JC ALERT    ;IF MAXIMUM, RING BELL AND WAIT FOR CR
  2540.     XCHG        ;RESTORE BUFFER POINTER TO HL
  2541.     MOV M,B        ;PUT INPUTTED CHARACTER IN BUFFER
  2542.     MOV A,B        ;OUTPUT IT
  2543.     CALL TYPE
  2544.     INX H        ;BUMP POINTER
  2545.     JMP INBUFA    ;GET NEXT CHARACTER
  2546.  
  2547. DELETE:    XCHG        ;SAVE BUFFER POINTER IN DE
  2548.     POP H        ;ADDRESS BEGINNING OF BUFFER
  2549.     PUSH H        ;RESTORE STACK
  2550.     INX H        ;ADDRESS COUNT FIELD
  2551.     MOV B,A        ;SAVE DELETE CHAR - 7FH OR 08H
  2552.     MOV A,M
  2553.     SUI 1        ;DECREASE COUNT
  2554.     MOV M,A
  2555.     JC NODEL    ;DON'T DELETE PAST BEGINING OF BUFFER.
  2556.     XCHG        ;RESTORE BUFFER POINTER TO HL
  2557.     DCX H        ;POINT TO LAST BYTE INPUTTED
  2558.     MOV A,B        ;GET BACK EITHER 7FH OR 08H
  2559.     MOV B,M        ;GET CHARACTER BEING DELETED
  2560.     MVI M,20H    ;RESTORE BLANK
  2561.     CPI 8
  2562.     JZ BKSPC
  2563.     CPI 7FH
  2564.     JZ BKSPC0
  2565.     JMP INBUFA    ;GET NEXT CHARACTER
  2566. NODEL:    INR M        ;DON'T LEAVE COUNT NEGATIVE
  2567.     XCHG        ;RESTORE POINTER TO HL
  2568.     JMP INBUFA
  2569. BKSPC0:    MVI A,08H
  2570. BKSPC:    CALL TYPE    ;TRUE ERASE IF 08H
  2571.     MVI A,20H
  2572.     CALL TYPE
  2573.     MVI A,8
  2574.     CALL TYPE
  2575.     JMP INBUFA
  2576.  
  2577. INBUFO:    MVI A,'#'
  2578.     CALL TYPE
  2579.     CALL CRLF
  2580.     JMP ISTART
  2581.  
  2582. RETYPE:    POP D
  2583.     PUSH D
  2584.     INX D        ;POINT TO CURRENT NUMBER..
  2585.     LDAX D        ;..OF CHARACTERS.
  2586.     MOV B,A
  2587.     MVI A,'#'
  2588.     CALL TYPE
  2589.     CALL CRLF
  2590.     MOV A,B        ;TEST IF ZERO INPUT
  2591.     ORA A
  2592.     JZ INBUFA
  2593. CTLRLP:    INX D
  2594.     LDAX D
  2595.     CALL TYPE
  2596.     DCR B
  2597.     JNZ CTLRLP
  2598.     JMP INBUFA
  2599.     
  2600. ALERT:    MVI A,7
  2601.     CALL TYPE
  2602.     DCR M
  2603.     XCHG
  2604.     JMP INBUFA
  2605.  
  2606. PCRLF:    CALL CRLF
  2607.     JMP INBUFA
  2608.  
  2609. INBUFR:    CALL CRLF
  2610.     POP D
  2611.     POP B
  2612.     POP H
  2613.     POP PSW
  2614.     RET
  2615.  
  2616. ICLEAR:    POP D        ;ACCOUNTS FOR CALL
  2617.     POP H        ;ADDRESS BUFFER IN HL
  2618.     PUSH H        ;RESTORE..
  2619.     PUSH D        ;..STACK
  2620.     MOV B,M        ;SAVE MAXIMUM IN B
  2621.     INX H        ;POINT TO FIRST..
  2622.     INX H        ;..BUFFER BYTE.
  2623.     MVI A,20H
  2624. CLEARL:    MOV M,A
  2625.     INX H
  2626.     DCR B
  2627.     JNZ CLEARL
  2628.     RET
  2629.  
  2630. CONIN:    PUSH H
  2631.     PUSH D
  2632.     PUSH B
  2633. CONINLP:CALL STAT
  2634.     JZ CONINLP
  2635.     CALL KEYIN
  2636.     CALL UCASE
  2637.     POP B
  2638.     POP D
  2639.     POP H
  2640.     RET
  2641. ;==========================================
  2642. ;LOADS A COMMAND LINE ADDRESSED BY DE REGISTERS (MAX # CHARACTERS IN LINE
  2643. ;IN DE, NUMBER OF CHARS IN LINE IN DE+1, LINE STARTS IN DE+2) INTO FCB
  2644. ;ADDRESSED BY HL REGISTERS. THE FCB SHOULD BE AT LEAST 33 BYTES IN LENGTH.
  2645. ;THE COMMAND LINE BUFFER MUST HAVE A MAXIMUM LENGTH OF AT LEAST ONE MORE
  2646. ;THAN THE GREATEST NUMBER OF CHARACTERS THAT WILL BE NEEDED.
  2647.  
  2648. CPMLINE:PUSH PSW
  2649.     PUSH B
  2650.     PUSH D
  2651.     PUSH H
  2652.     CALL INIT    ;FILLS FCBS WITH BLANKS AND NULLS
  2653.     XCHG        ;GET START OF COMMAND LINE IN HL.
  2654.     INX H        ;ADDRESS # BYTES IN CMD LINE.
  2655.     MOV E,M        ;LOAD DE PAIR WITH # BYTES.
  2656.     MVI D,0
  2657.     INX H
  2658.     DAD D        ;POINT TO BYTE AFTER LAST CHAR..
  2659.     MVI M,0DH    ;..IN CMD LINE AND STORE DELIMITER.
  2660.     POP H        ;RESTORE HL AND DE.
  2661.     POP D
  2662.     PUSH D
  2663.     PUSH H
  2664.     INX D        ;ADDRESS START OF COMMAND.
  2665.     INX D
  2666.     CALL CDRIVE
  2667.     MVI C,8        ;TRANSFER FIRST FILENAME TO FCB.
  2668.     CALL TRANS
  2669.     CPI 0DH
  2670.     JZ CDONE
  2671.     CPI 20H        ;IF SPACE, THEN START OF..
  2672.     JZ NAME2    ;..SECOND FILENAME.
  2673.     POP H        ;FILETYPE MUST BE AFTER..
  2674.     PUSH H        ;..EIGHTH BYTE OF NAME.
  2675.     LXI B,9
  2676.     DAD B
  2677.     MVI C,3        ;TRANSFER TYPE OF FIRST FILE
  2678.     CALL TRANS
  2679.     CPI 0DH
  2680.     JZ CDONE
  2681. NAME2:    LDAX D        ;EAT MULTIPLE SPACES..
  2682.     CPI 20H        ;..BETWEEN NAMES.
  2683.     JNZ NAME2C
  2684.     INX D
  2685.     JMP NAME2
  2686.     LDAX D
  2687.     CPI 0DH        ;TEST IF FIRST NAME..
  2688.     JZ CDONE    ;..ONLY AND THEN SPACE.
  2689. NAME2C:    POP H        ;SECOND NAME STARTS IN 16TH BYTE.
  2690.     PUSH H        ;POINT HL TO THIS BYTE.
  2691.     LXI B,16
  2692.     DAD B
  2693.     CALL CDRIVE
  2694.     MVI C,8
  2695.     CALL TRANS
  2696.     CPI 0DH
  2697.     JZ CDONE
  2698.     POP H        ;SECOND TYPE STARTS IN 25TH BYTE.
  2699.     PUSH H
  2700.     LXI B,25
  2701.     DAD B
  2702.     MVI C,3
  2703.     CALL TRANS
  2704. CDONE:    POP H
  2705.     PUSH H
  2706.     INX H        ;POINT TO FIRST CHAR OF FIRST NAME IN FCB.
  2707.     CALL CSCAN    ;CHECK FOR * (AMBIGUOUS NAMES).
  2708.     POP H
  2709.     PUSH H
  2710.     LXI B,17    ;POINT TO FIRST CHAR OF SECOND NAME IN FCB.
  2711.     DAD B
  2712.     CALL CSCAN
  2713.     POP H
  2714.     POP D
  2715.     POP B
  2716.     POP PSW
  2717.     RET
  2718.  
  2719. INIT:    PUSH H        ;INITIALIZES FCB WITH 1 NULL (FOR FIRST DRIVE),..
  2720.     PUSH B        ;..11 BLANKS, 4 NULLS, 1 NULL (FOR 2ND DRIVE),..
  2721.     MVI M,0        ;..11 BLANKS, AND 4 NULLS.
  2722.     INX H
  2723.     MVI B,11
  2724.     MVI A,20H
  2725.     CALL INITFILL
  2726.     MVI B,5
  2727.     MVI A,0
  2728.     CALL INITFILL
  2729.     MVI B,11
  2730.     MVI A,20H
  2731.     CALL INITFILL
  2732.     MVI B,4
  2733.     MVI A,0
  2734.     CALL INITFILL
  2735.     POP B
  2736.     POP H
  2737.     RET
  2738.  
  2739. INITFILL:
  2740.     MOV M,A
  2741.     INX H
  2742.     DCR B
  2743.     JNZ INITFILL
  2744.     RET
  2745.  
  2746. CDRIVE:    INX D        ;CHECK 2ND BYTE OF FILENAME. IF IT..
  2747.     LDAX D        ;..IS A ":", THEN DRIVE WAS SPECIFIED.
  2748.     DCX D
  2749.     CPI ':'
  2750.     JNZ DEFDR    ;ELSE ZERO FOR DEFAULT DRIVE ('INIT' PUT ZERO)
  2751.     LDAX D
  2752.     ANI 5FH
  2753.     SUI 40H        ;CALCULATE DRIVE (A=1, B=2,...)..
  2754.     MOV M,A        ;..AND PLACE IT IN FCB.
  2755.     INX D        ;ADDRESS FIRST BYTE OF..
  2756.     INX D        ;..IN CMD LINE,..
  2757. DEFDR:    INX H        ;..AND NAME FIELD IN FCB.
  2758.     RET
  2759.  
  2760. TRANS:    LDAX D        ;TRANSFER FROM CMD LINE TO FCB..
  2761.     INX D        ;..UP TO NUMBER OF CHARS SPECIFIED..
  2762.     CPI 0DH        ;..BY C-REG. KEEP SCANNING FIELD..
  2763.     RZ        ;..WITHOUT TRANSFER UNTIL A DELIMITING..
  2764.     CPI '.'        ;..FIELD CHAR SUCH AS '.', BLANK, OR..
  2765.     RZ        ;..C/R (FOR END OF CMD LINE).
  2766.     CPI 20H
  2767.     RZ
  2768.     DCR C
  2769.     JM TRANS    ;ONCE C-REG IS LESS THAN ZERO, KEEP READING..
  2770.     MOV M,A        ;..CMD LINE BUT DO NOT TRANSFER TO FCB.
  2771.     INX H
  2772.     JMP TRANS
  2773.  
  2774. CSCAN:    MVI B,8        ;SCAN FILE NAME ADDRESSED BY HL.
  2775. TSTNAM:    MOV A,M
  2776.     CPI '*'        ;IF '*' FOUND, FILL IN REST OF FIELD..
  2777.     JZ FILL1    ;..WITH '?' FOR AMBIGUOUS NAME.
  2778.     INX H
  2779.     DCR B
  2780.     JNZ TSTNAM
  2781.     JMP TSTTYP
  2782. FILL1:    CALL FILL
  2783.  
  2784. TSTTYP:    MVI B,3        ;SCAN AND FILL TYPE FIELD FOR NAME..
  2785. TSTLTYP:MOV A,M        ;..SPECIFIED ABOVE.
  2786.     CPI '*'
  2787.     JZ FILL2
  2788.     INX H
  2789.     DCR B
  2790.     RZ
  2791.     JMP TSTLTYP
  2792. FILL2:    CALL FILL
  2793.     RET
  2794.  
  2795. FILL:    MVI M,'?'    ;ROUTINE TRANSFERS '?'.
  2796.     INX H
  2797.     DCR B
  2798.     JNZ FILL
  2799.     RET
  2800. ;======================================
  2801. ;IN-LINE COMPARE. COMPARES STRING ADDRESSED BY DE-REG TO STRING
  2802. ;AFTER CALL (ENDS WITH ZERO). RETURN WITH CARRY SET MEANS STRINGS
  2803. ;NOT THE SAME. ALL REGISTERS EXCEPT A-REG ARE UNAFFECTED.
  2804. ILCOMP:    XTHL        ;POINT HL TO 1ST CHAR.
  2805.     PUSH D
  2806. ILCMPL:    MOV A,M        ;HL POINTS TO IN-LINE STRING.
  2807.     ORA A        ;END OF STRING IF ZERO.
  2808.     JZ SAME
  2809.     LDAX D
  2810.     CMP M
  2811.     JNZ NOTSAME
  2812.     INX H
  2813.     INX D
  2814.     JMP ILCMPL
  2815. NOTSAME:MVI A,0        ;IF NOT SAME, FINISH THRU..
  2816. NSLP:    INX H        ;..STRING SO RETURN WILL..
  2817.     CMP M        ;..GO TO INSTRUCTION AFTER..
  2818.     JNZ NSLP    ;..STRING AND NOT REMAINDER OF STRING.
  2819.     STC
  2820. SAME:    POP D
  2821.     INX H        ;AVOIDS A NOP INSTRUCTION..
  2822.     XTHL        ;..WHEN RETURNING.
  2823.     RET
  2824. ;==================================
  2825. ;MULTI-FILE ACCESS SUBROUTINE.  ALLOWS PROCESSING
  2826. ;OF MULTIPLE FILES (E.G. *.ASM) FROM DISK.  THIS
  2827. ;ROUTINE BUILDS THE PROPER NAME IN THE FCB EACH
  2828. ;TIME IT IS CALLED.
  2829. ;THE FCB WILL BE SET UP WITH THE NEXT NAME, READY TO
  2830. ;DO NORMAL PROCESSING (OPEN, READ, ETC.) WHEN ROUTINE IS CALLED.
  2831. ;CARRY IS SET IF NO MORE NAMES CAN BE FOUND
  2832. MFNAME:    PUSH B
  2833.     PUSH D
  2834.     PUSH H
  2835.     MVI C,STDMA
  2836.     LXI D,80H
  2837.     CALL BDOS
  2838.     POP H
  2839.     POP D
  2840.     POP B
  2841.     XRA A
  2842.     STA FCBEXT
  2843.     LDA MFFLG1
  2844.     ORA A
  2845.     JNZ MFN01
  2846.     MVI A,1
  2847.     STA MFFLG1
  2848.     LXI H,FCB
  2849.     LXI D,MFREQ
  2850.     LXI B,12
  2851.     CALL MOVER
  2852.     LDA FCB
  2853.     STA MFCUR ;SAVE DISK IN CURR FCB
  2854.     LXI H,MFREQ
  2855.     LXI D,FCB
  2856.     LXI B,12
  2857.     CALL MOVER
  2858.     PUSH B
  2859.     PUSH D
  2860.     PUSH H
  2861.     MVI C,SRCHF
  2862.     LXI D,FCB
  2863.     CALL BDOS
  2864.     POP H
  2865.     POP D
  2866.     POP B
  2867.     JMP MFN02
  2868. MFN01:    LXI H,MFCUR
  2869.     LXI D,FCB
  2870.     LXI B,12
  2871.     CALL MOVER
  2872.     PUSH B
  2873.     PUSH D
  2874.     PUSH H
  2875.     MVI C,SRCHF
  2876.     LXI D,FCB
  2877.     CALL BDOS
  2878.     POP H
  2879.     POP D
  2880.     POP B
  2881.     LXI H,MFREQ
  2882.     LXI D,FCB
  2883.     LXI B,12
  2884.     CALL MOVER
  2885.     PUSH B
  2886.     PUSH D
  2887.     PUSH H
  2888.     MVI C,SRCHN
  2889.     LXI D,FCB
  2890.     CALL BDOS
  2891.     POP H
  2892.     POP D
  2893.     POP B
  2894. MFN02:    INR A
  2895.     STC
  2896.     JNZ MFFIX1
  2897.     STA MFFLG1
  2898.     RET
  2899. MFFIX1:    DCR A
  2900.     ANI 3
  2901.     ADD A
  2902.     ADD A
  2903.     ADD A
  2904.     ADD A
  2905.     ADD A
  2906.     ADI 81H
  2907.     MOV L,A
  2908.     MVI H,0
  2909.     PUSH H ;SAVE NAME POINTER
  2910.     LXI D,MFCUR+1
  2911.     LXI B,11
  2912.     CALL MOVER
  2913.     POP H
  2914.     LXI D,FCB+1
  2915.     LXI B,11
  2916.     CALL MOVER
  2917.     XRA A
  2918.     STA FCBEXT
  2919.     STA FCBRNO
  2920.     RET
  2921. ;
  2922. ;MULTI-FILE ACCESS WORK AREA
  2923. ;
  2924. MFFLG1:    DB    0    ;1ST TIME SW
  2925. MFREQ:    DS    12    ;REQ NAME
  2926. MFCUR:    DS    12    ;CURR NAME
  2927. ;=====================================
  2928. ;MOVE SUBROUTINE
  2929. MOVER:    MOV    A,M
  2930.     STAX    D
  2931.     INX    H
  2932.     INX    D
  2933.     DCX    B
  2934.     MOV    A,B
  2935.     ORA    C
  2936.     JNZ    MOVER
  2937.     RET
  2938. ;================================
  2939. DIRLST:    LXI D,CMDBUF    ;PUT COMMAND LINE IN FCB
  2940.     LXI H,5CH
  2941.     CALL CPMLINE
  2942.     LXI H,SRCHFCB
  2943.     CALL INITFCBS
  2944.     LDA 6CH        ;GET DRIVE #
  2945.     STA SRCHFCB
  2946.     LDA 6DH
  2947.     CPI 20H        ;IF BLANK GET ALL NAMES
  2948.     PUSH PSW
  2949.     CZ QSTMARK
  2950.     POP PSW
  2951.     CNZ MOVENAME    ;ELSE MOVE NAME INTO FCB
  2952.     CALL DRIVE
  2953.     LXI D,80H
  2954.     MVI C,STDMA
  2955.     CALL BDOS
  2956.     XRA A
  2957.     STA DNAMECT    ;CR AFTER 4 NAMES
  2958.     LXI D,SRCHFCB
  2959.     MVI C,SRCHF    ;DO FIRST SEARCH
  2960.     CALL BDOS
  2961.     CPI 0FFH
  2962.     JZ NOFILE
  2963. DIRLP:    CALL GETADD
  2964.     LXI D,15    ;OFFSET FOR RECORD COUNT
  2965.     DAD D
  2966.     MOV A,M
  2967.     ORA A
  2968.     JZ NEXTSR    ;NO LIST IF FILE IS ZERO LENGTH
  2969.     LXI D,-5
  2970.     DAD D        ;POINT TO $SYS ATTRIB BYTE
  2971.     MOV A,M
  2972.     ANI 80H
  2973.     JNZ NEXTSR    ;NO LIST IF $SYS FILE
  2974.     LXI D,-10
  2975.     DAD D        ;POINT TO BEGINNING OF NAME
  2976.     INX H        ;POINT TO FIRST LETTER
  2977.     LXI D,PRNTNAME
  2978.     MVI B,8
  2979.     CALL MOVE
  2980.     INX D
  2981.     MVI B,3
  2982.     CALL MOVE
  2983.     CALL ILPRT
  2984. PRNTNAME:
  2985.     DB '            ',' : ',0   ;12 SPACES
  2986.     LDA DNAMECT
  2987.     INR A
  2988.     STA DNAMECT
  2989.     ANI 03H
  2990.     ORA A
  2991.     CZ CRLF
  2992. NEXTSR:    LXI D,SRCHFCB
  2993.     MVI C,SRCHN    ;DO NEXT SEARCH
  2994.     CALL BDOS
  2995.     CPI 0FFH
  2996.     JZ DIRDONE
  2997.     JMP DIRLP
  2998. NOFILE:    CALL ILPRT
  2999.     DB 'NOT FOUND',0
  3000. DIRDONE:CALL CRLF
  3001.     RET
  3002.  
  3003. QSTMARK:MVI A,'?'    ;IF BLANK IN FCB, PUT IN 11 ?'s
  3004.     MVI B,11
  3005.     LXI H,SRCHFCB+1
  3006. QSTLP:    MOV M,A
  3007.     INX H
  3008.     DCR B
  3009.     JNZ QSTLP
  3010.     RET
  3011.  
  3012. MOVENAME:
  3013.     LXI H,6DH
  3014.     LXI D,SRCHFCB+1
  3015.     MVI B,11
  3016.     CALL MOVE        ;MOVE IN CP/M PROGRAM
  3017.     RET
  3018.  
  3019. GETADD:    ANI 03H            ;GET MOD4 FOR CP/M 1.4
  3020.     ADD A
  3021.     ADD A
  3022.     ADD A            ;ADD 32
  3023.     ADD A
  3024.     ADD A
  3025.     MOV E,A
  3026.     MVI D,0
  3027.     LXI H,80H        ;ADD DMA OFFSET
  3028.     DAD D
  3029.     RET
  3030.  
  3031. DRIVE:    LDA SRCHFCB        ;IF NO DRIVE, CAL
  3032.     ORA A            ;LOGGED IN DRIVE
  3033.     JZ CALCDR
  3034.     ADI 40H
  3035.     JMP PRNTHD
  3036. CALCDR:    MVI C,25
  3037.     CALL BDOS
  3038.     ADI 41H
  3039. PRNTHD:    STA DRNAME
  3040.     CALL ILPRT
  3041.     DB CR,LF,'DRIVE '
  3042. DRNAME:    DB ' ',CR,LF,0
  3043.     RET
  3044.  
  3045. SRCHFCB:DS 33
  3046. DNAMECT:DS 1
  3047. ;================================
  3048. NFILFLG:DB FALSE    ;Terminal file open flag
  3049.  
  3050. OPTION:    DB 0    ;primary option
  3051. OPTBL    EQU $
  3052. QFLG:    DB 'Q'    ;secondary option flags
  3053. RSEEFLG:DB 'R'
  3054. SSEEFLG:DB 'S'
  3055. VSEEFLG:DB 'V'
  3056. TERMFLG:DB 'T'
  3057. BATCHFLG:DB 'N'    ;0=Non-batch
  3058. OPTBE    EQU $
  3059.  
  3060. RESTROPT:    ;MUST BE IN SAME ORDER AS TABLE ABOVE
  3061.     DB 'Q','R','S','V','T','N'
  3062. CRCFLG:    DB 'C'    ;use CRC instead of cksum
  3063.  
  3064. RESTSN:    DB 0,0,0,0,0
  3065.     DW DBUF
  3066.     DB 0,0,0,0,0,0,0
  3067.  
  3068. SECNOB    EQU $
  3069. RCVSNO:        DB 0
  3070. SECNO:        DW 0    ;sector no.
  3071. ERRCT:        DB 0
  3072. EOFLG:        DB 0    ;end of file flag
  3073. SECPTR:        DW DBUF
  3074. SECINBF:    DB 0
  3075. MAXEXT:        DB 0
  3076. RCNT:        DW 0    ;no. of records to send
  3077. DATAFLG:    DB 0
  3078. EXACFL:        DB 0    ;literalise next char flag
  3079. COLCNT:        DB 0    ;column counter
  3080. SECNOE    EQU $
  3081.  
  3082. FSTFLG:    DB    TRUE    ;multiple file transmit flag
  3083. FIRSTME:DB    0FFH    ;first SOH received switch(it is zero after 1st SOH)
  3084. LSTFLG:    DB    FALSE    ;true=print echo on
  3085. LSTRET:    DB    FALSE    ;print toggle save
  3086. BUFBEG:    DW    PRTBUF    ;start of prtbuf
  3087. BUFRIN:    DW    PRTBUF    ;i/p pointer
  3088. BUFROUT:DW    PRTBUF    ;o/p pointer
  3089. BUFEND:    DW    PRTBUF+(RING*1024)    ;end of prtbuf
  3090. CMDBUF:    DB    80H,0
  3091.     DS    80H
  3092. HLSAVE:    DS    2        ;memory pointer, terminal mode
  3093. DISKNO:    DS    1
  3094. SENDFLG:DS    1
  3095. NBSAVE:    DS    2
  3096. BGNMS:    DS    2
  3097. FILECT:    DS    1
  3098. NAMECT:    DS    1
  3099.  
  3100.     DS    64
  3101. STAK:    DS    2
  3102. FCB3:    DS    33        ;terminal file fcb
  3103. FCB4:    DS    33        ;file transfer fcb
  3104. FCBBUF:    DS    15
  3105. DBUF:    DS    DBUFSIZ*1024    ;FILE BUFFER FOR SEND & RECIEVE MODES
  3106. NAMEBUF:DS    64*12        ;BUFFER FOR FILE NAMES IN BATCH MODE.
  3107.     ORG $ + 100H AND 0FF00H    ;must be on page boundary
  3108. CRCTBL:    DS    512        ;crc lookup table
  3109. PRTBUF:    DS    RING*1024    ;print buffer
  3110. BOTTRAM:DS    1        ;MEMORY BUFFER FOR TERMINAL FILE
  3111.         END    100H
  3112.