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 / RCPM / ZMD150.LBR / ZMD.ZZ0 / ZMD.Z80
Text File  |  2000-06-30  |  134KB  |  4,856 lines

  1. ;
  2.  
  3.     TITLE  ZMD.Z80    - 09/29/88 - Z80 RCP/M File Transfer Program
  4. ;                     Copyrighted (c) 1987, 1988
  5. ;                     Robert W. Kramer III
  6.  
  7.     PAGE
  8. ;-                                     -;
  9. ;                         Update History                                  ;
  10. ;                                                                         ;
  11. ;    Date    Release                 Comments                     ;
  12. ;  --------    -------      ----------------------------------------------  ;
  13. ;                                      ;
  14. ;  09/29/88    v1.50    - If an LBR/ARK/ARC member extraction is being      ;
  15. ;              made, a check at OPNOK5: determines if (FCB+9)  ;
  16. ;              is an 'L' for a .LBR member extraction.  If so, ;
  17. ;              ZMD informs the receiver that the file is ready ;
  18. ;              for downloading.  If (FCB+9) is other than an      ;
  19. ;              'L' an ARC/ARK member extraction is assumed and ;
  20. ;              the receiver is told to name the received file  ;
  21. ;              accordingly.  Extractions on LBR/ARC/ARK files  ;
  22. ;              with the high bit set in (FCB+9) triggers this  ;
  23. ;              test unreliable.  The simple fix has been made, ;
  24. ;              which strips the parity bit of (FCB+9) before      ;
  25. ;              anylizing it.                      ;
  26. ;            - Fixed a problem that caused some systems to      ;
  27. ;              ignore the first character typed in some ZMD      ;
  28. ;              utilities.  The modification was made at the      ;
  29. ;              TYPE: routine in ZMDSUBS.  Instead of using      ;
  30. ;              BDOS function 2 to display a character, we are  ;
  31. ;              now using BDOS call 6.              ;
  32. ;            - Fixed CONSTAT: routine in ZMDSUBS to properly      ;
  33. ;              react to cancel requests from Sysop.          ;
  34. ;            - Modified all low level I/O routines to preserve ;
  35. ;              HL, DE, and BC registers.  Whether you're using ;
  36. ;              BYE's extended BDOS calls or have a custom I/O  ;
  37. ;              overlay installed in ZMD, those registers are      ;
  38. ;              will return intact.  This allows those writing  ;
  39. ;              overlays to not have to worry about register      ;
  40. ;              integrity.                      ;
  41. ;            - Single file Receive now defaults to 1k blocks.  ;
  42. ;            - Library extractions now default to 1k blocks.      ;
  43. ;            - Fixed bugs in the handshaking that have been      ;
  44. ;              around since 1k Batch was implemented on CPM      ;
  45. ;              systems.  This required several modifications      ;
  46. ;              to the SNDFIL routines.  All of them were      ;
  47. ;              modified specifically for the Batch routines,      ;
  48. ;              however, other Send routines were directly      ;
  49. ;              effected by them.                  ;
  50. ;                                      ;
  51. ;                 1.    ZMD does not use the BDOS call 35 to get  ;
  52. ;                the file size since this information is      ;
  53. ;                supplied in the directory entry for each  ;
  54. ;                extent retreived during filename lookup.  ;
  55. ;                                      ;
  56. ;                 2. We no longer open a file to send until      ;
  57. ;                the receiver has ACKnowledged header 0      ;
  58. ;                *AND* sent his invitation for CRC ('C').  ;
  59. ;                Previously, opening the file immediately  ;
  60. ;                after the header 0 ACK caused the 'C' to  ;
  61. ;                be missed during the time the sender is      ;
  62. ;                opening the file and filling his transmit ;
  63. ;                buffer.                      ;
  64. ;                                      ;
  65. ;                 3. I personally feel there is no need to      ;
  66. ;                purge the line of incoming characters at  ;
  67. ;                anytime during a batch session. All of the;
  68. ;                occurences of CALL CATCH have been removed;
  69. ;                from the Send batch routines with the      ;
  70. ;                exception of the GTACK routine, in which  ;
  71. ;                case a call to CATCH is only made if the  ;
  72. ;                current byte received is other than an      ;
  73. ;                ACK, NAK, 7Bh, FBh, or a CANCEL.      ;
  74. ;                                      ;
  75. ;                I do not have the resources to change all ;
  76. ;                the other CP/M file transfer utilities      ;
  77. ;                floating around, so you may still notice  ;
  78. ;                some minor delays between files in BATCH  ;
  79. ;                protocol.  Since most of the problem was  ;
  80. ;                in the Send routines, you'll not notice      ;
  81. ;                lengthy delays when using ZMD to send.      ;
  82. ;                Delays when using ZMD to receive will be  ;
  83. ;                dependant upon what software the sender      ;
  84. ;                is using.  (IBM comm programs don't seem  ;
  85. ;                to have this problem, however all CP/M      ;
  86. ;                comm programs will have these irritating  ;
  87. ;                delays - except ZMD).              ;
  88. ;                                      ;
  89. ;            - Added code to initialize KDRV with current      ;
  90. ;              drive at program startup.  CPM3 systems were      ;
  91. ;              experiencing problems with BDOS 46.          ;
  92. ;            - CPM3 BDOS call 46 returns the current disk space;
  93. ;              free in the first 3 bytes of the currently set  ;
  94. ;              DMA.  This was being done during a check for      ;
  95. ;              the batch intention and destroying the current  ;
  96. ;              command line buffer (at 80h where DMA address is;
  97. ;              usually set).  CPM3 systems should now have no  ;
  98. ;              problems with ZMD.                  ;
  99. ;            - Fixed bug to allow 255 files to be transferred  ;
  100. ;              when descriptions are disabled (either by the      ;
  101. ;              ZINSTL program or by using the 'RW' option).      ;
  102. ;            - Added CKWILD routine to prevent commands such   ;
  103. ;              as 'ZMD R *.*' enter '*.*' into the directory.  ;
  104. ;              Using any wildcards in the filename or extent   ;
  105. ;              of the receive filename will trigger YMODEM 1k  ;
  106. ;              Batch.                      ;
  107. ;            - Log file routines were writing some filename      ;
  108. ;              attributes to the log file.  Fixed at PUTLOG:      ;
  109. ;            - Modified ZMDSUBS.REL and send/send Batch code   ;
  110. ;              to take care of incorrect drive display problem ;
  111. ;              for local terminal.  Created new subroutine to  ;
  112. ;              poke the current binary 'BDOS' drive/user area  ;
  113. ;              into (DUU) and (DUD) in both SNDFIL: and SBTCH: ;
  114. ;              routines.  Both DUD and DUU have been moved to  ;
  115. ;              the ZMDSUBS file for global use.          ;
  116. ;            - Fixed EDATE routines for LOG and FOR files.      ;
  117. ;              Previously, the EDATE setting had no effect on  ;
  118. ;              the ZMD.Z80 program.                  ;
  119. ;            - Fixed message upload routine at RCVFL to check  ;
  120. ;              for access restrictions.  If ACCESS is set to      ;
  121. ;              NO, the message upload will be accepted, else      ;
  122. ;              bit 3 of AFBYTE will be anylized.          ;
  123. ;                                      ;
  124. ;  03/18/88    v1.49    - No change(s) made to this file          ;
  125. ;  03/13/88    v1.48    - Had a small problem with TPA fix which has been ;
  126. ;              corrected.  CHKTPA was calculating the total      ;
  127. ;              number of bytes available for DBUF, but wasn't  ;
  128. ;              clearing register L (forcing an even amount of  ;
  129. ;              sectors before initializing OUTSIZ buffer limit ;
  130. ;              comparison word).  This may have introduced      ;
  131. ;              minimal garbage to your FOR file if your FOR      ;
  132. ;              file is large enough to fill available TPA with ;
  133. ;              ZMD, ZFORS or to the log file if running ZMDEL. ;
  134. ;            - Rewrote OUTCHR routine in ZMDSUBS.          ;
  135. ;            - Redefined buffer table at end of programs. STACK;
  136. ;              and filename buffers now EQUated with offsets      ;
  137. ;              from the last switch/toggle in program instead  ;
  138. ;              of with DS directive.                  ;
  139. ;            - Some systems which do NOT have an interrupt      ;
  140. ;              driven keyboard may have noticed problems when  ;
  141. ;              an invalid key was entered in the ZNEWP, ZFORP  ;
  142. ;              and ZMDEL programs.  In ZNEWP and ZFORP, if a   ;
  143. ;              CR was entered to pause the output, output was  ;
  144. ;              limited to one line at a time per key pressed.  ;
  145. ;              If an invalid key was hit, output would have      ;
  146. ;              remained in a paused state until one of the      ;
  147. ;              abort keys were pressed.  This was difficult to ;
  148. ;              find since my keyboard is interrupt driven and  ;
  149. ;              I could not duplicate the problem on my own      ;
  150. ;              system.                      ;
  151. ;            - Fixed a problem in the MODE parsing routines      ;
  152. ;              that caused ZMD to default to 128 byte blocks      ;
  153. ;              in single file SEND mode.  Now defaults to 1k      ;
  154. ;              YMODEM.                      ;
  155. ;  02/25/88    v1.47    - Fixed a problem that caused only partial display;
  156. ;              of the help guide if an invalid command such as ;
  157. ;              ZMD RPC with no filename was entered.       ;
  158. ;            - Repaired routine that loads access flags byte      ;
  159. ;              into AFBYTE.  If ACCESS was disabled and BYE      ;
  160. ;              was running, a check for a modem overlay was      ;
  161. ;              being made that caused a system hang up.  v1.46 ;
  162. ;              was the only version with this problem.      ;
  163. ;            - And then there were TPA problems. Past versions ;
  164. ;              of ZMD required at least 48k TPA to run.  If      ;
  165. ;              your system has less, and descriptions enabled, ;
  166. ;              you most likely had a system hang up during the ;
  167. ;              FOR file read/write operations.  This version      ;
  168. ;              will run on any system with as little as 24k of ;
  169. ;              available TPA.  Maximum number of uploads is      ;
  170. ;              automatically calculated according to your TPA  ;
  171. ;              limitations.  If upload descriptions have been  ;
  172. ;              disabled (either during installation or during  ;
  173. ;              program execution with the RW or RP options),   ;
  174. ;              as many as 255 files may be uploaded.          ;
  175. ;            - Fixed time out error in CRC receive routine.      ;
  176. ;              Register B contains the number of seconds to      ;
  177. ;              wait for a character on entry to RECV and some- ;
  178. ;              how I inadvertanly removed the line that loads  ;
  179. ;              this value on entry. (Label RCVCRC2)          ;
  180. ;            - Fixed description routine so that the caller      ;
  181. ;              will be asked for the category of each uploaded ;
  182. ;              file if ASKAREA is disabled. Problem caused ZMD ;
  183. ;              to ask only 1 time for the file descriptor of      ;
  184. ;              uploaded files - no matter how many of them      ;
  185. ;              there were.                      ;
  186. ;  01/27/88    v1.46    - Fixed BYE time routines.  Now displays correct  ;
  187. ;              time on system when exiting.              ;
  188. ;            - Fixed SUBS file so that discrepency check will  ;
  189. ;              not turn off CLOCK, and DSTAMP if MODE is set      ;
  190. ;              to 255.  (So ZFORS and ZFORP can react to the      ;
  191. ;              clock related features without BYE running).      ;
  192. ;            - Added prompt to tell remote when ZMD is waiting ;
  193. ;              for him to come back to terminal mode.  Gets      ;
  194. ;              redisplayed every 3 seconds for a total of      ;
  195. ;              approximately 30 seconds before continuing on      ;
  196. ;              automatically.                     ;
  197. ;            - Added code to SUBS file that determines if we   ;
  198. ;              are in private mode or not. If so, only private ;
  199. ;              drive/user information is displayed when asking ;
  200. ;              for file descriptors/categories choice.  If in  ;
  201. ;              regular mode or in SPACE routines only the      ;
  202. ;              regular drive/user is shown.  Fix is for upload ;
  203. ;              routing routines.                    ;
  204. ;            - Repaired message file exit routine.  Command      ;
  205. ;              line wasn't being properly built.            ;
  206. ;            - Fixed so that batch mode is not valid with the  ;
  207. ;              RM option.  (Slipped by during a rewrite of the ;
  208. ;              command tail parsing routines).          ;
  209. ;  01/17/88    v1.45    - First public release                  ;
  210. ;  01/14/88     v1.43    - Removed MBYE/BYE3 specific switches in ZMDHDR.  ;
  211. ;              Added new switch CLOCK.  Removed Extended BDOS  ;
  212. ;              calls from time and date routines.  Rewrote for ;
  213. ;              100% compatibility with BYE5/MBYE/BYE3 remote      ;
  214. ;              console programs.  RTC switch can be set for       ;
  215. ;              user defined time and date routines at RTCTIM      ;
  216. ;              in ZMDHDR.Z80                      ;
  217. ;            - Fixed an error in send routines that allowed       ;
  218. ;              FCB+9-FCB+12 to remain initialized to nulls, if ;
  219. ;              file requested had less than 3 characters in      ;
  220. ;              the filename extent.                    ;
  221. ;  12/29/87    v1.41    - Removed and rewrote description routines to be  ;
  222. ;              universal with ZMD, ZFORS and ZINSTL programs.  ;
  223. ;              Routine is now requested from ZMDSUBS.REL      ;
  224. ;  12/23/87    v1.40    - Fixed numerous trivial bugs.              ;
  225. ;            - Rewrote the help and time/date routines.      ;
  226. ;            - Added code to determine if BIOS local console      ;
  227. ;              output address has been included in the modem      ;
  228. ;              overlay and if not calculate it according to      ;
  229. ;              standard CP/M specifications and store it for      ;
  230. ;              program use.                      ;
  231. ;  12/13/87    v1.39    - Rewrote common subroutines for inclusion in      ;
  232. ;              ZMDSUBS.REL subroutines file.              ;
  233. ;  12/07/87    v1.38    - Modified to support drive/user area requests      ;
  234. ;              in SEND BATCH mode.  Drive/user restrictions      ;
  235. ;              remain enforced.                  ;
  236. ;  10/02/87    v1.37    - Wrote code for automatic host disk block size   ;
  237. ;              detection.  All file sizes (and total file      ;
  238. ;              sizes) are rounded to reflect this block size.  ;
  239. ;  08/29/87    V1.36    - Rewrote all time routines.  Moved RTC reader      ;
  240. ;              code insert address to ZMDHDR.  Moved all date  ;
  241. ;              and time routines together to be updated all      ;
  242. ;              in same pass.  Values stored at end of program  ;
  243. ;              to free up registers and retain values for any  ;
  244. ;              subsequent use.                  ;
  245. ;  08/14/87    v1.35    - Removed access restriction routines and rewrote ;
  246. ;              completely.  Access switches now bit mapped.      ;
  247. ;  07/24/87    v1.34    - Updated to detect and process batch filename      ;
  248. ;              requests automatically.  (AUTO-BATCH).      ;
  249. ;            - Removed entire SBTCH routines and threw away.      ;
  250. ;              Rewrote from scratch to enhance speed,      ;
  251. ;              efficiency, readability, and user friendliness. ;
  252. ;              ZMD is capable of locating multiple filenames      ;
  253. ;              on multiple drive user areas with full drive      ;
  254. ;              and user area, filename, and time restrictions  ;
  255. ;              in force in 5 seconds (all other CP/M file      ;
  256. ;              transfer programs take 7 minutes or more) to      ;
  257. ;              find maximum 255 filenames.              ;
  258. ;            - Complete rewrites of: command line parsing,      ;
  259. ;              exit, abort, credit and descriptions routines.  ;
  260. ;  06/18/87    v1.30    - Removed conditional assembly and modified to      ;
  261. ;              support .COM file installation/reconfiguration  ;
  262. ;              without reassembling.                  ;
  263. ;  06/17/87    v1.29    - Converted entire program to Microsoft MACRO-80  ;
  264. ;              language.  Programs no longer compatible with      ;
  265. ;              8080 microcomputers.                  ;
  266. ;-                                                                       -;
  267.  
  268. ;-------------------------------------------------------------------------;
  269. ; EXTERNAL Declarations:                          |
  270. ;-------------------------------------------------------------------------
  271. ;
  272.  
  273.     EXTRN    BCDBIN,BLKSIZ,BUFSTR,BYECHK,CATCH,CHARLN,CKDIR,CLEARIT
  274.     EXTRN    CMDBUF,CNREC,CONIN,CONONL,CONSTAT,CPDEHL,CPM3,CRCCHK
  275.     EXTRN    CRCVAL,DATDEC,DATMSG,DBUF,DECOUT,DELAY,DIVREC,DSCFLG
  276.     EXTRN    DSKSAV,DVHLDE,ERXIT,EXIT,FILCNT,FILTM1,FINCRC,FUNCHK
  277.     EXTRN    GETDSC,GETKIND,GETOFF,GETSPD,GTCURDU,HEXO,ILPRT,ILPRTB
  278.     EXTRN    ILPRTL,INCRNO,INITFCB,INITFLG,INITIT,INPUT,KDRV,KIND
  279.     EXTRN    KSHOW,KTIM,LBRARC,LCASE,LOGBUF,LOW41K,MATCH,MCHFTYP
  280.     EXTRN    MEMFCB,MODE,MOVFCB,MSGFLG,NAMBUF,NOARK,OLDDRV
  281.     EXTRN    OLDUSR,PGSIZE,PRINTV,PRIVATE,RDARC,RDCOUNT,RECAR1
  282.     EXTRN    RECARE,RECDR1,RECDRX,RECTBL,RECV,RENFCB,RENTYP,RSDMA
  283.     EXTRN    RSTLCK,SEND,SENDBEL,SETLCK,SHOCAT,SHONM,SHONM3,SHOSPD
  284.     EXTRN    SNDABT,SPCDRV,STACK,STDMA,STORTM,TYPE,UCASE,USRSAV
  285.     EXTRN    WAIT1,WHLCHK,XTIM,NEWNAM,SHONM4,NOROOM,BYEBDOS,BATCH
  286.     EXTRN    FILIMT,PUPFLG,CHKTPA
  287.  
  288. ;
  289. ;-------------------------------------------------------------------------;
  290. ; PUBLIC Declarations:                              |
  291. ;-------------------------------------------------------------------------;
  292. ;
  293.  
  294.     PUBLIC    KTABLE,XTABLE,KECTBL,DONE,EOTFLG,ABORT,ABORTX,HELP
  295.     PUBLIC    KFLG,FCBBUF,HDRADR,RCNT,RECDNO,SAVEHL,RCDCNT,TIME
  296.  
  297. ;
  298. ;-------------------------------------------------------------------------;
  299. ; Program Starts Here                              |
  300. ;-------------------------------------------------------------------------;
  301.  
  302.  
  303.        .Z80
  304.     ASEG
  305.     ORG    100H        ; Program starts 
  306.     JP    BEGIN        ; Jump around configuration table
  307.     INCLUDE    ZMDHDR.Z80    ; Include the ZMD header overlay
  308.        .REQUEST ZMDSUBS        ; Include the ZMD subroutines
  309.  
  310. ;
  311. ;
  312. ; Save current CP/M stack address
  313. ;
  314. BEGIN:    LD    (STACK),SP    ; Save current CP/M stack address
  315.     LD    SP,STACK    ; Initialize new one for ZMD
  316.  
  317. ;
  318. ; Save current drive and user area for later
  319. ;
  320.     LD    A,255
  321.     CALL    RECAR1        ; Get current user
  322.     LD    (OLDUSR),A    ; Save current user
  323.     LD    C,CURDRV    ; Current drive
  324.     CALL    BDOS
  325.     LD    (OLDDRV),A    ; Save current drive
  326.     ADD    A,'A'        ; Make it ASCII
  327.     LD    (KDRV),A    ; And store as default drive for DPB info
  328.  
  329. ;
  330. ; Display signon message and check environmental discrepencies
  331. ;
  332.     LD    HL,ZMDNAM    ; Point to this program's name
  333.     CALL    PRINTV        ; Display it and version number
  334.  
  335. ;
  336. ; If running under CPM3 tell rest of program
  337. ;
  338.     LD    C,GETVER    ; Get CPM version
  339.     CALL    BDOS
  340.     CP    48        ; Version 3.0?
  341.     JR    C,$+5        ; No, it's 2.n so skip next
  342.     LD    (CPM3),A    ; Else set CPM3 switch on
  343.  
  344. ;
  345. ; Locate modem I/O routines
  346. ;
  347.     CALL    BYECHK        ; BYE extended BDOS valid?
  348.     CP    5
  349.     JR    NZ,BEGIN0    ; No, check for I/O overlay
  350.     LD    A,255
  351.     LD    (BYEBDOS),A    ; Enable BYE extended BDOS for modem I/O
  352.     JR    BEGIN1
  353.  
  354. BEGIN0:    LD    A,(MDINP+2)    ; Check for MDINP address
  355.     OR    A        ; Anything there?
  356.     JP    Z,NOIO        ; No overlay either, bitch then exit
  357.     LD    (INITFLG),A    ; Tell exit routine to 'UNINIT'
  358.     CALL    MINIT        ; Initialize system routine (if included)
  359.  
  360. ;
  361. ; Get bit mapped access flags byte
  362. ;
  363. BEGIN1:    LD    A,(ACCESS)    ; Using access flags byte?
  364.     OR    A
  365.     JR    Z,BEGIN3    ; No
  366.  
  367.     CALL    BYECHK        ; Check version of BYE
  368.     CP    5        ; BYE5?
  369.     JR    NZ,BEGIN2    ; No
  370.  
  371.     LD    E,255
  372.     LD    C,85        ; Get access flags byte
  373.     CALL    BDOS
  374.     LD    (AFBYTE),A    ; Store it
  375.     JR    BEGIN3
  376.  
  377. BEGIN2:    LD    DE,ACBOFF    ; Offset to access flags byte
  378.     CALL    GETOFF        ; Get address
  379.     LD    A,(HL)        ; HL points to access flags byte
  380.     LD    (AFBYTE),A    ; Store it
  381.  
  382. ;
  383. ; Set WRTLOC, display time on system
  384. ;
  385. BEGIN3:    CALL    SETLCK        ; Set WRTLOC if needed
  386.     CALL    CATCH        ; Gobble up garbage characters from line
  387.     CALL    TIME        ; Get clock values and display time on
  388.  
  389. ;
  390. ;-------------------------------------------------------------------------;
  391. ; P a r s e   ' M o d e '   f r o m   C o m m a n d   T a i l          |
  392. ;-------------------------------------------------------------------------;
  393. ;
  394. ; Second character in CP/M FCB contains program mode
  395. ;
  396.     LD    HL,FCB+1
  397.     LD    A,(HL)        ; Get the main option
  398.     LD    (MODE),A    ; Save it for later use
  399.     CP    'F'        ; Free space?
  400.     JP    Z,SPACE        ; Yes
  401.     CP    'A'        ; .ARC/.ARK member extraction?
  402.     JP    Z,CKSND-3    ; Yes
  403.     CP    'L'        ; .LBR member extraction?
  404.     JP    Z,CKSND-3    ; Yes
  405.     CP    'S'        ; Send a file?
  406.     JP    Z,CKSND        ; Yes
  407.     CP    'R'        ; Receive a file?
  408.     JP    NZ,HELP        ; No, show help guide
  409.  
  410. ;
  411. ; Check additional 'R'eceive mode options
  412. ;
  413.     INC    HL        ; Point to next option
  414.     LD    A,(HL)        ; Put in A
  415.     CP    'P'        ; Receive Private?
  416.     JR    Z,CKRCV2-3    ; Yes
  417.     CP    'W'        ; Receive Privileged?  (No descriptions)
  418.     JR    NZ,CKRCV1    ; No
  419.     LD    A,(PUPOPT)    ; Is >0 if allowing privileged uploads
  420.     LD    (PUPFLG),A    ; Sets our flag this way
  421.     OR    A        ; Allowed?
  422.     JP    Z,HELP        ; No, show help guide
  423.     JR    CKRCV2        ; Else get next option
  424.  
  425. CKRCV1:    CP    'M'        ; Receive message?
  426.     JR    NZ,CKRCV3    ; No
  427.     LD    A,(FCB1+1)    ; See if a filename was requested
  428.     CP    ' '
  429.     JP    Z,HELP        ; No, batch mode not allowed
  430.     LD    A,(MSGFIL)    ; Is >0 if allowing message uploads
  431.     LD    (MSGFLG),A     ; Sets our flag this way
  432.     OR    A        ; Allowed?
  433.     JP    Z,HELP        ; No, show help guide
  434.     LD    A,'P'        ; Else...
  435.     LD    (PRIVATE),A    ; Set the private flag
  436.  
  437. CKRCV2:    INC    HL        ; Point to next option
  438.     LD    A,(HL)        ; Put in A
  439.  
  440. CKRCV3:    CP    ' '        ; Anything there?
  441.     JP    Z,BCHMSG    ; No, see if requesting Batch
  442.     CP    'B'        ; Batch mode?
  443.     JP    Z,BCHMSG    ; Yes
  444.     CP    'C'        ; Force Checksum?
  445.     JP    Z,CHKMSG    ; Yes
  446.     CP    'X'        ; Force 128 byte packets?
  447.     JP    Z,XMDMSG    ; Yes
  448.     CP    'K'        ; Force 1k packets?
  449.     JP    Z,YMDMSG    ; Yes
  450.     JP    HELP        ; Invalid option, show help guide
  451.  
  452. ;
  453. ; Check additional 'S'end mode options
  454. ;
  455.     LD    (LBRARC),A    ; Set .LBR/.ARK/.ARC extraction flag
  456.  
  457. CKSND:    INC    HL        ; Next option on command line
  458.     LD    A,(LBRARC)    ; Get the member extraction flag
  459.     OR    A        ; Is is set?
  460.     JR    Z,CKSND0    ; No, we can check for batch
  461.     LD    A,(HL)        ; Get the character
  462.      CP    ' '        ; Any more options?
  463.     JP    Z,YMDMSG    ; No, and batch not used with extractions
  464.  
  465. CKSND0:    LD    A,(HL)        ; Get the character back
  466.     CP    ' '        ; Any more options?
  467.     JR    Z,BCHMSG    ; No, check for batch intention
  468.     CP    'C'        ; Force checksums?
  469.     JP    Z,CHKMSG    ; Show protocol
  470.     CP    'X'        ; Force XMODEM protocol?
  471.     JP    Z,XMDMSG    ; Show protocol
  472.     CP    'K'        ; Force 1k protocol?
  473.     JP    Z,YMDMSG    ; Show protocol
  474.     LD    A,(LBRARC)    ; Get LBR/ARC extraction flag
  475.     OR    A        ; Enabled?
  476.     JP    NZ,NOMSG    ; Yes, ignore Batch
  477.     LD    A,(HL)        ; Get option back
  478.     CP    'B'        ; Forcing batch?
  479.     JR    NZ,CKSND1    ; No
  480.     LD    A,(PRIVATE)    ; Get special download area flag
  481.     OR    A        ; Enabled?
  482.     JP    NZ,NOMSG    ; Yes, don't allow batch
  483.     JP    BCMSG2        ; Go set batch flag and display mode
  484.  
  485. CKSND1:    CP    'P'        ; Send private?
  486.     JP    NZ,HELP        ; No
  487.     LD    (PRIVATE),A    ; Enable private download
  488.     JR    CKSND        ; Loop for more options
  489.  
  490. ;
  491. ; Display the currently selected (or default) protocol.
  492. ;
  493. BCHMSG:    LD    A,(MODE)    ; Get main option again
  494.     CP    'R'        ; Receiving?
  495.     JR    NZ,BCMSG1    ; No
  496.     LD    A,(FCB1+1)    ; Was a file requested?
  497.     CP    ' '
  498.     JR    Z,BCMSG2    ; No, in batch receive
  499.  
  500.     LD    HL,FCB1+1    ; Point to secondary FCB
  501.     CALL    CKWILD        ; Check for wildcards
  502.     LD    A,(BATCH)    ; Batch enabled now?
  503.     OR    A
  504.     JR    NZ,BCMSG2    ; Yes, report protocol
  505.     JR    YMDMSG        ; Else, single file receive.  Default to 1k
  506.  
  507. ;
  508. ; Scan the command line to see if there was any intention of batch and if
  509. ; so, set program environment to Ymodem 1k batch protocol.
  510. ;
  511. BCMSG1:    XOR    A        ; Clear accumulator
  512.     LD    (MODE),A    ; Gets us back from the SBTCH routines
  513.     CALL    SBTCH        ; Check for batch intention
  514.     LD    A,'S'
  515.     LD    (MODE),A    ; Fix the transfer mode flag
  516.     LD    A,(BATCH)    ; Get the batch mode flag
  517.     OR    A        ; Was it enabled?
  518.     JR    Z,YMDMSG    ; No, sending single file.  Default to 1k
  519.  
  520. BCMSG2:    CALL    LOW41K        ; 1k packets allowed?
  521.     JP    C,TOOSLOW    ; No, can't use batch
  522.     LD    A,1
  523.     LD    (BATCH),A    ; Enable batch
  524.     CALL    ILPRTB
  525.     DB    '1k Batch',0
  526.     JR    MSGEND
  527.  
  528. YMDMSG:    CALL    LOW41K        ; 1k packets allowed?
  529.     JR    C,NOMSG        ; No
  530.     LD    (KFLG),A    ; Enable 1k
  531.     CALL    ILPRTB
  532.     DB    '1k',0
  533.     JR    MSGEND
  534.  
  535. XMDMSG:    XOR    A        ; Clear accumulator
  536.     LD    (KFLG),A    ; Disable 1k blocks
  537.     CALL    ILPRTB
  538.     DB    '128 byte CRC',0
  539.     JR    MSGEND
  540.  
  541. CHKMSG:    XOR    A        ; Clear accumulator
  542.     LD    (CRCFLG),A    ; Disable CRC
  543.     LD    (KFLG),A    ; Disable 1k blocks (not allowed in Checksum)
  544.     CALL    ILPRTB
  545.     DB    '128 byte Checksum',0
  546.  
  547. MSGEND:    CALL    ILPRTB
  548.     DB    ' enabled',0
  549.  
  550. NOMSG:    CALL    CHKTPA        ; Calculate TPA limitations
  551.     CALL    ILPRTB
  552.     DB    CR,LF,0
  553.     LD    A,(MODE)    ; Get transfer mode
  554.     CP    'R'        ; Receiving?
  555.     JP    Z,RCVFL        ; Yes
  556.     LD    A,'S'
  557.     LD    (MODE),A    ; Else make mode an 'S' (send mode)
  558.  
  559. ;
  560. ;-------------------------------------------------------------------------;
  561. ; ----> SNDFIL  -  S e n d  f i l e ( s )                  |
  562. ;-------------------------------------------------------------------------;
  563. ;
  564. ; The file specified in the ZMD command line is transferred over the phone
  565. ; to another computer with modem using the "S"end option. The data is sent
  566. ; 1 record at a time with headers, checksums, and retransmission on errors.
  567. ;
  568. SNDFIL:    LD    A,(BATCH)    ; Batch mode requested?
  569.     OR    A
  570.     JP    NZ,SBTCH    ; Yes, go handle batch mode
  571.  
  572. ;
  573. ; Take care of single file transfer - not in batch
  574. ;
  575.     CALL    LOGDU        ; Log into drive and get DPB info
  576.     CALL    GTCDUD        ; Get current binary drive/user in DUU/DUD
  577.     CALL    CNREC        ; Calculate number of records (unless LBRARC)
  578.     CALL    CATCH        ; Clear the decks
  579.     CALL    OPNFIL        ; Open the file and check restrictions
  580.  
  581. ;
  582. ; Loop back here for the start of each BATCH file sent
  583. ;
  584. SNDFL1:    LD    E,60        ; Number of seconds to wait for initial 'NAK'
  585.  
  586. SNDFL2:    CALL    FUNCHK        ; Check for function keys
  587.     CALL    SNDABT        ; Local abort?
  588.     LD    B,1
  589.     CALL    RECV        ; Wait 1 second for initial NAK
  590.     JR    C,SNDFL3    ; No character
  591.     CP    CRC        ; CRC request?
  592.     JR    Z,SNDFL4    ; Yes
  593.     CP    KSND        ; 1k request?
  594.     JR    Z,SNDFL7    ; Yes
  595.     CP    NAK        ; NAK for checksum?
  596.     JR    Z,SNDFL8    ; Yes
  597.     CP    CANCEL        ; Cancel?
  598.     JP    Z,ABORT        ; Yes
  599.  
  600. SNDFL3:    DEC    E        ; One less second
  601.     JP    Z,ABORT        ; Abort if 0
  602.     JR    SNDFL2        ; Else wait some more
  603.  
  604. ;
  605. ; Got a 'C', now wait up to 1 second for 'K'
  606. ;
  607. SNDFL4:    LD    A,(BATCH)    ; In batch mode?
  608.     OR    A
  609.     JR    NZ,SNDFL7    ; Yes, don't wait for 'K'
  610.     LD    B,1
  611.     CALL    RECV        ; Get character from remote
  612.     JR    C,SNDFL5    ; No character received, so not using 1k
  613.     AND    7FH        ; Strip high bit
  614.     CP    '{'
  615.     JR    Z,SNDFL4    ; Disregard noisy lines
  616.     CP    KSND        ; Requesting 1k?
  617.     JR    Z,SNDFL7    ; Exit if yes, otherwise set CRC
  618.  
  619. ;
  620. ; Turn on the flag for CRC
  621. ;
  622. SNDFL5:    LD    A,(KFLG)    ; KFLG manually set from 'SK'?
  623.     OR    A
  624.     JR    NZ,SNDFL7    ; If yes, keep it set
  625.  
  626. SNDFL6:    XOR    A
  627.     LD    (KFLG),A    ; Defaults to 128 character blocks
  628.     INC    A
  629.     LD    (CRCFLG),A    ; Insures in CRC mode
  630.     CALL    ILPRTL
  631.     DB    CR
  632.     DB    'CRC',0
  633.     JP    SNDFL10
  634.  
  635. ;
  636. ; Turn on the flag for 1k blocks and insure in CRC mode
  637. ;
  638. SNDFL7:    CALL    LOW41K        ; 1k packets allowed?
  639.     JP    C,SNDFL6    ; No
  640.     LD    (KFLG),A    ; Set the flag for 1k blocks
  641.     LD    (CRCFLG),A    ; Insures in CRC mode
  642.     LD    A,(BATCH)    ; In Ymodem Batch?
  643.     OR    A
  644.     CALL    NZ,OPNFIL    ; Yes, then open file/check restrictions
  645.     CALL    ILPRTL
  646.     DB    CR
  647.     DB    'Ymodem',0
  648.     JR    SNDFL10
  649.  
  650. ;
  651. ; Turn on checksum flag, insure sending 128 character blocks
  652. ;
  653. SNDFL8:    LD    A,(BATCH)    ; In batch mode now?
  654.     OR    A
  655.     JR    NZ,SNDFL9    ; If yes, exit
  656.     XOR    A
  657.     LD    (CRCFLG),A    ; Make sure in checksum mode
  658.     LD    (KFLG),A    ; Defaults to 128 character blocks
  659.     CALL    ILPRTL
  660.     DB    CR
  661.     DB    'Checksum',0
  662.     JR    SNDFL10
  663.  
  664. SNDFL9:    CALL    ILPRTL
  665.     DB    CR
  666.     DB    '-- Checksum not used in batch'
  667.     DB    CR,LF,0
  668.     JP    SNDFL2        ; If yes, ignore checksum request
  669.  
  670. SNDFL10:CALL    ILPRTL
  671.     DB    ' requested '
  672.     DB    CR,LF,0
  673.     CALL    RDBLOK        ; Put up to 16k from file into buffer
  674.     CALL    SETFLG        ; Disable 1k if less than 8 records left
  675.  
  676. ;
  677. ; Loop back here to send the next 1k/128 byte block after a successful trans-
  678. ; mission.  If using 1k blocks, check the ACK ratio.  Check total error count
  679. ; vs. records sent, and switch from 1k to 128 byte transmissions if higher.
  680. ;
  681. SNDLP:    LD    A,(KFLG)    ; Using 1k blocks?
  682.     OR    A
  683.     JP    Z,RDRECD    ; If not, skip checking 1k error ratio
  684.     LD    A,(ERRCNT)    ; See if we got any errors last record
  685.     CP    4        ; 4 or more?
  686.     JR    NC,SNDLP1    ; Yes, switch to 128 size
  687.     LD    A,(ACCERR)    ; See if up to minimum errors yet
  688.     CP    3        ; Had as many as three errors yet?
  689.     JR    C,RDRECD    ; If not, don't get excited too quickly
  690.  
  691.     LD    HL,(RECDNO)    ; Get current record number increment
  692.     LD    DE,65528    ; Have not successfully sent this 1k yet
  693.     ADD    HL,DE        ; Subtract the current increment, then
  694.     LD    DE,(ACCERR)    ; Number of non-'ACK' errors in HL
  695.     CALL    DVHLDE        ; Get ratio in BC of records/hit
  696.     CALL    GETSPD        ; Get current speed
  697.     CP    5        ; 1200 baud?
  698.     LD    A,70        ; for 1200 bps
  699.     JR    Z,$+4        ; If 1200, skip next line
  700.     LD    A,42        ; for 2400 bps
  701.     CP    C        ; Compare with actual ratio
  702.     JR    C,RDRECD    ; Continue if less hits than allowed
  703.  
  704. SNDLP1:    XOR    A        ; Clear A
  705.     LD    (KFLG),A    ; Reset system to 128 byte blocks
  706.     CALL    ILPRTL        ; Inform locally
  707.     DB    ' - YMODEM 1k blocks disabled'
  708.     DB    CR,LF,0
  709.  
  710. ;
  711. ; Read a record, refill buffer if empty, update record read
  712. ;
  713. RDRECD:    LD    A,(RECNBF)    ; Any records in the buffer?
  714.     OR    A
  715.     JR    Z,RDBLOCK    ; No, go get some
  716.     LD    A,(KFLG)    ; Using 1k blocks?
  717.     OR    A
  718.     JR    Z,RDREC1    ; No, exit
  719.     LD    A,(RECNBF)    ; See how many records in buffer
  720.     CP    8        ; 8 or more records?
  721.     JR    NC,RDREC2    ; Yes, stay in 1k blocks
  722.     XOR    A
  723.     LD    (KFLG),A    ; Reset the 1k flag for 128 byte
  724.  
  725. RDREC1:    LD    A,(RECNBF)    ; Point to number of records in buffer
  726.     DEC    A        ; Decrement it for 128 character blocks
  727.     LD    (RECNBF),A    ; Store it
  728.     JP    SNDLP2        ; Send it
  729.  
  730. RDREC2:    SUB    8        ; Subtract 8 records (1k worth)
  731.     LD    (RECNBF),A    ; Store it
  732.     JP    SNDLP2        ; Send it
  733.  
  734. ;
  735. ; Buffer is empty - read in another block of 16k
  736. ;
  737. RDBLOCK:LD    A,(EOFLG)    ; Get 'EOF' flag
  738.     CP    1        ; Is it set?
  739.     SCF            ; To show 'EOF'
  740.     JP    Z,SNDLP2    ; Got 'EOF'
  741.     CALL    RDBLOK        ; Read up to 16k into DBUF
  742.     JR    RDRECD        ; Pass record to caller
  743.  
  744. ;
  745. ; Read up to 16k from the disk file into the buffer, ready to send
  746. ;
  747. RDBLOK:    LD    C,0        ; Set number of records in block to 0
  748.     LD    DE,DBUF        ; Point to disk buffer as destination
  749.  
  750. RDBLOK1:PUSH    BC
  751.     PUSH    DE
  752.     LD    A,(LBRARC)    ; Get ARK/ARC/LBR extraction flag
  753.     OR    A        ; Enabled?
  754.     JR    Z,RDBLOK2    ; No, skip next
  755.     LD    A,(FCB+9)    ; Get filetype byte 1
  756.     AND    7FH        ; Strip high bit
  757.     CP    'A'        ; Is it an ARK/ARC extraction?
  758.     CALL    Z,RDARC        ; Yes, (flags saved at RDARC)
  759.     JR    Z,RDBLOK3    ; Same flags
  760.  
  761. RDBLOK2:CALL    STDMA        ; Set DMA address
  762.     LD    C,READ
  763.     LD    DE,FCB
  764.     CALL    BDOS
  765.  
  766. RDBLOK3:POP    DE
  767.     POP    BC
  768.     OR    A        ; Read ok?
  769.     JR    NZ,RDBLOK5    ; If not, error or end of file
  770.     LD    HL,128        ; Add length of one record
  771.     ADD    HL,DE        ; To next buffer
  772.     EX    DE,HL        ; Buffer to 'DE'
  773.     INC    C        ; More records?
  774.     LD    A,(BUFSIZ)
  775.     ADD    A,A
  776.     ADD    A,A
  777.     ADD    A,A
  778.     CP    C
  779.     JR    NZ,RDBLOK1    ; Read more
  780.  
  781. ;
  782. ; Buffer is full or got EOF
  783. ;
  784. RDBLOK4:LD    (RECNBF),A    ; Store record count
  785.     LD    HL,DBUF        ; Get the beginning buffer address
  786.     LD    (RECPTR),HL    ; Save for next record
  787.     JP    RSDMA        ; Reset DMA address to default
  788.  
  789. RDBLOK5:DEC    A        ; 'EOF'?
  790.     JR    NZ,READERR    ; Got 'EOF'
  791.  
  792. RDBLOK6:INC    A
  793.     LD    (EOFLG),A    ; Set EOF flag
  794.     LD    A,C
  795.     JR    RDBLOK4
  796.  
  797. READERR:CALL    ILPRTB
  798.     DB    CR,LF
  799.     DB    '-- Read Error: ',0
  800.     CALL    SHONM3
  801.     JP    EXIT
  802.  
  803. ;
  804. ; Now send the next record
  805. ;
  806. SNDLP2:    JP    C,SNDEOF    ; Send 'EOF' if done
  807.     CALL    INCRNO        ; Bump record number if sent ok
  808.     XOR    A        ; Initialize error count to zero
  809.     LD    (ERRCNT),A
  810.  
  811. SNDRPT:    CALL    CKABORT        ; Check for remote abort
  812.     CALL    SNDABT        ; Check for local abort
  813.     CALL    SNDHDR        ; Send a header
  814.     CALL    SNDREC        ; Send data record
  815.     CALL    SNDCHK        ; Send CRC or checksum value
  816.     CALL    GTACK        ; Get the 'ACK'
  817.     CP    ACK        ; ACK?
  818.     JR    NZ,SNDRPT    ; No, repeat transmission
  819.     LD    DE,128        ; For 128 character blocks
  820.     LD    A,(KFLG)    ; See if last block sent was 1k
  821.     OR    A
  822.     JR    Z,$+5        ; No, skip next line
  823.     LD    DE,1024        ; Else set for 1024 character blocks
  824.     LD    HL,(RECPTR)    ; Get the buffer pointer
  825.     ADD    HL,DE        ; Increment for the record just sent
  826.     LD    (RECPTR),HL    ; New buffer address for next block
  827.     LD    A,(LBRARC)    ; Get LBR/ARC/ARK extraction flag
  828.     OR    A        ; Enabled?
  829.     JP    Z,SNDLP        ; No
  830.     LD    A,(KFLG)    ; 1k enabled?
  831.     LD    DE,65535    ; 128 byte
  832.     OR    A
  833.     JR    Z,$+5
  834.     LD    DE,65528    ; 1k
  835.     LD    HL,(RCNT)    ; Alter the records-sent count
  836.     ADD    HL,DE
  837.     LD    (RCNT),HL    ; One less transmission to go
  838.     OR    A        ; 'K' flag set?
  839.     CALL    NZ,SETFLG    ; Yes, see if enough records for 1k packet
  840.     LD    HL,(RCNT)    ; See if anything was actually sent
  841.     LD    A,H
  842.     OR    L        ; L and H both zero now?
  843.     JP    NZ,SNDLP    ; No, continue
  844.  
  845. ;
  846. ; End of Transmission (Send mode)
  847. ;
  848. SNDEOF:    LD    A,(LOGLDS)    ; Counting transfers?
  849.     OR    A
  850.     JR    Z,SNDEOF1    ; No
  851.     LD    A,(PRIVATE)    ; Is this a private transfer?
  852.     OR    A
  853.     JR    NZ,SNDEOF1    ; Yes, don't increment download count
  854.     LD    IY,(DNLDS)    ; Get Downloads counter address
  855.     INC    (IY)        ; One more download since log in
  856.  
  857. SNDEOF1:CALL    LOGCALL        ; Log transfer if supposed to
  858.     CALL    EOFSND
  859.     CALL    ADDTON        ; Update BYE's time on byte if supposed to
  860.     CALL    ALLDON
  861.     JP    DONE
  862.  
  863. ;
  864. ; See if enough records left to use 1k protocol
  865. ;
  866. SETFLG:    LD    HL,(RCNT)
  867.     LD    A,H        ; Anything in the 'H' register?
  868.     OR    A
  869.     RET    NZ        ; Yes, enough records for another 1k packet
  870.     LD    A,L        ; Get number of records in 'L' register
  871.     CP    8        ; At least 8 yet?
  872.     RET    NC        ; Yes, keep going
  873.     XOR    A        ; Reset the 'K' flag
  874.     LD    (KFLG),A
  875.     RET
  876.  
  877. ;
  878. ; HL points to filename FCB - now search for it wildcards.  If any, enable
  879. ; BATCH flag and pad with '?' as needed
  880. CKWILD:    LD    B,8        ; Check first 8 bytes
  881.     CALL    CKWLD1
  882.     LD    B,3        ; And check filetype
  883.  
  884. CKWLD1:    LD    A,(HL)        ; Get the character
  885.     CP    '*'        ; '*'?
  886.     JR    NZ,CKWLD2    ; No, check for little wildcards
  887.     LD    (BATCH),A    ; Enable AUTO-BATCH
  888.     LD    A,'?'        ; Fill rest with '?' character
  889.     JP    INITIT        ; Initialize
  890.  
  891. CKWLD2:    CP    '?'        ; '?'?
  892.     JR    NZ,$+5        ; No, don't enable AUTO-BATCH
  893.     LD    (BATCH),A    ; Enable AUTO-BATCH
  894.     INC    HL        ; Point to next character
  895.     DJNZ    CKWLD1        ; Loop until B=0
  896.     RET
  897.  
  898. ;
  899. ; Get the current drive/user
  900. ;
  901. GTCDUD:    LD    A,0FFH        ; Stuffed into E at RECAR1
  902.     CALL    RECAR1        ; Get current user area
  903.     LD    (DUU),A        ; Store it
  904.     LD    C,CURDRV    ; Get current drive
  905.     CALL    BDOS
  906.     LD    (DUD),A     ; Store it
  907.     RET
  908.  
  909. ;
  910. ;-------------------------------------------------------------------------;
  911. ; S e n d   B a t c h                              |
  912. ;-------------------------------------------------------------------------;
  913. ;
  914. ; Copy original command line buffer to internal work buffer
  915. ;
  916. SBTCH:    LD    A,(FSTFLG)    ; If first time through
  917.     OR    A
  918.     JP    NZ,SBTCH1    ; If not first time, exit
  919.  
  920.     LD    HL,TBUF        ; Source
  921.     LD    DE,CMDBUF    ; Destination
  922.     LD    BC,128        ; Count
  923.     LDIR            ; Move
  924.  
  925. ;
  926. ; Locate end of command line and place a ' ' as a delimiter
  927. ;
  928.     LD    HL,CMDBUF    ; Point to number of bytes in line
  929.     LD    B,0        ; Zero high order
  930.     LD    C,(HL)        ; Number of characters in command line
  931.     INC    HL        ; Point to start of line
  932.     ADD    HL,BC        ; Plus number of characters equals end of line
  933.     LD    (HL),' '    ; Place the delimiter at end of line
  934.     INC    BC        ; Increment character count for delimiter
  935.  
  936. ;
  937. ; Count ambiguous/unambiguous filenames in command line
  938. ;
  939.     XOR    A        ; Clear accumulator
  940.     LD    (FILCNT),A    ; Reset the file count
  941.     LD    (NAMECT),A    ; Reset name count (used in parsing routines)
  942.     LD    HL,CMDBUF+2    ; Point to command tail option
  943.     LD    A,' '        ; Looking for space/non-space characters
  944.     CPIR            ; On command option, look for next space
  945.     JP    PO,SCANDN    ; If at end of line, done
  946.     CPI            ; Find first character of first name
  947.     JP    PO,SCANDN    ; If at end of line, done
  948.     JR    Z,$-5        ; Eat extra spaces
  949.     DEC    HL        ; CPI is one ahead of us, so back up
  950.     LD    (BGNMS),HL    ; Store address of beginning name
  951.     INC    HL        ; And it was supposed to be, so restore it
  952.  
  953. SCANLP:    CPIR            ; Move to end of current name (next space)
  954.     EX    AF,AF'        ; Save A (match char) & current flags (result)
  955.     LD    A,(NAMECT)    ; Get current name count
  956.     INC    A        ; Bump it one
  957.     LD    (NAMECT),A    ; Put it back
  958.     CP    255        ; 255 names?
  959.     JR    Z,SCANDN    ; Yes, that's all we allow
  960.     EX    AF,AF'        ; Restore A and old flags
  961.     JP    PO,SCANDN    ; If at end of line, done
  962.     CPI            ; Find next non-space character
  963.     JP    PO,SCANDN    ; If at end of line, done
  964.     JR    Z,$-5        ; Was a space, keep looking
  965.     JR    SCANLP        ; Found next non-space, find next name
  966.  
  967. SCANDN:    LD    A,(NAMECT)    ; Get the ambiguous filename count
  968.     OR    A        ; Were there any?
  969.     JP    Z,HELP        ; No, they must need help
  970.     CP    1        ; Just 1 name?
  971.     JR    Z,$+5        ; If only 1, don't force AUTO-BATCH here
  972.     LD    (BATCH),A    ; Else set batch mode flag (for AUTO-BATCH)
  973.     LD    HL,NAMBUF    ; Get start of batch filename buffer
  974.     LD    (NBSAVE),HL    ; Save as address of the first name
  975.  
  976. ;
  977. ; Place a name in work buffer 
  978. ;
  979. TNLP:    LD    B,0        ; Initialize character count
  980.     LD    HL,(BGNMS)    ; Source is address of first name
  981.     LD    DE,FCBBUF+2    ; Destination
  982.  
  983. TNLP1:    LD    A,(HL)        ; Get a byte in A
  984.     CP    ' '        ; A space?
  985.     JR    Z,TNLP2        ; Yes, done with name
  986.     LD    (DE),A        ; Move character to FCB buffer
  987.     INC    HL        ; Increment pointers
  988.     INC    DE
  989.     INC    B        ; Bump count of characters in name
  990.     JR    TNLP1        ; Loop until space
  991.  
  992. TNLP2:    INC    HL        ; Point to next character
  993.     LD    A,(HL)        ; Put it in A
  994.     CP    ' '        ; Is it a ' '?
  995.     JR    Z,TNLP2        ; Yes, eat extra spaces
  996.     LD    (BGNMS),HL    ; Store address of next name
  997.     LD    HL,FCBBUF+1    ; # characters in filename
  998.     LD    (HL),B        ; Before name
  999.  
  1000. ;
  1001. ; Initialize FCB for search routines
  1002. ;
  1003.     LD    A,0        ; String of all 0's for intitialization
  1004.     LD    HL,FCB        ; Destination
  1005.     LD    B,16        ; 16 bytes
  1006.     CALL    INITIT        ; Initialize FCB
  1007.  
  1008.     LD    HL,FCBBUF+1    ; Point to # of bytes in command line
  1009.     LD    D,0        ; Zero high order
  1010.     LD    E,(HL)        ; Load DE pair with # bytes
  1011.     INC    HL        ; Increment to start of command line
  1012.     ADD    HL,DE        ; Point to byte after last character
  1013.     LD    (HL),CR        ; Store CR for delimiter
  1014.  
  1015. ;
  1016. ; Check for valid drive/user combination and move filename to FCB
  1017. ;
  1018.     LD    HL,FCBBUF+2    ; Start of filename
  1019.     LD    DE,DUSAVE    ; Isolate possible 'duu:'
  1020.     LD    BC,4        ; Up to 4 bytes
  1021.     LDIR            ; For logging into specified d/u
  1022.  
  1023.     LD    HL,FCBBUF+1    ; Point to amount of characters in filename
  1024.     LD    B,(HL)        ; In B for d/u parsing routines
  1025.     INC    B        ; Increment character count for CR terminator
  1026.     INC    HL        ; And point to start filename again
  1027.     LD    (SAVEHL),HL    ; Initialize 'current' address pointer
  1028.  
  1029.     LD    A,(MODE)    ; Get transfer mode
  1030.     PUSH    AF        ; Save it while checking valid d/u
  1031.     XOR    A         ; Zero accumulator for new mode
  1032.     LD    (MODE),A    ; Save it (keeps us out of trouble in LGDU1:)
  1033.     CALL    LGDU1        ; Check valid d/u and copy filename to FCB
  1034.     CALL    GTCDUD        ; Get current binary drive user in DUU/DUD
  1035.     POP    AF        ; Get possible previously determined mode
  1036.     LD    (MODE),A    ; Restore
  1037.     LD    HL,FCB+1    ; Filename FCB
  1038.     CALL    CKWILD        ; Check it for wildcards, enable Batch if any
  1039.  
  1040.     LD    A,(MODE)    ; Get file transfer mode
  1041.     OR    A        ; 0=checking batch intention
  1042.     RET    Z        ; All done if so
  1043.  
  1044. ;
  1045. ; Now search directory and store first matching filename
  1046. ;
  1047.     CALL    RSDMA        ; Reset to default memory address
  1048.     LD    A,'?'
  1049.      LD    (FCBEXT),A    ; Fetch all extents of matching filenames
  1050.     XOR    A
  1051.     LD    (FCBRNO),A    ; Clear FCB record number byte
  1052.     LD    DE,FCB        ; Use default FCB for search
  1053.     LD    C,SRCHF        ; Search for first occurence
  1054.     CALL    BDOS
  1055.     CP    0FFH        ; Anything found?
  1056.     JP    Z,NEXTNM    ; No, go get next ambiguous filename
  1057.     LD    HL,(LIST)    ; Initialize list pointer parameters
  1058.     LD    (LISTPOS),HL    ; Save current position of list
  1059.  
  1060. ;
  1061. ; Calculate offset to matched directory entry
  1062. ;
  1063. FNDENT:    AND    3        ; Zero based, two bit index
  1064.     ADD    A,A        ; *2
  1065.     ADD    A,A        ; *4
  1066.     ADD    A,A        ; *8
  1067.     ADD    A,A        ; *16
  1068.     ADD    A,A        ; *32 to make position index
  1069.     LD    C,A        ; Put in BC
  1070.     XOR    B        ; Clear MSB
  1071.     LD    HL,TBUF        ; Address of default command line buffer
  1072.     ADD    HL,BC        ; And offset to matched directory entry
  1073.     LD    A,(DUD)        ; Get drive number
  1074.     LD    (HL),A        ; Put in front of name in name buffer
  1075.  
  1076. ;
  1077. ; Check the match for download restrictions
  1078. ;
  1079.     PUSH    HL        ; Save address of matched entry
  1080.     PUSH    HL        ; Save another copy
  1081.     POP    IX        ; As address of filename to check
  1082.     CALL    RESTRCT        ; Check for download restrictions
  1083.     POP    HL        ; Get our matched entry address back
  1084.     JP    NZ,DONEXT    ; NZ=entry not allowed
  1085.  
  1086. ;
  1087. ; Trap zero length file before adding to list
  1088. ;
  1089.     PUSH    HL        ; Save matched entry address
  1090.     POP    IY        ; Get a copy in IY
  1091.     LD    A,(IY+12)    ; Get the extent byte
  1092.     OR    A        ; Is this the first extent?  (#0)
  1093.     JR    NZ,COPYNM    ; No, can't be 0 length (at least 16k already)
  1094.     LD    A,(IY+15)    ; Get it
  1095.     OR    A        ; Any records?
  1096.     JP    Z,DONEXT    ; No, zero length, but in batch so no messages
  1097.  
  1098. ;
  1099. ; Copy the name to list
  1100. ;
  1101. COPYNM:    LD    A,(FSTFLG)    ; Displayed the following message yet?
  1102.     OR    A
  1103.     JR    NZ,NAM2LST    ; Yes, they alreay know to wait
  1104.     PUSH    HL        ; Save matched entry address
  1105.     CALL    ILPRTB
  1106.     DB    CR,LF
  1107.     DB    'Locating selection(s)...',0
  1108.     LD    A,1
  1109.     LD    (FSTFLG),A    ; Set so message don't show again
  1110.     POP    HL        ; Restore matched entry address
  1111.  
  1112. NAM2LST:LD    DE,(LISTPOS)    ; Pointer to current load point in list
  1113.     LD    B,12        ; Move drive number and name to list
  1114.  
  1115. NM2LST1:LD    A,(HL)        ; HL contains address of entry
  1116.     AND    7FH        ; All done with high bits
  1117.     LD    (DE),A        ; Move it to list
  1118.     INC    HL        ; Increment pointer
  1119.     INC    DE
  1120.     DJNZ    NM2LST1        ; Loop until B equals 0
  1121.     LD    A,(HL)        ; Get the EX byte
  1122.     LD    (DE),A        ; Put it in list
  1123.     INC    HL        ; Increment to RC byte
  1124.     INC    HL
  1125.     INC    HL
  1126.     INC    DE
  1127.     LD    A,(HL)        ; Get it
  1128.     LD    (DE),A        ; Put it in list
  1129.     INC    DE        ; Point to start of next name in list
  1130.     LD    A,(DUU)
  1131.     LD    (DE),A
  1132.     INC    DE
  1133.     INC    DE
  1134.     LD    (LISTPOS),DE    ; Store address of next load point
  1135.  
  1136. ;
  1137. ; Search for next occurance of specified filename
  1138. ;
  1139. DONEXT:    LD    C,SRCHN        ; Search next function code
  1140.     LD    DE,FCB        ; Filename specification field
  1141.     CALL    BDOS
  1142.     CP    0FFH        ; See if all through directory yet
  1143.     JP    NZ,FNDENT    ; If not, calculate code offset and add 2 list
  1144.  
  1145. ;
  1146. ; Trap conditions of 0 files found
  1147. ;
  1148.      LD    HL,(LISTPOS)    ; Get the end of list address
  1149.     LD    DE,(LIST)     ; Get beginning of list address
  1150.     CALL    CPDEHL        ; Are they the same?
  1151.     JP    Z,NEXTNM    ; Yes, none of the files found were allowed
  1152.  
  1153. ;
  1154. ; Prepare associated sort parameters
  1155. ;
  1156.     LD    HL,(LIST)    ; Adjust I and J pointers for initial sort
  1157.     LD    (LISTI),HL    ; Beginning of list
  1158.     LD    DE,ITEMSZ    ; Get offset to next name
  1159.     ADD    HL,DE        ; Add the offset
  1160.     LD    (LISTJ),HL    ; Into J variable
  1161.  
  1162. ;
  1163. ; Don't need a sort if only 1 file extent found
  1164. ;
  1165.     LD    HL,(LIST)    ; Was there more than one entry found?
  1166.     LD    BC,ITEMSZ
  1167.     ADD    HL,BC
  1168.     EX    DE,HL
  1169.     LD    HL,(LISTPOS)    ; Next load name of list is start of buffer
  1170.     LD    (LISTEND),HL    ; Set list end marker
  1171.     CALL    CPDEHL        ; Compare DE address with HL address
  1172.     JP    Z,MINNN        ; If same, no sort needed
  1173.  
  1174. ;
  1175. ; Sort the list by disk, filename, and EX byte.
  1176. ;
  1177. SORT:    LD    HL,(LISTI)    ; Compare entries I and J
  1178.     LD    DE,(LISTJ)
  1179.     LD    B,13        ; Number of bytes to compare
  1180.     CALL    MATCH        ;
  1181.     JR    NC,SORT1    ; Swap entries if J is larger than I
  1182.     LD    HL,(LISTI)    ; Get our original pointers back
  1183.     LD    DE,(LISTJ)
  1184.     LD    B,ITEMSZ    ; Counter for number of bytes to swap
  1185.  
  1186. SWAP:    LD    C,(HL)        ; Get character from string 1
  1187.     LD    A,(DE)        ; And one from other string
  1188.     LD    (HL),A        ; Second into first
  1189.     LD    A,C        ; First into second
  1190.     LD    (DE),A
  1191.     INC    HL        ; Bump swap pointers
  1192.     INC    DE
  1193.     DJNZ    SWAP        ; Loop until B=0
  1194.  
  1195. SORT1:    LD    HL,(LISTJ)    ; Increment J pointer
  1196.     LD    DE,ITEMSZ    ; By the amount of items per entry
  1197.     ADD    HL,DE
  1198.     LD    (LISTJ),HL
  1199.     LD    DE,(LISTEND)    ; Get the address of the end of list
  1200.     CALL    CPDEHL        ; DE and HL the same?
  1201.     JR    NZ,SORT        ; No, so more J loop
  1202.  
  1203.     LD    HL,(LISTI)    ; Get the I pointer
  1204.     LD    DE,ITEMSZ    ; Get offset to next name
  1205.     ADD    HL,DE        ; Add
  1206.     LD    (LISTI),HL 
  1207.     ADD    HL,DE        ; Add offset to next name
  1208.     LD    (LISTJ),HL    ; Start J loop over again
  1209.     LD    DE,(LISTEND)    ; Get the address of the end of list
  1210.     CALL    CPDEHL        ; DE and HL the same?
  1211.     JR    NZ,SORT        ; No, must be more I loop to go
  1212.  
  1213. ;
  1214. ; List minimization loop
  1215. ;
  1216.     LD    HL,(LIST)    ; Point to the beginning of our list
  1217.     LD    (LISTI),HL    ; Initialize current name pointer
  1218.     LD    DE,ITEMSZ    ; Get offset to next name
  1219.     ADD    HL,DE        ; Add it to current name address
  1220.     LD    (LISTJ),HL    ; Store as next name
  1221.  
  1222. MINCL:    LD    DE,(LISTEND)    ; End of list address
  1223.     LD    HL,(LISTJ)    ; Next name address
  1224.     CALL    CPDEHL        ; Are they the same?
  1225.     JR    Z,MINNN        ; Yes, go set kbytes on last name (End of list)
  1226.  
  1227.     LD    DE,(LISTJ)    ; Next name address
  1228.     LD    HL,(LISTI)    ; Current name address
  1229.     LD    B,12        ; # of bytes to check
  1230.     CALL    MATCH        ; Are they the same?
  1231.     JR    NZ,MINNN    ; No, go set kbytes on last extent (Next name)
  1232.  
  1233. ;
  1234. ; Increment next name pointer and get parameter bytes
  1235. ;
  1236.     LD    HL,(LISTJ)    ; Fetch EX and RC from next name
  1237.     LD    DE,ITEMSZ    ; Offset to next name
  1238.     ADD    HL,DE        ; Add it
  1239.     LD    (LISTJ),HL    ; Save bumped J value
  1240.  
  1241.     DEC    HL        ; Point to parameter bytes of previous name
  1242.     DEC    HL
  1243.     DEC    HL
  1244.     LD    B,(HL)        ; Save the RC byte
  1245.     DEC    HL
  1246.     LD    C,(HL)        ; Save the EX number
  1247.  
  1248.     LD    HL,(LISTI)    ; Point at current name
  1249.     ADD    HL,DE        ; Point at current name info bytes
  1250.     DEC    HL
  1251.     DEC    HL
  1252.     DEC    HL
  1253.     LD    D,(HL)        ; Fetch that RC byte
  1254.     DEC    HL
  1255.     LD    E,(HL)        ; Fetch current EX byte
  1256.  
  1257.     LD    A,E        ; Check if new EXtent is bigger than last
  1258.     CP    C
  1259.     JR    NC,MINCL    ; Skip using size of a less or equal EX
  1260.     LD    (HL),C        ; Put new sizes into the location
  1261.     INC    HL
  1262.     LD    (HL),B        ; New RC byte too
  1263.     JR    MINCL        ; Continue handling as current file
  1264.  
  1265. ;
  1266. ; File size computation loop
  1267. ;
  1268. MINNN:    LD    HL,(LISTI)    ; Point to name to convert records
  1269.     LD    DE,ITEMSZ-4    ; Index to largest extent number
  1270.     ADD    HL,DE        ; Add the offset
  1271.     LD    B,(HL)        ; Get the extent number for a loop counter
  1272.     INC    HL        ; Bump to the last extent RC byte
  1273.     PUSH    HL        ; Save pointer to list parameters
  1274.     LD    HL,0        ; Zero extent total record count
  1275.     LD    DE,128        ; Set size of one extent
  1276.  
  1277. ;
  1278. ; Calculate total number of 128 byte records
  1279. ;
  1280. MINEL:    LD    A,B        ; Get the number of extents left
  1281.     OR    A        ; Any more?
  1282.     JR    Z,MINELD    ; No, done with 128 multiply
  1283.     ADD    HL,DE        ; Else add another 128 to HL
  1284.     DEC    B        ; 1 less extent left
  1285.     JR    MINEL        ; Loop until no more
  1286.  
  1287. MINELD:    EX    DE,HL        ; Total extent size to DE
  1288.     POP    HL        ; Get back RC byte pointer
  1289.     LD    B,0
  1290.     LD    C,(HL)        ; Get final extent size to BC
  1291.     EX    DE,HL        ; Add remainder to total records in DE
  1292.     ADD    HL,BC
  1293.     LD    B,H        ; Move total record count to BC
  1294.     LD    C,L
  1295.     LD    HL,(TOTREC)    ; Get current total records
  1296.     ADD    HL,BC        ; Add records of this file
  1297.     LD    (TOTREC),HL    ; And save it for later display
  1298.     EX    DE,HL        ; Get table entry pointer back in HL
  1299.     CALL    ROUNDK        ; Get disk space needed for file DE
  1300.     LD    (HL),D        ; Put kilobyte count in table
  1301.     DEC    HL
  1302.     LD    (HL),E
  1303.     LD    A,(FILCNT)    ; Bump the file count
  1304.     CP    255        ; 255 file names yet?
  1305.     JR    Z,MINN0        ; Yes, that's all we allow
  1306.     INC    A        ; Else bump it one
  1307.     LD    (FILCNT),A    ; Store it
  1308.     LD    HL,(FILEK)    ; Get current total file kilobytes
  1309.     ADD    HL,DE        ; Add in the current file's kilobyte size
  1310.     LD    (FILEK),HL    ; And store it
  1311.     LD    HL,(LISTI)    ; Source
  1312.     LD    DE,(NBSAVE)    ; Destination
  1313.     LD    BC,16        ; 16 byte count
  1314.     LDIR            ; Move filename to names buffer
  1315.     LD    (NBSAVE),DE    ; And store address to put next filename
  1316.  
  1317. MINN0:    LD    DE,(LISTJ)    ; Done with all names
  1318.     LD    HL,(LISTEND)    ; Check if at end of list
  1319.     CALL    CPDEHL
  1320.     JR    Z,NEXTNM    ; Get next ambiguous filename, if finished
  1321.     LD    HL,(LISTI)    ; Point to LISTI value
  1322.     LD    DE,ITEMSZ    ; Point to next position
  1323.     ADD    HL,DE
  1324.     LD    (LISTI),HL    ; Set new working LISTI
  1325.     LD    DE,(LISTI)
  1326.     LD    HL,(LISTJ)    ; Next name position to copy from
  1327.     CALL    CPDEHL        ; See if pointers only one apart
  1328.     JR    Z,MINN1        ; If so, don't cover up one name
  1329.     LD    BC,ITEMSZ
  1330.     LDIR            ; Move that name up there
  1331.     JR    MINN2
  1332.  
  1333. MINN1:    LD    DE,ITEMSZ    ; No open slot, so just move LISTJ up one slot
  1334.     ADD    HL,DE
  1335.  
  1336. MINN2:    LD    (LISTJ),HL
  1337.     JP    MINCL        ; Go to MIN NAME start of loop
  1338.  
  1339. NEXTNM:    LD    A,(OLDDRV)
  1340.     CALL    RECDRX        ; Restore default drive
  1341.     LD    A,(OLDUSR)
  1342.     CALL    RECAR1        ; Restore default user
  1343.     LD    A,(NAMECT)    ; Get number of names found
  1344.     DEC    A        ; Decrement it
  1345.     LD    (NAMECT),A    ; Put it back
  1346.     JP    NZ,TNLP        ; Loop until zero
  1347.     LD    (FSTFLG),A    ; Done with first time flag, reinitialize it
  1348.     LD    HL,NAMBUF    ; Save start of buffer
  1349.     LD    (NBSAVE),HL
  1350.  
  1351.     LD    A,(FILCNT)    ; Get total files
  1352.     LD    (SHOCNT),A
  1353.     OR    A        ; Were there any?
  1354.     JR    NZ,NXTNM1    ; Yes
  1355.     CALL    ILPRT
  1356.     DB    CR,LF,0
  1357.     JP    NOFILE        ; No
  1358.  
  1359. NXTNM1:    CALL    ILPRTB
  1360.     DB    CR
  1361.     DB    'Number of files found    > ',0
  1362.     LD    A,(SHOCNT)
  1363.     LD    L,A
  1364.     LD    H,0
  1365.     CALL    DECOUT        ; Show number of files found
  1366.     LD    HL,(TOTREC)
  1367.     LD    (RCNT),HL
  1368.     LD    A,1
  1369.     LD    (SBSHOW),A    ; Get's us back early
  1370.     CALL    OPNOK2        ; Go show total file stats
  1371.     XOR    A
  1372.     LD    (SBSHOW),A
  1373.  
  1374. SBTCH1:    LD    A,(FILCNT)    ; Get the count of files to send
  1375.     OR    A        ; Is there any?
  1376.     JP    Z,SNDFN        ; No
  1377.     LD    A,(FSTFLG)    ; Past first batch file yet?
  1378.     LD    (CONONL),A    ; Toggle to local display only
  1379.     OR    A
  1380.     CALL    NZ,CLEARIT    ; Else show local
  1381.     CALL    ILPRT
  1382.     DB    CR,LF,LF
  1383.     DB    'Total transfer time      > ',0
  1384.     CALL    GETSPD        ; Get speed indicator
  1385.     CP    1        ; Are we at 300 bps?
  1386.     LD    HL,XTABLE    ; This gives us 128-byte transfer time
  1387.     JR    Z,$+5        ; Yes, skip next line, show 128-byte time
  1388.     LD    HL,KTABLE    ; This gives us 1k transfer time
  1389.     LD    D,0
  1390.     LD    E,A        ; Set up for table access
  1391.     ADD    HL,DE        ; Index to proper factor
  1392.     ADD    HL,DE
  1393.     LD    E,(HL)
  1394.     INC    HL
  1395.     LD    D,(HL)
  1396.     LD    HL,(TOTREC)    ; Get number of records
  1397.     CALL    FILTM1
  1398.     CALL    XFRTIM        ; Check for time restrictions
  1399.     CALL    ILPRT
  1400.     DB    CR,LF,0
  1401.     LD    A,(FSTFLG)
  1402.     OR    A
  1403.     CALL    Z,DLRDY
  1404.  
  1405. ;
  1406. ; Send the batch filename to remote
  1407. ;
  1408. SNDFN:    CALL    CKABORT        ; Check for remote abort
  1409.     LD    HL,FCB
  1410.     CALL    INITFCB        ; Initialize FCB
  1411.     XOR    A
  1412.     LD    (ERRCNT),A    ; Reset the error count
  1413.     INC    A
  1414.     LD    (CONONL),A    ; Set to local display only
  1415.     LD    A,(FILCNT)    ; Get file count
  1416.     OR    A
  1417.     JP    Z,CCHECK    ; No more files, exit
  1418.     LD    A,1
  1419.     LD    (CRCFLG),A    ; Make sure in CRC mode
  1420.  
  1421.     LD    A,0FFH
  1422.     CALL    RECAR1        ; Get the current user area
  1423.     LD    B,A        ; Save current user area
  1424.     PUSH    BC        ; On stack
  1425.     LD    HL,(NBSAVE)    ; Get start of filename
  1426.     LD    BC,14        ; Offset to user area
  1427.     ADD    HL,BC        ; Point to binary user area
  1428.     LD    A,(HL)        ; Get it
  1429.     POP    BC        ; Get current user area back
  1430.     CP    B        ; Same?
  1431.     CALL    NZ,RECAR1    ; No, but it is now
  1432.     CALL    SPCDRV        ; Get disk parameter block info
  1433.  
  1434.     LD    HL,(NBSAVE)    ; Get address of next batch filename
  1435.     INC    (HL)        ; Escape default situation in FCB drive byte
  1436.     LD    DE,FCB        ; Where to put it
  1437.     LD    BC,12        ; 12 bytes for drive and filename
  1438.     LDIR            ; Move
  1439.     LD    BC,4        ; Next filename is 4 bytes away
  1440.     ADD    HL,BC        ; Add offset
  1441.     LD    (NBSAVE),HL    ; Store address for next filename
  1442.     LD    HL,(RECPTR)    ; Where to load the 0 block
  1443.     EX    DE,HL        ; Put into DE
  1444.     LD    HL,FCB+1    ; Get the start of the filename in HL
  1445.     LD    B,8
  1446.  
  1447. SZMD1:    LD    A,(HL)
  1448.     AND    7FH        ; Strip any high bit set
  1449.     OR    A
  1450.     JR    Z,SZMD6        ; Null pathname
  1451.     CP    ' '
  1452.     JR    Z,SZMD3
  1453.  
  1454. SZMD2:    CALL    LCASE        ; Put file name in lower case for UNIX
  1455.     LD    (DE),A
  1456.     INC    HL
  1457.     INC    DE
  1458.     DJNZ    SZMD1
  1459.     JR    SZMD4
  1460.  
  1461. SZMD3:    INC    HL        ; Skip over spaces if short name
  1462.     DJNZ    SZMD3
  1463.  
  1464. SZMD4:    LD    A,(HL)
  1465.     CP    ' '
  1466.     JR    Z,SZMD6        ; Missing file type field
  1467.     LD    A,'.'        ; Send name-type seperator
  1468.     LD    (DE),A
  1469.     INC    DE
  1470.     LD    B,3
  1471.  
  1472. SZMD5:    LD    A,(HL)
  1473.     AND    7FH        ; Strip any high bit set
  1474.     CP    ' '
  1475.     JR    Z,SZMD6
  1476.     CALL    LCASE        ; Put in lower case for UNIX
  1477.     LD    (DE),A
  1478.     INC    HL
  1479.     INC    DE
  1480.     DJNZ    SZMD5
  1481.  
  1482. SZMD6:    EX    DE,HL        ; Get the address back to HL
  1483.     LD    (HL),0
  1484.     INC    HL
  1485.     LD    (HDRADR),HL
  1486.     CALL    CNREC        ; Get number of records in this file
  1487.     CALL    CHARLN        ; Include the ASCII character length
  1488.  
  1489. SZMD7:    LD    (HL),0        ; Fill rest with zeroes
  1490.     INC    L        ; Pad to end of block with binary 0
  1491.     JR    NZ,SZMD7
  1492.     LD    HL,(RCNT)
  1493.     LD    (BUFSTR),HL    ; Store the file length at end of block
  1494.     XOR    A        ; Make sure the header starts with Zero
  1495.     LD    (RCDCNT),A
  1496.  
  1497. ;
  1498. ; Wait for 'C' from remote to indicate he is ready
  1499. ;
  1500. CCHECK:    LD    E,60        ; Wait up to 60 seconds to abort
  1501.  
  1502. CCHECK1:CALL    CKABORT        ; Manually requesting an abort?
  1503.     LD    B,3
  1504.     CALL    RECV        ; Wait up to 5 seconds for a character
  1505.     JR    C,CCHECK2    ; No character, decrement counter
  1506.     CP    CANCEL        ; If they sent a CTL-X, abort now
  1507.     CALL    Z,CKCAN
  1508.     CP    CRC        ; If they sent a CRC, go to work
  1509.     JR    Z,SZMD8
  1510.     JR    CCHECK        ; None of these, wait some more
  1511.  
  1512. CCHECK2:DEC    E        ; One less to go
  1513.     JR    NZ,CCHECK1
  1514.     JP    ACKMSG        ; Abort if timed out and no character
  1515.  
  1516. SZMD8:    LD    A,(FILCNT)    ; Any files to send?
  1517.     OR    A
  1518.     JR    NZ,SZMD9    ; Yes, continue
  1519.     XOR    A        ; Reset the pointers
  1520.     LD    (ACKCHK),A    ; Reset flag for normal GTACK use
  1521.     LD    (RCDCNT),A    ; Reset the record counter
  1522.     LD    (KFLG),A    ; Show in 128 size now
  1523.     LD    HL,(RECPTR)
  1524.     LD    (HL),A        ; Reset record pointer
  1525.     LD    A,SOH        ; Send a start of header
  1526.     CALL    SEND
  1527.     CALL    SNDHNM        ; This header is a zero count
  1528.     CALL    SNDREC        ; Send an empty record
  1529.     CALL    SNDCRC        ; Send the CRC for the empty record
  1530.     LD    A,(GOTONE)    ; Did we actually send at least one?
  1531.     OR    A
  1532.     JP    Z,ABORT        ; If not, don't act like we did
  1533.     CALL    EOFSND        ; No more files so send EOT to finish
  1534.     CALL    XFRDON
  1535.     JP    EXIT
  1536.  
  1537. ;
  1538. ; Now send the 128 byte filename record
  1539. ;
  1540. SZMD9:    DEC    A        ; Decrement file count for this one
  1541.     LD    (FILCNT),A    ; Store it
  1542.  
  1543. SZMD10:    XOR    A
  1544.     LD    (KFLG),A
  1545.     LD    A,SOH        ; Send SOH
  1546.     LD    (ACKCHK),A
  1547.     CALL    SEND        ; Send SOH character to the modem
  1548.     CALL    SNDHNM        ; Send header (record number, inverse)
  1549.     CALL    SNDREC        ; Send a 128 byte record
  1550.     CALL    SNDCRC        ; Send a two byte CRC
  1551.     CALL    GTACK
  1552.     CP    ACK
  1553.     JR    NZ,SZMD10    ; Not an ACK, send it again
  1554.     XOR    A
  1555.     LD    (ACKCHK),A    ; Reset flag for normal GTACK use
  1556.     CALL    LOW41K        ; Check speed being used
  1557.     JR    C,$+7        ; Don't allow 1k blocks if less than MINKSPD
  1558.     LD    A,1
  1559.     LD    (KFLG),A    ; Change to 1k for normal file xfer
  1560.     XOR    A        ; Clear A
  1561.     LD    (ERRCNT),A    ; Start fresh for the main file
  1562.     JP    SNDFL1
  1563.  
  1564. ;
  1565. ; Send EOT.  Get Acknowledgement from remote.  Try up to 4 times then abort.
  1566. ;
  1567. EOFSND:    LD    A,EOT        ; Send an 'EOT'
  1568.     CALL    SEND
  1569.     LD    A,(CHKEOT)    ; Did not get an ACK, try again
  1570.     INC    A
  1571.     LD    (CHKEOT),A    ; Limit number of retries to 4
  1572.     CP    4        ;    (to prevent possible 'lock-up')
  1573.     RET    NC        ; Quit if already sent 4 or more
  1574.     CALL    GTACK        ; Get the ACK
  1575.     CP    ACK
  1576.     JR    NZ,EOFSND    ; Resend if no ACK
  1577.     RET
  1578.  
  1579. ALLDON:    LD    A,(BATCH)    ; In batch mode?
  1580.     OR    A
  1581.     RET    NZ        ; If yes, ignore message
  1582.     CALL    ILPRT        ; (Want to keep this a separate message)
  1583.     DB    CR,LF,0
  1584.  
  1585. XFRDON:    CALL    ILPRTL
  1586.     DB    CR,LF
  1587.     DB    '-- Transfer completed'
  1588.     DB    CR,LF,0
  1589.     RET
  1590.  
  1591. ;
  1592. ;-------------------------------------------------------------------------;
  1593. ; ---->  RCVFL  -  R e c e i v e   f i l e ( s )              |
  1594. ;-------------------------------------------------------------------------;
  1595. ;
  1596. ; The filename specified in ZMD command line is transferred over the phone
  1597. ; from the user's computer to the RCPM system via modem using the 'R'
  1598. ; (receive) option.  The data is sent one record at a time, with headers
  1599. ; and checksums and retransmissions on errors.  'RM' option is disallowed
  1600. ; at time of command tail parsing at beginning of program (MSGFLG cannot
  1601. ; be set unless MSGFIL is enabled).
  1602. ;
  1603. RCVFL:    LD    A,(MSGFLG)    ; Get message file upload flag
  1604.     OR    A        ; Enabled?
  1605.     JR    Z,RCVF2        ; No, skip the rest
  1606.     CALL    WHLCHK        ; Yes, WHEEL byte set?
  1607.     JR    NZ,RCVF1    ; Yes, turn it off and skip access check
  1608.  
  1609.     LD    A,(ACCESS)    ; Checking access restrictions?
  1610.     OR    A
  1611.     JR    Z,RCVF3        ; No
  1612.     LD    A,(AFBYTE)    ; Get access flags byte
  1613.     AND    8        ; Test for write access (bit 3)
  1614.     JP    Z,NOACC        ; Not allowed to write messages
  1615.  
  1616. RCVF1:    XOR    A        ; Clear A
  1617.     LD    HL,(WHEEL)    ; Point to WHEEL byte
  1618.     LD    (HL),A        ; And stuff a 0 to turn WHEEL off
  1619.     JR    RCVF3        ; WHEEL 'was' on, so skip access check
  1620.  
  1621. ;
  1622. ; Check additional receive flags
  1623. ;
  1624. RCVF2:    LD    A,(ACCESS)    ; Checking access restrictions?
  1625.     OR    A
  1626.     JR    Z,RCVF3        ; No
  1627.     CALL    WHLCHK        ; SYSOP online?
  1628.     JR    NZ,RCVF3    ; Yep, skip all this checking
  1629.     LD    A,(PUPFLG)    ; Privileged transfer option request?
  1630.     OR    A
  1631.     LD    A,(AFBYTE)    ; Get access flags byte
  1632.     JR    Z,$+7        ; No
  1633.     AND    80H        ; Test for privileged user access (bit 7)
  1634.     JP    Z,NOACC        ; Not allowed to use "RW" option
  1635.     AND    40H        ; Test for upload access (bit 6)
  1636.     JP    Z,NOACC        ; Not allowed to upload files
  1637.  
  1638. ;
  1639. ; User has the access he asked for
  1640. ;
  1641. RCVF3:    LD    A,(BATCH)    ; Requesting batch mode?
  1642.     OR    A
  1643.     JP    NZ,RBTCH    ; Yes, go do batch stuff first
  1644.     CALL    RCVFL1        ; Find drive/user/filetype permitted
  1645.     LD    IX,FCB
  1646.     CALL    RESTRCT        ; Check restrictions on uploads
  1647.     CALL    CONTIN        ; Display drive/user area
  1648.     CALL    MAKEFIL        ; Open the file, ready to receive
  1649.  
  1650. ;
  1651. ; Receive records until EOT
  1652. ;
  1653. RCVLP:    XOR    A
  1654.     LD    (ERRCNT),A    ; Initialize error count to zero
  1655.     CALL    RCVRECD        ; Receive a record
  1656.     JR    NC,RCVLP1    ; If not EOT, store this record and get next
  1657.     LD    HL,(RECDNO)    ; Get number of records
  1658.     LD    A,H
  1659.     OR    L        ; 0 length file?
  1660.     JP    Z,ABORT        ; Yes, abort and erase file
  1661.     LD    A,(EOTFLG)    ; This the first EOT character?
  1662.     OR    A
  1663.     JP    NZ,RCVEOT    ; No, exit
  1664.     LD    A,NAK
  1665.     LD    (EOTFLG),A    ; Set the flag
  1666.     CALL    SEND        ; Send a NAK
  1667.     JR    RCVLP        ; Go wait another EOT
  1668.  
  1669. ;
  1670. ; Increment record number
  1671. ;
  1672. RCVLP1:    CALL    INCRNO        ; Bump record number, if received ok
  1673.     LD    HL,(RECPTR)    ; Get buffer address
  1674.     LD    DE,128        ; 128 chars/record
  1675.     LD    A,(KFLG)    ; Using 1k blocks?
  1676.     OR    A
  1677.     JR    Z,$+5        ; If not, skip next line
  1678.     LD    DE,1024        ; 1k/record
  1679.     ADD    HL,DE        ; To next buffer
  1680.     LD    (RECPTR),HL    ; Save buffer address
  1681.     LD    A,(KFLG)    ; Using 1k blocks?
  1682.     OR    A
  1683.     LD    A,(RECNBF)    ; Get number of records in buffer
  1684.     JR    Z,$+6        ; If not, skip next 2 lines
  1685.     ADD    A,8        ; Increment it 8 records for 1k
  1686.     JR    $+3        ; Skip next line
  1687.     INC    A        ; Else only 1 record
  1688.     LD    (RECNBF),A    ; Store new record count
  1689.  
  1690. ;
  1691. ; If 16k in buffer, write to disk
  1692. ;
  1693.     LD    C,A        ; Put the record count in C
  1694.     LD    A,(BUFSIZ)    ; Buffer size in A
  1695.     ADD    A,A
  1696.     ADD    A,A
  1697.     ADD    A,A
  1698.     CP    C        ; Is the buffer full, yet?
  1699.     CALL    Z,WRBLOCK    ; No, return
  1700.     CALL    SNDACK        ; Ack the record
  1701.     JP    RCVLP        ; Loop until 'EOF'
  1702.  
  1703. ;
  1704. ; End of transmission received
  1705. ;
  1706. RCVEOT:    CALL    SNDACK        ; ACK the record
  1707.     CALL    WRBLOCK
  1708.     JP    RCVEOT0
  1709.  
  1710. WRBLOCK:LD    A,(RECNBF)    ; Number of records in the buffer
  1711.     OR    A        ; 0 means end of file
  1712.     RET    Z        ; None to write
  1713.     LD    C,A        ; Save count
  1714.     LD    DE,DBUF        ; Point to disk buff
  1715.  
  1716. WRBLOK1:PUSH    HL
  1717.     PUSH    DE
  1718.     PUSH    BC
  1719.     CALL    STDMA        ; Set DMA
  1720.     LD    DE,FCB        ; Then write the block
  1721.     LD    C,WRITE
  1722.     CALL    BDOS
  1723.     POP    BC
  1724.     POP    DE
  1725.     POP    HL
  1726.     OR    A        ; Write error?
  1727.     JR    Z,WRBLOK2    ; No
  1728.     CALL    RSDMA        ; Reset DMA to normal
  1729.     LD    A,CANCEL    ; Cancel
  1730.     CALL    SEND        ; Sender
  1731.     CALL    SEND
  1732.     CALL    SEND
  1733.     CALL    CLOSFIL        ; Kill received file
  1734.     CALL    ILPRTB        ; Exit with msg:
  1735.     DB    CR,LF
  1736.     DB    '-- Write Error: ',0
  1737.     CALL    SHONM3
  1738.     JP    EXIT
  1739.  
  1740. WRBLOK2:LD    HL,128        ; Length of 1 record
  1741.     ADD    HL,DE        ; 'HL'= next buff
  1742.     EX    DE,HL        ; To 'DE' for setdma
  1743.     DEC    C        ; More records?
  1744.     JR    NZ,WRBLOK1    ; Yes, loop
  1745.     XOR    A        ; Get a zero
  1746.     LD    (RECNBF),A    ; Reset number of records
  1747.     LD    HL,DBUF        ; Reset buffer
  1748.     LD    (RECPTR),HL    ; Save buffer address
  1749.     JP    RSDMA
  1750.  
  1751. ;
  1752. ; Write record to log file if LOGCAL is YES
  1753. ;
  1754. RCVEOT0:CALL    CLOSFIL        ; Close the file
  1755.     LD    HL,(RECDNO)    ; Get # of records
  1756.     LD    (RCNT),HL    ; Stuff in RCNT
  1757.     CALL    XTIM        ; Calculate approximate transfer time
  1758.     CALL    STORTM        ; Store time
  1759.     CALL    LOGCALL        ; Log transfer if supposed to
  1760.  
  1761. RCVEOT1:LD    A,(LOGLDS)    ; Counting uploads?
  1762.     OR    A
  1763.     JR    Z,RCVEOT2    ; No
  1764.     LD    A,(PRIVATE)    ; Private upload?
  1765.     OR    A
  1766.     JR    NZ,RCVEOT2    ; Yes, no credit for private uploads
  1767.     LD    IY,(UPLDS)    ; Get Upload Counter
  1768.     INC    (IY)        ; One more upload since log in
  1769.  
  1770. RCVEOT2:CALL    ALLDON        ; If not in BATCH, print transfer complete
  1771.     JP    CRED        ; Credit upload time and ask for descriptions
  1772.  
  1773. ;
  1774. ;-------------------------------------------------------------------------;
  1775. ; R e c e i v e   B a t c h                          |
  1776. ;-------------------------------------------------------------------------;
  1777. ;
  1778. RBTCH:    XOR    A        ; Using batch so reset some flags
  1779.     LD    (FRSTIM),A    ; Needs to be reset for each new file
  1780.     LD    A,(FSTFLG)    ; First batch file?
  1781.     OR    A
  1782.     JR    Z,RBTCH0    ; Yes, give them time to setup
  1783.     LD    A,CRC
  1784.     CALL    SEND        ; In case he's quick like us
  1785.     JP    RBTCH1
  1786.  
  1787. ;
  1788. ; Initial setup only
  1789. ;
  1790. RBTCH0:    CALL    RCVFL1        ; Find drive/user/filetype permitted
  1791.     CALL    CONTIN        ; Display drive/user area
  1792.     LD    HL,NAMBUF
  1793.     LD    (NBSAVE),HL
  1794.     LD    A,1
  1795.     LD    (FSTFLG),A    ; No need to run those routines again
  1796.  
  1797. ;
  1798. ; Get the batch file name and display
  1799. ;
  1800. RBTCH1:    LD    HL,FCB
  1801.     CALL    INITFCB        ; Initialize FCB
  1802.     XOR    A
  1803.     LD    (RCVTRY),A
  1804.     INC    A        ; Set to local display only
  1805.     LD    (CONONL),A
  1806.  
  1807. RBTCH2:    CALL    CKABORT        ; Check for user abort
  1808.     LD    B,5
  1809.     CALL    RECV        ; Wait up to 5 seconds for SOH from remote
  1810.     JR    C,RBTCH3    ; No character, decrement counter
  1811.     CP    CANCEL        ; Was it a CTL-X for cancel?
  1812.     CALL    Z,CKCAN        ; Check for abort
  1813.     CP    SOH
  1814.     JR    Z,RBTCH5    ; Got SOH
  1815.     JR    RBTCH2        ; None of these, wait some more
  1816.  
  1817. RBTCH3:    LD    A,CRC        ; Send a 'C'
  1818.     CALL    SEND
  1819.  
  1820. RBTCH4:    LD    A,(RCVTRY)
  1821.     INC    A
  1822.     LD    (RCVTRY),A
  1823.     CP    20
  1824.     JR    C,RBTCH2
  1825.     JP    ABORT        ; Quit and try to force him to quit also
  1826.  
  1827. RBTCH5:    LD    B,5
  1828.     CALL    RECV        ; Wait up to 5 seconds for sector number
  1829.     JP    C,TOTERR
  1830.     LD    D,A        ; Save sector number in D
  1831.     OR    A        ; Must be a 0 if sending batch
  1832.     JP    NZ,WRGHDR
  1833.     LD    B,5
  1834.     CALL    RECV        ; Wait up to 5 seconds for reciprocal
  1835.     JP    C,TOTERR
  1836.     CPL            ; Invert it and compare to sector #
  1837.     CP    D
  1838.     JP    NZ,CRCERR    ; Bad match
  1839.     LD    HL,0
  1840.     LD    (CRCVAL),HL    ; Clear CRC counter
  1841.     LD    E,128        ; Expecting a 128 character block
  1842.     LD    HL,(RECPTR)    ; Point to the buffer address
  1843.  
  1844. RBTCH6:    LD    B,5
  1845.     CALL    RECV        ; Up to 5 seconds for 128 byte header block
  1846.     JP    C,TOTERR    ; Exit if no character
  1847.     LD    (HL),A        ; Store the character
  1848.     INC    HL        ; Point to next buffer location
  1849.     DEC    E        ; One less to go
  1850.     JR    NZ,RBTCH6 
  1851.     LD    E,2        ; Number of CRC bytes to get
  1852.  
  1853. RBTCH7:    LD    B,5
  1854.     CALL    RECV        ; Up to 5 seconds for CRC bytes
  1855.     JP    C,TOTERR
  1856.     DEC    E        ; Done?
  1857.     JR    NZ,RBTCH7    ; No
  1858.     CALL    CRCCHK        ; Compare CRC received against ours
  1859.     OR    A        ; Ok?
  1860.     JP    NZ,CRCERR    ; No
  1861.     CALL    SNDACK        ; Yes, acknowledge to remote
  1862.  
  1863. ;
  1864. ; Decode pathname into CPM format
  1865. ;
  1866.     LD    DE,FCB+1    ; Where to put it
  1867.     LD    HL,(RECPTR)    ; Where to get it
  1868.     LD    B,8        ; Filename length
  1869.  
  1870. RBTCH8:    LD    A,(HL)        ; Get the character from the buffer
  1871.     OR    A        ; Was it a zero?
  1872.     JR    Z,RBTCH12    ; If yes, all done
  1873.     CP    '.'        ; Was it a delimiter?
  1874.     JR    Z,RBTCH9
  1875.     CALL    UCASE        ; Insure name is in upper case
  1876.     CP    '_'        ; Is it an underline?
  1877.     JR    NZ,$+4        ; No
  1878.     LD    A,'-'        ; Else make it a dash
  1879.     LD    (DE),A        ; Store filename character in FCB
  1880.     INC    DE        ; Increment pointers
  1881.     INC    HL
  1882.     DJNZ    RBTCH8        ; If not 8, keep going
  1883.     LD    A,(HL)        ; Get the character back
  1884.     OR    A        ; We had 8, was there an extent?
  1885.     JR    Z,RBTCH11    ; If zero, was all done
  1886.     JR    RBTCH10        ; Else must be a '.'
  1887.  
  1888. RBTCH9:    LD    A,' '        ; Spaces to make up 8 spaces for name
  1889.     LD    (DE),A        ; Store space character in FCB
  1890.     INC    DE        ; Increment pointers
  1891.     DJNZ    RBTCH9        ; Keep going until in extent area
  1892.  
  1893. RBTCH10:INC    HL        ; Skip the '.' position
  1894.     LD    B,3        ; Extent length
  1895.  
  1896. RBTCH11:LD    A,(HL)        ; Get the character from the buffer
  1897.     OR    A        ; Was it a zero?
  1898.     JR    Z,RBTCH12    ; If yes, all done
  1899.     CALL    UCASE        ; Insure extent is in upper case
  1900.     LD    (DE),A        ; Store extent character
  1901.     INC    DE        ; Increment pointers
  1902.     INC    HL
  1903.     DJNZ    RBTCH11        ; Keep going until finished
  1904.  
  1905. RBTCH12:LD    A,(FCB+1)    ; See if there was any filename at all
  1906.     CP    ' '
  1907.     JP    Z,RBCHDON    ; No, all done, no more files
  1908.     CALL    CLEARIT        ; Clear screen locally if suppose to
  1909.  
  1910. RBTCH13:LD    HL,(BUFSTR)    ; Get the file length, if provided
  1911.     LD    A,H
  1912.     OR    L
  1913.     JR    NZ,$+7        ; If not both zero, length is provided 
  1914.     CALL    SHONM        ; Else show the filename
  1915.     JR    RBTCH14        ; And wait to receive
  1916.     LD    (RCNT),HL    ; Store the file length
  1917.     CALL    OPNOK1        ; Show filename and file sizes
  1918.     CALL    ILPRTL
  1919.     DB    CR,LF
  1920.     DB    'Ymodem transfer time     > ',0
  1921.     CALL    GETSPD        ; Get speed indicator
  1922.     CP    5        ; Are we less than 1200 bps?
  1923.     JR    C,$+7        ; Yes, skip 1k time
  1924.     CALL    KTIM        ; Get 1k transfer time
  1925.     JR    $+5        ; Skip 128 byte transfer time
  1926.     CALL    XTIM        ; Get 128 byte transfer time
  1927.     CALL    XFRTIM        ; Display transfer time
  1928.  
  1929. RBTCH14:CALL    ILPRTL
  1930.     DB    CR,LF,LF,0    ; Finish the filename line
  1931.     XOR    A        ; Reset the carry flag
  1932.     LD    (RCVTRY),A    ; Reset the error counter
  1933.     LD    IX,FCB
  1934.     CALL    RESTRCT        ; Check restrictions on uploads
  1935.     CALL    CHEKFIL        ; Already have a file with that name?
  1936.     CALL    MAKEFIL        ; If not, make it
  1937.     CALL    BCHINR
  1938.     CALL    WAITMSG        ; Display '[ waiting ]' message locally
  1939.     LD    A,CRC
  1940.     CALL    SEND
  1941.     JP    RCVLP        ; Start receiving the file
  1942.  
  1943. RBCHDON:XOR    A        ; Zero the batch mode flag
  1944.     LD    (BATCH),A
  1945.     LD    A,(GOTONE)    ; Were there any files received?
  1946.     OR    A
  1947.     JP    Z,ABORT        ; No, abort
  1948.     CALL    XFRDON        ; Show transmission is finished
  1949.     JP    CRED        ; Ask for descriptions
  1950.  
  1951. CRCERR:    CALL    ILPRTL
  1952.     DB    '-- CRC error'
  1953.     DB    CR,LF,0
  1954.     JP    INCERR
  1955.  
  1956. WRGHDR:    CALL    ILPRTL
  1957.     DB    '-- Wrong header type'
  1958.     DB    CR,LF,0
  1959.     JR    INCERR
  1960.  
  1961. TOTERR:    CALL    ILPRTL
  1962.     DB    '-- Timeout receiving filename'
  1963.     DB    CR,LF,0
  1964.  
  1965. INCERR:    CALL    WAIT1        ; Make sure sender has stopped
  1966.     LD    A,NAK        ; Tell sender it was not successful
  1967.     CALL    SEND
  1968.     LD    A,(RCVTRY)    ; Increment the error counter
  1969.     INC    A
  1970.     LD    (RCVTRY),A
  1971.     CP    33
  1972.     JP    C,RBTCH4    ; Send a NAK and tell him to try again
  1973.     JP    ABORT        ; Else abort
  1974.  
  1975. ;
  1976. ;-------------------------------------------------------------------------;
  1977. ; C r e d i t   R o u t i n e s                          |
  1978. ;-------------------------------------------------------------------------;
  1979. ;
  1980. ; The following credits the caller for the amount of time spent uploading
  1981. ; any non-private files with descriptions.
  1982. ;
  1983. CRED:    LD    A,(BATCH)
  1984.     OR    A
  1985.     JR    NZ,CRED0A
  1986.     LD    E,10        ; Set up for a 30 second wait
  1987.  
  1988. CRED0:    LD    B,3        ; 3 seconds to receive a character
  1989.     CALL    RECV
  1990.     JR    NC,CRED0A    ; Got one, continue
  1991.     CALL    ILPRTB        ; Make sure this goes to modem
  1992.     DB    CR
  1993.     DB    '-- Hit a key'
  1994.     DB    CR,0        ; Let them know we're waiting
  1995.     DEC    E        ; 2 less seconds
  1996.     JR    NZ,CRED0    ; Wait until 0
  1997.  
  1998. CRED0A:    LD    A,(CREDIT)    ; Credit caller with upload time?
  1999.     OR    A
  2000.     JP    Z,CRED2        ; No
  2001.     CALL    WHLCHK        ; WHEEL byte set?
  2002.     JP    NZ,CRED2    ; Yes, skip credit
  2003.     LD    A,(PUPFLG)    ; Privileged transfer request?
  2004.     OR    A
  2005.     JP    NZ,CRED2    ; Yes, skip credit
  2006.     LD    A,(PRIVATE)    ; Was this a private file?
  2007.     OR    A
  2008.     JP    NZ,CRED2    ; Yes, skip credit
  2009.     LD    A,(BATCH)    ; In batch mode now?
  2010.     OR    A
  2011.     JP    NZ,CRED1    ; If yes, skip following messages
  2012.  
  2013.     CALL    ILPRTB        ; Show to remote also
  2014.     DB    CR,LF
  2015.     DB    'Thanks for the ',0
  2016.     CALL    SHOCAT        ; Show upload area descriptor, if supposed to
  2017.     CALL    ILPRTB
  2018.     DB    'upload(s)!',CR,LF,0
  2019.     CALL    ILPRTB
  2020.     DB    'Upload time has been credited to time left.',0
  2021.  
  2022. CRED1:    LD    A,(MAXTOS)    ; Get maximum time allowed
  2023.     OR    A        ; Unlimited?
  2024.     JR    Z,CRED2        ; Yes, skip credit
  2025.     LD    HL,(RECDNO)    ; Else get the number of records
  2026.     LD    (RCNT),HL 
  2027.     CALL    XTIM        ; Get transfer time in C
  2028.     LD    A,(MAXTOS)    ; Get maximum time allowed back
  2029.     INC    A        ; Increment to next full minute
  2030.     ADD    A,C        ; Add upload time
  2031.     LD    (MAXTOS),A    ; Save for internal use
  2032.  
  2033. ;
  2034. ; If not still in BATCH mode, ask for file description
  2035. ;
  2036. CRED2:    LD    A,(BATCH)    ; Still in batch?
  2037.     OR    A
  2038.     JP    NZ,DONE        ; Yes, see if anymore files left
  2039.     LD    A,(HIDEIT)    ; Did we make this upload a $SYS file?
  2040.     OR    A
  2041.     JR    Z,CRED3        ; No, skip all this
  2042.     CALL    WHLCHK        ; Wheel byte set?
  2043.     JR    NZ,CRED3    ; Yes, file not set to $SYS
  2044.     LD    A,(PRIVATE)    ; Was this a private upload?
  2045.     OR    A
  2046.     JR    NZ,CRED3    ; Yes, file not set to $SYS
  2047.     CALL    ILPRTB
  2048.     DB    CR,LF
  2049.     DB    'Uploads remain hidden until cleared by Sysop.',0
  2050.  
  2051. CRED3:    CALL    ILPRTB
  2052.     DB    CR,LF,LF,0
  2053.     CALL    RSTLCK        ; Clear WRTLOC before descriptions
  2054.     CALL    ADDTON        ; Update BYE's time on byte if supposed to
  2055.  
  2056. ;
  2057. ;-------------------------------------------------------------------------;
  2058. ; D e s c r i p t i o n   R o u t i n e s                  |
  2059. ;-------------------------------------------------------------------------;
  2060.  
  2061. ASK:    LD    A,(PRIVATE)    ; Private upload?
  2062.     OR    A
  2063.     JP    NZ,EXIT        ; Yes, no descriptions
  2064.     LD    A,(PUPFLG)    ; Privileged transfer request?
  2065.     OR    A
  2066.     JP    NZ,EXIT        ; Yes, no descriptions
  2067.     LD    A,(DESCRIB)    ; Requiring descriptions?
  2068.     OR    A
  2069.     JR    NZ,ASK1        ; Yes
  2070.  
  2071.     LD    A,(MSGDESC)    ; To BBS message base?
  2072.     OR    A
  2073.     JP    Z,EXIT        ; No
  2074.     LD    (DSCFLG),A    ; Set flag to show message base descriptions
  2075.     LD    A,(PRUSR)    ; Get the private user
  2076.     LD    (USER),A    ; FOR destination
  2077.     LD    A,(PRDRV)    ; Get the private drive
  2078.     LD    (DRIVE),A    ; FOR destination
  2079.  
  2080. ASK1:    CALL    GETTIME
  2081.     LD    HL,DATMSG+6
  2082.  
  2083.     LD    A,(EDATE)    ; European date format?
  2084.     OR    A
  2085.     JR    Z,ASK1A        ; No
  2086.     LD    A,(DAY)
  2087.     CALL    DATDEC        ; Print DD
  2088.     INC    HL
  2089.     LD    A,(MONTH)    ; Print MM
  2090.     JR    ASK1B        ; And finish with YY
  2091.  
  2092. ASK1A:    LD    A,(MONTH)
  2093.     CALL    DATDEC        ; Print MM
  2094.     INC    HL
  2095.     LD    A,(DAY)
  2096.  
  2097. ASK1B:    CALL    DATDEC        ; Print DD
  2098.     INC    HL
  2099.     LD    A,(YEAR)
  2100.     CALL    DATDEC        ; Print YY
  2101.  
  2102.     LD    A,(FILCNT)    ; Any batch filenames?
  2103.     OR    A
  2104.     JR    Z,ASK3        ; No
  2105.     LD    HL,NAMBUF    ; Point to name buffer
  2106.     LD    (NBSAVE),HL
  2107.  
  2108. ASK2:    LD    IY,FILCNT    ; One less file to describe
  2109.     DEC    (IY)
  2110.     LD    HL,(NBSAVE)    ; Get address of next batch filename
  2111.     LD    DE,FCB        ; Where to put it
  2112.     LD    BC,12
  2113.     LDIR
  2114.     LD    (NBSAVE),HL    ; Store address for next filename
  2115.  
  2116. ASK3:    LD    A,(DESCRIB)    ; FOR file descriptions?
  2117.     OR    A
  2118.     JR    Z,ASK6        ; No
  2119.  
  2120.     LD    A,(ASKAREA)    ; Using upload routing?
  2121.     OR    A
  2122.     JR    Z,ASK4        ; No, KIND contents doesn't matter
  2123.  
  2124.     LD    A,(KIND)    ; Do we have a the upload area yet?
  2125.     OR    A
  2126.     JR    NZ,ASK6        ; Yes, don't ask them twice
  2127.  
  2128.     CALL    ILPRTB
  2129.     DB    CR,LF,LF
  2130.     DB    'Upload category: '
  2131.     DB    CR,LF,0
  2132.     JR    ASK5
  2133.  
  2134. ASK4:    LD    A,(ASKIND)    ; Need file descriptors for FOR entries?
  2135.     OR    A
  2136.     JR    Z,ASK6        ; No
  2137.  
  2138.     CALL    ILPRTB
  2139.     DB    CR,LF,LF,0
  2140.     CALL    SHONM3        ; Show the file name
  2141.  
  2142.     CALL    ILPRTB
  2143.     DB    ' - this file is for:'
  2144.     DB    CR,LF,0
  2145.  
  2146. ASK5:    CALL    GETKIND        ; Get file category for description header
  2147.     CALL    TYPE        ; Output to both consoles
  2148.  
  2149. ASK6:    CALL    ILPRTB
  2150.     DB    CR
  2151.     DB    'Describe ',0
  2152.     CALL    SHONM3        ; Show the filename
  2153.     CALL    ILPRTB
  2154.     DB    ' - 7 lines or less - ^W disables WRAP - CR when done',0
  2155.  
  2156.     LD    HL,FCB+1    ; FCB contains current filename
  2157.     LD    DE,NEWNAM    ; Needed in here for description routines
  2158.     LD    B,8        ; Filename is up to 8 bytes long
  2159.     CALL    ASK7        ; Go store it until a space
  2160.  
  2161.     LD    A,'.'
  2162.     LD    (DE),A        ; Add seperator
  2163.  
  2164.     INC    DE
  2165.     LD    HL,FCB+9    ; Point to file extent at FCB
  2166.     LD    B,3        ; File extent is up to 3 bytes long
  2167.     CALL    ASK7        ; Go store until space or B=3
  2168.  
  2169.     LD    A,LF        ; Stuff Terminator
  2170.     LD    (DE),A
  2171.  
  2172.     CALL    GETDSC        ; Show typing guide and get upload description
  2173.     JP    Z,ASK2        ; If we got a description, get next
  2174.     JP    ASK3        ; Else get this one over again
  2175.  
  2176. ;
  2177. ; Small subroutine to store the filename located at FCB+1 into buffer area
  2178. ; located at DE
  2179. ;
  2180. ASK7:    LD    A,(HL)        ; Get character
  2181.     AND    7FH        ; Done with high bits
  2182.     CP    ' '        ; A space?
  2183.     RET    Z        ; Yes, all done
  2184.     LD    (DE),A        ; Else store it in destination
  2185.     INC    HL        ; Increment source pointer
  2186.     INC    DE        ; Increment destination
  2187.     DJNZ    ASK7        ; Keep looping until B=0 or (HL)=' '
  2188.     RET
  2189.  
  2190. ;
  2191. ;-----------------------
  2192. ; Set upload drive/user
  2193. ;
  2194. RCVFL1:    CALL    LOGDU        ; Select drive/user for upload
  2195.     LD    A,(PUPFLG)    ; Place "RW" file as needed
  2196.     OR    A        ; Can only be set if user is privileged
  2197.     JR    NZ,RCVFL2    ; Privileged, else check if sysop...
  2198.     CALL    WHLCHK        ; Let WHEEL user put file wherever he wants
  2199.     JR    Z,RCVFL6    ; If WHEEL byte not set, stay normal
  2200.  
  2201. RCVFL2:    LD    A,(RCVDRV)
  2202.     OR    A
  2203.     JR    Z,RCVFL3
  2204.     SUB    'A'        ; Convert ASCII drive to binary
  2205.     JR    RCVFL4
  2206.  
  2207. RCVFL3:    LD    A,(OLDDRV)
  2208.  
  2209. RCVFL4:    INC    A
  2210.     LD    (FCB),A
  2211.     ADD    A,'A'-1        ; Convert binary to ASCII
  2212.     LD    (DRV),A        ; Drive
  2213.     LD    A,(RCVDRV)    ; See if a drive was requested
  2214.     OR    A
  2215.     LD    A,(OLDUSR)    ; Current user
  2216.     JR    Z,RCVFL5    ; If not, use current user
  2217.     LD    A,(RCVUSR)    ; Else get requested user
  2218.  
  2219. RCVFL5:    LD    (USR),A        ; User
  2220.     RET
  2221.  
  2222. RCVFL6:    LD    A,(SETAREA)
  2223.     OR    A
  2224.     JR    NZ,RCVFL7
  2225.     LD    A,(ASKAREA)
  2226.     OR    A
  2227.     JR    Z,RCVFL8
  2228.  
  2229. RCVFL7:    LD    A,(DRV)
  2230.     SUB    40H
  2231.     LD    (FCB),A
  2232.  
  2233. RCVFL8:    LD    A,(PRIVATE)    ; Receiving to a private area?
  2234.     OR    A
  2235.     RET    Z        ; If not, exit
  2236.     LD    A,(PRDRV)    ; Private area takes precedence
  2237.     SUB    40H        ; Convert to binary
  2238.     LD    (FCB),A        ; Store drive to be used
  2239.     RET
  2240.  
  2241. ;
  2242. ; Display where file(s) will go, open file and display name
  2243. ;
  2244. CONTIN:    LD    A,(ASKAREA)    ; Upload routing enabled?
  2245.     OR    A
  2246.     JR    NZ,CONT0    ; No
  2247.     LD    A,(ASKIND)
  2248.     OR    A
  2249.     JR    Z,CONT1
  2250.  
  2251. CONT0:    CALL    WHLCHK        ; Is WHEEL byte set?
  2252.     JR    NZ,CONT1    ; No, skip this
  2253.     CALL    GETKIND        ; Get upload area
  2254.     LD    A,CR        ; So the line feed (LF) doesn't get printed
  2255.     LD    (CONT1+4),A
  2256.  
  2257. CONT1:    CALL    ILPRTB
  2258.     DB    CR,LF
  2259.     DB    'Receiving on:  Drive ',0
  2260.     LD    A,(PRIVATE)    ; Private upload?
  2261.     OR    A
  2262.     LD    A,(PRUSR)    ; Get private user area
  2263.     LD    B,A        ; Put in B for now
  2264.     LD    A,(PRDRV)    ; Get private drive
  2265.     JR    NZ,CONT2+3    ; Yes, priority 1
  2266.     LD    A,(USR)        ; Get the regular user area
  2267.     LD    B,A        ; And put it in B
  2268.     LD    A,(PUPFLG)    ; Privileged upload?
  2269.     OR    A
  2270.     JR    NZ,CONT2    ; Yes, priority 2
  2271.     CALL    WHLCHK        ; WHEEL set?
  2272.     JR    NZ,CONT2    ; Yes, priority 3
  2273.     LD    A,(SETAREA)    ; Uploading to designated drive/user?
  2274.     OR    A
  2275.     JR    NZ,CONT2    ; Yes, priority 4
  2276.     LD    A,(ASKAREA)    ; Upload routing enabled?
  2277.     OR    A
  2278.     JR    Z,CONT3        ; No
  2279.  
  2280. CONT2:    LD    A,(DRV)        ; Get regular upload drive
  2281.     PUSH    AF        ; Save ASCII upload drive
  2282.     SUB    40H        ; Convert drive to binary
  2283.     LD    (FCB),A        ; Store it in File Control Block
  2284.     POP    AF        ; Get ASCII drive back
  2285.     JR    CONT4        ; All done, now display it
  2286.  
  2287. CONT3:    LD    A,(OLDUSR)    ; Get current user area for default
  2288.     LD    B,A        ; Save in B
  2289.     DB    0,0        ; Contains 'LD B,n' (DUU) from GETDU
  2290.     LD    A,(OLDDRV)    ; Get current drive for default
  2291.     ADD    A,'A'        ; Convert to ASCII
  2292.     DB    0,0        ; Contains 'LD A,n' (DUD) from GETDU
  2293.  
  2294. CONT4:    LD    (KDRV),A    ; Save it for KSHOW
  2295.     CALL    TYPE        ; Print the drive to store on
  2296.     CALL    ILPRTB
  2297.     DB    ', User ',0
  2298.     LD    A,B        ; B contains the user area
  2299.     LD    (USR),A        ; Save for MSGDESC upload info
  2300.     LD    H,0
  2301.     LD    L,A        ; Binary user area in L
  2302.     CALL    DECOUT        ; Decimal output
  2303.     CALL    ILPRTB
  2304.     DB    '.  (',0
  2305.     CALL    KSHOW        ; Show available space remaining
  2306.     CALL    ILPRTB
  2307.     DB    ')',0
  2308.     CALL    CHEKFIL        ; See if file exists
  2309.  
  2310.     LD    A,(DESCRIB)    ; Descriptions enabled?
  2311.     OR    A
  2312.     JR    NZ,CONT5    ; Yes
  2313.     LD    A,(MSGDESC)    ; Message base descriptions?
  2314.     OR    A
  2315.     JR    Z,CONT6        ; No
  2316.  
  2317. CONT5:    LD    A,(PRIVATE)    ; Private upload?
  2318.     OR    A
  2319.     JR    NZ,CONT6    ; Yes, no descriptions
  2320.     LD    A,(PUPFLG)    ; Privileged upload?
  2321.     OR    A
  2322.     JR    NZ,CONT6    ; Yes, no descriptions
  2323.     CALL    ILPRTB
  2324.     DB    CR,LF
  2325.     DB    'Description(s) needed - ',0
  2326.     JR    CONT7
  2327.  
  2328. CONT6:    CALL    ILPRTB
  2329.     DB    CR,LF,0
  2330.  
  2331. CONT7:    CALL    ILPRTB
  2332.     DB    'Abort: ^X pause ^X'
  2333.     DB    CR,LF,LF,0
  2334.     CALL    WAITMSG
  2335.     RET
  2336.  
  2337. ;
  2338. ; Increment the file count
  2339. ;
  2340. BCHINR:    LD    HL,(NBSAVE)    ; Where to put the name
  2341.     LD    DE,FCB        ; Where to get the name
  2342.     EX    DE,HL
  2343.     LD    BC,12        ; Move current filename to buffer for ASK:
  2344.     LDIR
  2345.     EX    DE,HL
  2346.     LD    (NBSAVE),HL    ; Store address for next filename
  2347.     LD    A,(FILCNT)    ; Increment the file count
  2348.     INC    A
  2349.     LD    (FILCNT),A
  2350.     RET
  2351.  
  2352. ;
  2353. ;-------------------------------------------------------------------------;
  2354. ; T r a n s f e r   c o m p l e t e                      |
  2355. ;-------------------------------------------------------------------------;
  2356. ;
  2357. ; Done transferring current file.  Check to see if in BATCH mode and if so,
  2358. ; display filename transferred and reset flags for next possible file.
  2359. ; Otherwise eat garbage from line, reset WRTLOC, do timekeeping and exit
  2360. ; to CP/M (Forward text file to BBS message base if supposed to).
  2361. ;
  2362. DONE:    LD    A,(BATCH)    ; Still in batch mode?
  2363.     OR    A
  2364.     JP    Z,EXIT        ; No.  All done
  2365.     LD    A,(OLDDRV)    ; Restore the original drive
  2366.     CALL    RECDRX
  2367.     LD    A,(OLDUSR)    ; Restore the original number
  2368.     CALL    RECAR1
  2369.     CALL    RSDMA        ; Reset to default DMA address
  2370.     LD    A,1        ; Display filename locally only
  2371.     LD    (GOTONE),A    ; Indicates there was a file handled
  2372.     CALL    ILPRTL        ; Display the file name
  2373.     DB    CR,LF,0
  2374.     CALL    SHONM3        ; Show the filename at FCB+1
  2375.     CALL    ILPRT
  2376.     DB    ' transferred',CR,LF,0
  2377.  
  2378. ;
  2379. ; Now reset some flags for another possible batch file
  2380. ;
  2381.     XOR    A
  2382.     LD    (EOFLG),A    ; Clear end of file flag
  2383.     LD    (EOTFLG),A    ; And end of transmission flag
  2384.     LD    (CHKEOT),A    ; Clear the "resend EOT" flag
  2385.     LD    HL,0
  2386.     LD    (ACCERR),HL    ; Reset the accumulate error count
  2387.     LD    (RECNBF),HL    ; Zero number of records in the buffer
  2388.     LD    (RECDNO),HL    ; Zero the current record number
  2389.     LD    (RCDCNT),HL    ; Zero the transmit record counter
  2390.     LD    HL,DBUF        ; Reset buffer pointers
  2391.     LD    (RECPTR),HL
  2392.     LD    A,(MODE)    ; Get transfer mode
  2393.     CP    'S'        ; Sending files?
  2394.     JP    Z,SNDFIL    ; Yes
  2395.  
  2396.     LD    A,(FILIMT)    ; Maximum upload (TPA limitation)
  2397.     LD    B,A        ; Into B for comparison
  2398.     LD    A,(FILCNT)    ; Get current count received
  2399.     CP    B        ; Received BATCH transfer limit yet?
  2400.     JP    C,RCVFL
  2401.     LD    A,CANCEL
  2402.     CALL    SEND
  2403.     CALL    SEND
  2404.     CALL    SEND
  2405.     CALL    WAIT1
  2406.  
  2407.     CALL    ILPRTB
  2408.     DB    CR,LF
  2409.     DB    '-- ',0
  2410.     LD    A,(FILIMT)
  2411.     LD    H,0
  2412.     LD    L,A
  2413.     CALL    DECOUT
  2414.     CALL    ILPRTB
  2415.     DB    ' file limit in BATCH receive',CR,LF,0
  2416.  
  2417.     XOR    A
  2418.     LD    (BATCH),A    ; Reset the batch mode flag to zero
  2419.     JP    CRED3        ; Go back and ask for descriptions
  2420.  
  2421. ;
  2422. ;-------------------------------------------------------------------------;
  2423. ; C o m m o n  S u b r o u t i n e s                      |
  2424. ;-------------------------------------------------------------------------;
  2425. ;
  2426. ; Universal access check routine checks restrictions of current file being
  2427. ; considered for transfer.
  2428. ;
  2429. ; On entry:  IX  = start address of byte before filename
  2430. ; On exit:    Z  = File ok to send/receive
  2431. ;         NZ     = Transfer denied
  2432. ;
  2433. ; Each bit of this word contains an image of the high bit within the filename
  2434. ; pointed to by IX+1 on entry.
  2435. HBITMAP:DW    0000000000000000B
  2436.  
  2437. ;
  2438. ; First, make a bit map containing an image of the high bits in the filename
  2439. ; pointed to by IX+1 on entry.
  2440. ;
  2441. RESTRCT:LD    B,11        ; Number of bytes to map
  2442.     LD    HL,0        ; Initialize destination for bit map
  2443.     PUSH    IX        ; Save current filename address
  2444.     INC    IX        ; Skip past drive indicator
  2445.  
  2446. ACCMASK:LD    A,(IX)        ; Get next character of filename
  2447.     AND    80H        ; Isolate attribute bit
  2448.     RLCA            ; Move MS bit into LS bit
  2449.     OR    L        ; OR in any previously set bits
  2450.     LD    L,A        ; Save result
  2451.     ADD    HL,HL        ; Shift HL left one bit for next time
  2452.     INC    IX        ; IY+1 equals next character in filename-type
  2453.     DJNZ    ACCMASK        ; Loop through all 11 bytes
  2454.     POP    IX        ; Get our original filename pointer back
  2455.  
  2456. ;
  2457. ; Most significant bit will already be in bit 11 of HL, so only 4 shifts are
  2458. ; necessary
  2459. ;
  2460.     ADD    HL,HL        ; 000?????$??????00
  2461.     ADD    HL,HL        ; 00??????$?????000
  2462.     ADD    HL,HL        ; 0???????$????0000
  2463.     ADD    HL,HL        ; ????????$???00000
  2464.     LD    (HBITMAP),HL    ; Store filename high bit image
  2465.  
  2466. ;
  2467. ; See which (if any) restrictions we need to enforce
  2468. ;
  2469.     CALL    WHLCHK        ; WHEEL byte set?
  2470.     JP    NZ,SENDOK    ; Yes, transfer is approved
  2471.     LD    A,(ACCMAP)    ; Get user defined restriction flags
  2472.     LD    B,A
  2473.     LD    A,(MODE)    ; Get the file transfer mode
  2474.     CP    'S'        ; Sending?
  2475.     JR    Z,RSTRCT2    ; Yes, check send restrictions
  2476.  
  2477. ;
  2478. ; Check RECEIVE restrictions
  2479. ;
  2480.     LD    IX,FCB
  2481.     BIT    NOCOMR,B    ; Rename '.COM' uploads to '.OBJ'?
  2482.     JR    Z,RSTRCT1    ; No, check for ZCPR restrictions
  2483.     LD    DE,COMCHG    ; Compare to 'COM'
  2484.     CALL    MCHFTYP        ; Are they the same?
  2485.     CALL    Z,RENTYP    ; Yes, rename it to 'OBJ'
  2486.  
  2487. RSTRCT1:BIT    ZCPR,B        ; Using with ZCPR?
  2488.     RET    Z        ; No, all done
  2489.     LD    DE,SYSCHK    ; Compare to 'SYS'
  2490.     CALL    MCHFTYP        ; Are they the same?
  2491.     JR    Z,FTYPERR    ; Yes, tell them to use a different filetype
  2492.     LD    DE,NDRCHK    ; Compare to 'NDR'
  2493.     CALL    MCHFTYP        ; ...
  2494.     JR    Z,FTYPERR    ; ...
  2495.     LD    DE,RCPCHK    ; Compare to 'RCP'
  2496.     CALL    MCHFTYP        ; ...
  2497.     RET    NZ        ; If no match, filetype is ok to receive
  2498.  
  2499. FTYPERR:CALL    ERXIT
  2500.     DB    CR,LF
  2501.     DB    '-- Use a different file extent','$'
  2502.  
  2503. ;
  2504. ; Check SEND restrictions
  2505. ;
  2506. RSTRCT2:LD    A,(BATCH)    ; In BATCH?
  2507.     OR    A
  2508.     JR    NZ,RSTRT2A    ; Yes, require send access for any batch file
  2509.     BIT    DWNTAG,B    ; Allow F3 tagged file regardless of access?
  2510.     JR    Z,RSTRT2A    ; No, skip this
  2511.     BIT    5,H        ; Byte 3 of filename set?
  2512.     JP    NZ,SENDOK    ; Yes, send it immediately
  2513.  
  2514. RSTRT2A:LD    A,(ACCESS)
  2515.     OR    A
  2516.     JR    Z,RSTRCT3
  2517.     LD    A,(AFBYTE)    ; Get BYE or BBS bit mapped access flag
  2518.     AND    20H        ; Download access allowed?
  2519.     JP    Z,NOACC        ; No, inform user of restricted function
  2520.  
  2521. RSTRCT3:LD    A,(LBRARC)    ; Get member extraction flag
  2522.     OR    A        ; Enabled?
  2523.     JR    NZ,RSTRCT4    ; Yes, skip these restrictions
  2524.     BIT    TAGFIL,B    ; Restricting tagged files?
  2525.     JR    Z,RSTRCT4    ; No
  2526.     BIT    7,H        ; First byte of filename set?
  2527.     JR    NZ,NOSEND    ; Yes, can't send it
  2528.  
  2529. RSTRCT4:BIT    NOSYS,B        ; Restricting $SYS files?
  2530.     JR    Z,RSTRCT5    ; No
  2531.     BIT    6,L        ; First byte of filetype set?
  2532.     JR    NZ,NOSEND    ; Yes, can't send
  2533.  
  2534. RSTRCT5:LD    A,(LBRARC)    ; Get member extraction flag
  2535.     OR    A        ; Enabled?
  2536.     RET    NZ        ; Yes, and file was not tagged (returning NZ)
  2537.     BIT    NOLBS,B        ; Restricting files with labels (#)?
  2538.     JR    Z,RSTRCT6    ; No
  2539.     LD    A,(IX+11)    ; Get possible label
  2540.     AND    7FH        ; Strip the high bit
  2541.     CP    '#'        ; Labeled?
  2542.     JR    Z,NOSEND    ; Yes, can't send
  2543.  
  2544. RSTRCT6:BIT    NOCOMS,B    ; Allow sending 'COM' files?
  2545.     JP    Z,SENDOK    ; Yes
  2546.     LD    DE,COMCHG    ; Point to string to compare with
  2547.     CALL    MCHFTYP        ; Is it a .COM file?
  2548.     JP    NZ,SENDOK    ; No
  2549.  
  2550. ;
  2551. ; Common exit point
  2552. COMTRY:    LD    A,(BATCH)    ; In batch mode?
  2553.     OR    A
  2554.     JP    NZ,NOSND2    ; Yes, just set flag to not include (NZ)
  2555.     POP    HL        ; Remove call from OPNOK from stack
  2556.     CALL    ERXIT
  2557.     DB    CR,LF
  2558.     DB    '-- Can''t send .COM files','$'
  2559.  
  2560. NOSEND:    LD    A,(BATCH)    ; Are we in batch mode?
  2561.     OR    A
  2562.     JP    NZ,NOSND2    ; Yes, no error messages, just checking
  2563.     LD    DE,LBRNAM
  2564.     CALL    NOSND0
  2565.     JR    Z,NOSND1
  2566.     LD    DE,ARKNAM
  2567.     CALL    NOSND0
  2568.     JR    Z,NOSND1
  2569.     LD    DE,ARCNAM
  2570.     CALL    NOSND0
  2571.     JR    Z,NOSND1
  2572.     CALL    ERXIT
  2573.     DB    CR,LF
  2574.     DB    '-- File is not for distribution','$'
  2575.  
  2576. NOSND0:    LD    B,3
  2577.     LD    HL,FCB+9
  2578.     CALL    MATCH
  2579.     RET
  2580.  
  2581. NOSND1:    CALL    ERXIT
  2582.     DB    CR,LF
  2583.     DB    '-- Individual members only','$'
  2584.  
  2585. NOSND2:    LD    A,1        ; Return NZ if file not allowed
  2586.     OR    A
  2587.     RET
  2588.  
  2589. SENDOK:    XOR    A        ; Return Z if file is ok
  2590.     RET
  2591.  
  2592. ;
  2593. ; See if next character is ' ' or non ' '.  File name error if no ASCII
  2594. ; character.
  2595. ;
  2596. CHKFSP:    LD    A,(BATCH)    ; Requesting batch mode now?
  2597.     OR    A
  2598.     JR    Z,CHKFSP2    ; Exit if not
  2599.     LD    A,(MODE)    ; Sending batch?
  2600.     CP    'S'
  2601.     JR    Z,CHKFSP2    ; If yes, exit
  2602.     DEC    B
  2603.     JR    Z,CHKFSP1
  2604.     INC    B
  2605.     JR    CHKFSP2
  2606.  
  2607. CHKFSP1:POP    HL        ; Do not return to LOGDU
  2608.     RET            ; Return instead to SNDFIL
  2609.  
  2610. CHKFSP2:DEC    B
  2611.     JP    Z,NFN1        ; Error if end of chars.
  2612.     LD    A,(HL)
  2613.     CP    ' '+1
  2614.     RET    NC        ; Ok if valid character so return
  2615.     INC    HL
  2616.     JR    CHKFSP
  2617.  
  2618. ;
  2619. ; Check next character to see if a space or non-space, go to menu if a command
  2620. ; error.
  2621. ;
  2622. CHKSP:    LD    A,(BATCH)    ; Requesting batch mode?
  2623.     OR    A
  2624.     JR    Z,CHKSP2    ; Exit if not
  2625.     LD    A,(MODE)    ; Sending in batch mode now?
  2626.     CP    'S'
  2627.     JR    Z,CHKSP2    ; If yes, exit
  2628.     DEC    B
  2629.     JR    Z,CHKSP1
  2630.     INC    B
  2631.     JR    CHKSP2
  2632.  
  2633. CHKSP1:    POP    HL        ; Don't return to LOGDU
  2634.     RET            ; Return to SNDFIL
  2635.  
  2636. CHKSP2:    DEC    B
  2637.     JP    Z,HELP
  2638.     INC    HL
  2639.     LD    A,(HL)        ; Get the character there
  2640.     CP    ' '        ; Space character?
  2641.     RET            ; Z = space, NZ = non-space
  2642.  
  2643. ;
  2644. ; Determine the amount of disk storage needed for the current file.  On
  2645. ; entry:  BC = total record count of file
  2646. ;
  2647. ROUNDK:    LD    DE,(BLKSIZ)    ; Fetch block size in kilobytes
  2648.     PUSH    DE        ; Save block size
  2649.     PUSH    BC        ; Save file record count
  2650.     LD    B,3        ; Make a mask for size limit
  2651.  
  2652. MSKCMP:    OR    A        ; Clear carry
  2653.     RL    E        ; Make mask for size limit
  2654.     RL    D        ; Shift until
  2655.     DJNZ    MSKCMP        ; Shift until DE is A
  2656.     DEC    DE        ; Mask of records per block
  2657.     POP    BC        ; Get a copy of file record count
  2658.     PUSH    BC
  2659.  
  2660.     LD    A,C        ; Mask file size with block size mask
  2661.     AND    E
  2662.     LD    C,A
  2663.     LD    A,B
  2664.     AND    D
  2665.     OR    C        ; Zero result indicates no block
  2666.     POP    BC
  2667.     PUSH    AF        ; Remainder in file size
  2668.     LD    A,D        ; Compliment mask and zero file size
  2669.     CPL            ; Remainder in BC
  2670.     AND    B
  2671.     LD    B,A
  2672.     LD    A,E
  2673.     CPL
  2674.     AND    C
  2675.     LD    C,A
  2676.     LD    E,3        ; Shift count to divide masked file
  2677.  
  2678. MINKL:    OR    A        ; Clear carry
  2679.     RR    B        ; Rotate high byte through carry
  2680.     RR    C
  2681.     DEC    E        ; Decrement shift count
  2682.     JR    NZ,MINKL
  2683.  
  2684.     POP    AF        ; Check if even block size
  2685.     POP    DE        ; Get back block size
  2686.     PUSH    HL        ; Save kilobyte insert address
  2687.     LD    HL,0        ; Initial zero of remainderI
  2688.     JR    Z,MINKS        ; Zero if even
  2689.     EX    DE,HL        ; Block size to HL if remainder
  2690.  
  2691. MINKS:    ADD    HL,BC        ; Add in total kilobyte count
  2692.     EX    DE,HL        ; Total size to DE
  2693.     POP    HL        ; Get back load address
  2694.     RET
  2695.  
  2696. ;
  2697. ; Log into drive and user
  2698. ;
  2699. ; (If specified).  If none mentioned, falls through to 'TRAP' routine for
  2700. ; normal use.
  2701. ;
  2702. LOGDU:    LD    HL,TBUF        ; Point to default buffer command line
  2703.     LD    B,(HL)        ; Store number of characters in command
  2704.     INC    B        ; Add in current location
  2705.     CALL    CHKSP        ; Skip spaces to find 1st command
  2706.     JR    Z,$-3        ; Loop until non-space character
  2707.     CALL    CHKSP        ; Skip 1st command (non-spaces)
  2708.     JR    NZ,$-3        ; Loop until a space
  2709.     INC    HL
  2710.     CALL    CHKFSP        ; Skip spaces to find 2nd command
  2711.     LD    (SAVEHL),HL    ; Save start address of the 2nd command
  2712.  
  2713. ;
  2714. ; Now pointing to the first byte in the argument.  (If it was of a format
  2715. ; similar to: 'B6:HELLO.DOC' then we point at the drive character 'B'.  Then
  2716. ; transfer up to 4 bytes from the command line buffer (pointed at by HL) to
  2717. ; the drive/user storage buffer pointed at by DE
  2718. ;
  2719. LGDU1:    PUSH    HL        ; Save command line position
  2720.     PUSH    BC        ; And character count
  2721.     LD    DE,DUSAVE    ; Destination buffer
  2722.     LD    C,4        ; Drive/user is 4 characters maximum 'B15:'
  2723.  
  2724. LGDU2:    LD    A,(HL)        ; Get character
  2725.     CP    ' '+1        ; Space or return?
  2726.     JP    C,TRAP        ; Yes, all done
  2727.     LD    (DE),A        ; Else store it in DUSAVE
  2728.     INC    HL        ; Increment to next argument
  2729.     INC    DE        ; Increment DUSAVE
  2730.     CP    ':'        ; Was it a colon?
  2731.     JR    Z,LGDU3        ; Yes, was drive/user requested
  2732.     DEC    B        ; One less position to check
  2733.     DEC    C        ; One less to go
  2734.     JR    NZ,LGDU2    ; Loop until a colon or C=0
  2735.     JP    TRAP        ; Move name to FCB
  2736.  
  2737. ;
  2738. ; Get Disk and User from DUSAVE and log in if valid.
  2739. ;
  2740. LGDU3:    EXX            ; Save HL (buffer) pointer and BC (char count)
  2741.     POP    BC        ; We don't need these back, but fix the stack
  2742.     POP    HL
  2743.     EXX            ; And get HL and BC back to continue
  2744.     LD    A,(BATCH)    ; Requesting batch mode?
  2745.     OR    A
  2746.     JR    Z,LGDU4        ; No
  2747.     LD    A,(MODE)    ; Get program transfer mode
  2748.     CP    'R'        ; Receiving batch?
  2749.     JR    Z,LGDU5        ; Yes, skip next two lines
  2750.  
  2751. LGDU4:    CALL    CHKFSP        ; See if a file name is included
  2752.     LD    (SAVEHL),HL    ; Save location of the filename
  2753.  
  2754. LGDU5:    LD    A,(PRIVATE)    ; Uploading to a private area?
  2755.     OR    A
  2756.     JP    NZ,TRAP2    ; If yes, going to a specified area
  2757.  
  2758.     LD    A,(OLDDRV)    ; Get current drive
  2759.     LD    (DUD),A
  2760.     ADD    A,'A'
  2761.     LD    (RCVDRV),A
  2762.  
  2763.     LD    HL,DUSAVE    ; Point to drive/user
  2764.     LD    A,(HL)        ; Get 1st character
  2765.     CP    '0'        ; It is a ' ', CR or LF?
  2766.     JR    C,LGDU6        ; Yes, skip next 2 lines
  2767.     CP    '9'+1        ; Is it an ASCII number 0-9?
  2768.     JR    C,LGDU10
  2769.  
  2770. LGDU6:    LD    (RCVDRV),A    ; Allows SYSOP to upload to any drive
  2771.     CP    'A'-1
  2772.     JR    C,LGDU9        ; Satisfied with current drive
  2773.     SUB    'A'
  2774.     LD    (DUD),A
  2775.  
  2776.     LD    A,(PUPFLG)    ; Privileged user upload request?
  2777.     OR    A
  2778.     LD    A,(DUD)
  2779.     JR    NZ,LGDU8    ; Yes
  2780.  
  2781.     CALL    WHLCHK
  2782.     LD    A,(DUD)
  2783.     JR    NZ,LGDU8
  2784.  
  2785.     LD    A,(USEMAX)    ; Using ZCPR low memory bytes?
  2786.     OR    A
  2787.     JR    NZ,LGDU7    ; Yes
  2788.     LD    A,(MAXDRV)
  2789.     LD    C,A
  2790.     LD    A,(DUD)
  2791.     CP    C
  2792.     JP    NC,ILLDU    ; Drive selection not available
  2793.     JR    LGDU8
  2794.  
  2795. LGDU7:    LD    A,(DUD)        ; Get the drive back
  2796.     LD    IY,(DRIVMAX)    ; Point to max drive byte
  2797.     INC    (IY)
  2798.     CP    (IY)        ; And check it
  2799.     PUSH    AF        ; Save flags from the CP
  2800.     DEC    (IY)        ; Restore max drive to normal
  2801.     POP    AF        ; Restore flags from the CP
  2802.     JP    NC,ILLDU
  2803.  
  2804. LGDU8:    INC    HL        ; Get 2nd character
  2805.  
  2806. LGDU9:    LD    A,(HL)
  2807.     CP    ':'
  2808.     JP    Z,LGDU17    ; Colon for drive only, no user number
  2809.     CALL    CKNUM        ; Check if numeric
  2810.  
  2811. LGDU10:    SUB    '0'        ; Convert ASCII to binary
  2812.     LD    (DUU),A        ; Save it
  2813.     INC    HL        ; Get 3rd character if any
  2814.     LD    A,(HL)
  2815.     CP    ':'
  2816.     JR    Z,LGDU11
  2817.     LD    A,(DUU)
  2818.     CP    1        ; Is first number a '1'?
  2819.     JP    NZ,ILLDU
  2820.     LD    A,(HL)
  2821.     CALL    CKNUM
  2822.     SUB    38
  2823.     LD    (DUU),A
  2824.     INC    HL        ; Get 4th (and last character) if any
  2825.     LD    A,(HL)
  2826.     CP    ':'
  2827.     JP    NZ,ILLDU
  2828.  
  2829. LGDU11:    LD    A,(MODE)
  2830.     CP    'R'        ; Receiving a file?
  2831.     LD    A,(DUU)
  2832.     JR    Z,LGDU12
  2833.     LD    A,(SPLDRV)
  2834.     SUB    'A'
  2835.     LD    C,A
  2836.     LD    A,(DUD)
  2837.     CP    C
  2838.     JR    NZ,LGDU12
  2839.     LD    A,(SPLUSR)
  2840.     LD    C,A
  2841.     LD    A,(DUU)
  2842.     CP    C
  2843.     JR    Z,LGDU15
  2844.  
  2845. LGDU12:    CALL    WHLCHK        ; SYSOP using the system?
  2846.     JR    Z,LGDU13
  2847.     LD    A,(DUU)        ; Restore desired user area
  2848.     LD    (RCVUSR),A    ; Allows SYSOP to upload anywhere
  2849.     JR    NZ,LGDU15    ; If yes, let him have all user areas
  2850.  
  2851. LGDU13:    LD    A,(USEMAX)    ; Using ZCPR low memory bytes?
  2852.     OR    A
  2853.     JR    NZ,LGDU14    ; Yes
  2854.     LD    A,(MAXUSR)    ; Check for maximum user download area
  2855.     ADD    A,1
  2856.     LD    C,A
  2857.     LD    A,(DUU)
  2858.     CP    C
  2859.     JP    NC,ILLDU    ; Error if more (and not special area)
  2860.     JR    LGDU15
  2861.  
  2862. LGDU14:    LD    A,(DUU)
  2863.     LD    IY,(USRMAX)    ; Point at maximum user byte
  2864.     CP    (IY)        ; And check it
  2865.     JP    NC,ILLDU
  2866.  
  2867. LGDU15:    LD    E,A
  2868.     LD    A,(SETAREA)    ; Using designated drv/usr for reg. uploads?
  2869.     OR    A
  2870.     JR    NZ,LGDU16    ; Yes
  2871.     LD    A,(ASKAREA)    ; Using upload routing?
  2872.     OR    A
  2873.     JR    NZ,LGDU16    ; Yes
  2874.     LD    A,E
  2875.     LD    (CONT3+5),A    ; Store requested user area
  2876.     LD    A,6        ; 'LD B,n' instruction
  2877.     LD    (CONT3+4),A
  2878.  
  2879. LGDU16:    LD    C,SETUSR    ; Set to requested user area
  2880.     CALL    BDOS
  2881.  
  2882. LGDU17:    LD    A,(DUD)        ; Get drive
  2883.     LD    E,A
  2884.     LD    A,(SETAREA)    ; Using designated drv/usr for reg. uploads?
  2885.     OR    A
  2886.     JR    NZ,LGDU18    ; Yes
  2887.     LD    A,(ASKAREA)    ; Using upload routing?
  2888.     OR    A
  2889.     JR    NZ,LGDU18    ; Yes
  2890.     LD    A,E
  2891.     ADD    A,'A'
  2892.     LD    (CONT3+12),A    ; Store requested drive
  2893.     LD    A,3EH        ; 'LD A,n' instruction
  2894.     LD    (CONT3+11),A
  2895.  
  2896. LGDU18:    LD    C,SELDSK    ; Set to requested drive
  2897.     CALL    BDOS
  2898.     JR    TRAP2        ; Now find file selected
  2899.  
  2900. ;
  2901. ; If we get here, no d/u was specified.  Restore original command line pointer
  2902. ; and character count and move name to FCB.
  2903. ;
  2904. TRAP:    POP    BC        ; Get original character count back
  2905.     POP    HL        ; And original command line buffer position
  2906.  
  2907. ;
  2908. ; Check for no file name or ambiguous name
  2909. ;
  2910. TRAP1:    LD    A,(PRIVATE)    ; Get the private transfer flag
  2911.     OR    A        ; Is it enabled?
  2912.     JR    Z,TRAP2        ; No, current du stays normal
  2913.     LD    A,(SPLUSR)    ; Get the special download user area
  2914.     CALL    RECAR1        ; Set user area to special download user
  2915.     LD    A,(SPLDRV)    ; Get the special download drive
  2916.     CALL    RECDR1        ; Set drive to special download drive
  2917.  
  2918. TRAP2:    CALL    SPCDRV        ; Keep DPB info straight
  2919.     LD    HL,FCB
  2920.     CALL    INITFCB        ; Make sure FCB initialized
  2921.     CALL    MOVFCB        ; Move the filename into the file block
  2922.     LD    HL,FCB+1    ; Point to file name
  2923.     LD    A,(HL)        ; Get first character
  2924.     CP    ' '        ; Any there?
  2925.     JR    NZ,TRAP3    ; Yes, check wildcards
  2926.     LD    HL,FCB+9    ; Else point to file extent
  2927.     LD    A,(HL)        ; Get character
  2928.     CP    ' '        ; Space also?
  2929.     JP    Z,NFN        ; Yes, we have no filename, exit with error
  2930.     LD    HL,FCB+1    ; Else point to start again
  2931.  
  2932. TRAP3:    LD    A,(PRIVATE)    ; Get the private transfer flag
  2933.     OR    A        ; Is it enabled?
  2934.     RET    Z        ; No, then don't trap wildcards
  2935.     LD    B,11        ; Else check all 11 characters of filename
  2936.  
  2937. TRAP4:    LD    A,(HL)        ; Get char from FCB
  2938.     CP    '?'        ; Ambiguous?
  2939.     JR    Z,NOWILD    ; Yes, exit with error message
  2940.     CP    '*'        ; Even more ambiguous?
  2941.     JR    Z,NOWILD    ; Yes, exit with error message
  2942.     INC    HL        ; Point to next character
  2943.     DJNZ    TRAP4        ; Not done, check some more
  2944.     RET
  2945.  
  2946. CKNUM:    CP    '0'
  2947.     JR    C,ILLDU        ; Error if less than ascii '0'
  2948.     CP    '9'+1
  2949.     RET    C        ; Error if more than ascii '9'
  2950.  
  2951. ILLDU:    CALL    ERXIT
  2952.     DB    CR,LF
  2953.     DB    '-- Unauthorized drive/user','$'
  2954.  
  2955. NFN:    CALL    ILPRT
  2956.     DB    CR,LF,0
  2957.  
  2958. NFN1:    CALL    ERXIT        ; Print message, exit
  2959.     DB    '-- No filename(s) requested','$'
  2960.  
  2961. NOWILD:    CALL    ERXIT        ; Print message, exit
  2962.     DB    CR,LF
  2963.     DB    '-- Wildcards not valid for PRIVATE downloads','$'
  2964.  
  2965. ;
  2966. ; Previous record repeated, due to the last ACK being garbaged.  ACK it so the
  2967. ; sender will catch up
  2968. ;
  2969. RCVACK:    CALL    SNDACK        ; Send the ACK
  2970.     XOR    A
  2971.     LD    (ERRCNT),A    ; Reset the error count
  2972.  
  2973. ;
  2974. ; Receive a record - returns with carry bit set if EOT received
  2975. ;
  2976. RCVRECD:CALL    FUNCHK        ; Check function keys
  2977.     CALL    SNDABT        ; See if wanting to abort
  2978.     LD    A,(FRSTIM)    ; Have we started, yet?
  2979.     OR    A
  2980.     LD    B,10        ; Check every ten seconds if already started
  2981.     JR    Z,$+4        ; If yes, skip next line
  2982.     LD    B,5        ; Check every 5 seconds until started
  2983.     CALL    RECV        ; Get character
  2984.     JP    C,RCVSTOT    ; Timeout error if no character received
  2985.     CP    SOH        ; SOH?
  2986.     JP    Z,RCVSOH    ; Yes, get record
  2987.     CP    STX        ; STX for 1k blocks?
  2988.     JR    NZ,$+11        ; No
  2989.     LD    (KFLG),A    ; Set the 1k flag
  2990.     LD    (CRCFLG),A    ; Insure in CRC mode for 1k blocks
  2991.     JP    RCVS1
  2992.  
  2993.     CP    CANCEL        ; Was it a CTL-X to abort?
  2994.     CALL    Z,CKCAN        ; If yes, check for aborting
  2995.     OR    A        ; Get another character, if a null
  2996.     JR    Z,RCVRECD
  2997.     CP    7BH        ; V.22 synch character, ignore
  2998.     JR    Z,RCVRECD
  2999.     CP    0FBH        ; V.22 synch character with high bit set
  3000.     JR    Z,RCVRECD
  3001.     CP    EOT        ; See if end of transmission
  3002.     SCF            ; Set carry
  3003.     RET    Z        ; Return with carry set
  3004.     CP    CRC        ; Ignore our own character coming back
  3005.     JR    Z,RCVRECD
  3006.     CP    KSND        ; Ignore our own character coming back
  3007.     JR    Z,RCVRECD
  3008.     CP    NAK        ; Ignore our own character coming back
  3009.     JR    Z,RCVRECD
  3010.     CALL    ILPRTL        ; Show locally only
  3011.     DB    CR,'-- ',0
  3012.     LD    A,B
  3013.     CALL    HEXO
  3014.     CALL    ILPRTL
  3015.     DB    'H received not SOH',CR,LF,0
  3016.     JR    RCVSR
  3017.  
  3018. ;
  3019. ; Checksum error
  3020. ;
  3021. CKSMERR:CALL    ILPRTL
  3022.     DB    ' - Checksum error',CR,LF,0
  3023.     JR    RCVSR        ; Go check the error limit and send NAK
  3024.  
  3025. ;
  3026. ; Bad record number in header error
  3027. ;
  3028. HDRERR:    CALL    ILPRTL
  3029.     DB    ' - Error in header',CR,LF,0
  3030.     JR    RCVSR        ; Go check error limit and send NAK
  3031.  
  3032. ;
  3033. ; Timed out on receive error
  3034. ;
  3035. RCVSTOT:LD    A,(FRSTIM)    ; First time flag set yet?
  3036.     OR    A
  3037.     JR    Z,RCVSR        ; If not, don't show an error
  3038.     CALL    TOTMSG
  3039.  
  3040. ;
  3041. ; Didn't get SOH or EOT or did not get valid header so purge the line,  then
  3042. ; send NAK.
  3043. ;
  3044. RCVSR:    CALL    WAIT1        ; Get anything coming in and discard
  3045.     CALL    SNDABT        ; See if wanting to abort
  3046.     LD    A,(FRSTIM)    ; Get first time switch
  3047.     OR    A        ; Has first 'SOH' been received?
  3048.     LD    A,NAK
  3049.     JR    NZ,RCVSR1    ; Yes, then send 'NAK'
  3050.     LD    A,(CRCFLG)    ; Get the 'CRC' flag
  3051.     OR    A        ; 'CRC' in effect?
  3052.     LD    A,NAK        ; Put 'NAK' in 'A' register
  3053.     JR    Z,RCVSR1    ; No, send the 'NAK' for checksum
  3054.     LD    A,CRC        ; Tell sender we have 'CRC'
  3055.     CALL    SEND
  3056.     LD    A,(KFLG)    ; Requesting 1k transmissions?
  3057.     OR    A
  3058.     JR    Z,RCVSR1    ; If not, exit
  3059.     LD    A,KSND        ; Tell sender we also have 1k capability
  3060.  
  3061. RCVSR1:    CALL    SEND        ; The 'NAK' or 'CRC' request
  3062.     LD    A,(ERRCNT)    ; Get the error count
  3063.     INC    A        ; Increment error count
  3064.     LD    (ERRCNT),A    ; Store new value
  3065.     LD    B,A        ; Keep the error count for now
  3066.     LD    A,(FRSTIM)    ; Have we gotten under way yet?
  3067.     OR    A
  3068.     LD    A,B        ; get the value back
  3069.     JR    Z,RCVSR2    ; If not, exit
  3070.     CP    10        ; 10 errors the limit, once under way
  3071.     JP    NC,ABORT    ; Abort if over the limit
  3072.     CALL    RDCOUNT        ; Display record count before repeating
  3073.     JP    RCVRECD        ; Less than 10, keep going
  3074.  
  3075. RCVSR2:    CP    7        ; 7 times for 1k/CRC yet? (40 seconds)
  3076.     JP    C,RCVRECD    ; Keep trying if less
  3077.     XOR    A        ; Else flip to checksum mode
  3078.     LD    (CRCFLG),A
  3079.     LD    A,B        ; Get the count back
  3080.     CP    3        ; Another 3 times for checksum?
  3081.     JP    C,RCVRECD    ; If less, try again, quit at 60 seconds
  3082.     JP    ABORT
  3083.  
  3084. ;
  3085. ; Aborts with 1 CTL-X if first time flag is not set, two otherwise
  3086. ;
  3087. CKCAN:    LD    A,(FRSTIM)    ; First time flag set yet?
  3088.     OR    A
  3089.     JR    Z,CKCAN1    ; If not, abort
  3090.     LD    B,2
  3091.     CALL    RECV        ; Maximum of 2 seconds for extra ^X
  3092.     RET    C        ; No additional character, ignore single ^X
  3093.     CP    CANCEL        ; Got a character, is it a ^X?
  3094.     RET    NZ        ; No, ignore 1st ^X and return
  3095.  
  3096. CKCAN1:    POP    HL        ; Reset stack for CALL    CKCAN
  3097.     JP    ABORT        ; Got 2nd ^X, abort and close file
  3098.  
  3099. ;
  3100. ; Got SOH - get block number (complemented)
  3101. ;
  3102. RCVSOH:    XOR    A
  3103.     LD    (KFLG),A    ; If SOH, clear the 1k flag
  3104.  
  3105. RCVS1:    LD    A,1        ; Get something to store
  3106.     LD    (FRSTIM),A    ; Indicate first 'SOH' or 'STX' recvd.
  3107.     LD    B,5
  3108.     CALL    RECV        ; Wait up to 5 seconds for block number
  3109.     JP    C,RCVSTOT    ; Got timeout
  3110.     LD    D,A        ; Save block number
  3111.     LD    B,5
  3112.     CALL    RECV        ; 5 seconds for complimented record number
  3113.     JP    C,RCVSTOT    ; Timeout
  3114.     CPL            ; Get the complement
  3115.     CP    D        ; Same as original block number?
  3116.     JP    NZ,HDRERR    ; No, go report bad record number in header
  3117.     LD    A,D        ; Get record number
  3118.     LD    (RCVCNT),A    ; Save it
  3119.     LD    C,0        ; Initialize checksum
  3120.     LD    HL,0        ; Initialize CRC
  3121.     LD    (CRCVAL),HL    ; Clear CRC counter
  3122.     LD    DE,128        ; For 128 character blocks
  3123.     LD    A,(KFLG)    ; Using 1k blocks?
  3124.     OR    A
  3125.     JR    Z,$+5        ; If not, skip next line
  3126.     LD    DE,1024        ; If using 1k blocks
  3127.     LD    HL,(RECPTR)    ; Get buffer address
  3128.  
  3129. RCVCHR:    LD    B,5
  3130.     CALL    RECV        ; 5 seconds for character
  3131.     JP    C,RCVSTOT    ; Timeout
  3132.     LD    (HL),A        ; Store the character
  3133.     INC    HL        ; Point to next character
  3134.     DEC    DE        ; One less to go
  3135.     LD    A,E        ; See if 'D' and 'E' are both empty
  3136.     OR    D
  3137.     JR    NZ,RCVCHR    ; No, get next character
  3138.     LD    A,(CRCFLG)    ; Using 'CRC'?
  3139.     OR    A
  3140.     JP    NZ,RCVCRC    ; If yes go get 'CRC'
  3141.  
  3142. ;
  3143. ; Verify checksum
  3144. ;
  3145.     LD    D,C        ; Save checksum
  3146.     LD    B,5
  3147.     CALL    RECV        ; Up to 5 seconds for checksum
  3148.     JP    C,RCVSTOT    ; Timeout
  3149.     CP    D        ; Checksum ok?
  3150.     JP    NZ,CKSMERR    ; No, report error
  3151.  
  3152. ;
  3153. ; Got a record, it's a duplicate if equal to the previous number, it's OK if
  3154. ; previous + 1 record
  3155. ;
  3156. CHKSNUM:LD    A,(RCVCNT)    ; Get received record number
  3157.     LD    B,A        ; Save it
  3158.     LD    A,(RCDCNT)    ; Get previous record number
  3159.     CP    B        ; Previous record repeated?
  3160.     JP    Z,RCVACK    ; If yes 'ACK' to catch up
  3161.     INC    A        ; Increment by 1 for 120 character block
  3162.     CP    B        ; Match this one we just got?
  3163.     JP    NZ,ABORT    ; No match, stop the sender, exit
  3164.     RET            ; Else return with carry not set, was ok
  3165.  
  3166. ;
  3167. ; Receive the Cyclic Redundancy Check characters (2 bytes) and see if the CRC
  3168. ; received matches the one calculated.    If they match,  get next record, else
  3169. ; send a NAK requesting the record be sent again.
  3170. ;
  3171. RCVCRC:    LD    E,2        ; Number of bytes to receive
  3172.  
  3173. RCVCRC2:LD    B,5
  3174.     CALL    RECV        ; Up to 5 seconds for CRC byte
  3175.     JP    C,RCVSTOT    ; Timeout
  3176.     DEC    E        ; Decrement the number of bytes
  3177.     JR    NZ,RCVCRC2    ; Get both bytes
  3178.     CALL    CRCCHK        ; Check received CRC against calc'd CRC
  3179.     OR    A        ; Is CRC okay?
  3180.     JR    Z,CHKSNUM    ; Yes, go check record numbers
  3181.     CALL    ILPRTL        ; Show locally only 
  3182.     DB    ' - CRC error',CR,LF,0
  3183.     JP    RCVSR        ; Go check error limit and send NAK
  3184.  
  3185. ;
  3186. ;------------------
  3187. ; Send subroutines
  3188. ;------------------
  3189. ;
  3190. ; Send an ACK for the record
  3191. ;
  3192. SNDACK:    LD    A,ACK        ; Get 'ACK'
  3193.     JP    SEND        ; And send it
  3194.  
  3195. ;
  3196. ; Send SOH, block number and complemented block number (3 bytes total)
  3197. ;
  3198. SNDHDR:    LD    A,(KFLG)    ; Sending 1k blocks?
  3199.     OR    A
  3200.     LD    A,STX        ; If yes, send a STX rather than SOH
  3201.     JR    NZ,$+4
  3202.     LD    A,SOH        ; Send start of header
  3203.     CALL    SEND
  3204.  
  3205. SNDHNM:    LD    A,(RCDCNT)    ; Send the current record number
  3206.     CALL    SEND
  3207.     LD    A,(RCDCNT)    ; Get the record number again
  3208.     CPL            ; Complemented
  3209.     JP    SEND        ; From SENDHDR
  3210.  
  3211. ;
  3212. ; Send data record
  3213. ;
  3214. SNDREC:    LD    C,0        ; Initialize checksum
  3215.     LD    HL,0        ; Initialize CRC
  3216.     LD    (CRCVAL),HL
  3217.     LD    A,(KFLG)    ; Sending 1k blocks?
  3218.     OR    A
  3219.     LD    DE,1024
  3220.     JR    NZ,$+5        ; If yes, skip the next line
  3221.     LD    DE,128
  3222.     LD    HL,(RECPTR)    ; Get buffer address
  3223.  
  3224. SENDC:    LD    A,(HL)        ; Get a character
  3225.     CALL    SEND        ; Send it
  3226.     INC    HL        ; Point to next character
  3227.     DEC    DE
  3228.     LD    A,E
  3229.     OR    D
  3230.     JR    NZ,SENDC    ; If DE not zero, keep going
  3231.     RET            ; From SENDREC
  3232.  
  3233. ;
  3234. ; Send the CRC or checksum value
  3235. ;
  3236. SNDCHK:    LD    A,(CRCFLG)    ; See if sending 'CRC' or 'checksum'
  3237.     OR    A
  3238.     JR    NZ,SNDCRC    ; If not zero, send the 'CRC' value
  3239.  
  3240. ;
  3241. ; Send Checksum
  3242. ;
  3243. SNDCKS:    LD    A,C        ; Send the checksum
  3244.     JP    SEND        ; From SNDCKS
  3245.  
  3246. ;
  3247. ; Send CRC (2 characters).  Call FINCRC to calculate the CRC which will be
  3248. ; in 'DE' upon return.
  3249. ;
  3250. SNDCRC:    CALL    FINCRC        ; Calculate the 'CRC' for this record
  3251.     LD    A,D        ; Put first 'CRC' byte in accumulator
  3252.     CALL    SEND        ; Send it
  3253.     LD    A,E        ; Put second 'CRC' byte in accumulator
  3254.     CALL    SEND        ; Send it
  3255.     XOR    A        ; Set zero return code
  3256.     RET
  3257.  
  3258. ;
  3259. ; Get acknowlegement
  3260. ;
  3261. ; After a record is sent, a character is returned telling if it was received
  3262. ; properly or not.  An ACK allows the next record to be sent.  A NAK causes
  3263. ; the current record to be resent.  If no character (or any character other
  3264. ; than ACK or NAK) is received after a short wait (10-12 seconds), a timeout
  3265. ; error message is shown and the record will be resent.
  3266. ;
  3267. GTACK:    LD    B,12
  3268.     CALL    RECV        ; Wait up to 12 seconds for ACK or NAK
  3269.     JR    NC,GTACK1    ; Got one
  3270.     CALL    TOTMSG
  3271.     JP    ACKERR        ; Set the carry bit and return
  3272.  
  3273. GTACK1:    CP    ACK        ; See if an ACK already
  3274.     RET    Z        ; If yes, return
  3275.     CP    NAK        ; See if a NAK
  3276.     JR    Z,GTACK2    ; If yes, print error, then resend
  3277.     CP    07BH        ; V.22 synch character?
  3278.     JR    Z,GTACK        ; If yes, ignore it
  3279.     CP    0FBH        ; V.22 synch character?
  3280.     JR    Z,GTACK        ; If yes, ignore it
  3281.     CP    CANCEL        ; CTL-X to cancel attempt?
  3282.     CALL    Z,CKCAN
  3283.  
  3284. GTACK2:    LD    B,A        ; Save the character
  3285.     LD    A,(CHKEOT)    ; Sending EOT?
  3286.     OR    A
  3287.     JP    NZ,ACKERR    ; If yes, don't show error (for ZMD)
  3288.     CALL    ILPRTL
  3289.     DB    ' - ',0
  3290.     LD    A,B
  3291.     CP    NAK
  3292.     JR    Z,GTACK3
  3293.     CALL    HEXO
  3294.     CALL    ILPRTL
  3295.     DB    'H',0
  3296.     JR    GTACK4
  3297.  
  3298. GTACK3:    CALL    ILPRTL
  3299.     DB    'NAK',0
  3300.  
  3301. GTACK4:    CALL    ILPRTL
  3302.     DB    ' received not ACK',CR,LF,0
  3303.     CALL    CATCH        ; None of them, establish clear line again
  3304.  
  3305. ;
  3306. ; Timeout or error on ACK - bump error count then resend the record if
  3307. ; error limit is not exceeded
  3308. ;
  3309. ACKERR:    LD    A,(ACCERR)    ; Count accumulated errors on ACK
  3310.     INC    A        ; Add in this error
  3311.     LD    (ACCERR),A
  3312.     LD    A,(ERRCNT)    ; Get count
  3313.     INC    A        ; Bump it
  3314.     LD    (ERRCNT),A    ; Save back
  3315.     CP    10        ; At limit?
  3316.     JR    NC,ACKMSG    ; If yes, send error message and abort
  3317.     LD    A,(ACKCHK)    ; Checking after a batch header?
  3318.     OR    A
  3319.     CALL    Z,RDCOUNT    ; Yes, show the record count for repeat
  3320.  
  3321.     LD    A,B        ; Get character back
  3322.     CP    NAK        ; NAK?
  3323.     JP    NZ,GTACK    ; No, ignore and wait for ACK or NAK
  3324.     RET            ; And go back
  3325.  
  3326. ;
  3327. ; Reached error limit
  3328. ;
  3329. ACKMSG:    CALL    WAIT1        ; Wait for any input to stop
  3330.     LD    A,CANCEL    ; Tell remote we are quitting
  3331.     CALL    SEND
  3332.     CALL    SEND
  3333.     CALL    SEND
  3334.     LD    B,2
  3335.     CALL    RECV        ; Up to 2 seconds for remote to quit too
  3336.     LD    A,BS
  3337.     CALL    SEND        ; Clear any CTL-X from buffer
  3338.     CALL    SEND
  3339.     CALL    SEND
  3340.     CALL    ERXIT
  3341.     DB    CR
  3342.     DB    '-- File transfer aborted','$'
  3343.  
  3344. ;
  3345. ; Routines to trap abort conditions
  3346. ;
  3347. ; Check to see if a cancel requested.  Fall through to ABORT if so.
  3348. ;
  3349. CKABORT:CALL    CONSTAT
  3350.     OR    A
  3351.     RET    Z
  3352.     CALL    CONIN
  3353.     CP    CANCEL
  3354.     RET    NZ
  3355.  
  3356. ;
  3357. ; Aborts send or receive routines and returns to command line
  3358. ;
  3359. ABORT:    CALL    WAIT1        ; 1- second delay to clear input
  3360.     CALL    CATCH
  3361.     LD    A,(EOTFLG)    ; Timed out after only 1 EOT?
  3362.     OR    A
  3363.     JP    NZ,RCVEOT+3    ; Accept as valid EOT then
  3364.     LD    A,CANCEL    ; Show you are cancelling
  3365.     CALL    SEND        ; They may quit also with enough CTL-X
  3366.     CALL    SEND
  3367.     CALL    SEND
  3368.     CALL    WAIT1        ; 1-second delay to clear input
  3369.     CALL    CATCH
  3370.     LD    A,BS
  3371.     CALL    SEND
  3372.     CALL    SEND
  3373.     CALL    SEND
  3374.  
  3375. ABORTX:    CALL    CATCH        ; Eat garbage characters
  3376.     CALL    ABRTMSG        ; Show we have aborted
  3377.     LD    A,(MODE)    ; Get file transfer mode
  3378.     CP    'R'        ; Sending a file?
  3379.     JP    NZ,EXIT        ; Yes, quit to CP/M
  3380.  
  3381. ;
  3382. ; Take care of received file (if any).
  3383. ;
  3384. CLOSFIL:LD    C,CLOSE        ; Get function
  3385.     LD    DE,FCB        ; Point to file
  3386.     CALL    BDOS        ; Close it
  3387.     INC    A        ; Close ok?
  3388.     JR    NZ,CLOSFL1    ; Yes
  3389.     CALL    ILPRT        ; No, abort
  3390.     DB    CR,LF
  3391.     DB    '-- Received file not closed',0
  3392.     JP    NTDEL1
  3393.  
  3394. CLOSFL1:LD    A,(EOTFLG)    ; Get end of transmission flag
  3395.     OR    A        ; Received entire file?
  3396.     RET    NZ        ; Yes, return to RCVEOT routines
  3397.     CALL    ILPRTB
  3398.     DB    CR,LF
  3399.     DB    '-- Upload has been cancelled',0
  3400.  
  3401. ;
  3402. ; Delete the received file
  3403. ;
  3404.     LD    C,DELETE    ; Get function
  3405.     LD    DE,FCB        ; Point to file
  3406.     CALL    BDOS        ; Delete it
  3407.     INC    A        ; Delete ok?
  3408.     JR    Z,NOTDEL    ; No
  3409.     CALL    ERXIT        ; Print second half of message
  3410.     DB    CR,LF
  3411.     DB    '-- Partial file is deleted','$'
  3412.  
  3413. ;
  3414. ; Unsuccessful delete
  3415. ;
  3416. NOTDEL:    CALL    ILPRT
  3417.     DB    CR,LF
  3418.     DB    '-- Received file not deleted'
  3419.  
  3420. NTDEL1: CALL    ERXIT
  3421.     DB    ' or no file received','$'
  3422.  
  3423. ;
  3424. ; See if a file exists.  If it exists, ask for a different name.
  3425. ;
  3426. CHEKFIL:LD    A,(SETAREA)    ; Uploading to designated drive/user?
  3427.     OR    A
  3428.     JR    NZ,CHEKF1    ; Yes
  3429.     LD    A,(ASKAREA)    ; Upload routing enabled?
  3430.     OR    A
  3431.     JR    NZ,CHEKF1    ; Yes
  3432.     LD    A,(PRIVATE)    ; Receiving in private area?
  3433.     OR    A
  3434.     JR    Z,$+5        ; No
  3435.  
  3436. CHEKF1:    CALL    RECARE        ; Set the designated area up
  3437.     LD    C,SRCHF        ; See if it exists
  3438.     LD    DE,FCB        ; Point to control block
  3439.     CALL    BDOS
  3440.     INC    A        ; Found?
  3441.     RET    Z        ; No, return
  3442.     LD    A,CANCEL    ; Tell the remote we are aborting
  3443.     CALL    SEND        ; Send several cancel requests
  3444.     CALL    SEND
  3445.     CALL    SEND
  3446.  
  3447. CHEKF2:    LD    B,1
  3448.     CALL    RECV        ; Up to 1 seconds for character
  3449.     JR    NC,CHEKF2    ; Wait until no more characters
  3450.     LD    A,(BATCH)    ; Using batch mode now?
  3451.     LD    (CONONL),A    ; If not, send message to modem also
  3452.     OR    A
  3453.     JR    Z,CHEKF3    ; If not, exit
  3454.     LD    A,CANCEL
  3455.     CALL    SEND
  3456.     CALL    SEND
  3457.     CALL    SEND
  3458.     LD    A,BS
  3459.     CALL    SEND
  3460.  
  3461. CHEKF3:    CALL    ERXIT        ; Exit, print error message
  3462.     DB    CR,LF
  3463.     DB    '-- File already exists','$'
  3464.  
  3465. ;
  3466. ; Make the file to be received
  3467. ;
  3468. MAKEFIL:XOR    A        ; Set extent and record number to 0
  3469.     LD    (FCBEXT),A
  3470.     LD    (FCBRNO),A
  3471.     LD    A,(HIDEIT)
  3472.     OR    A
  3473.     JR    Z,MAKEF1    ; HIDEIT not enabled, skip all this
  3474.     CALL    WHLCHK
  3475.     JR    NZ,MAKEF1    ; Don't make it $SYS if SYSOP online
  3476.     LD    A,(PRIVATE)
  3477.     OR    A
  3478.     JR    NZ,MAKEF1    ; Don't make it $SYS if private upload
  3479.  
  3480.     LD    DE,FCB+10    ; Point at second char of file extent
  3481.     LD    A,(DE)
  3482.     OR    80H        ; And turn on the high bit (Make file $SYS)
  3483.     LD    (DE),A        ; Put it back
  3484.  
  3485. MAKEF1:    LD    C,MAKE        ; Get BDOS FNC
  3486.     LD    DE,FCB        ; Point to FCB
  3487.     CALL    BDOS        ; To the make
  3488.     PUSH    AF        ; Save MAKE error code
  3489.  
  3490.     LD    C,SETFILE    ; Set up for BDOS FUNCTION 30
  3491.     LD    DE,FCB
  3492.     CALL    BDOS        ; Set file attributes
  3493.     POP    AF        ; Error code from BDOS make function
  3494.     INC    A        ; 0FFH=bad?
  3495.     RET    NZ        ; Open ok
  3496.  
  3497.     LD    HL,FCB+1
  3498.     JP    NOROOM        ; Tell them directory might be full
  3499.  
  3500. ;
  3501. ; Open file to be sent
  3502. ;
  3503. OPNFIL:    XOR    A        ; Zero accumulator
  3504.     LD    (FCBEXT),A    ; Set extent to 0
  3505.     LD    (FCBRNO),A    ; Set record number to 0
  3506.     LD    DE,FCB        ; Point to file
  3507.     LD    C,OPEN        ; Open it
  3508.     CALL    BDOS
  3509.     INC    A        ; Open ok?
  3510.     JR    NZ,OPNOK    ; Yes, check restrictions
  3511.  
  3512.     LD    A,(LBRARC)    ; Get extraction flag
  3513.     OR    A        ; Enabled?
  3514.     JP    Z,NOFILE    ; No, abort
  3515.     LD    HL,ARCNAM    ; Force .ARC filetype
  3516.     CALL    CHNGEXT        ; Try to open it
  3517.     JR    NZ,OPNOK    ; File found
  3518.     LD    HL,ARKNAM    ; Force .ARK filetype
  3519.     CALL    CHNGEXT        ; Try to open it
  3520.     JR    NZ,OPNOK    ; File found
  3521.     LD    HL,LBRNAM    ; Force .LBR filetype
  3522.     CALL    CHNGEXT        ; Try to open it
  3523.     JR    NZ,OPNOK    ; File found
  3524.     JP    NOARK        ; Not found and no more filetypes to try
  3525.  
  3526. CHNGEXT:LD    DE,FCB+9
  3527.     LD    BC,3
  3528.     LDIR
  3529.     LD    C,OPEN
  3530.     LD    DE,FCB
  3531.     CALL    BDOS
  3532.     INC    A
  3533.     RET            ; Z flag set=file not found
  3534.  
  3535. ;
  3536. ; Requested file was found, now check some restrictions
  3537. ;
  3538. OPNOK:    LD    IX,FCB        ; Point to filename
  3539.     CALL    RESTRCT        ; Check it for restrictions
  3540.     LD    A,(LBRARC)    ; Get the member extraction flag
  3541.     OR    A        ; Enabled?
  3542.     JR    Z,OPNOK1    ; No, skip this
  3543.     CALL    RSDMA        ; Reset to default DMA address
  3544.     LD    C,READ        ; Read first file record
  3545.     LD    DE,FCB
  3546.     CALL    BDOS
  3547.     OR    A        ; Read ok?
  3548.     JP    NZ,READERR    ; If not, error
  3549.     CALL    CKDIR        ; Take care of LBR stuff
  3550.  
  3551. OPNOK1:    LD    HL,(RCNT)    ; Get record count
  3552.     LD    A,H
  3553.     OR    L
  3554.     JP    Z,ZEROLN    ; Can't send 0-length files
  3555.     LD    A,(BATCH)
  3556.     OR    A
  3557.     JR    Z,OPNOK1A    ; Don't clear screen unless in BATCH mode
  3558.     LD    A,(FSTFLG)    ; Get first file sent flag
  3559.     OR    A        ; Sent it already?
  3560.     LD    A,1        ; Show we have for next time
  3561.     LD    (FSTFLG),A
  3562.     CALL    Z,CLEARIT    ; No, need to clear screen here first time
  3563.  
  3564. OPNOK1A:CALL    SHONM        ; Show the name of this file
  3565.     CALL    LOW41K        ; Less than MINKSPD?
  3566.     JR    C,OPNOK3    ; Yes, don't show 1k packets
  3567.  
  3568. OPNOK2:    CALL    ILPRT
  3569.     DB    CR,LF
  3570.     DB    'Ymodem packets total     > ',0
  3571.     LD    HL,(RCNT)    ; Get record count
  3572.     CALL    DIVREC        ; Divide number of records by 8
  3573.     CALL    DECOUT        ; Show # of 1k packets
  3574.  
  3575. OPNOK3:    CALL    ILPRT
  3576.     DB    CR,LF
  3577.     DB    'Xmodem packets total     > ',0
  3578.     LD    HL,(RCNT)    ; Get original count
  3579.     CALL    DECOUT        ; Show # of 128 byte packets
  3580.     LD    A,(MODE)    ; Get transfer mode
  3581.     CP    'R'        ; Receiving?
  3582.     RET    Z        ; Yes, all done
  3583.  
  3584.     CALL    ILPRT
  3585.     DB    CR,LF
  3586.     DB    'Disk space you need      > ',0
  3587.  
  3588.     LD    A,(SBSHOW)    ; Displaying intial BATCH screen to remote?
  3589.     OR    A
  3590.     PUSH    AF        ; Save answer
  3591.     LD    HL,(FILEK)    ; Get precalculated total 'k' for all files
  3592.     JR    NZ,OPNOK4    ; Go show it
  3593.     LD    BC,(RCNT)    ; Else get single file record count back
  3594.     CALL    ROUNDK        ; Round disk space needed
  3595.     EX    DE,HL
  3596. ;
  3597. OPNOK4:    CALL    DECOUT        ; Decimal output
  3598.     CALL    ILPRT
  3599.     DB    'k  (',0
  3600.     LD    HL,(BLKSIZ)    ; Get host disk block size
  3601.     CALL    DECOUT        ; Decimal output
  3602.     CALL    ILPRT
  3603.     DB    'k blocks)',0
  3604.     POP    AF        ; Displaying initial BATCH screen to remote?
  3605.     RET    NZ        ; Yes, then we're done in here
  3606.  
  3607. ;
  3608. ; Show transfer time, first for 1k blocks, then for 128-byte blocks. If we are
  3609. ; at 300 bps, report both transfer times the same.  (skip the 1k times for
  3610. ; speeds slower than MINKSPD bps.)
  3611. ;
  3612. KSPD:    CALL    LOW41K        ; Less than MINKSPD?
  3613.     JR    C,XSPD        ; Yes, skip 1k display
  3614.     CALL    ILPRT
  3615.     DB    CR,LF
  3616.     DB    'Ymodem time / 1k         > ',0
  3617.     CALL    GETSPD        ; Get current modem speed
  3618.     CP    1        ; At 300 bps?
  3619.     JR    Z,KSPD1        ; 1k transfer time in BC (minutes) if >300
  3620.     CALL    KTIM
  3621.     JR    KSPD2
  3622.  
  3623. KSPD1:    LD    HL,XECTBL
  3624.     LD    (RECTBL+1),HL
  3625.     CALL    XTIM
  3626.  
  3627. KSPD2:    CALL    STORTM        ; Store it
  3628.     CALL    XFRTIM        ; Display it
  3629.  
  3630. XSPD:    CALL    ILPRT
  3631.     DB    CR,LF
  3632.     DB    'Xmodem time / 128 byte   > ',0
  3633.     LD    HL,XECTBL    ; 128 size values (300 bps)
  3634.     LD    (RECTBL+1),HL
  3635.     CALL    XTIM        ; Xmodem transfer time
  3636.     LD    A,(KFLG)    ; If 'SK' set, 1k time already stored
  3637.     OR    A
  3638.     CALL    Z,STORTM
  3639.     CALL    XFRTIM
  3640.     LD    HL,KECTBL    ; Restore to original 1k values
  3641.     LD    (RECTBL+1),HL
  3642.     CALL    ILPRT
  3643.     DB    CR,LF,0
  3644.  
  3645.     LD    A,(BATCH)    ; In batch mode?
  3646.     OR    A
  3647.     JP    Z,OPNOK5    ; No, couldn't have been here before
  3648.     LD    A,(FSTFLG)    ; Yes, been here before?
  3649.     OR    A
  3650.     JP    Z,OPNOK5    ; No, following gets shown next time
  3651.  
  3652. ;
  3653. ; In batch, show files remaining after this one is sent
  3654. ;
  3655.     CALL    ILPRTL
  3656.     DB    CR,LF
  3657.     DB    'Files remaining          > ',0
  3658.     LD    A,(SHOCNT)    ; Get cumulative files
  3659.     DEC    A
  3660.     LD    (SHOCNT),A    ; Less one
  3661.     LD    L,A
  3662.     LD    H,0
  3663.     CALL    DECOUT
  3664.  
  3665.     CALL    ILPRTL
  3666.     DB    CR,LF
  3667.     DB    'Ymodem packets remaining > ',0
  3668.     LD    HL,(RCNT)    ; Get this file's record count again
  3669.     EX    DE,HL        ; Put in DE
  3670.     LD    HL,(TOTREC)    ; Total records remaining
  3671.     LD    A,L
  3672.     SUB    E
  3673.     LD    L,A
  3674.     LD    A,H
  3675.     SBC    A,D
  3676.     LD    H,A
  3677.     JR    NC,$+5
  3678.     LD    HL,0        ; In case of a slightly negative number
  3679.     PUSH    HL        ; Save it for Xmodem packets show
  3680.     CALL    DIVREC        ; Divide number of records by 8
  3681.     CALL    DECOUT
  3682.  
  3683.     CALL    ILPRTL
  3684.     DB    CR,LF
  3685.     DB    'Xmodem packets remaining > ',0
  3686.     POP    HL        ; Get total records remaining after this file
  3687.     LD    (TOTREC),HL
  3688.     CALL    DECOUT        ; Show remote remaining records
  3689.     CALL    ILPRTL
  3690.     DB    CR,LF,LF,0
  3691.     CALL    WAITMSG        ; Display '[ waiting ]' message locally
  3692.     RET
  3693.  
  3694. ;
  3695. ; If sending an ARC or ARK file, tell user to rename to .ARK or .ARC file type.
  3696. ;
  3697. OPNOK5:    LD    A,(LBRARC)    ; Get extraction flag
  3698.     OR    A        ; Enabled?
  3699.     JP    Z,DLRDY        ; No, skip this
  3700.     LD    A,(FCB+9)    ; Point to member filetype
  3701.     AND    7FH        ; Strip parity
  3702.     CP    'L'        ; LBR member extraction?
  3703.     JP    Z,DLRDY        ; Yes, skip this
  3704.     CALL    ILPRTB
  3705.     DB    CR,LF
  3706.     DB    'You MUST name file       > ',0
  3707.     LD    D,8        ; Filename count - ignore filetype
  3708.     LD    HL,MEMFCB    ; Get requested member name
  3709.  
  3710. OPNOK6:    LD    A,(HL)
  3711.     CP    ' '        ; Short filename?
  3712.     JR    Z,OPNOK7    ; If so, fill in type
  3713.     CALL    TYPE
  3714.  
  3715.     DEC    D        ; One less...
  3716.     INC    HL        ; Next character
  3717.     JR    NZ,OPNOK6    ; Loop until done
  3718.  
  3719. OPNOK7:    LD    A,(FCB+11)    ; Get last character of parent filetype
  3720.     LD    ($+9),A        ; Stuff it below to display
  3721.     CALL    ILPRTB
  3722.     DB    '.AR?'        ; Either a 'C' or a 'K' gets poked at '?'
  3723.     DB    CR,LF,0
  3724.     CALL    DLRDY        ; Tell them their download(s) are ready
  3725.     RET
  3726.  
  3727. ;
  3728. ; These routines display the transfer time in minutes & seconds and check for
  3729. ; time restrictions,  if a clock is enabled.
  3730. ;
  3731. XFRTIM:    PUSH    HL        ; Save seconds in 'L'
  3732.     CALL    WHLCHK        ; Sysop online?
  3733.     JR    NZ,SKPTIM    ; Yes, then skip the limit
  3734.  
  3735.     LD    A,(MAXTOS)
  3736.     OR    A
  3737.     JR    Z,SKPTIM
  3738.     LD    D,C        ; Save minutes for now
  3739.     INC    D        ; Increment to next full minute
  3740.     LD    A,(TIMEON)    ; Using TIMEON?
  3741.     OR    A
  3742.     LD    A,D        ; Get length of this program
  3743.     JR    Z,XFRTM1    ; No, don't increment time
  3744.     LD    HL,TON        ; Point to time on system
  3745.     ADD    A,(HL)        ; Else add time on system to transfer time
  3746.  
  3747. XFRTM1:    LD    (XFRMIN),A    ; Store it
  3748.     OR    A
  3749.     LD    A,B        ; Get hours in A
  3750.     JR    NZ,$+3        ; Don't increment if not zero
  3751.     INC    A        ; Increment to next full minute
  3752.     LD    (XFRMIN+1),A
  3753.  
  3754. SKPTIM:    LD    H,B        ; Get most significant in H (hours)
  3755.     LD    L,C        ; Get least significant byte of minutes in L
  3756.     CALL    DECOUT        ; Print decimal number of minutes
  3757.     CALL    ILPRT
  3758.     DB    ':',0
  3759.     POP    HL        ; Get seconds back
  3760.     LD    A,L        ; Get the number of seconds
  3761.     CP    10        ; 10 seconds or more?
  3762.     JR    NC,$+7        ; If yes, disregard next two lines
  3763.     CALL    ILPRT
  3764.     DB    '0',0
  3765.     CALL    DECOUT        ; Print decimal number of seconds
  3766.     CALL    ILPRT
  3767.     DB    ' at ',0
  3768.     CALL    GETSPD        ; Get modem speed value in A
  3769.     CALL    SHOSPD        ; Display in BPS
  3770.  
  3771. ;
  3772. ; Determine if the caller has enough time left online to make the
  3773. ; requested download(s).
  3774. ;
  3775. XFRTM3:    LD    A,(MODE)    ; Get transfer mode
  3776.     CP    'R'        ; Receiving?
  3777.     RET    Z        ; Yes, all done
  3778.  
  3779.     LD    A,(MAXTOS)    ; Get maximum time allowed
  3780.     OR    A        ; Unlimited?
  3781.     RET    Z        ; Yes, skip time restriction
  3782.  
  3783.     LD    A,(XFRMIN+1)    ; Get most significant byte of minutes
  3784.     OR    A        ; 0?
  3785.     JR    NZ,OVERTM    ; If not, over 255 minutes
  3786.     LD    A,(XFRMIN)    ; Get least significant byte of minute count
  3787.     LD    B,A        ; Put in B
  3788.     LD    A,(MAXTOS)    ; Get maximum time allowed
  3789.     INC    A
  3790.     SBC    A,B
  3791.     RET    NC
  3792.  
  3793. ;
  3794. ; There is not enough time to download the requested file(s). Inform user and
  3795. ; abort to CP/M.
  3796. ;
  3797. OVERTM:    CALL    ILPRTB
  3798.     DB    CR,LF,LF,0
  3799.     CALL    ABRTMSG        ; Display both local and remote we aborted
  3800.     CALL    ILPRTB
  3801.     DB    CR,LF,LF
  3802.     DB    'Required send time exceeds the ',0
  3803.     LD    A,(TLOS)    ; Get time left on system
  3804.     LD    H,0        ; Zero H
  3805.     LD    L,A        ; Time left on system in L
  3806.     CALL    DECOUT        ; Decimal output routine
  3807.     CALL    ERXIT        ; Display following message and abort to CP/M
  3808.     DB    ' minutes allowed','$'
  3809.  
  3810. ;
  3811. ;-------------------------------------------------------------------------;
  3812. ; L o g   F i l e   T r a n s f e r                      |
  3813. ;-------------------------------------------------------------------------;
  3814. ;
  3815. ; Main log file routine, adds record to log file
  3816. ;
  3817. LOGCALL:LD    A,(LOGCAL)    ; Logging file transfers?
  3818.     OR    A
  3819.     RET    Z        ; No
  3820.     CALL    GTCURDU        ; Get current drive/user in USRSAV and DSKSAV
  3821.  
  3822.     LD    HL,FCBCLR    ; FCB to initialize
  3823.     LD    DE,LSTCLR    ; Filename to insert
  3824.     CALL    RENFCB        ; Initialize FCB
  3825.  
  3826.     LD    A,(LASTDRV)
  3827.     SUB    'A'
  3828.     LD    (DEFDSK),A
  3829.     LD    A,(LASTUSR)
  3830.     LD    (DEFUSR),A
  3831.     LD    DE,FCBCLR
  3832.     CALL    OPENF        ; Open LASTCALR file
  3833.     JR    NZ,LGCAL1
  3834.     CALL    ILPRT
  3835.     DB    CR,LF
  3836.     DB    '-- File not Found: LASTCALR.???'
  3837.     DB    CR,LF,0
  3838.     RET            ; Now go send EOT
  3839.  
  3840. LGCAL1:    LD    C,SETRRD    ; Get random record #
  3841.     LD    DE,FCBCLR    ; (for first record in file)
  3842.     CALL    BDOS
  3843.  
  3844.     LD    DE,DBUF        ; Set DMA to DBUF
  3845.     CALL    STDMA
  3846.  
  3847.     LD    C,RRDM        ; Read first (and only) record
  3848.     LD    DE,FCBCLR
  3849.     CALL    BDOS
  3850.  
  3851.     LD    HL,DBUF        ; Set pointer to beginning of record
  3852.     LD    A,(CLOCK)    ; Is there a clock installed?
  3853.     OR    A
  3854.     JR    Z,LGCAL2    ; No, skip this then
  3855.     LD    DE,0        ; Zero DE
  3856.     LD    A,(LCNAME)    ; Offset to start of caller's name
  3857.     LD    E,A        ; To E
  3858.     ADD    HL,DE        ; HL now points to start of name
  3859.  
  3860. LGCAL2:    LD    (CLRPTR),HL
  3861.     LD    DE,LOGBUF    ; Set DMA address to LOGBUF
  3862.     CALL    STDMA
  3863.  
  3864.     LD    HL,FCBLOG    ; FCB to initialize
  3865.     LD    DE,LOGNAM    ; Filename to insert
  3866.     CALL    RENFCB        ; Initialize FCB
  3867.  
  3868.     LD    A,(LOGDRV)
  3869.     SUB    'A'
  3870.     LD    (DEFDSK),A
  3871.     LD    A,(LOGUSR)
  3872.     LD    (DEFUSR),A
  3873.     LD    DE,FCBLOG
  3874.     CALL    OPENF        ; Open log file
  3875.     JR    NZ,LGCAL5    ; If file exists, skip create
  3876.     LD    DE,FCBLOG
  3877.     LD    C,MAKE        ; Create a new file if needed
  3878.     CALL    BDOS
  3879.     INC    A
  3880.     JR    NZ,LGCAL3    ; No error, continue
  3881.     CALL    ILPRT        ; File create error
  3882.     DB    CR,LF
  3883.     DB    '-- Directory Full: ',0
  3884.     LD    HL,LOGNAM
  3885.     CALL    SHONM4
  3886.     RET            ; Go back and send EOT
  3887.  
  3888. LGCAL3:    LD    DE,LOGBUF    ; Set DMA back to LOGBUF 
  3889.     CALL    STDMA
  3890.  
  3891.     LD    C,SETRRD    ; Set random record #
  3892.     LD    DE,FCBLOG    ; (for first record in file)
  3893.     CALL    BDOS
  3894.  
  3895. LGCAL4:    LD    A,EOF
  3896.     LD    (LOGBUF),A
  3897.     JR    LGCAL6
  3898.  
  3899. LGCAL5:    LD    DE,LOGBUF    ; Set DMA to LOGBUF
  3900.     CALL    STDMA
  3901.  
  3902.     LD    C,FILSIZ    ; Get file length
  3903.     LD    DE,FCBLOG
  3904.     CALL    BDOS
  3905.     LD    HL,(FCBLOG+33)    ; Back up to last record
  3906.     LD    A,L
  3907.     OR    H
  3908.     JR    Z,LGCAL4    ; Unless zero length file
  3909.     DEC    HL
  3910.     LD    (FCBLOG+33),HL
  3911.     LD    DE,FCBLOG
  3912.     LD    C,RRDM        ; And read it
  3913.     CALL    BDOS
  3914.  
  3915. LGCAL6:    CALL    RSTLP        ; Initialize LOGPTR and LOGCNT
  3916.  
  3917. LGCAL7:    LD    A,(LOGCNT)
  3918.     INC    A
  3919.     LD    (LOGCNT),A
  3920.     CP    129
  3921.     JR    NZ,LGCAL8
  3922.     LD    HL,(FCBLOG+33)
  3923.     INC    HL
  3924.     LD    (FCBLOG+33),HL
  3925.     LD    HL,LOGBUF+1
  3926.     LD    (LOGPTR),HL
  3927.     LD    A,1
  3928.     LD    (LOGCNT),A
  3929.     LD    A,EOF
  3930.     JR    LGCAL8A
  3931.  
  3932. LGCAL8:    LD    HL,(LOGPTR)
  3933.     LD    A,(HL)
  3934.     INC    HL
  3935.     LD    (LOGPTR),HL
  3936.  
  3937. LGCAL8A:CP    EOF
  3938.     JR    NZ,LGCAL7    ; Until EOF
  3939.     LD    A,(LOGCNT)    ; Then backup one character
  3940.     DEC    A
  3941.     LD    (LOGCNT),A
  3942.     LD    HL,(LOGPTR)
  3943.     DEC    HL
  3944.     LD    (LOGPTR),HL
  3945.  
  3946. ;
  3947. ; Print file transfer mode to LOG file (R, S, P, A, L)
  3948. ;
  3949.     LD    A,(PUPFLG)
  3950.     OR    A        ; Privileged upload option request?
  3951.     JR    Z,LGCAL8B    ; No, skip next 2 lines
  3952.     LD    A,'P'        ; Else,
  3953.     JR    LGCAL9        ; Show as private upload for log file
  3954.  
  3955. LGCAL8B:LD    A,(PRIVATE)
  3956.     OR    A
  3957.     JR    NZ,LGCAL9
  3958.     LD    A,(MODE)    ; Get transfer mode back and put in file
  3959.  
  3960. LGCAL9:    CALL    PUTLOG
  3961.  
  3962. ;
  3963. ; Print baud rate to LOG file
  3964. ;
  3965.     CALL    GETSPD        ; Get speed factor
  3966.     ADD    A,30H
  3967.     CALL    PUTLOG
  3968.     CALL    PUTSP        ; Blank
  3969.  
  3970. ;
  3971. ; Print program size (in minutes and seconds) to LOG file
  3972. ;
  3973.     LD    A,(PGSIZE)    ; Now the program size in minutes..
  3974.     CALL    PNDEC        ; Of transfer time (mins)
  3975.     LD    A,':'
  3976.     CALL    PUTLOG        ; ':'
  3977.     LD    A,(PGSIZE+2)
  3978.     CALL    PNDEC        ; And seconds
  3979.     CALL    PUTSP        ; Blank
  3980.  
  3981. ;
  3982. ; Log the drive and user area as a prompt
  3983. ;
  3984.     LD    A,(FCB)
  3985.     OR    A
  3986.     JR    NZ,WDRV
  3987.     LD    A,(DSKSAV)
  3988.     INC    A
  3989.  
  3990. WDRV:    ADD    A,'A'-1
  3991.     CALL    PUTLOG
  3992.     LD    A,(USRSAV)
  3993.     CALL    PNDEC
  3994.     LD    A,'>'        ; Make it look like a prompt
  3995.     CALL    PUTLOG
  3996.     LD    A,(LBRARC)
  3997.     OR    A        ; Member extraction?
  3998.     JR    Z,WDRV1        ; No, won't be member name
  3999.     LD    HL,MEMFCB    ; Name of file in library
  4000.     LD    B,11
  4001.     CALL    PUTSTR
  4002.     CALL    PUTSP        ; ' '
  4003.  
  4004. ;
  4005. ; Put filename in LOG file
  4006. ;
  4007. WDRV1:    LD    HL,FCB+1    ; Now the name of the file
  4008.     LD    B,11
  4009.     CALL    PUTSTR
  4010.     LD    A,(LBRARC)
  4011.     OR    A        ; Member extraction?
  4012.     JR    Z,WDRV2        ; No, won't be member name
  4013.     LD    C,1
  4014.     JR    SPLOOP
  4015.  
  4016. WDRV2:    LD    C,13
  4017.  
  4018. SPLOOP:    PUSH    BC
  4019.     CALL    PUTSP        ; Put ' '
  4020.     POP    BC
  4021.     DEC    C
  4022.     JR    NZ,SPLOOP
  4023.  
  4024. ;
  4025. ; Print number of 'k' to LOG file
  4026. ;
  4027.     LD    HL,(RECDNO)    ; Get record count
  4028.     CALL    DIVREC        ; Divide record count by 8
  4029.  
  4030. EXKB2:    CALL    PNDEC3        ; Print to log file (right just xxxk)
  4031.     LD    HL,LOGK        ; 'k '
  4032.     LD    B,2
  4033.     CALL    PUTSTR
  4034.     XOR    A
  4035.     LD    (COMMA),A    ; Reset field counter
  4036.  
  4037. ;
  4038. ; Print date and time of transfer to LOG file
  4039. ;
  4040.     LD    A,(CLOCK)    ; Clock available in BYE?
  4041.     OR    A
  4042.     JR    NZ,EXKB3    ; Yes, continue
  4043.     LD    A,(RTC)        ; Else how about an RTC overlay?
  4044.     OR    A
  4045.     JR    Z,CLOOP        ; Nope, foget date and time
  4046.  
  4047. EXKB3:    CALL    GETTIME        ; Get CURRENT time for log
  4048.  
  4049.     LD    A,(EDATE)    ; European date format?
  4050.     OR    A
  4051.     JR    Z,EXKB4        ; No
  4052.  
  4053.     LD    A,(DAY)
  4054.     CALL    PNDEC        ; Print DD
  4055.     LD    A,'/'        ; '/'
  4056.     CALL    PUTLOG
  4057.     LD    A,(MONTH)
  4058.     CALL    PNDEC        ; Print MM
  4059.     JR    EXKB5
  4060.  
  4061. EXKB4:    LD    A,(MONTH)
  4062.     CALL    PNDEC        ; Print MM
  4063.     LD    A,'/'        ; '/'
  4064.     CALL    PUTLOG
  4065.     LD    A,(DAY)
  4066.     CALL    PNDEC        ; Print DD
  4067.  
  4068. EXKB5:    LD    A,'/'        ; '/'
  4069.     CALL    PUTLOG
  4070.     LD    A,(YEAR)
  4071.     CALL    PNDEC        ; Print YY
  4072.     CALL    PUTSP        ; ' '
  4073.     LD    A,(HOUR)    ; Get current hour
  4074.     CALL    PNDEC        ; Print hr to file
  4075.     LD    A,':'        ; With ':'
  4076.     CALL    PUTLOG        ; Between HH:MM
  4077.     LD    A,(MINUTE)    ; Get min
  4078.     CALL    PNDEC        ; And print min
  4079.     CALL    PUTSP        ; Print a space
  4080.  
  4081. ;
  4082. ; Print name of caller to LOG file
  4083. ;
  4084. CLOOP:    LD    HL,(CLRPTR)
  4085.     LD    A,(HL)
  4086.     INC    HL
  4087.     LD    (CLRPTR),HL
  4088.     CP    EOF        ; End of file?
  4089.     JR    Z,QUIT        ; Yes
  4090.     CP    CR        ; Do not print 2nd line of 'LASTCALR'
  4091.     JR    NZ,CLOP1
  4092.  
  4093. CEND:    CALL    PUTLOG
  4094.     LD    A,LF
  4095.     CALL    PUTLOG        ; And add a LF
  4096.     JR    QUIT
  4097.  
  4098. CLOP1:    CP    ' '        ; Space?
  4099.     JR    NZ,CLOP1A    ; No, check for comma
  4100.     LD    A,','        ; Convert space to comma for field checking
  4101.  
  4102. CLOP1A:    CP    ','        ; Comma?
  4103.     JR    NZ,CLOP2
  4104.     LD    A,(COMMA)
  4105.     CP    1        ; Is this the second comma or space?
  4106.     JR    NZ,CLOP1B    ; No, bump the counter
  4107.     LD    A,CR
  4108.     JR    CEND        ; Yes, stop taking data from lastcalr
  4109.  
  4110. CLOP1B:    INC    A        ; Bump it one
  4111.     LD    (COMMA),A
  4112.     LD    A,' '        ; Instead send a ' '
  4113.  
  4114. CLOP2:    CALL    PUTLOG
  4115.     JR    CLOOP
  4116.  
  4117. QUIT:    LD    A,EOF        ; Put in EOF
  4118.     CALL    PUTLOG
  4119.     LD    A,(LOGCNT)    ; Check count of chars in buffer
  4120.     CP    1
  4121.     JR    NZ,QUIT        ; Fill last buffer & write it
  4122.     LD    DE,FCBCLR    ; Close lastcaller file
  4123.     LD    C,CLOSE
  4124.     CALL    BDOS
  4125.     INC    A
  4126.     JR    Z,QUIT1
  4127.     LD    HL,(FCBLOG+33)    ; Move pointer back to show
  4128.     DEC    HL        ; Actual file size
  4129.     LD    (FCBLOG+33),HL
  4130.     LD    DE,FCBLOG    ; Close log file
  4131.     LD    C,CLOSE
  4132.     CALL    BDOS
  4133.     INC    A
  4134.     RET    NZ        ; If OK, return now...
  4135.  
  4136. QUIT1:    CALL    ILPRT        ; If error, oops
  4137.     DB    CR,LF
  4138.     DB    '-- Close Error: ',0
  4139.     LD    HL,LOGNAM
  4140.     CALL    SHONM4
  4141.     RET            ; Go back and send EOT
  4142.  
  4143. ;
  4144. ;------------------------- 
  4145. ; LOGCAL Support Routines
  4146. ;
  4147. ; Open file with FCB pointed to by DE (disk/user passed in DEFDSK and DEFUSR)
  4148. ;
  4149. OPENF:    PUSH    DE        ; Save FCB address
  4150.     LD    A,(DEFDSK)     ; Get disk for file
  4151.     CALL    RECDRX        ; Log into it
  4152.     LD    A,(DEFUSR)     ; Get default user
  4153.     CALL    RECAR1        ; Log into it
  4154.     POP    DE        ; Get FCB address
  4155.     LD    A,(CPM3)    ; Using with CPM3?
  4156.     OR    A
  4157.     JR    Z,OPENF1    ; No
  4158.     PUSH    DE        ; Save FCB address
  4159.     CALL    RSDMA        ; Set DMA to 80H
  4160.     POP    DE        ; Get back pointer to FCB
  4161.     PUSH    DE        ; Save FCB pointer again
  4162.     LD    C,SRCHF        ; Search for first match
  4163.     CALL    BDOS
  4164.     INC    A        ; Did file match?
  4165.     POP    DE
  4166.     RET    Z        ; No, return
  4167.     PUSH    DE
  4168.     DEC    A        ; A=directory code (0-3)
  4169.     ADD    A,A        ; *2
  4170.     ADD    A,A        ; *4
  4171.     ADD    A,A        ; *8
  4172.     ADD    A,A        ; *16
  4173.     ADD    A,A        ; *32
  4174.     LD    E,A
  4175.     LD    D,0
  4176.     LD    HL,TBUF        ; Add (32*dir code) to default DMA
  4177.     ADD    HL,DE        ; to find first match filename
  4178.     POP    DE        ; DE=FCB
  4179.     PUSH    DE        ; Save DE again
  4180.     INC    HL        ; Move HL past user # byte in buffer
  4181.     INC    DE        ; Move DE past drive # byte in FCB
  4182.     LD    BC,11
  4183.     LDIR            ; Move name found to FCB
  4184.     POP    DE        ; And continue with open
  4185.  
  4186. OPENF1:    LD    C,OPEN        ; Open file
  4187.     CALL    BDOS
  4188.     CP    0FFH        ; Not present?
  4189.     RET            ; Return to caller
  4190.  
  4191. ;
  4192. ; Write character to log file
  4193. ;
  4194. PUTLOG:    LD    HL,(LOGPTR)    ; Get pointer
  4195.     AND    7FH        ; Strip any attributes
  4196.     LD    (HL),A        ; Put data
  4197.     INC    HL        ; Increment pointer
  4198.     LD    (LOGPTR),HL    ; Update pointer
  4199.     LD    B,A        ; Save character in B
  4200.     LD    A,(LOGCNT)    ; Get count
  4201.     INC    A        ; Increment it
  4202.     LD    (LOGCNT),A    ; Update count
  4203.     CP    129        ; Check it
  4204.     RET    NZ        ; If not EOB, return
  4205.     PUSH    BC        ; Save character
  4206.     LD    DE,FCBLOG    ; Else, write this sector
  4207.     LD    C,WRDM
  4208.     CALL    BDOS
  4209.     OR    A
  4210.     JR    Z,ADVRCP    ; If ok, cont.
  4211.     CALL    ILPRT
  4212.     DB    CR,LF
  4213.     DB    '-- Disk Full: ',0
  4214.     LD    HL,LOGNAM
  4215.     CALL    SHONM4
  4216.     RET
  4217.  
  4218. ADVRCP:    LD    HL,(FCBLOG+33)    ; Advance record number
  4219.     INC    HL
  4220.     LD    (FCBLOG+33),HL
  4221.     CALL    RSTLP        ; Reset buffer pointers
  4222.     POP    AF        ; Get saved character
  4223.     JP    PUTLOG        ; Put it in buffer and return
  4224.  
  4225. RSTLP:    LD    HL,LOGBUF    ; Reset pointers
  4226.     LD    (LOGPTR),HL    ; And return
  4227.     LD    A,0
  4228.     LD    (LOGCNT),A
  4229.     RET
  4230.  
  4231. ;
  4232. ; Print number in decimal format (into log file)  IN: HL=binary number
  4233. ; OUT: nnn=right justified with spaces
  4234. ;
  4235. PNDEC3:    LD    A,H        ; Check high byte
  4236.     OR    A
  4237.     JR    NZ,DECOT    ; If on, is at least 3 digits
  4238.     LD    A,L        ; Else, check low byte
  4239.     CP    100
  4240.     JR    NC,TEN
  4241.     CALL    PUTSP
  4242.  
  4243. TEN:    CP    10
  4244.     JR    NC,DECOT
  4245.     CALL    PUTSP
  4246.     JR    DECOT
  4247.  
  4248. ;
  4249. ; Print number in decimal format (into log file)
  4250. ;
  4251. PNDEC:    CP    10        ; Two column decimal format routine
  4252.     JR    C,ONE        ; One or two digits to area number?
  4253.     JR    TWO
  4254.  
  4255. ONE:    PUSH    AF
  4256.     LD    A,'0'
  4257.     CALL    PUTLOG
  4258.     POP    AF
  4259.  
  4260. TWO:    LD    H,0
  4261.     LD    L,A
  4262.  
  4263. DECOT:    PUSH    BC
  4264.     PUSH    DE
  4265.     PUSH    HL
  4266.     LD    BC,-10
  4267.     LD    DE,-1
  4268.  
  4269. DECOT2:    ADD    HL,BC
  4270.     INC    DE
  4271.     JR    C,DECOT2
  4272.     LD    BC,10
  4273.     ADD    HL,BC
  4274.     EX    DE,HL
  4275.     LD    A,H
  4276.     OR    L
  4277.     CALL    NZ,DECOT
  4278.     LD    A,E
  4279.  
  4280. DECOT3:    ADD    A,'0'
  4281.     CALL    PUTLOG
  4282.  
  4283. DECOT4:    POP    HL
  4284.     POP    DE
  4285.     POP    BC
  4286.     RET
  4287.  
  4288. ;
  4289. ; Put string to log file
  4290. ;
  4291. PUTSTR:    LD    A,(HL)
  4292.     PUSH    HL
  4293.     PUSH    BC
  4294.     CALL    PUTLOG
  4295.     POP    BC
  4296.     POP    HL
  4297.     INC    HL
  4298.     DJNZ    PUTSTR
  4299.     RET
  4300.  
  4301. ;
  4302. ; Puts a single space in log file, saves PSW/HL
  4303. ;
  4304. PUTSP:    PUSH    AF
  4305.     PUSH    HL
  4306.     LD    A,' '
  4307.     CALL    PUTLOG
  4308.     POP    HL
  4309.     POP    AF
  4310.     RET
  4311.  
  4312. ;
  4313. ;-------------------------------------------------------------------------;
  4314. ; T I M E   &   D A T E      R o u t i n e s                    |
  4315. ;-------------------------------------------------------------------------;
  4316. ;
  4317. ; Get RTCBUF address if running BYE
  4318. ;
  4319. TIME:    LD    A,(CLOCK)    ; Clock in BYE?
  4320.     OR    A
  4321.     JR    Z,TIME1        ; No
  4322.     LD    DE,25        ; Offset to RTCBUF address
  4323.     CALL    GETOFF        ; Point to JP COLDBOOT + offset in DE
  4324.     LD    E,(HL)        ; HL points to RTCBUF address
  4325.     INC    HL        ; To most significant byte of address
  4326.     LD    D,(HL)
  4327.     EX    DE,HL        ; Back to HL
  4328.     LD    (RTCBUF),HL    ; Save for later use
  4329.     CALL    GETTIME        ; Store RTCBUF contents internally
  4330.  
  4331.     LD    HL,(RTCBUF)    ; Get RTC buffer address
  4332.     LD    DE,7        ; Offset to time on system (TOS) word
  4333.     ADD    HL,DE        ; Address in HL
  4334.     LD    A,(HL)        ; Get minutes on system
  4335.     LD    (TON),A        ; Store time on system for SHOWTOS
  4336.  
  4337. ;
  4338. ; Get MAXTOS if restricting downloads to time left
  4339. ;
  4340.     LD    A,(TIMEON)    ; Policing time on system?
  4341.     OR    A
  4342.     JP    Z,SHOWTOS    ; No
  4343.     LD    DE,24        ; Offset to maximum time allowed
  4344.     CALL    GETOFF        ; Point to JP COLDBOOT + offset in D
  4345.  
  4346.     LD    A,(MODE)    ; Exiting? (Gets set NZ in exit routine)
  4347.     OR    A
  4348.     JR    Z,TIME0        ; No, skip next
  4349.     LD    A,(MAXTOS)    ; Reset maximum time allowed
  4350.     LD    (HL),A
  4351.     JR    TIME0A
  4352.  
  4353. TIME0:    LD    A,(HL)        ; Get maximum time allowed
  4354.     LD    (MAXTOS),A    ; Store it
  4355.     LD    (HL),0        ; Disable BYE from checking time for now
  4356.  
  4357. TIME0A:    LD    A,(TON)
  4358.     LD    B,A        ; Save time on system for comparison
  4359.     LD    A,(MAXTOS)    ; Get maximum time allowed
  4360.     SUB    B        ; Get time left on system
  4361.     LD    (TLOS),A    ; Store time left on system
  4362.     JP    SHOWTOS        ; Go show TON
  4363.  
  4364. ;
  4365. ; Get TON if RTC
  4366. ;
  4367. TIME1:    LD    A,(RTC)        ; Clock reader code installed in ZMD?
  4368.     OR    A
  4369.     JP    Z,SHOWTOS    ; No
  4370.     CALL    GETTIME
  4371.  
  4372.     LD    HL,(LHOUR)    ; Get address to logon hour
  4373.     LD    A,(HOUR)
  4374.     CP    (HL)        ; Same as current hour?
  4375.     INC    HL        ; Point to logon minute
  4376.     LD    D,(HL)        ; Get it in D
  4377.     JR    NZ,TIME2    ; No, not the same
  4378.     LD    A,(MINUTE)    ; Else get current minute
  4379.     SUB    D        ; Subtract logon minute
  4380.     LD    (TON),A        ; Store it as time on system
  4381.     JR    TIME3        ; Get maximum allowed
  4382.  
  4383. TIME2:    LD    A,60        ; Fake an hour
  4384.     SUB    D        ; Subtract logon minute
  4385.     LD    HL,MINUTE    ; Point to current minute
  4386.     ADD    A,(HL)        ; Add them
  4387.     LD    (TON),A        ; Store as current time on system
  4388.  
  4389. ;
  4390. ; Get MAXTOS if TIMEON
  4391. ;
  4392. TIME3:    LD    A,(TIMEON)    ; Restricting downloads to time left?
  4393.     OR    A
  4394.     JR    Z,SHOWTOS    ; No
  4395.     CALL    WHLCHK        ; WHEEL byte set?
  4396.     JR    NZ,SHOWTOS    ; Yes, just display time on system
  4397.     LD    A,(MODE)    ; Else been here before?
  4398.     OR    A
  4399.     JR    NZ,TIME4    ; Yes (MODE is 0 first time through)
  4400.     LD    A,(MAXMIN)
  4401.     LD    (MAXTOS),A    ; Else set maximum time allowed
  4402.     LD    (TLOS),A    ; And current time left on system
  4403.  
  4404. TIME4:    LD    A,(MAXTOS)    ; Get current maximum time allowed
  4405.     OR    A        ; Unlimited?
  4406.     JR    Z,SHOWTOS    ; Yes, just display time on system
  4407.     LD    A,(MAXMIN)    ; Else get original maximum minutes allowed
  4408.     LD    B,A        ; Into B
  4409.     LD    A,(TON)        ; Get current time on system
  4410.     SUB    B        ; Time up?
  4411.     JR    C,SHOWTOS    ; No, just display time on system
  4412.  
  4413.     CALL    ILPRTB
  4414.     DB    CR,LF,LF
  4415.     DB    '-- Your time is up, please share the system with others'
  4416.     DB    CR,LF,0
  4417.     POP    HL
  4418.     LD    A,0CDH
  4419.     LD    (0),A
  4420.     JP    0
  4421.  
  4422. ;
  4423. ; Display the time on system
  4424. ;
  4425. SHOWTOS:LD    A,(DSPTOS)    ; Display time on system message?
  4426.     OR    A
  4427.     RET    Z        ; No, all done
  4428.     LD    A,(MODE)    ; Else exiting?
  4429.     OR    A
  4430.     JR    Z,SHOTOS1    ; Yes, no line feed
  4431.     CALL    ILPRTB
  4432.     DB    CR,LF,0
  4433.  
  4434. SHOTOS1:CALL    ILPRTB
  4435.     DB    'Online ',0
  4436.     LD    A,(TON)        ; Get time on system
  4437.     LD    H,0        ; Zero H
  4438.     LD    L,A        ; TON in L
  4439.     CALL    DECOUT        ; Decimal output
  4440.     CALL    ILPRTB
  4441.     DB    ' minute',0
  4442.     LD    A,(TON)        ; Get time on system
  4443.     CP    1        ; 1?
  4444.     JR    Z,SHOTOS2    ; Yes, leave display as 'minute'
  4445.     CALL    ILPRTB
  4446.     DB    's',0        ; Else make it plural
  4447.  
  4448. SHOTOS2:LD    A,(MODE)
  4449.     OR    A
  4450.     RET    NZ
  4451.     CALL    ILPRT
  4452.     DB    CR,LF,0
  4453.     RET
  4454.  
  4455. ;
  4456. ; Transfer BYE's RTCBUF contents to internal storage
  4457. ;
  4458. GETTIME:LD    A,(RTC)        ; User installed clock routines?
  4459.     OR    A
  4460.     JP    NZ,RTCTIM    ; Yes, go do it
  4461.     LD    HL,(RTCBUF)
  4462.  
  4463.     LD    A,(HL)        ; 00:
  4464.     CALL    BCDBIN        ; Convert to binary
  4465.     LD    (HOUR),A    ; Save
  4466.  
  4467.     CALL    GETTIM3        ; :00
  4468.     LD    (MINUTE),A    ; Save
  4469.  
  4470.     INC    HL        ; Skip seconds
  4471.     INC    HL        ; Skip '19'nn
  4472.     CALL    GETTIM3        ; YY
  4473.     LD    (YEAR),A    ; Save
  4474.  
  4475.     CALL    GETTIM3        ; MM
  4476.     LD    (MONTH),A    ; Save
  4477.  
  4478.     CALL    GETTIM3        ; DD
  4479.     LD    (DAY),A        ; Save
  4480.     RET            ; And return
  4481.  
  4482. GETTIM3:INC    HL        ; Increment to next RTC byte value
  4483.     LD    A,(HL)        ; Get it
  4484.     JP    BCDBIN        ; Return with binary value in A
  4485.  
  4486. ;
  4487. ; Add the time of the last upload/download to BYE's time on system byte
  4488. ;
  4489. ADDTON:    LD    A,(TIMEON)    ; Using TIMEON?
  4490.     OR    A
  4491.     RET    Z
  4492.  
  4493.     CALL    BYECHK        ; If so, see if BYE is running
  4494.     OR    A        ; 0 if no clock, or 0 if no BYE.
  4495.     LD    HL,TON        ; Prepare for internal RTC
  4496.     JR    Z,ADDTN1
  4497.  
  4498.     LD    HL,(RTCBUF)    ; Get RTC buffer address
  4499.     LD    DE,7        ; Get offset to TOS word
  4500.     ADD    HL,DE        ; Add offset, HL contains TON address
  4501.  
  4502. ADDTN1:    PUSH    HL        ; Save it
  4503.     LD    HL,(RECDNO)
  4504.     LD    (RCNT),HL
  4505.     CALL    XTIM        ; Calculate transfer time
  4506.     POP    HL        ; Restore TON address
  4507.     LD    A,(HL)        ; Get time on in A
  4508.     LD    B,A        ; Save it
  4509.     LD    A,(MODE)    ; Get current transfer mode
  4510.     CP    'S'        ; Is this a download?
  4511.     JR    Z,ADDTN2    ; Yes, subtract download time
  4512.     LD    A,(CREDIT)    ; Else crediting upload time?
  4513.     OR    A
  4514.     RET    Z        ; No, skip this
  4515.     LD    A,B        ; Else get time on system back
  4516.     SUB    C        ; Subtract upload time
  4517.     LD    (HL),A        ; Store it
  4518.     RET    
  4519.  
  4520. ADDTN2:    LD    A,B
  4521.     INC    A        ; Bump it one
  4522.     ADD    A,C        ; Add transfer time
  4523.     LD    (HL),A        ; Put it back for BYE
  4524.     RET
  4525.  
  4526. ;
  4527. ;-------------------------------------------------------------------------;
  4528. ; A v a i l a b l e   U p l o a d   S p a c e                  |
  4529. ;-------------------------------------------------------------------------;
  4530. ;
  4531. ; This routine is called with the 'F' option from both CP/M (with 'ZMD F')
  4532. ; or from The HELP Guide routines.  First determine where uploads are
  4533. ; suppose to go.
  4534. ;
  4535. SPACE:    CALL    RSTLCK        ; Go reset WRTLOC if needed
  4536.     CALL    WHLCHK        ; WHEEL byte set?
  4537.     JR    NZ,SPACE1    ; Yes, give space for current drive/user
  4538.     LD    A,(ASKAREA)
  4539.     OR    A
  4540.     JR    NZ,SPACE2
  4541.     LD    A,(SETAREA)
  4542.     OR    A
  4543.     JR    NZ,SPACE2    ; Yes
  4544.  
  4545. SPACE1:    LD    A,(OLDDRV)    ; Get currently logged drive
  4546.     ADD    A,'A'        ; Make it ASCII
  4547.     LD    (DRV),A
  4548.     LD    (KDRV),A    ; Store it for KSHOW
  4549.     LD    A,(OLDUSR)    ; Get currently logged user
  4550.     LD    (USR),A        ; Store it for KSHOW
  4551.  
  4552. SPACE2:    CALL    WHLCHK
  4553.     CALL    Z,GETKIND    ; Get upload area if ASKAREA
  4554.     CALL    ILPRTB
  4555.     DB    CR
  4556.     DB    '  Regular ',0
  4557.     CALL    SPACE8
  4558.     CALL    ILPRTB
  4559.     DB    CR,LF
  4560.     DB    '  Private ',0
  4561.     LD    A,1
  4562.     LD    (PRVSPC),A
  4563.     CALL    SPACE8
  4564.     JP    EXIT        ; Exit to CP/M
  4565.  
  4566. ;
  4567. ; Displays the file descriptor/category when showing available upload space.
  4568. ;
  4569. SPACE8:    CALL    WHLCHK
  4570.     CALL    Z,SHOCAT    ; Show upload area descriptor, if supposed to
  4571.     CALL    ILPRTB
  4572.     DB    'uploads received on ',0
  4573.     LD    A,(PRVSPC)    ; Want private area space?
  4574.     OR    A
  4575.     JR    NZ,SPACE9    ; Yes, do private stuff
  4576.     LD    A,(DRV)        ; Get drive to receive regular upload
  4577.     LD    (KDRV),A    ; Store it for KSHOW
  4578.     CALL    TYPE        ; Output to modem
  4579.     LD    A,(USR)        ; Get user area to receive regular upload
  4580.     JR    SPACE10        ; Go show free space
  4581.  
  4582. SPACE9:    LD    A,(PRDRV)    ; Get drive to receive private upload
  4583.     LD    (KDRV),A    ; Store it for KSHOW
  4584.     CALL    TYPE        ; Output to modem
  4585.     LD    A,(PRUSR)    ; Get user area to receive private upload
  4586.  
  4587. SPACE10:LD    H,0
  4588.     LD    L,A        ; User area in L
  4589.     CALL    DECOUT        ; Decimal output
  4590.     CALL    ILPRTB
  4591.     DB    ':',0
  4592.     LD    A,(PRVSPC)    ; Getting private info?
  4593.     OR    A
  4594.     JR    Z,SPACE11    ; No
  4595.     LD    A,(DRV)        ; Else get regular drive
  4596.     LD    HL,PRDRV    ; Point to private drive
  4597.     CP    (HL)        ; Private same as regular drive?
  4598.     RET    Z        ; Yes, don't report 'k' this time
  4599.  
  4600. SPACE11:CALL    ILPRTB
  4601.     DB    '   (',0
  4602.     LD    A,(KDRV)    ; Get upload drive
  4603.     CALL    KSHOW        ; Show available space for drive
  4604.     CALL    ILPRTB
  4605.     DB    ')',0
  4606.     RET
  4607.  
  4608. ;
  4609. ;-------------------------------------------------------------------------;
  4610. ; R u n t i m e   H e l p   G u i d e                      |
  4611. ;-------------------------------------------------------------------------;
  4612. ;
  4613. ; Either 'ZMD' was entered by itself from CP/M, or an invalid option
  4614. ; given.
  4615. ;
  4616. HELP:    CALL    ILPRTB
  4617.     DB    CR,LF,'                 mode   drive/user'
  4618.     DB    CR,LF,'                /      /'
  4619.     DB    CR,LF,'Usage:  ZMD    SK   {du:}   <fn>'
  4620.     DB    CR,LF,'               /             /'
  4621.     DB    CR,LF,'       protocol      filename'
  4622.     DB    CR,LF
  4623.     DB    CR,LF,'Mode:                             Protocol:'
  4624.     DB    CR,LF,'  S  - Send file from BBS           '
  4625.     DB    'X  - Xmodem 128 byte blocks  (CRC)'
  4626.     DB    CR,LF,'  SP - Send from private area       '
  4627.     DB    'C  - Xmodem 128 byte blocks  (Checksum)'
  4628.       DB    CR,LF,'  A  - Send ARK/ARC/LBR member      '
  4629.     DB    'K  - Ymodem 1024 byte blocks (CRC only)'
  4630.     DB    CR,LF,'  R  - Receive file from YOU'
  4631.       DB    CR,LF,'  RP - Receive in private area',0
  4632.  
  4633.  
  4634.     CALL    ILPRTB
  4635.     DB    CR,LF,0
  4636.     LD    A,(MSGFIL)
  4637.     OR    A
  4638.     JR    Z,HELP1 
  4639.       CALL    ILPRTB
  4640.     DB    '  RM - Receive preformatted message base upload',0
  4641.  
  4642. HELP1:    CALL    ILPRTB
  4643.     DB    CR,LF,0
  4644.     CALL    WHLCHK
  4645.     JR    Z,HELP2
  4646.     CALL    ILPRTB
  4647.     DB    '  RW - Receive without description(s)',0
  4648.  
  4649. HELP2:    CALL    ILPRTB
  4650.     DB    CR,LF,'  F  - Displays available upload space'
  4651.     DB    CR,LF
  4652.     DB    CR,LF
  4653.     DB    CR,LF
  4654.     DB    '--SPACE BAR displays specific examples--',0
  4655.  
  4656.     CALL    INPUT
  4657.     CP    ' '
  4658.     JP    NZ,EXIT
  4659.  
  4660.     LD    HL,ZMDNAM
  4661.     CALL    PRINTV
  4662.     CALL    ILPRTB
  4663.     DB    'Usage examples:'
  4664.     DB    CR,LF
  4665.     DB    CR,LF,' ZMD S   filename.ext         '
  4666.     DB    'Send single file        (Automatic detect)'
  4667.     DB    CR,LF,' ZMD S   B4:filename.ext      '
  4668.     DB    'Send single file        (Automatic detect)'
  4669.      DB    CR,LF,' ZMD SK  filename.ext         '
  4670.     DB    'Send single file        (Ymodem 1k)'
  4671.      DB    CR,LF,' ZMD S   filename.*           '
  4672.     DB    'Send from current d/u   (Ymodem 1k Batch)'
  4673.      DB    CR,LF,' ZMD S   D1:*.*  B9:*.doc     '
  4674.     DB    'Send from multiple d/u  (Ymodem 1k Batch)'
  4675.     DB    CR,LF,' ZMD A   librnam lbrmber.ext  '
  4676.     DB    'Send ARK/ARC/LBR member (Automatic detect)'
  4677.      DB    CR,LF,' ZMD AK  librnam lbrmber.ext  '
  4678.     DB    'Send ARK/ARC/LBR member (Ymodem 1k)'
  4679.     DB    CR,LF
  4680.     DB    CR,LF,' ZMD R   filename.ext         '
  4681.     DB    'Receive single file     (Automatic detect)'
  4682.      DB    CR,LF,' ZMD R                        '
  4683.     DB    'Receive multiple files  (Ymodem 1k Batch)'
  4684.      DB    CR,LF,' ZMD RPC filename.ext         '
  4685.     DB    'Receive to private area (Checksum)'
  4686.     DB    CR,LF,LF
  4687.      DB    'Protocol may be omitted for automatic protocol detection.'
  4688.      DB    CR,LF
  4689.     DB    'Ymodem 1k Batch is enabled upon detection of wildcards or'
  4690.     DB    ' multiple'
  4691.     DB    CR,LF
  4692.         DB    '   filenames on command line (can also be forced with'
  4693.     DB    ' ''SB'' mode).',0
  4694.     JP    EXIT 
  4695.  
  4696.  
  4697. ABRTMSG:CALL    ILPRTB
  4698.     DB    CR
  4699.     DB    '-- ZMD Aborted',0
  4700.     RET
  4701.  
  4702. NOACC:    CALL    SENDBEL        ; Send a bell out modem only
  4703.     CALL    ERXIT
  4704.     DB    CR,LF
  4705.     DB    '-- Restricted Function - Access Denied','$'
  4706.  
  4707. ZEROLN:    CALL    ERXIT
  4708.     DB    CR,LF
  4709.     DB    '-- File empty - ZMD aborted','$'
  4710.  
  4711. NOFILE:    CALL    ERXIT
  4712.     DB    CR
  4713.     DB    '-- No matching filename(s) found','$'
  4714.  
  4715. NOIO:    XOR    A
  4716.     LD    (RTC),A
  4717.     LD    (TIMEON),A
  4718.     LD    (DSPTOS),A
  4719.     LD    (CLOCK),A
  4720.     CALL    ERXIT
  4721.     DB    BELL
  4722.     DB    '-- Modem I/O unavailable - Aborting','$'
  4723.  
  4724. TOOSLOW:CALL    ERXIT
  4725.     DB    CR,LF,LF
  4726.     DB    '-- YMODEM 1k/BATCH not valid - Modem speed too slow','$'
  4727.  
  4728.  
  4729. TOTMSG:    CALL    ILPRTL
  4730.     DB    ' - Timeout, no character received',CR,LF,0
  4731.     RET
  4732.  
  4733. DLRDY:    CALL    ILPRT
  4734.     DB    CR,LF
  4735.     DB    'Your file(s) now ready to download',0
  4736.     CALL    CONT6
  4737.     RET
  4738.  
  4739. WAITMSG:CALL    ILPRTL
  4740.     DB    ' -- Waiting --'
  4741.     DB    CR,0
  4742.     RET
  4743.  
  4744. ;
  4745. ;-------------------------------
  4746. ; File type restriction storage
  4747. ;-------------------------------
  4748. ;
  4749. ; Don't allow ___                (If ZCPR is YES)
  4750. ;         \
  4751. SYSCHK:    DB    'SYS'
  4752. NDRCHK:    DB    'NDR'
  4753. RCPCHK:    DB    'RCP'
  4754.  
  4755. ;
  4756. ; If receiving __     change it to __       (If NOCOMR is YES)
  4757. ;         \             \
  4758. COMCHG:    DB    'COM',            'OBJ'
  4759. PRLCHG:    DB    'PRL',            'OBP'
  4760.  
  4761. ;
  4762. ; If the library extraction flag (LBRARC) is set and an unsuccessful open with
  4763. ; the default filetype occurs, the following file types are copied to FCB+9
  4764. ; and the open attempt is repeated.
  4765. ARCNAM:    DB    'ARC'        ; Copied to FCB+9
  4766. LBRNAM:    DB    'LBR'        ; Copied to FCB+9
  4767. ARKNAM:    DB    'ARK'        ; Copied to FCB+9
  4768.  
  4769. ;
  4770. ;---------------------
  4771. ; LOGCALL allocations
  4772. ;---------------------
  4773. ;
  4774. DEFDSK:    DB    0        ; Disk for open stored here
  4775. DEFUSR:    DB    0        ; User for open stored here
  4776. CLRPTR:    DW    LOGBUF
  4777. LOGPTR:    DW    DBUF
  4778. LOGCNT:    DB    0
  4779. LOGK:    DB    'k '
  4780. DUSAVE:    DB    0,0,0,0        ; Buffer for drive/user
  4781.  
  4782. ;
  4783. ;------------------
  4784. ; Time allocations
  4785. ;------------------
  4786. ;
  4787. MAXTOS:    DB    0        ; Maximum time left on system
  4788. RTCBUF:    DW    0        ; RTCBUF address
  4789. TLOS:    DB    0        ; Current time left on system
  4790. TON:    DB    0        ; Current time on system
  4791.  
  4792. ;
  4793. XTABLE:    DW    5,   13,  19,  25,  30,  48,  85, 141, 210, 280,   0
  4794. KTABLE:    DW    5,   14,  21,  27,  32,  53, 101, 190, 330, 525,   0
  4795. XECTBL:    DB    192, 74,  51,  38,  32,  20,  11,   8,   5,   3,   0
  4796. KECTBL:    DB    192, 69,  46,  36,  30,  18,  10,   5,   3,   2,   0
  4797.  
  4798. ;
  4799. ;--------------------
  4800. ; Batch mode storage
  4801. ;--------------------
  4802. ;
  4803. BGNMS:    DW    0        ; Start address of filenames in TBUFF
  4804. LIST:    DW    DBUF        ; Filename storage in send batch mode
  4805. LISTPOS:DW    0        ; Next position to store matching filename
  4806. LISTEND:DW    0        ; Address of last matching filename
  4807. LISTI:    DW    0        ; Pointer 1 for two-dimensional bubble sort
  4808. LISTJ:    DW    0        ; Pointer 2 for two-dimensional bubble sort
  4809. FILEK:    DW    0        ; Total kilobytes  of files found (send batch)
  4810. FCBBUF:    DS    21        ; Batch filename from command line
  4811. FSTFLG:    DB    0        ; Set to 1 when command line scan done
  4812. NAMECT:    DB    0        ; # of names on command line
  4813. NBSAVE:    DW    0        ; Start address in NAMBUF for next file
  4814. SBSHOW:    DB    0        ; Set shows partial stat display in batch
  4815. SHOCNT:    DB    0        ; Counter to show files left
  4816. TOTREC:    DW    0        ; Total records to be sent
  4817.  
  4818. ;
  4819. ;------------------------
  4820. ; Temporary storage area
  4821. ;------------------------
  4822. ;
  4823. ACKCHK:    DB    0        ; Lets batch header user GTACK routine
  4824. AFBYTE:    DB    0        ; Access flags byte storage
  4825. CHKEOT:    DB    0        ; Prevents locking up after an EOT
  4826. COMMA:    DB    0        ; Field counter for logcal
  4827. CRCFLG:    DB    1        ; For sending checksum rather than CRC
  4828. EOFLG:    DB    0        ; EOF (End of file) flag
  4829. EOTFLG:    DB    0        ; EOT (End of transmission) status flag
  4830. ERRCNT:    DB    0        ; Error count
  4831. FRSTIM:    DB    0        ; Turned on after first 'SOH' received
  4832. GOTONE:    DB    0        ; Prevents asking for a description
  4833. KFLG:    DB    1        ; For sending 1k blocks (Defaults to 1k)
  4834. PRVSPC:    DB    0        ; Shows in private display in SPACE: if set
  4835. RCVCNT:    DB    0        ; Record number received
  4836. RCVTRY:    DB    0        ; Keeps track of number of attempts
  4837. RCVDRV:    DB    0        ; Requested drive number
  4838. RCVUSR:    DB    0        ; Requested user number
  4839.  
  4840. ACCERR:    DW    0        ; No 'ACK' error count for 1k ratio
  4841. HDRADR:    DW    0        ; Current location in batch header block
  4842. RCNT:    DW    0        ; Record count
  4843. RECDNO:    DW    0        ; Current record number
  4844. RCDCNT:    DW    0        ; Used in sending the record header
  4845. RECPTR:    DW    DBUF
  4846. RECNBF:    DW    0        ; Number of records in the buffer
  4847. SAVEHL:    DW    0        ; Saves TBUF command line address
  4848. XFRMIN:    DW    0        ; Transfer time in mins for TIMEON
  4849.  
  4850. ;
  4851.     END            ; 'Almost'...
  4852.