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 / ZCPR2 / MCOPY.MAC < prev    next >
Text File  |  2000-06-30  |  37KB  |  1,723 lines

  1. ;  PROGRAM:  MCOPY
  2. ;  AUTHOR:  RICHARD CONN
  3. ;  VERSION:  3.0
  4. ;  DATE:  16 JAN 83
  5. ;  PREVIOUS VERSIONS:  2.8 (14 JAN 83), 2.7 (11 JAN 83)
  6. ;  PREVIOUS VERSIONS:  2.6 (9 JAN 83), 2.5 (8 JAN 83), 2.4 (7 JAN 83)
  7. ;  PREVIOUS VERSIONS:  2.3 (6 JAN 83), 2.2 (19 DEC 82)
  8. ;  PREVIOUS VERSIONS:  2.1 (7 DEC 82), 2.0 (14 NOV 82), 1.7 (21 JULY 82)
  9. ;  PREVIOUS VERSIONS:  1.6 (12 JULY 82), 1.5 (12 JULY 82)
  10. ;  PREVIOUS VERSIONS:  1.4 (10 JULY 82), 1.3 (9 JULY 82)
  11. ;  PREVIOUS VERSIONS:  1.0 (27 Oct 80), 1.1 (2 NOV 80), 1.2 (11 APR 81)
  12. VERS    equ    30
  13.  
  14. ;
  15. ;    This program is Copyright (c) 1982, 1983 by Richard Conn
  16. ;    All Rights Reserved
  17. ;
  18. ;    ZCPR2 and its utilities, including this one, are released
  19. ; to the public domain.  Anyone who wishes to USE them may do so with
  20. ; no strings attached.  The author assumes no responsibility or
  21. ; liability for the use of ZCPR2 and its utilities.
  22. ;
  23. ;    The author, Richard Conn, has sole rights to this program.
  24. ; ZCPR2 and its utilities may not be sold without the express,
  25. ; written permission of the author.
  26. ;
  27.  
  28.  
  29. ;
  30. ;    MCOPY is a program which repeatedly copies a file from drive
  31. ; A: onto drive B:.  It prompts the user to mount a disk in drive B:,
  32. ; copies the file from drive A: to drive B:, verifies the copy (if not
  33. ; overridden), and then performs the function again.
  34. ;
  35. ;    MCOPY performs its function in the following steps:
  36. ;        1.  If CP/M 2.x or MP/M, MCOPY determines the attributes
  37. ; of the destination file (if it exists) and clears them (file becomes
  38. ; R/W and DIR)
  39. ;        2.  MCOPY deletes the destination file (if it exists)
  40. ;        3.  MCOPY copies the source file to the destination
  41. ;        4.  If CP/M 2.x or MP/M, MCOPY determines the attributes
  42. ; of the source file and makes the attributes of the destination file
  43. ; identical to those of the source
  44. ;        5.  MCOPY reads both the source and destination files and
  45. ; compares them byte-for-byte
  46. ;
  47.  
  48. ;  CP/M Constants
  49. CPM    EQU    0    ; CP/M WARM BOOT
  50. BDOSE    EQU    CPM+5    ; BDOS ENTRY POINT
  51. FCB    EQU    CPM+5CH    ; SPECIFIED FCB
  52. BUFF    EQU    CPM+80H    ; DEFAULT BUFFER AND INPUT LINE
  53.  
  54. ;  ASCII Constants, et al
  55. ON    EQU    0FFH    ; ON CODE
  56. OFF    EQU    0    ; OFF CODE
  57. CR    EQU    0DH    ; <CR>
  58. LF    EQU    0AH    ; <LF>
  59. CTRLC    EQU    'C'-'@'    ; ^C
  60. CTRLZ    EQU    'Z'-'@'    ; ^Z
  61. OPTC    EQU    '/'    ; OPTION DELIMITER
  62. DIV    EQU    '!'    ; COPY/VERIFY PHASE DELIMITER
  63. FLIMIT    EQU    1024    ; 1024 FILES PERMITTED
  64.  
  65. ;
  66. ;  SYSLIB ROUTINES
  67. ;
  68.     EXT    CLINE,COMPHD,ZGPINS,RETUD,LOGUD,BLINE
  69.     EXT    ZFNAME,DPARAMS,DIRF,DIRFS,FSIZE,DFREE
  70.     EXT    DIRPACK,INITFCB,F$EXIST
  71.     EXT    EVAL,CRCCLR,CRCUPD,CRCDONE
  72.     EXT    BDOS,CIN,COUT
  73.     EXT    F$DELETE,F$OPEN,F$MAKE,F$CLOSE,F$READ,F$WRITE
  74.     EXT    PHLDC,PADC,PSTR,PRINT
  75.     EXT    MOVEB,CAPS,CRLF
  76.     EXT    CODEND
  77.  
  78. ;
  79. ;  Branch to Start of Program
  80. ;
  81.     JMP    START
  82.  
  83. ;
  84. ;******************************************************************
  85. ;
  86. ;  SINSFORM -- ZCPR2 Utility Standard General Purpose Initialization Format
  87. ;
  88. ;    This data block precisely defines the data format for
  89. ; initial features of a ZCPR2 system which are required for proper
  90. ; initialization of the ZCPR2-Specific Routines in SYSLIB.
  91. ;
  92.  
  93. ;
  94. ;  EXTERNAL PATH DATA
  95. ;
  96. EPAVAIL:
  97.     DB    0FFH    ; IS EXTERNAL PATH AVAILABLE? (0=NO, 0FFH=YES)
  98. EPADR:
  99.     DW    40H    ; ADDRESS OF EXTERNAL PATH IF AVAILABLE
  100.  
  101. ;
  102. ;  INTERNAL PATH DATA
  103. ;
  104. INTPATH:
  105.     DB    0,0    ; DISK, USER FOR FIRST PATH ELEMENT
  106.             ; DISK = 1 FOR A, '$' FOR CURRENT
  107.             ; USER = NUMBER, '$' FOR CURRENT
  108.     DB    0,0
  109.     DB    0,0
  110.     DB    0,0
  111.     DB    0,0
  112.     DB    0,0
  113.     DB    0,0
  114.     DB    0,0    ; DISK, USER FOR 8TH PATH ELEMENT
  115.     DB    0    ; END OF PATH
  116.  
  117. ;
  118. ;  MULTIPLE COMMAND LINE BUFFER DATA
  119. ;
  120. MCAVAIL:
  121.     DB    0FFH    ; IS MULTIPLE COMMAND LINE BUFFER AVAILABLE?
  122. MCADR:
  123.     DW    0FF00H    ; ADDRESS OF MULTIPLE COMMAND LINE BUFFER IF AVAILABLE
  124.  
  125. ;
  126. ;  DISK/USER LIMITS
  127. ;
  128. MDISK:
  129.     DB    4    ; MAXIMUM NUMBER OF DISKS
  130. MUSER:
  131.     DB    31    ; MAXIMUM USER NUMBER
  132.  
  133. ;
  134. ;  FLAGS TO PERMIT LOG IN FOR DIFFERENT USER AREA OR DISK
  135. ;
  136. DOK:
  137.     DB    0FFH    ; ALLOW DISK CHANGE? (0=NO, 0FFH=YES)
  138. UOK:
  139.     DB    0FFH    ; ALLOW USER CHANGE? (0=NO, 0FFH=YES)
  140.  
  141. ;
  142. ;  PRIVILEGED USER DATA
  143. ;
  144. PUSER:
  145.     DB    10    ; BEGINNING OF PRIVILEGED USER AREAS
  146. PPASS:
  147.     DB    'chdir',0    ; PASSWORD FOR MOVING INTO PRIV USER AREAS
  148.     DS    41-($-PPASS)    ; 40 CHARS MAX IN BUFFER + 1 for ending NULL
  149.  
  150. ;
  151. ;  CURRENT USER/DISK INDICATOR
  152. ;
  153. CINDIC:
  154.     DB    '$'    ; USUAL VALUE (FOR PATH EXPRESSIONS)
  155.  
  156. ;
  157. ;  DMA ADDRESS FOR DISK TRANSFERS
  158. ;
  159. DMADR:
  160.     DW    80H    ; TBUFF AREA
  161.  
  162. ;
  163. ;  NAMED DIRECTORY INFORMATION
  164. ;
  165. NDRADR:
  166.     DW    00000H    ; ADDRESS OF MEMORY-RESIDENT NAMED DIRECTORY
  167. NDNAMES:
  168.     DB    64    ; MAX NUMBER OF DIRECTORY NAMES
  169. DNFILE:
  170.     DB    'NAMES   '    ; NAME OF DISK NAME FILE
  171.     DB    'DIR'        ; TYPE OF DISK NAME FILE
  172.  
  173. ;
  174. ;  REQUIREMENTS FLAGS
  175. ;
  176. EPREQD:
  177.     DB    0FFH    ; EXTERNAL PATH?
  178. MCREQD:
  179.     DB    0FFH    ; MULTIPLE COMMAND LINE?
  180. MXREQD:
  181.     DB    0FFH    ; MAX USER/DISK?
  182. UDREQD:
  183.     DB    0FFH    ; ALLOW USER/DISK CHANGE?
  184. PUREQD:
  185.     DB    0FFH    ; PRIVILEGED USER?
  186. CDREQD:
  187.     DB    0FFH    ; CURRENT INDIC AND DMA?
  188. NDREQD:
  189.     DB    0FFH    ; NAMED DIRECTORIES?
  190. Z2CLASS:
  191.     DB    2    ; CLASS 2
  192.     DB    'ZCPR2'
  193.     DS    10    ; RESERVED
  194.  
  195. ;
  196. ;  END OF SINSFORM -- STANDARD DEFAULT PARAMETER DATA
  197. ;
  198. ;******************************************************************
  199. ;
  200.  
  201. ;
  202. ;  USER-DEFINABLE INITIAL FLAG CONDITIONS
  203. ;    THE DEFAULT CONDITIONS FOR MCOPY MAY BE READILY PATCHED BY THE USER
  204. ; VIA DDT FOR HIS DESIRED DEFAULT VALUES
  205. ;
  206. DVERFLG:
  207.     DB    ON    ; SET VERIFY OPTION
  208. DINSP:
  209.     DB    OFF    ; SET NO INSPECT
  210. DQUIET:
  211.     DB    OFF    ; SET NO QUIET OPERATION
  212. DNCOPY:
  213.     DB    OFF    ; SET NO MULTIPLE COPIES BY DEFAULT
  214. DDDISK:
  215.     DB    'C'-'A'    ; DEFAULT DESTINATION DISK IS C
  216. DDUSER:
  217.     DB    0    ; DEFAULT DESTINATION USER IS 0
  218.  
  219. ;
  220. ;  BEGINNING OF MCOPY PROGRAM
  221. ;
  222. START:
  223.     CALL    ZGPINS    ; INIT ZCPR2 BUFFERS
  224. ;
  225. ;  PRINT BANNER
  226. ;
  227.     CALL    BANNER
  228. ;
  229. ;  SET DEFAULT FLAGS
  230. ;
  231.     LDA    DVERFLG    ; VERIFY
  232.     STA    VERFLG
  233.     LDA    DINSP    ; INSPECT
  234.     STA    INSP
  235.     LDA    DQUIET    ; QUIET
  236.     STA    QUIET
  237.     LDA    DNCOPY    ; MULTIPLE COPIES
  238.     STA    NCOPY
  239.     LDA    DDDISK    ; GET DEFAULT DEST DISK
  240.     STA    DDISK    ; SET DEST DISK
  241.     LDA    DDUSER    ; GET DEFAULT DEST USER
  242.     STA    DUSER    ; SET DEST USER
  243. ;
  244. ;  OBTAIN AND SAVE CURRENT USER AND DISK
  245. ;
  246.     CALL    RETUD    ; GET USER/DISK
  247.     MOV    A,B    ; SAVE DISK
  248.     STA    CDISK
  249.     STA    SDISK    ; SET DEFAULT SOURCE DISK
  250.     MOV    A,C    ; SAVE USER
  251.     STA    CUSER
  252.     STA    SUSER    ; SAVE DEFAULT SOURCE USER
  253.     LXI    H,BUFF    ; PT TO COMMAND LINE CHAR COUNT
  254.     CALL    CLINE    ; SAVE COMMAND LINE AS STRING
  255. ;
  256. ;  SET OTHER FLAGS
  257. ;
  258.     XRA    A    ; A=0
  259.     STA    EXIST    ; TURN OFF EXIST TEST
  260. ;
  261. ;  CHECK FOR EMPTY COMMAND LINE AND PROCESS COMMAND MODE IF SO
  262. ;    ON ENTRY, HL PTS TO FIRST CHAR OF STRING FROM CLINE
  263. ;
  264. START1:
  265.     MOV    A,M    ; GET CHAR
  266.     ORA    A    ; EOL?
  267.     JZ    MRUNNER    ; INTERACTIVE COMMAND SESSION
  268.     INX    H    ; PT TO NEXT
  269.     CPI    ' '    ; JUST SPACES?
  270.     JZ    START1
  271. ;
  272. ;  COMMAND LINE WAS NOT EMPTY -- CHECK FOR HELP REQUEST
  273. ;
  274.     DCX    H    ; PT TO FIRST CHAR
  275.     CPI    '/'    ; IF OPENING OPTION, MUST BE HELP
  276.     JZ    MHELP
  277. ;
  278. ;  SEE IF OPTIONS ARE AVAILABLE IN THE COMMAND LINE
  279. ;
  280.     SHLD    MFPTR    ; SET PTR TO FIRST CHAR OF FILE NAME SPECS
  281. ;
  282. ;  SKIP TO END OF FILE NAME SPECS
  283. ;
  284. START2:
  285.     MOV    A,M    ; SKIP TO <SP> OR EOL
  286.     INX    H    ; PT TO NEXT
  287.     CPI    ' '+1    ; <SP> OR LESS?
  288.     JNC    START2
  289.     ORA    A    ; AT EOL?
  290.     JZ    MCOPY0    ; PERFORM DEFAULT MCOPY FUNCTION IF AT EOL
  291. ;
  292. ;  SCAN FOR OPTION
  293. ;
  294. OPTION:
  295.     MOV    A,M    ; GET OPTION CHAR
  296.     ORA    A    ; EOL?
  297.     JZ    MCOPY0    ; DO MCOPY
  298.     INX    H    ; PT TO NEXT
  299.     PUSH    H    ; SAVE PTR
  300.     LXI    H,OPTTAB    ; PT TO OPTION TABLE
  301.     CALL    CMDER    ; PROCESS COMMAND
  302.     POP    H    ; GET PTR
  303.     JMP    OPTION
  304.  
  305. ;  COMMAND PROCESSOR -- COMMAND LETTER IN A, HL PTS TO TABLE
  306. CMDER:
  307.     PUSH    B    ; SAVE BC
  308.     CALL    CAPS    ; CAPITALIZE COMMAND
  309.     MOV    B,A    ; COMMAND IN B
  310. CMDER1:
  311.     MOV    A,M    ; GET COMMAND LETTER
  312.     ORA    A    ; DONE?
  313.     JZ    CMDER2
  314.     CMP    B    ; MATCH?
  315.     JNZ    CMDER3
  316. CMDER2:
  317.     INX    H    ; PT TO ADDRESS
  318.     MOV    E,M    ; GET IT IN DE
  319.     INX    H
  320.     MOV    D,M
  321.     XCHG        ; HL PTS TO COMMAND ADDRESS
  322.     POP    B    ; RESTORE BC
  323.     PCHL        ; RUN COMMAND
  324. CMDER3:
  325.     INX    H    ; SKIP TO NEXT ENTRY IN TABLE
  326.     INX    H
  327.     INX    H
  328.     JMP    CMDER1
  329.  
  330. ;  OPTION COMMAND TABLE
  331. OPTTAB:
  332.     DB    ' '    ; DONE
  333.     DW    OPTS
  334.     DB    OPTC    ; SKIP OPTC
  335.     DW    OPTS
  336.     DB    'E'    ; EXIST TEST
  337.     DW    OPTE
  338.     DB    'I'    ; INSPECT
  339.     DW    OPTI
  340.     DB    'M'    ; MULTIPLE COPY
  341.     DW    OPTM
  342.     DB    'Q'    ; QUIET
  343.     DW    OPTQ
  344.     DB    'V'    ; VERIFY
  345.     DW    OPTV
  346.     DB    0    ; END OF TABLE
  347.     DW    OHELP
  348.  
  349. ;  INVALID OPTION CHAR -- CLEAR STACK (RET ADR AND HL) AND PRINT HELP
  350. OHELP:
  351.     POP    H    ; CLEAR RET ADR
  352.     POP    H    ; CLEAR HL
  353.  
  354. ;  PRINT HELP MESSAGE
  355. MHELP:
  356.     CALL    PRINT
  357.     DB    'MCOPY -- Multiple File Copy Program',CR,LF
  358.     DB    '  MCOPY copies files from the disk on Drive A: to several'
  359.     DB    CR,LF,'other disks, successively mounted on Drive '
  360.     DB    'B:',CR,LF
  361.     DB    '  MCOPY command line is:',CR,LF,LF
  362.     DB    '    MCOPY [dir:=][dir:]filename.typ[,[dir:]fn.typ][,...]'
  363.     DB    ' [ooo]',CR,LF,LF
  364.     DB    'where options are enclosed by "[]", "dir:" is a named dir of '
  365.     DB    'the form:',CR,LF
  366.     DB    '    direct: (named dir) or du: (disk/user)',CR,LF
  367.     DB    '"filename.typ" is the ambiguous file spec of the files to '
  368.     DB    'copy ',CR,LF
  369.     DB    'and "o" is none or more of:',CR,LF
  370.     DB    '    E -- Test of Existence of File and Allow User to '
  371.     db    'Approve',CR,LF
  372.     DB    '    I -- Allow User to Approve Each File (Inspect)',CR,LF
  373.     DB    '    M -- Enable Multiple Copy Feature',CR,LF
  374.     DB    '    Q -- Quiet Operation (No Activity Display)',CR,LF
  375.     DB    '    V -- Disable Automatic Verify',CR,LF
  376.     DB    '    ? -- Print this HELP information',CR,LF
  377.     DB    '  If "dir:=" is specified, MCOPY copies to the indicated '
  378.     DB    'directory,',CR,LF
  379.     DB    'else it copies to the default directory.',CR,LF
  380.     DB    '  The user may interact directly with MCOPY by using just'
  381.     DB    CR,LF,'"MCOPY" as his command.',CR,LF
  382.     DB    0
  383.     RET        ; RETURN TO ZCPR2
  384.  
  385. ;  VERIFY FLAG TOGGLE OPTION
  386. OPTV:
  387.     CALL    VT    ; TOGGLE VERFLG
  388. ;  SKIP OPTION
  389. OPTS:
  390.     RET
  391.  
  392. ;  EXIST TEST TOGGLE OPTION
  393. OPTE:
  394.     CALL    ET    ; TOGGLE EXIST
  395.     RET
  396.  
  397. ;  NCOPY FLAG TOGGLE OPTION
  398. OPTM:
  399.     CALL    MT    ; TOGGLE NCOPY
  400.     RET
  401.  
  402. ;  INSPECT FLAG TOGGLE OPTION
  403. OPTI:
  404.     CALL    IT    ; TOGGLE INSPECT
  405.     RET
  406.  
  407. ;  QUIET FLAG TOGGLE OPTION
  408. OPTQ:
  409.     CALL    QT    ; TOGGLE QUIET
  410.     RET
  411.  
  412. ;
  413. ;  **** INTERACTIVE MCOPY LOOP ****
  414. ;
  415. MRUNNER:
  416.     LXI    SP,STACK    ; RESET STACK
  417.     CALL    PRINT
  418.     DB    CR,LF,'MCOPY Status: ',0
  419.     LDA    EXIST    ; EXISTENCE TEST
  420.     ORA    A    ; 0=NO
  421.     MVI    A,'E'    ; PREP FOR CHAR
  422.     CALL    PMODE
  423.     LDA    INSP    ; FILE INSPECTION
  424.     ORA    A    ; 0=NO
  425.     MVI    A,'I'    ; PREP FOR CHAR
  426.     CALL    PMODE
  427.     LDA    NCOPY    ; MULTIPLE COPIES
  428.     ORA    A    ; 0=NO
  429.     MVI    A,'M'    ; PREP FOR CHAR
  430.     CALL    PMODE
  431.     LDA    QUIET    ; QUIET MODE
  432.     ORA    A    ; 0=NO
  433.     MVI    A,'Q'    ; PREP FOR CHAR
  434.     CALL    PMODE
  435.     LDA    VERFLG    ; VERIFY
  436.     ORA    A    ; 0=NO
  437.     MVI    A,'V'    ; PREP FOR CHAR
  438.     CALL    PMODE
  439.     CALL    PRINT
  440.     DB    ' -- MCOPY Command (? for Help)? ',0
  441.     CALL    CIN    ; GET RESPONSE
  442.     CALL    COUT    ; ECHO
  443.     LXI    H,CMDTBL    ; PT TO MCOPY COMMAND TABLE
  444.     CALL    CMDER    ; PROCESS COMMANDS
  445.     JMP    MRUNNER    ; CONTINUE
  446. ;
  447. ;  MCOPY COMMAND TABLE AND EXECUTED ROUTINES
  448. ;
  449. CMDTBL:
  450.     DB    'C'    ; COPY
  451.     DW    CMDC
  452.     DB    'D'    ; DIRECTORY
  453.     DW    CMDD
  454.     DB    'E'    ; EXISTENCE TEST
  455.     DW    CMDE
  456.     DB    'F'    ; FREE SPACE
  457.     DW    CMDF
  458.     DB    'I'    ; INSPECT
  459.     DW    CMDI
  460.     DB    'L'    ; LOG IN DISK
  461.     DW    CMDL
  462.     DB    'M'    ; MULTIPLE COPIES
  463.     DW    CMDM
  464.     DB    'Q'    ; QUIET
  465.     DW    CMDQ
  466.     DB    'S'    ; STATUS
  467.     DW    CMDS
  468.     DB    'V'    ; VERIFY
  469.     DW    CMDV
  470.     DB    'X'    ; EXIT
  471.     DW    CMDX
  472.     DB    'C'-'@'    ; ^C
  473.     DW    CMDX
  474.     DB    0    ; END OF TABLE
  475.     DW    MCPYHLP    ; HELP MESSAGE
  476.  
  477. ;  COPY COMMAND TO COPY A SET OF FILES
  478. CMDC:
  479.     CALL    PRINT
  480.     DB    0DH,0AH,'    File Spec (<CR>=Abort)? ',0
  481.     LXI    H,INBUF    ; INPUT LINE BUFFER
  482.     MVI    A,0FFH    ; CAPITALIZE INPUT
  483.     CALL    BLINE    ; GET LINE FROM USER
  484.     ORA    A    ; ABORT IF NONE
  485.     RZ
  486. CMDC1:
  487.     MOV    A,M    ; SKIP OVER SPACES
  488.     INX    H    ; PT TO NEXT
  489.     CPI    ' '
  490.     JZ    CMDC1
  491.     DCX    H    ; PT TO NON-SPACE CHAR
  492.     ORA    A    ; EOL?
  493.     RZ
  494.     SHLD    MFPTR    ; PT TO FIRST CHAR OF FILE NAME SPEC
  495.     CALL    COPY    ; COPY FILES
  496.     RET
  497.  
  498. ;  DISPLAY DIRECTORY
  499. CMDD:
  500.     CALL    PRINT
  501.     DB    CR,LF,'** Directory Display **',0
  502.     MVI    C,13    ; RESET SYSTEM
  503.     CALL    BDOS
  504.     LXI    H,0    ; SET TOTAL FILE SIZES
  505.     SHLD    FTOTAL
  506.     CALL    PRINT
  507.     DB    CR,LF,'    File Spec (<CR>=',0
  508.     LDA    DDISK    ; PRINT DISK/USER
  509.     ADI    'A'
  510.     CALL    COUT
  511.     LDA    DUSER
  512.     CALL    PADC
  513.     CALL    PRINT
  514.     DB    ':*.*)? ',0
  515.     LXI    H,INBUF    ; INPUT LINE BUFFER
  516.     MVI    A,0FFH    ; CAPITALIZE INPUT
  517.     CALL    BLINE    ; GET LINE FROM USER
  518.     ORA    A    ; WILD IF NONE
  519.     JNZ    CMDD1
  520.     LXI    D,WILD    ; MAKE FILE SPEC WILD
  521.     XCHG        ; COPY INTO BUFFER
  522.     MVI    B,4    ; 4 BYTES
  523.     CALL    MOVEB
  524.     XCHG        ; PT TO FIRST CHAR WITH HL
  525. CMDD1:
  526.     PUSH    H    ; SAVE PTR
  527.     CALL    CODEND    ; GET SCRATCH AREA ADDRESS
  528.     MOV    B,H    ; ... IN BC
  529.     MOV    C,L
  530.     POP    H
  531.     LXI    D,FCBS    ; LOAD FCB
  532.     CALL    ZFNAME    ; EXTRACT FILE NAME INFO
  533.     JZ    CMDUDER    ; ERROR?
  534.     MOV    A,B    ; GET DISK
  535.     CPI    0FFH    ; CURRENT DISK?
  536.     JNZ    CMDD2
  537.     LDA    DDISK    ; GET DEST DISK
  538.     INR    A    ; ADJUST
  539. CMDD2:
  540.     DCR    A    ; ADJUST FOR SELECT
  541.     STA    DDISK    ; SET DEST DISK
  542.     MOV    A,C    ; GET USER
  543.     CPI    '?'    ; '?' IS INVALID
  544.     JZ    CMDUDER
  545.     CPI    0FFH    ; CURRENT USER?
  546.     JNZ    CMDD3
  547.     LDA    DUSER    ; GET DEST USER
  548. CMDD3:
  549.     STA    DUSER    ; SET DEST USER
  550.     CALL    LOGD    ; LOG IN DEST
  551.     CALL    CODEND    ; HL PTS TO BUFFER
  552.     LXI    D,FCBS    ; DE PTS TO FCB
  553.     LDA    DUSER    ; GET USER
  554.     ORI    0C0H    ; SELECT BOTH NON-SYS AND SYS FILES
  555.     CALL    DIRFS    ; LOAD WITH SIZING INFO
  556.     JZ    CMDTPA    ; TPA OVERFLOW
  557.     MOV    A,B    ; ANY FILES?
  558.     ORA    C    ; 0=NONE
  559.     JNZ    CMDD4
  560.     CALL    PRINT
  561.     DB    CR,LF,'No Matching Files',0
  562.     RET
  563. CMDD4:
  564.     XRA    A    ; SET COUNT
  565.     STA    BCNT
  566.     CALL    CRLF    ; NEW LINE
  567. CMDD5:
  568.     INX    H    ; PT TO FILE NAME
  569.     CALL    PRFN    ; PRINT FILE NAME
  570.     DCX    H    ; PT TO USER
  571.     CALL    FSIZE    ; COMPUTE FILE SIZE
  572.     PUSH    H    ; SAVE HL
  573.     LHLD    FTOTAL    ; GET ACCUMULATED TOTAL
  574.     DAD    D    ; ADD IN NEW FILE
  575.     SHLD    FTOTAL    ; NEW TOTAL
  576.     POP    H    ; GET PTR
  577.     XCHG        ; FILE SIZE IN HL
  578.     CALL    PHLDC    ; PRINT AS DECIMAL
  579.     MVI    A,'K'
  580.     CALL    COUT
  581.     LXI    H,16    ; PT TO NEXT ENTRY
  582.     DAD    D    ; HL PTS TO NEXT ENTRY
  583.     DCX    B    ; COUNT DOWN
  584.     MOV    A,B    ; DONE?
  585.     ORA    C
  586.     JZ    CMDD6
  587.     LDA    BCNT    ; NEW LINE COUNT
  588.     INR    A
  589.     STA    BCNT
  590.     ANI    3    ; NEW LINE EVERY 4 ENTRIES
  591.     JZ    CMDD5A
  592.     CALL    PRINT    ; PRINT FENCE SINCE NOT NEW LINE
  593.     DB    '  ',0
  594.     JMP    CMDD5
  595. CMDD5A:
  596.     CALL    CRLF    ; NEW LINE
  597.     JMP    CMDD5
  598. CMDD6:
  599.     CALL    PRINT
  600.     DB    CR,LF,'** ',0
  601.     LHLD    FTOTAL    ; PRINT TOTAL SPACE USED
  602.     CALL    PHLDC    ; PRINT AS DECIMAL
  603.     CALL    PRINT
  604.     DB    'K Occupied by Displayed Files, ',0
  605.     CALL    DFREE    ; COMPUTE AMOUNT OF FREE SPACE LEFT ON DISK
  606.     XCHG        ; HL=FREE SPACE
  607.     CALL    PHLDC    ; PRINT AS DEC
  608.     CALL    PRINT
  609.     DB    'K Remaining on Disk ',0
  610.     LDA    DDISK    ; PRINT DISK LETTER
  611.     ADI    'A'
  612.     CALL    COUT
  613.     CALL    PRINT
  614.     DB    ' **',0
  615.     RET
  616. CMDUDER:
  617.     CALL    PRINT
  618.     DB    CR,LF,'Invalid User or Disk Specified',0
  619.     RET
  620. CMDTPA:
  621.     CALL    PRINT
  622.     DB    CR,LF,'TPA Overflow',0
  623.     RET
  624. WILD:    DB    '*.*',0
  625.  
  626. ;  COMPUTE AMOUNT OF FREE SPACE LEFT ON DESTINATION DISK
  627. CMDF:
  628.     CALL    PRINT
  629.     DB    CR,LF,'** Free Space Data **',0
  630.     MVI    C,13    ; RESET SYSTEM
  631.     CALL    BDOS
  632.     CALL    PRINT
  633.     DB    CR,LF,'    Disk (<CR>=',0
  634.     LDA    DDISK    ; GET DEST DISK
  635.     ADI    'A'    ; CONVERT TO LETTER
  636.     CALL    COUT
  637.     CALL    PRINT
  638.     DB    ')? ',0
  639.     CALL    CIN    ; GET RESPONSE
  640.     CALL    CAPS
  641.     CALL    COUT
  642.     CALL    CRLF    ; NEW LINE
  643.     CPI    CR    ; SOURCE DISK?
  644.     JZ    CMDF1
  645.     CPI    ' '    ; SOURCE DISK?
  646.     JZ    CMDF1
  647.     SUI    'A'    ; CONVERT TO DISK NUMBER
  648.     STA    DDISK    ; SET DISK
  649.     JC    CMDFER
  650.     MOV    B,A    ; SAVE IN B
  651.     LDA    MDISK    ; COMPARE AGAINST MAX
  652.     CMP    B
  653.     JC    CMDFER
  654. CMDF1:
  655.     CALL    LOGD    ; LOG IN DEST
  656.     CALL    DPARAMS    ; GET DISK PARAMETERS
  657.     CALL    DFREE    ; COMPUTE FREE SPACE
  658.     XCHG        ; HL=SPACE
  659.     CALL    CRLF
  660.     CALL    PHLDC    ; PRINT AS DECIMAL
  661.     CALL    PRINT
  662.     DB    'K Bytes Remaining on Disk ',0
  663.     LDA    DDISK
  664.     ADI    'A'
  665.     CALL    COUT
  666.     RET
  667. CMDFER:
  668.     CALL    PRINT
  669.     DB    CR,LF,'Error -- Disk Letter Invalid',0
  670.     RET
  671.  
  672. ;  TOGGLE INSPECT
  673. CMDI:
  674.     CALL    ITOG    ; TOGGLE WITH MESSAGE
  675.     RET
  676.  
  677. ;  LOG IN NEW USER/DISK
  678. CMDL:
  679.     CALL    PRINT
  680.     DB    CR,LF,'Select Current Disk/User --',0
  681.     LXI    H,CDISK    ; PT TO ENTRY
  682.     CALL    CMDL0
  683.     CALL    PRINT
  684.     DB    CR,LF,'Select Source Disk/User --',0
  685.     LXI    H,SDISK    ; PT TO ENTRY
  686.     CALL    CMDL0
  687.     CALL    PRINT
  688.     DB    CR,LF,'Select Destination Disk/User --',0
  689.     LXI    H,DDISK    ; PT TO ENTRY
  690. CMDL0:
  691.     CALL    PRINT
  692.     DB    CR,LF,'    New Disk (<CR>=',0
  693.     MOV    A,M    ; GET DISK
  694.     ADI    'A'
  695.     CALL    COUT
  696.     CALL    PRINT
  697.     DB    ')? ',0
  698.     CALL    CIN    ; GET RESPONSE
  699.     CALL    CAPS
  700.     CALL    COUT
  701.     CALL    CRLF
  702.     CPI    CR
  703.     JZ    CMDL1
  704.     CPI    ' '
  705.     JZ    CMDL1
  706.     SUI    'A'    ; CONVERT TO NUMBER
  707.     JC    CMDLER
  708.     MOV    B,A
  709.     LDA    MDISK    ; CHECK AGAINST MAX
  710.     CMP    B
  711.     JC    CMDLER
  712.     MOV    A,B    ; GET SELECTED DISK
  713.     MOV    M,A    ; PUT DISK
  714. CMDL1:
  715.     INX    H    ; PT TO USER
  716. CMDL2:
  717.     PUSH    H    ; SAVE PTR
  718.     CALL    PRINT
  719.     DB    '    New User (<CR>=',0
  720.     MOV    A,M    ; GET USER NUMBER
  721.     CALL    PADC
  722.     CALL    PRINT
  723.     DB    ')? ',0
  724.     LXI    H,INBUF    ; GET INTO INPUT LINE BUFFER
  725.     MVI    A,0FFH    ; CAPITALIZE
  726.     CALL    BLINE
  727.     POP    D    ; GET PTR TO USER
  728.     ORA    A    ; ANY RESPONSE?
  729.     RZ
  730.     PUSH    D    ; SAVE PTR TO USER
  731.     CALL    EVAL    ; EVALUATE
  732.     POP    H    ; GET PTR TO USER
  733.     MOV    A,D    ; GET RESULT
  734.     ORA    A    ; MUST BE ZERO HIGH
  735.     JNZ    CMDLUER
  736.     LDA    MUSER    ; CHECK AGAINST MAX
  737.     CMP    E
  738.     JC    CMDLUER
  739.     MOV    A,E    ; GET NUMBER
  740.     MOV    M,A    ; PUT USER
  741.     RET
  742. CMDLER:
  743.     CALL    PRINT
  744.     DB    CR,LF,'Invalid Disk -- Reenter',0
  745.     JMP    CMDL0
  746. CMDLUER:
  747.     CALL    PRINT
  748.     DB    CR,LF,'Invalid User -- Reenter',0
  749.     JMP    CMDL2
  750.  
  751. ;  TOGGLE EXIST
  752. CMDE:
  753.     CALL    ETOG    ; TOGGLE WITH MESSAGE
  754.     RET
  755.  
  756. ;  TOGGLE NCOPY
  757. CMDM:
  758.     CALL    MTOG    ; TOGGLE WITH MESSAGE
  759.     RET
  760.  
  761. ;  TOGGLE QUIET
  762. CMDQ:
  763.     CALL    QTOG    ; TOGGLE WITH MESSAGE
  764.     RET
  765.  
  766. ;  DISPLAY STATUS
  767. CMDS:
  768.     CALL    PRINT
  769.     DB    CR,LF,'Current Disk/User is ',0
  770.     LXI    H,CDISK
  771.     CALL    CMDS1
  772.     CALL    PRINT
  773.     DB    CR,LF,'Source Disk/User is ',0
  774.     LXI    H,SDISK
  775.     CALL    CMDS1
  776.     CALL    PRINT
  777.     DB    CR,LF,'Destination Disk/User is ',0
  778.     LXI    H,DDISK
  779. CMDS1:
  780.     MOV    A,M    ; GET DISK
  781.     ADI    'A'
  782.     CALL    COUT
  783.     INX    H
  784.     MOV    A,M    ; GET USER
  785.     CALL    PADC
  786.     MVI    A,':'
  787.     CALL    COUT
  788.     RET
  789.  
  790. ;  TOGGLE VERIFY
  791. CMDV:
  792.     CALL    VTOG    ; TOGGLE WITH MESSAGE
  793.     RET
  794.  
  795. ;  EXIT TO CP/M
  796. CMDX:
  797.     CALL    PRINT
  798.     DB    CR,LF,'** MCOPY Exiting **',0
  799.     JMP    CPM
  800.  
  801. ;  TOGGLE QUIET FUNCTION
  802. QT:
  803.     LDA    QUIET    ; GET FLAG
  804.     CMA        ; FLIP IT
  805.     STA    QUIET    ; PUT FLAG
  806.     RET
  807.  
  808. ;  TOGGLE EXIST TEST FUNCTION
  809. ET:
  810.     LDA    EXIST    ; GET FLAG
  811.     CMA        ; FLIP IT
  812.     STA    EXIST    ; PUT FLAG
  813.     RET
  814.  
  815. ;  TOGGLE NCOPY FUNCTION (MULTIPLE COPIES)
  816. MT:
  817.     LDA    NCOPY    ; GET FLAG
  818.     CMA        ; FLIP IT
  819.     STA    NCOPY    ; PUT FLAG
  820.     RET
  821.  
  822. ;  TOGGLE INSPECT FUNCTION
  823. IT:
  824.     LDA    INSP    ; GET FLAG
  825.     CMA        ; FLIP IT
  826.     STA    INSP    ; PUT FLAG
  827.     RET
  828.  
  829. ;  TOGGLE VERIFY FUNCTION
  830. VT:
  831.     LDA    VERFLG    ; GET FLAG
  832.     CMA        ; FLIP IT
  833.     STA    VERFLG    ; PUT FLAG
  834.     RET
  835.  
  836. ;  TOGGLE INSPECT MODE AND PRINT MESSAGE
  837. ITOG:
  838.     CALL    IT    ; TOGGLE AND FALL THRU TO PRINT
  839. ;  PRINT INSPECT MESSAGE
  840. IMSG:
  841.     CALL    PRINT
  842.     DB    CR,LF,'  File Selection Inspect Mode ',0
  843.     LDA    INSP
  844. ENPRT:
  845.     ORA    A    ; 0=NO
  846.     JZ    ENPRT1
  847.     CALL    PRINT
  848.     DB    'Enabled',0
  849.     RET
  850. ENPRT1:
  851.     CALL    PRINT
  852.     DB    'Disabled',0
  853.     RET
  854.  
  855. ;  TOGGLE EXIST TEST AND PRINT MESSAGE
  856. ETOG:
  857.     CALL    ET    ; TOGGLE AND FALL THRU TO PRINT
  858. ;  PRINT EXIST STATUS
  859. EMSG:
  860.     CALL    PRINT
  861.     DB    CR,LF,'  Existence Test Function ',0
  862.     LDA    EXIST
  863.     JMP    ENPRT
  864.  
  865. ;  TOGGLE MULTIPLE COPY AND PRINT MESSAGE
  866. MTOG:
  867.     CALL    MT    ; TOGGLE AND FALL THRU TO PRINT
  868. ;  PRINT MCOPY STATUS
  869. MMSG:
  870.     CALL    PRINT
  871.     DB    CR,LF,'  Multiple Copy Function ',0
  872.     LDA    NCOPY
  873.     JMP    ENPRT
  874.  
  875. ;  TOGGLE QUIET AND PRINT MESSAGE
  876. QTOG:
  877.     CALL    QT    ; TOGGLE AND FALL THRU TO PRINT
  878. ;  PRINT QUIET STATUS
  879. QMSG:
  880.     CALL    PRINT
  881.     DB    CR,LF,'  Quiet Operation ',0
  882.     LDA    QUIET
  883.     JMP    ENPRT
  884.  
  885. ;  TOGGLE VERIFY AND PRINT MESSAGE
  886. VTOG:
  887.     CALL    VT    ; TOGGLE AND FALL THRU TO PRINT
  888. ;  PRINT VERIFY STATUS
  889. VMSG:
  890.     CALL    PRINT
  891.     DB    CR,LF,'  Copy Verification ',0
  892.     LDA    VERFLG
  893.     JMP    ENPRT
  894.  
  895. ;  PRINT MCOPY COMMAND HELP MESSAGE
  896. MCPYHLP:
  897.     CALL    PRINT
  898.     DB    CR,LF,'    MCOPY Status:  E I M Q V'
  899.     DB    CR,LF,'These Status Characters have the following meanings:'
  900.     DB    CR,LF,'   E - File Existence Test Mode is ON'
  901.     DB    CR,LF,'   I - File Selection Inspect Mode is ON'
  902.     DB    CR,LF,'   M - Multiple Copy Function Mode is ON'
  903.     DB    CR,LF,'   Q - Quiet Mode is ON'
  904.     DB    CR,LF,'   V - Verify Mode is ON'
  905.     DB    CR,LF
  906.     DB    CR,LF,'The Status Characters, as commands, toggle their '
  907.     DB    'respective modes.'
  908.     DB    CR,LF,'Other valid MCOPY Commands are:'
  909.     DB    CR,LF,'   C - Copy a File or Set of Files'
  910.     DB    CR,LF,'   D - Directory Display'
  911.     DB    CR,LF,'   F - Compute Amount of Free Space on Disk'
  912.     DB    CR,LF,'   L - Log in New User/Disks'
  913.     DB    CR,LF,'   S - Display MCOPY Status (Cur and Dest User/Disk)'
  914.     DB    CR,LF,'   X or ^C - Exit MCOPY'
  915.     DB    0
  916.     RET
  917.  
  918. ;  PRINT CHAR IN A IF NZ, ELSE PRINT <SP>
  919. PMODE:
  920.     JZ    PMODE1    ; PRINT <SP>
  921.     JMP    COUT    ; PRINT CHAR
  922. PMODE1:
  923.     MVI    A,' '    ; PRINT <SP>
  924.     JMP    COUT
  925.  
  926. ;
  927. ;  PRINT MCOPY BANNER
  928. ;
  929. BANNER:
  930.     CALL    PRINT
  931.     DB    'MCOPY  Version '
  932.     DB    VERS/10+'0','.',(VERS MOD 10)+'0',0
  933.     RET
  934.  
  935. ;
  936. ;  **** MCOPY of COMMAND LINE ****
  937. ;
  938. MCOPY0:
  939.     LXI    SP,STACK    ; SET STACK
  940.     LDA    NCOPY    ; MULTIPLE COPIES?
  941.     ORA    A    ; 0=NO
  942.     JZ    NOPAUSE
  943.     CALL    SAKCHK    ; STRIKE ANY KEY CHECK
  944.     JZ    CPM    ; WARM BOOT IF ABORT
  945. NOPAUSE:
  946.     CALL    COPY    ; DO THE COPY
  947.     JMP    CPM    ; WARM BOOT WHEN DONE
  948.  
  949. ;
  950. ;  **** Begin Multiple Copy Procedure ****
  951. ;
  952. COPY:
  953.     LHLD    MFPTR    ; PT TO FIRST FILE NAME
  954.     SHLD    NXTPTR    ; SET PTR TO NEXT FILE NAME
  955.     LXI    H,0    ; HL=0
  956.     SHLD    FCOUNT    ; ZERO FILE COUNT
  957.     SHLD    VERCNT    ; ZERO ERROR COUNT
  958.     LDA    EXIST    ; IF EXIST, THEN MUST NOT BE QUIET
  959.     ORA    A    ; 0=NO EXIST
  960.     JZ    MCOPY
  961.     XRA    A    ; SET NO QUIET
  962.     STA    QUIET
  963. ;
  964. ;  **** MAIN COPY LOOP ****
  965. ;
  966. MCOPY:
  967.     LHLD    NXTPTR    ; GET PTR TO NEXT FILE NAME
  968.     MOV    A,M    ; GET FIRST CHAR
  969.     CPI    ' '+1    ; DONE IF <SP> OR LESS
  970.     JNC    MCOPY1    ; CONTINUE WITH PROCEDURE
  971. ;
  972. ;  MCOPY OF FILE SPECS IS NOW DONE
  973. ;  DONE WITH COPY PROCEDURE -- CONTINUE?
  974. ;
  975. COPYT:
  976.     CALL    PRINT
  977.     DB    CR,LF,'**** MCOPY Complete ****',CR,LF,'    ',0
  978.     LHLD    FCOUNT    ; GET FILE COUNT
  979.     CALL    PHLDC    ; PRINT AS DECIMAL
  980.     CALL    PRINT
  981.     DB    ' File',0
  982.     MOV    A,H    ; 1 FILE?
  983.     ORA    A
  984.     JNZ    COPYT1
  985.     MOV    A,L
  986.     CPI    1    ; 1 FILE?
  987.     JZ    COPYT2
  988. COPYT1:
  989.     MVI    A,'s'    ; ENDING S
  990.     CALL    COUT
  991. COPYT2:
  992.     CALL    PRINT
  993.     DB    ' Copied    ',0
  994.     LHLD    VERCNT    ; GET ERROR COUNT
  995.     CALL    PHLDC    ; PRINT AS DECIMAL
  996.     CALL    PRINT
  997.     DB    ' Copy Errors',0
  998.     LDA    NCOPY    ; MULTIPLE COPIES?
  999.     ORA    A    ; 0=NO
  1000.     RZ
  1001.     CALL    SAKCHK    ; CHECK FOR STRIKE OF ANY KEY
  1002.     RZ        ; RETURN IF ABORT
  1003.     JMP    COPY    ; COPY AGAIN FROM THE BEGINNING
  1004. ;
  1005. ;  BEGIN COPY OF FILE GROUP
  1006. ;
  1007. MCOPY1:
  1008.     CPI    ','    ; SKIP COMMA SEPARATOR IF THERE
  1009.     JNZ    MCPY0
  1010.     INX    H    ; PT TO CHAR AFTER COMMA
  1011. MCPY0:
  1012.     MOV    A,M    ; GET NEXT CHAR
  1013.     CPI    ' '+1    ; CHECK FOR ERROR
  1014.     JC    FORMERR
  1015.     PUSH    H    ; SAVE PTR TO NEXT FILE NAME
  1016.     CALL    CODEND    ; GET ADDRESS OF SCRATCH AREA
  1017.     MOV    B,H    ; BC=ADDRESS OF SCRATCH AREA
  1018.     MOV    C,L
  1019.     LXI    D,FCBS    ; GET POSSIBLE SOURCE FCB
  1020.     POP    H    ; GET PTR TO NEXT FILE SPEC
  1021.     CALL    ZFNAME    ; EXTRACT FILE NAME DATA
  1022.     JZ    UDERR    ; ERROR?
  1023.     MOV    A,M    ; GET DELIMITER
  1024.     CPI    '='    ; IF '=', WE HAVE A NEW DISK/USER
  1025.     JNZ    MCOPY2    ; FORM IS DIRS:FN.FT IF NO '='
  1026. ;
  1027. ;  FORM IS DIRD:=DIRS:FN.FT, SO SET DEST DISK/USER
  1028. ;
  1029.     MOV    A,B    ; CHECK FOR ANY DISK OR USER CHANGE
  1030.     ANA    C    ; IF BOTH FF, THEN NO CHANGE
  1031.     CPI    0FFH    ; BOTH FF?
  1032.     JZ    MCPY2
  1033.     LDA    CDISK    ; SET DEST TO CURRENT SINCE A CHANGE IS EXPECTED
  1034.     STA    DDISK    ; ... IN THIS WAY, A NEW DEST OF U: OR D: IS
  1035.     LDA    CUSER    ; ... INTERPRETED AS $U: OR D$: (I.E., IF LOGGED INTO
  1036.     STA    DUSER    ; ... B, A DEST OF 1: IS B1:)
  1037.     MOV    A,B    ; CHECK FOR DISK CHANGE
  1038.     CPI    0FFH    ; 0FFH=NO CHANGE
  1039.     JZ    MCPY1
  1040.     DCR    A    ; ADJUST
  1041.     STA    DDISK    ; SET NEW DEFAULT DISK
  1042. MCPY1:
  1043.     MOV    A,C    ; CHECK FOR USER CHANGE
  1044.     CPI    0FFH    ; 0FFH=NO CHANGE
  1045.     JZ    MCPY2
  1046.     CPI    '?'    ; ALL USERS NOT PERMITTED
  1047.     JZ    UDERR
  1048.     STA    DUSER    ; SET NEW DEFAULT USER
  1049. ;
  1050. ;  NOW DERIVE DIRS:FN.FT FORM AFTER THE '='
  1051. ;
  1052. MCPY2:
  1053.     INX    H    ; PT TO CHAR BEYOND '='
  1054.     MOV    A,M    ; GET CHAR
  1055.     CPI    ' '+1    ; FORMAT ERROR?
  1056.     JC    FORMERR
  1057.     PUSH    H    ; SAVE PTR
  1058.     CALL    CODEND    ; GET END OF CODE
  1059.     MOV    B,H    ; ... IN BC
  1060.     MOV    C,L
  1061.     POP    H    ; GET PTR TO NAME
  1062.     LXI    D,FCBS    ; LOAD FCB
  1063.     CALL    ZFNAME    ; GET SOURCE NAME
  1064.     JZ    UDERR    ; ERROR?
  1065. ;
  1066. ;  SAVE PTR TO NEXT CHAR AFTER DIRS:FN.FT, AND SET SOURCE DISK/USER
  1067. ;
  1068. MCOPY2:
  1069.     SHLD    NXTPTR    ; SAVE PTR TO NEXT CHAR
  1070.     MOV    A,B    ; CHECK FOR NO DISK OR USER CHANGE
  1071.     ANA    C
  1072.     CPI    0FFH    ; BOTH FF?
  1073.     JZ    MCPY22
  1074.     LDA    CDISK    ; IF CHANGE IN EITHER, ASSUME OLD SOURCE TO BE CURRENT
  1075.     STA    SDISK
  1076.     LDA    CUSER
  1077.     STA    SUSER
  1078.     MOV    A,B    ; CHECK FOR DISK CHANGE
  1079.     CPI    0FFH    ; 0FFH=NO CHANGE
  1080.     JZ    MCPY21
  1081.     DCR    A    ; ADJUST
  1082.     STA    SDISK    ; SET NEW DEFAULT DISK
  1083. MCPY21:
  1084.     MOV    A,C    ; CHECK FOR USER CHANGE
  1085.     CPI    0FFH    ; 0FFH=NO CHANGE
  1086.     JZ    MCPY22
  1087.     CPI    '?'    ; ALL USERS NOT PERMITTED
  1088.     JZ    UDERR
  1089.     STA    SUSER    ; SET NEW DEFAULT USER
  1090. MCPY22:
  1091.     CALL    PRINT
  1092.     DB    CR,LF,'    Copy ',0
  1093.     LDA    SDISK    ; GET NUMBER
  1094.     ADI    'A'    ; CONVERT TO LETTER
  1095.     CALL    COUT    ; PRINT
  1096.     LDA    SUSER    ; PRINT USER NUMBER
  1097.     CALL    PADC
  1098.     MVI    A,':'    ; SEPARATOR
  1099.     CALL    COUT
  1100.     MVI    A,' '
  1101.     CALL    COUT
  1102.     LXI    H,FCBS+1    ; PRINT FILE SPEC
  1103.     CALL    PRFN
  1104.     CALL    PRINT
  1105.     DB    ' to ',0
  1106.     LDA    DDISK    ; GET NUMBER
  1107.     ADI    'A'    ; CONVERT TO LETTER
  1108.     CALL    COUT    ; PRINT
  1109.     LDA    DUSER    ; PRINT USER NUMBER
  1110.     CALL    PADC
  1111.     MVI    A,':'
  1112.     CALL    COUT
  1113.     MVI    C,13    ; RESET DISK SYSTEM
  1114.     CALL    BDOS
  1115.     CALL    LOGS    ; LOG IN SOURCE USER/DISK
  1116.     LXI    D,FCBS    ; PT TO SOURCE FCB
  1117.     CALL    INITFCB    ; INIT FCB
  1118.     CALL    CODEND    ; PT TO BUFFER AREA
  1119.     LDA    SUSER    ; PREPARE FLAG FOR SELECTION
  1120.     ANI    1FH    ; ONLY USER NUMBER
  1121.     ORI    0C0H    ; SELECT NON-SYS AND SYS FILES
  1122.     CALL    DIRF    ; LOAD DIR, SELECT FILES, SORT, ETC
  1123.     JZ    TPAOVFL    ; TPA OVERFLOW ERROR?
  1124.     LDA    INSP    ; INSPECT FILES?
  1125.     ORA    A    ; 0=NO
  1126.     CNZ    INSPF    ; INSPECT FILES IF OPTION SELECTED
  1127.     MOV    A,B    ; CHECK FOR ANY FILES TO COPY
  1128.     ORA    C    ; 0=NONE
  1129.     JNZ    MCPY24
  1130. MCPY23:
  1131.     CALL    PRINT
  1132.     DB    CR,LF,'** NO Files Selected **'
  1133.     DB    CR,LF,'** Strike ^C to Abort, Anything Else to Continue: ',0
  1134.     CALL    CIN    ; GET RESPONSE
  1135.     CPI    'C'-'@'    ; ABORT?
  1136.     JZ    COPYT    ; END TEST
  1137.     JMP    MCOPY    ; CONTINUE WITH NEXT
  1138. MCPY24:
  1139.     PUSH    H    ; SAVE PTR AND COUNT
  1140.     PUSH    B
  1141.     LXI    D,16    ; SKIP TO END OF LOADED FILES AND MARK BEGINNING OF
  1142.             ;   WORK AREA
  1143. MCPY25:
  1144.     DAD    D    ; PT TO NEXT
  1145.     DCX    B    ; COUNT DOWN
  1146.     MOV    A,B    ; DONE?
  1147.     ORA    C
  1148.     JNZ    MCPY25
  1149.     MVI    A,64    ; SET PAGE LIMIT TO 16K
  1150.     STA    PAGLIM
  1151.     SHLD    WORKBF    ; SAVE PTR TO BEGINNING OF WORK BUFFER
  1152.     LDA    BDOSE+2    ; GET BASE PAGE OF BDOS
  1153.     SUI    10    ; GET BELOW BASE PAGE OF CCP
  1154.     SUB    H    ; COMPUTE SIZE OF BUFFER AREA
  1155.     CPI    64    ; 64 PAGES LEFT?
  1156.     JNC    PAGOK
  1157.     STA    PAGLIM    ; SET PAGE LIMIT
  1158. PAGOK:
  1159.     POP    B    ; RESTORE PTRS
  1160.     POP    H
  1161. ;
  1162. ;  MAIN COPYING LOOP
  1163. ;    FILE NAMES ARE PTED TO BY HL AND BC=NUMBER OF FILES
  1164. ;
  1165. MCPY26:
  1166.     PUSH    H    ; SAVE REGS
  1167.     PUSH    B
  1168.     CALL    MCOPYX    ; COPY SOURCE (HL) TO DESTINATION USING WORK BUFFER
  1169.     LDA    QUIET    ; CHECK FOR QUIET
  1170.     ORA    A    ; NZ=QUIET
  1171.     JNZ    MCPY27
  1172.     CALL    PRINT
  1173.     DB    CR,LF,'    Copy Complete',0
  1174. MCPY27:
  1175.     LDA    LSTCPY    ; LAST FILE COPIED?
  1176.     ORA    A    ; 0=NO
  1177.     JZ    MCPY28
  1178.     LDA    VERFLG    ; VERIFY?
  1179.     ORA    A    ; 0=NO
  1180.     CNZ    MCOPYV    ; DO VERIFY
  1181.     LHLD    FCOUNT    ; COUNT FILES
  1182.     INX    H
  1183.     SHLD    FCOUNT
  1184. MCPY28:
  1185.     POP    B    ; GET REGS
  1186.     POP    H
  1187.     LXI    D,16    ; PT TO NEXT FILE
  1188.     DAD    D    ; HL PTS TO NEXT FILE
  1189.     DCX    B    ; COUNT DOWN
  1190.     MOV    A,B
  1191.     ORA    C
  1192.     JNZ    MCPY26
  1193.     JMP    MCOPY    ; COPY NEXT FILE SPEC
  1194. ;
  1195. ;  COPY SOURCE FILE PTED TO BY HL TO DESTINATION
  1196. ;
  1197. MCOPYX:
  1198.     XRA    A    ; SET NO COPY OF LAST FILE
  1199.     STA    LSTCPY    ; SET FLAG
  1200.     LXI    D,FCBS    ; SET SOURCE FCB
  1201.     MVI    B,12    ; 12 BYTES
  1202.     CALL    MOVEB
  1203.     CALL    INITFCB    ; INIT SOURCE FCB
  1204.     LXI    D,FCBD    ; SET DESTINATION FCB
  1205.     MVI    B,12    ; 12 BYTES
  1206.     CALL    MOVEB
  1207.     CALL    DRW    ; CLEAR ATTRIBUTES IN FCB
  1208.     CALL    INITFCB    ; INIT DESTINATION FCB
  1209.     CALL    LOGD    ; LOG IN DESTINATION
  1210.     LXI    D,FCBD    ; PT TO FCB
  1211.     CALL    F$EXIST    ; DOES DEST EXIST?
  1212.     JZ    FNF    ; FILE NOT FOUND IF ZERO
  1213.     LDA    QUIET    ; QUIET?
  1214.     ORA    A    ; 0=NO
  1215.     JNZ    FFND
  1216.     CALL    PRINT
  1217.     DB    CR,LF,'Original File ',0
  1218.     LXI    H,FCBD+1    ; PRINT FILE NAME
  1219.     CALL    PRFN
  1220.     CALL    PRINT
  1221.     DB    ' on Destination',0
  1222. FFND:
  1223.     CALL    EATEST    ; EXIST APPROVED TEST?
  1224.     RZ        ; NOT APPROVED, SO ABORT
  1225.     CALL    DESTRW    ; MAKE DESTINATION R/W IF NOT ALREADY
  1226.     CALL    F$DELETE    ; DELETE FILE
  1227.     CALL    INITFCB        ; REINIT FCB
  1228.     JMP    FNF1    ; CREATE NEW FILE AND CONTINUE
  1229. FNF:
  1230.     LDA    QUIET    ; QUIET?
  1231.     ORA    A    ; 0=NO
  1232.     JNZ    FNF1
  1233.     CALL    PRINT
  1234.     DB    CR,LF,'No Original File ',0
  1235.     LXI    H,FCBD+1    ; PRINT FILE NAME
  1236.     CALL    PRFN
  1237.     CALL    PRINT
  1238.     DB    ' on Destination',0
  1239.     CALL    EATEST    ; EXIST APPROVED?
  1240.     RZ        ; NO?
  1241. FNF1:
  1242.     MVI    A,0FFH    ; SET COPY OF LAST FILE
  1243.     STA    LSTCPY    ; SET FLAG
  1244.     CALL    F$MAKE    ; CREATE NEW FILE
  1245. ;
  1246. ;  OPEN SOURCE FILE IN PREP FOR COPY
  1247. ;
  1248.     CALL    CRCCLR    ; CLEAR CRC VALUE
  1249.     CALL    LOGS    ; LOG IN SOURCE DISK
  1250.     LXI    D,FCBS    ; INIT FCB
  1251.     CALL    INITFCB
  1252.     CALL    F$OPEN    ; OPEN FILE
  1253.     CALL    CRLF    ; NEW LINE
  1254.     LXI    H,0
  1255.     SHLD    RKCNT    ; SET READ K COUNT
  1256.     SHLD    WKCNT    ; SET WRITE K COUNT
  1257. ;
  1258. ;  THIS LOOP, WHICH STARTS AT MCPYX, COPIES THE FILE FROM SOURCE TO DEST
  1259. ;
  1260. MCPYX:
  1261.     CALL    LOGS    ; LOG IN SOURCE
  1262.     LXI    D,FCBS    ; PT TO SOURCE FCB
  1263.     LHLD    WORKBF    ; PT TO BUFFER TO COPY INTO
  1264.     CALL    LOAD    ; LOAD FILE INTO WORKBF
  1265.     LDA    BCNT    ; IF COUNT=0, THEN DONE
  1266.     ORA    A
  1267.     JZ    MC2DONE
  1268. ;
  1269. ;  COPY TO DISK
  1270. ;
  1271. MCPYD:
  1272.     CALL    LOGD    ; LOG IN DESTINATION
  1273.     LDA    QUIET    ; CHECK FOR QUIET
  1274.     ORA    A    ; Z=NOT QUIET
  1275.     JNZ    MCPYD0
  1276.     CALL    PRINT
  1277.     DB    '  Writing .....K',0
  1278. MCPYD0:
  1279.     LHLD    WORKBF    ; PT TO BUFFER
  1280. MCPYD1:
  1281.     LXI    D,BUFF    ; COPY DATA TO BUFFER
  1282.     MVI    B,128    ; 128 BYTES
  1283.     CALL    MOVEB    ; COPY IT
  1284.     LXI    D,128    ; INCR HL BY 128
  1285.     DAD    D    ; HL PTS TO NEXT BLOCK
  1286.     LXI    D,FCBD    ; WRITE TO DESTINATION FILE
  1287.     CALL    F$WRITE
  1288.     ORA    A    ; OK?
  1289.     JNZ    MCPYDERR
  1290.  
  1291. ;  COUNT DOWN TO NEXT BLOCK
  1292.     LDA    BCNT    ; PRINT BLIPS
  1293.     ANI    7    ; MASK
  1294.     JNZ    MCPYD2
  1295.     LDA    QUIET    ; CHECK FOR QUIET
  1296.     ORA    A    ; Z=NOT QUIET
  1297.     JNZ    MCPYD2
  1298.     PUSH    H    ; SAVE HL
  1299.     LHLD    WKCNT    ; INCREMENT WRITE K COUNT
  1300.     INX    H
  1301.     SHLD    WKCNT
  1302.     CALL    PRKCNT    ; PRINT K COUNT
  1303.     POP    H
  1304. MCPYD2:
  1305.     LDA    BCNT    ; GET BLOCK COUNT
  1306.     DCR    A    ; COUNT DOWN
  1307.     STA    BCNT
  1308.     JNZ    MCPYD1
  1309.     LDA    QUIET    ; CHECK FOR QUIET OPERATION
  1310.     ORA    A    ; Z=NOT QUIET
  1311.     CZ    CRLF    ; NEW LINE
  1312.     LDA    CONT    ; CONTINUE?
  1313.     ORA    A    ; CONT IF NOT ZERO
  1314.     JNZ    MCPYX
  1315. ;
  1316. ;  END OF COPY LOOP
  1317. ;
  1318. MC2DONE:
  1319.     CALL    LOGS    ; LOG IN SOURCE
  1320.     LXI    D,FCBS    ; CLOSE SOURCE
  1321.     CALL    F$CLOSE
  1322.     CALL    LOGD    ; LOG IN DESTINATION
  1323.     LXI    D,FCBD    ; CLOSE DESTINATION
  1324.     CALL    F$CLOSE
  1325.     CALL    CRCDONE    ; GET CRCK VALUE
  1326.     SHLD    CRCVAL    ; SAVE CRC VALUE
  1327.     CALL    LOGS    ; LOG IN SOURCE DRIVE
  1328.     LXI    D,FCBS    ; FIND SOURCE
  1329.     MVI    C,17    ; SEARCH FOR FIRST
  1330.     CALL    BDOS
  1331.     RLC        ; MULTIPLY BY 32 TO GET OFFSET
  1332.     RLC
  1333.     RLC
  1334.     RLC
  1335.     RLC
  1336.     ANI    0E0H    ; MASK OUT LSB
  1337.     MOV    L,A    ; VALUE IN L
  1338.     MVI    H,0
  1339.     LXI    D,BUFF    ; ADD IN BUFFER BASE
  1340.     DAD    D
  1341.     LXI    D,FCBT
  1342.     MVI    B,16    ; MOVE 16 BYTES
  1343.     CALL    MOVEB
  1344.     CALL    LOGD    ; LOG IN DESTINATION DRIVE
  1345.     LXI    D,FCBT
  1346.     CALL    INITFCB    ; INIT FCB
  1347.     MVI    C,30    ; SET FILE ATTRIBUTES
  1348.     CALL    BDOS
  1349.     RET        ; MCOPYX RETURN
  1350.  
  1351. ;  FORMAT ERROR
  1352. FORMERR:
  1353.     CALL    PRINT
  1354.     DB    CR,LF,'MCOPY -- Format Error in Command Line'
  1355.     DB    CR,LF,'Error Starts at: ',0
  1356.     CALL    PSTR    ; PRINT ERROR
  1357.     RET
  1358.  
  1359. ;  USER/DISK ERROR
  1360. UDERR:
  1361.     CALL    PRINT
  1362.     DB    CR,LF,'MCOPY -- Error in User Number or Disk Letter',0
  1363.     RET
  1364.  
  1365. ;  TPA OVERFLOW
  1366. TPAOVFL:
  1367.     CALL    PRINT
  1368.     DB    CR,LF,'MCOPY -- TPA Overflow -- Aborting',0
  1369.     JMP    CPM
  1370.  
  1371. ;  WRITE ERROR
  1372. MCPYDERR:
  1373.     CALL    PRINT
  1374.     DB    CR,LF,'MCOPY -- Error in Creating Destination File',0
  1375.     JMP    CPM
  1376.  
  1377. ;  TEST FOR EXISTENCE REQUIREMENT AND GET USER RESPONSE
  1378. EATEST:
  1379.     LDA    EXIST    ; EXISTENCE TEST ON?
  1380.     ORA    A    ; 0=NO
  1381.     JZ    EAT1
  1382.     CALL    PRINT
  1383.     DB    CR,LF,'    -- Approve Copy (Y/N/other=Y)? ',0
  1384.     CALL    CIN    ; GET RESPONSE
  1385.     CALL    CAPS
  1386.     CPI    CR    ; YES?
  1387.     JZ    EAT1    ; COPY IF SO
  1388.     CALL    COUT
  1389.     CPI    'N'    ; NO?
  1390.     JNZ    EAT1    ; COPY IF NOT NO
  1391.     CALL    PRINT
  1392.     DB    ' -- Disapproved',0
  1393.     XRA    A    ; ZERO FOR NOT APPROVED
  1394.     RET
  1395. EAT1:
  1396.     MVI    A,0FFH    ; SET NZ FOR APPROVED
  1397.     ORA    A    ; SET FLAGS
  1398.     RET
  1399. ;
  1400. ;  MAKE DESTINATION FCB ENTRY R/W AND DIR
  1401. ;
  1402. DRW:
  1403.     LXI    H,FCBD+9    ; CLEAR ATTRIBUTES OF DEST
  1404.     MOV    A,M    ; GET IT
  1405.     ANI    7FH    ; CLEAR IT
  1406.     MOV    M,A
  1407.     INX    H    ; SAME TO NEXT
  1408.     MOV    A,M    ; GET IT AND CLEAR IT
  1409.     ANI    7FH
  1410.     MOV    M,A
  1411.     RET
  1412. DESTRW:
  1413.     CALL    DRW    ; MAKE ATTRIBUTES R/W AND NON-SYS
  1414.     LXI    D,FCBD    ; SET ATTRIBUTES
  1415.     MVI    C,30
  1416.     CALL    BDOS
  1417.     RET
  1418.  
  1419. ;
  1420. ;  LOAD BUFFER PTED TO BY HL FROM FILE WHOSE FCB IS PTED TO BY DE
  1421. ;    ON OUTPUT, BCNT=NUMBER OF BLOCKS LOADED (UP TO 128) AND
  1422. ;    CONT=0 IF DONE OR 128 IF NOT DONE
  1423. ;
  1424. LOAD:
  1425.     XRA    A    ; A=0
  1426.     STA    BCNT    ; SET BLOCK COUNT
  1427.     STA    CONT    ; TURN OFF CONTINUATION FLAG
  1428.     LDA    QUIET    ; QUIET?
  1429.     ORA    A    ; 0=NO
  1430.     JNZ    MCPY
  1431.     CALL    PRINT
  1432.     DB    'Reading .....K',0
  1433.  
  1434. ;  MAIN COPY LOOP
  1435. MCPY:
  1436.     CALL    F$READ    ; READ BLOCK
  1437.     ORA    A    ; END OF FILE?
  1438.     RNZ        ; RETURN
  1439.     PUSH    D    ; SAVE PTR TO FCB
  1440.     XCHG        ; SAVE PTR TO DESTINATION BUFFER IN DE
  1441.     LHLD    BDOSE+1    ; GET TOP OF TPA
  1442.     XCHG        ; ... IN DE, DEST IN HL
  1443.     MOV    A,H    ; IF SAME PAGE, WE ARE IN OVERFLOW
  1444.     CMP    D    ; D MUST BE > H
  1445.     JNC    TPAOVFL    ; OVERFLOW IF D<=H
  1446.     LXI    D,BUFF    ; PT TO BUFFER TO COPY FROM
  1447.     MVI    B,128    ; COPY 128 BYTES
  1448.     XCHG        ; HL PTS TO SOURCE, DE PTS TO DESTINATION
  1449. MCPYCRC:
  1450.     MOV    A,M    ; GET BYTE
  1451.     STAX    D    ; PUT BYTE
  1452.     CALL    CRCUPD    ; UPDATE CRC
  1453.     INX    H    ; PT TO NEXT
  1454.     INX    D
  1455.     DCR    B    ; COUNT DOWN
  1456.     JNZ    MCPYCRC
  1457.     XCHG        ; HL PTS TO DESTINATION AGAIN
  1458.     POP    D    ; GET PTR TO FCB
  1459.     LDA    BCNT    ; GET BLOCK COUNT
  1460.     INR    A    ; INCREMENT IT
  1461.     STA    BCNT    ; SET IT
  1462.     PUSH    PSW    ; PRINT BLIP FOR EVERY 1K
  1463.     ANI    7    ; CHECK FOR EVERY 8 BLOCKS
  1464.     JNZ    NOBLIP
  1465.     LDA    QUIET    ; CHECK FOR QUIET
  1466.     ORA    A    ; Z=NOT QUIET
  1467.     JNZ    NOBLIP
  1468.     PUSH    H    ; SAVE HL
  1469.     LHLD    RKCNT    ; INCREMENT READ K COUNT
  1470.     INX    H
  1471.     SHLD    RKCNT
  1472.     CALL    PRKCNT    ; PRINT K COUNT
  1473.     POP    H
  1474. NOBLIP:
  1475.     LDA    PAGLIM    ; GET PAGE LIMIT
  1476.     ADD    A    ; DOUBLE IT FOR BLOCKS
  1477.     MOV    B,A    ; LIMIT IN B
  1478.     POP    PSW    ; GET BLOCK COUNT
  1479.     CMP    B    ; BUFFER FULL?
  1480.     JNZ    MCPY
  1481.     STA    CONT    ; SET CONTINUATION FLAG
  1482.     RET
  1483.  
  1484. ;
  1485. ;  VERIFY PHASE
  1486. ;
  1487. MCOPYV:
  1488.     LDA    QUIET    ; CHECK FOR QUIET
  1489.     ORA    A    ; NZ=QUIET
  1490.     JNZ    MCPYV
  1491.     CALL    PRINT
  1492.     DB    ',  Verify Phase --',CR,LF,0
  1493.     LXI    H,0    ; SET READ K COUNT
  1494.     SHLD    RKCNT
  1495. MCPYV:
  1496.     CALL    CRCCLR    ; CLEAR CRCK VALUE
  1497.     CALL    LOGD    ; LOG IN DESTINATION
  1498.     LXI    D,FCBD    ; CLEAR DESTINATION FCB
  1499.     CALL    INITFCB    ; INIT FCB
  1500.     CALL    F$OPEN    ; OPEN FILE
  1501.  
  1502. ;  **** MAIN VERIFY LOOP ****
  1503. VERLOOP:
  1504.     LHLD    WORKBF    ; LOAD INPUT BUFFER FROM DESTINATION
  1505.     LXI    D,FCBD
  1506.     CALL    LOAD    ; LOAD AND COMPUTE CRC VALUE
  1507.     LDA    BCNT    ; DONE IF NO BYTES LOADED
  1508.     ORA    A
  1509.     JZ    VERCRC
  1510.     LDA    QUIET    ; NEW LINE IF NOT QUIET
  1511.     ORA    A    ; 0=NOT QUIET
  1512.     CZ    CRLF
  1513.     LDA    CONT    ; CONTINUE?
  1514.     ORA    A    ; 0=NO
  1515.     JNZ    VERLOOP
  1516. ;  VERIFY DONE
  1517. VERCRC:
  1518.     LHLD    CRCVAL    ; GET OLD CRC VALUE
  1519.     XCHG        ; ... IN DE
  1520.     CALL    CRCDONE    ; UPDATE COMPLETE
  1521.     CALL    COMPHD    ; COMPARE HL TO DE
  1522.     JNZ    VERERR
  1523.     LDA    QUIET    ; CHECK FOR QUIET
  1524.     ORA    A    ; NZ=QUIET
  1525.     RNZ
  1526.     CALL    PRINT
  1527.     DB    '    Verify Complete',0
  1528.     RET
  1529.  
  1530. ;  VERIFY ERROR
  1531. VERERR:
  1532.     LHLD    VERCNT    ; INCREMENT ERROR COUNT
  1533.     INX    H
  1534.     SHLD    VERCNT
  1535.     CALL    PRINT
  1536.     DB    '    ** Verify Error **',7,0
  1537.     RET
  1538.  
  1539. ;
  1540. ;  **** MCOPY Utilities ****
  1541. ;
  1542.  
  1543. ;
  1544. ;  PRINT K COUNT -- BACK UP 6 SPACES AND PRINT NUMBER IN HL FOLLOWED BY A K
  1545. ;
  1546. PRKCNT:
  1547.     PUSH    B    ; SAVE BC
  1548.     MVI    B,6    ; BACK UP
  1549.     MVI    A,'H'-'@'    ; ^H=BACKSPACE
  1550. PRKCNT1:
  1551.     CALL    COUT    ; BACK UP
  1552.     DCR    B    ; COUNT DOWN
  1553.     JNZ    PRKCNT1
  1554.     CALL    PHLDC    ; PRINT AS DECIMAL
  1555.     MVI    A,'K'    ; PRINT ENDING K
  1556.     CALL    COUT
  1557.     POP    B
  1558.     RET
  1559.  
  1560. ;
  1561. ;  CHECK TO SEE IF USER WANTS TO CONTINUE
  1562. ;
  1563. SAKCHK:
  1564.     CALL    PRINT
  1565.     DB    CR,LF,'    Strike RETURN when Ready or ^C or A to Abort - ',0
  1566.     CALL    CIN    ; GET RESPONSE
  1567.     CALL    CRLF    ; NEW LINE
  1568.     CALL    CAPS    ; CAPITALIZE
  1569.     CPI    'C'-'@'    ; ^C?
  1570.     RZ
  1571.     CPI    'A'    ; ABORT?
  1572.     RET
  1573. ;
  1574. ;  ALLOW USER TO INSPECT FILES FOR COPY
  1575. ;    FIRST FILE NAME PTED TO BY HL, BC = NUMBER OF FILES
  1576. ;    ON EXIT, BC = NUMBER OF SELECTED FILES
  1577. ;
  1578. INSPF:
  1579.     PUSH    H    ; SAVE PTR TO FIRST FILE
  1580.     PUSH    B    ; SAVE FILE COUNT
  1581.     LXI    D,16    ; ENTRIES ARE 16 BYTES APART
  1582. INSPF0:
  1583.     MOV    A,M    ; MARK FILE FOR NO COPY
  1584.     ANI    7FH    ; CLEAR MSB FOR NO COPY
  1585.     MOV    M,A
  1586.     DAD    D    ; PT TO NEXT
  1587.     DCX    B    ; COUNT DOWN
  1588.     MOV    A,B    ; DONE?
  1589.     ORA    C
  1590.     JNZ    INSPF0
  1591.     POP    B    ; RESTORE AND SAVE AGAIN
  1592.     POP    H
  1593.     PUSH    H
  1594.     PUSH    B
  1595. INSPF1:
  1596.     PUSH    H    ; SAVE PTR TO FILE
  1597.     INX    H    ; PT TO FN
  1598.     CALL    CRLF    ; NEW LINE
  1599.     CALL    PRFN    ; PRINT IT
  1600.     POP    H    ; GET PTR TO FILE
  1601.     CALL    PRINT
  1602.     DB    ' -- Copy (Y/N/S=Skip Rest/<CR>=Y)? ',0
  1603.     CALL    CIN    ; GET RESPONSE
  1604.     CALL    CAPS    ; CAPITALIZE
  1605.     CALL    COUT    ; ECHO
  1606.     CPI    'S'    ; SKIP?
  1607.     JZ    INSPFA
  1608.     CPI    'N'    ; NO?
  1609.     JZ    INSPF2
  1610.     MOV    A,M    ; GET USER NUMBER
  1611.     ORI    80H    ; MARK FILE
  1612.     MOV    M,A    ; SET USER NUMBER
  1613. INSPF2:
  1614.     LXI    D,16    ; PT TO NEXT FILE
  1615.     DAD    D
  1616.     DCX    B    ; COUNT DOWN
  1617.     MOV    A,B    ; DONE?
  1618.     ORA    C
  1619.     JNZ    INSPF1
  1620. INSPFA:
  1621.     POP    B    ; GET COUNT
  1622.     POP    H    ; GET PTR TO FIRST FILE
  1623.     JMP    DIRPACK    ; REPACK DIRECTORY
  1624.  
  1625. ;
  1626. ;  LOG IN SOURCE USER/DISK
  1627. ;
  1628. LOGS:
  1629.     LDA    SUSER    ; USER
  1630.     MOV    C,A    ; ... IN C
  1631.     LDA    SDISK    ; DISK
  1632.     MOV    B,A    ; ... IN B
  1633.     JMP    LOGUD    ; LOG IN USER/DISK
  1634.  
  1635. ;
  1636. ;  LOG IN DESTINATION USER/DISK
  1637. ;
  1638. LOGD:
  1639.     LDA    DUSER    ; USER
  1640.     MOV    C,A    ; ... IN C
  1641.     LDA    DDISK    ; DISK
  1642.     MOV    B,A    ; ... IN B
  1643.     JMP    LOGUD    ; LOG IN USER/DISK
  1644.  
  1645. ;
  1646. ;  PRINT FILE NAME
  1647. ;
  1648. PRFN:
  1649.     PUSH    H    ; SAVE REGS
  1650.     PUSH    B
  1651.     MVI    B,8    ; PRINT 8 CHARS
  1652.     CALL    PRFN1
  1653.     MVI    A,'.'    ; DOT
  1654.     CALL    COUT
  1655.     MVI    B,3    ; PRINT 3 CHARS
  1656.     CALL    PRFN1
  1657.     POP    B    ; GET REGS
  1658.     POP    H
  1659.     RET
  1660. PRFN1:
  1661.     MOV    A,M    ; GET CHAR
  1662.     INX    H    ; PT TO NEXT
  1663.     CALL    COUT    ; PRINT IT
  1664.     DCR    B    ; COUNT DOWN
  1665.     JNZ    PRFN1
  1666.     RET
  1667.  
  1668. ;
  1669. ;  **** BUFFERS ****
  1670. ;
  1671.  
  1672. ;  COMMAND LINE BUFFER
  1673. BUFSIZ    EQU    200    ; SIZE OF COMMAND LINE BUFFER
  1674. INBUF:    DB    BUFSIZ    ; FOR USE WITH INPUT LINE EDITOR
  1675.     DB    0
  1676.     DS    BUFSIZ+1    ; INPUT COMMAND LINE
  1677.  
  1678. ;  POINTERS
  1679. MFPTR:    DS    2    ; PTR TO FIRST CHAR OF NEXT FN SPEC
  1680. NXTPTR:    DS    2    ; PTR TO NEXT FN SPEC IN LINE
  1681. WORKBF:    DS    2    ; PTR TO BEGINNING OF WORK BUFFER
  1682.  
  1683. ;  FLAGS COPIED FROM DEFAULTS
  1684. VERFLG:    DS    1    ; VERIFY
  1685. INSP:    DS    1    ; INSPECT
  1686. QUIET:    DS    1    ; QUIET
  1687. NCOPY:    DS    1    ; MULTIPLE COPY
  1688.  
  1689. ;  DISKS AND USERS -- ORDER IS IMPORTANT -- cUSER MUST FOLLOW cDISK
  1690. CDISK:    DS    1    ; CURRENT DISK
  1691. CUSER:    DS    1    ; CURRENT USER
  1692. SDISK:    DS    1    ; SOURCE DISK
  1693. SUSER:    DS    1    ; SOURCE USER
  1694. DDISK:    DS    1    ; DESTINATION DISK
  1695. DUSER:    DS    1    ; DESTINATION USER
  1696.  
  1697. ;  CRC VALUE
  1698. CRCVAL:    DS    2    ; CRC CHECK VALUE
  1699.  
  1700. ;  FCBS
  1701. FCBS:    DS    40    ; SOURCE FCB
  1702. FCBD:    DS    40    ; DESTINATION FCB
  1703. FCBT:    DS    40    ; TEMPORARY FCB FOR ATTRIBUTE SETTINGS
  1704.  
  1705. ;  COUNTS AND FLAGS
  1706. RKCNT:    DS    2    ; READ K COUNT
  1707. WKCNT:    DS    2    ; WRITE K COUNT
  1708. PAGLIM:    DS    1    ; MAX NUMBER OF PAGES IN WORK BUFFER
  1709. LSTCPY:    DS    1    ; LAST FILE WAS COPIED FLAG
  1710. EXIST:    DS    1    ; TEST FOR EXISTENCE FLAG
  1711. FTOTAL:    DS    2    ; TOTAL SIZE OF FILES
  1712. FCOUNT:    DS    2    ; NUMBER OF FILES
  1713. VERCNT:    DS    2    ; ERROR COUNT
  1714. BCNT:    DS    1    ; BLOCK COUNT
  1715. CONT:    DS    1    ; CONTINUE FLAG (0=NO, 0FFH=YES)
  1716.  
  1717. ;  STACK AREA
  1718.     DS    100    ; 50-ELEMENT STACK
  1719. STACK    EQU    $
  1720.     DB    0    ; END OF MAINLINE
  1721.  
  1722.     END
  1723.