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 / ZSYS / SIMTEL20 / ZCPR3 / MCOPY.MQC / MCOPY.MAC
Text File  |  2000-06-30  |  22KB  |  1,072 lines

  1. ;  PROGRAM:  MCOPY
  2. ;  AUTHOR:  RICHARD CONN
  3. ;  VERSION:  4.0
  4. ;  DATE:  18 MAY 84
  5. ;  PREVIOUS VERSIONS:  3.0 (16 JAN 83)
  6. ;  PREVIOUS VERSIONS:  NUMEROUS
  7.  
  8. VERS    equ    42    ; Use 16k buffer  14 Dec 84  jww
  9.             ; Fix some bugs  Joe Wright  28 Aug 84
  10.             ; 1. Add check for directory full after f$make
  11.  
  12. z3env    SET    0F400H
  13.  
  14. ;
  15. ;    MCOPY is a program which repeatedly copies a file from drive
  16. ; A: onto drive B:.  It prompts the user to mount a disk in drive B:,
  17. ; copies the file from drive A: to drive B:, verifies the copy (if not
  18. ; overridden), and then performs the function again.
  19. ;
  20. ;    MCOPY performs its function in the following steps:
  21. ;        1.  MCOPY determines the attributes
  22. ; of the destination file (if it exists) and clears them (file becomes
  23. ; R/W and DIR)
  24. ;        2.  MCOPY deletes the destination file (if it exists)
  25. ;        3.  MCOPY copies the source file to the destination
  26. ;        4.  MCOPY determines the attributes
  27. ; of the source file and makes the attributes of the destination file
  28. ; identical to those of the source
  29. ;        5.  MCOPY reads both the source and destination files and
  30. ; compares them byte-for-byte
  31. ;
  32.  
  33. ;  SPECIAL Constants
  34. PLIM    EQU    4*16    ; SIZE OF BUFFER IN PAGES (4 * nK) [may be changed]
  35. ESIZE    EQU    16    ; NUMBER OF BYTES/ENTRY
  36.  
  37. ;  CP/M Constants
  38. WB    EQU    0    ; CP/M WARM BOOT
  39. BDOSE    EQU    WB+5    ; BDOS ENTRY POINT
  40. FCB    EQU    WB+5CH    ; SPECIFIED FCB
  41. BUFF    EQU    WB+80H    ; DEFAULT BUFFER AND INPUT LINE
  42. SDMA    EQU    26    ; SET DMA ADDRESS
  43.  
  44. ;  ASCII Constants, et al
  45. ON    EQU    0FFH    ; ON CODE
  46. OFF    EQU    0    ; OFF CODE
  47. CR    EQU    0DH    ; <CR>
  48. LF    EQU    0AH    ; <LF>
  49. CTRLC    EQU    'C'-'@'    ; ^C
  50. CTRLZ    EQU    'Z'-'@'    ; ^Z
  51. OPTC    EQU    '/'    ; OPTION DELIMITER
  52.  
  53. ;
  54. ;  LOAD @DE MACRO
  55. ;
  56. LDED    MACRO    ?ADR
  57.     XCHG
  58.     LHLD    ?ADR
  59.     XCHG
  60.     ENDM
  61.  
  62. ;
  63. ;  SYSLIB ROUTINES
  64. ;
  65.     EXT    Z3INIT,ZFNAME,GETQUIET
  66.     EXT    COMPHD,RETUD,LOGUD,PUTUD,GETUD
  67.     EXT    DIRQ,DIRPACK,DIRTDU
  68.     EXT    INITFCB,F$EXIST
  69.     EXT    CRCCLR,CRCUPD,CRCDONE
  70.     EXT    BDOS,CIN,COUT,CONDIN
  71.     EXT    F$DELETE,F$OPEN,F$MAKE,F$CLOSE,F$READ,F$WRITE
  72.     EXT    PADC,EPSTR,EPRINT
  73.     EXT    MOVEB,CAPS,CRLF
  74.     EXT    CODEND
  75.  
  76. ;
  77. ; Environment Definition
  78. ;
  79.     if    z3env ne 0
  80. ;
  81. ; External ZCPR3 Environment Descriptor
  82. ;
  83.     jmp    start
  84.     db    'Z3ENV'    ;This is a ZCPR3 Utility
  85.     db    1    ;External Environment Descriptor
  86. z3eadr:
  87.     dw    z3env
  88. start:
  89.     lhld    z3eadr    ;pt to ZCPR3 environment
  90. ;
  91.     else
  92. ;
  93. ; Internal ZCPR3 Environment Descriptor
  94. ;
  95.     MACLIB    Z3BASE.LIB
  96.     MACLIB    SYSENV.LIB
  97. z3eadr:
  98.     jmp    start
  99.     SYSENV
  100. start:
  101.     lxi    h,z3eadr    ;pt to ZCPR3 environment
  102.     endif
  103.  
  104. ;
  105. ; Start of Program -- Initialize ZCPR3 Environment
  106. ;
  107.     call    z3init    ;initialize the ZCPR3 Env and the VLIB Env
  108.     jmp    startx
  109.  
  110. ;
  111. ;  USER-DEFINABLE INITIAL FLAG CONDITIONS
  112. ;    THE DEFAULT CONDITIONS FOR MCOPY MAY BE READILY PATCHED BY THE USER
  113. ; VIA DDT FOR HIS DESIRED DEFAULT VALUES
  114. ;
  115. DVERFLG:
  116.     DB    ON    ; SET VERIFY
  117. DINSP:
  118.     DB    OFF    ; SET NO INSPECT
  119. DNCOPY:
  120.     DB    OFF    ; SET NO MULTIPLE COPIES BY DEFAULT
  121. DDDISK:
  122.     DB    'B'-'A'    ; DEFAULT DESTINATION DISK IS B
  123. DDUSER:
  124.     DB    0    ; DEFAULT DESTINATION USER IS 0
  125. BACKDIR:
  126.     DB    'BACKUP  '    ; NAME OF BACKUP DIRECTORY
  127.  
  128. ;
  129. ;  BEGINNING OF MCOPY PROGRAM
  130. ;
  131. STARTX:
  132. ;
  133. ;  PRINT BANNER
  134. ;
  135.     CALL    EPRINT
  136.     DB    'MCOPY  Version '
  137.     DB    VERS/10+'0','.',(VERS MOD 10)+'0',0
  138. ;
  139. ;  SET UP DYNAMIC BUFFERS
  140. ;
  141.     LXI    H,0    ; GET SP
  142.     DAD    SP
  143.     SHLD    STACK    ; SAVE IT
  144.     CALL    CODEND    ; DETERMINE FREE SPACE
  145.     SHLD    INLINE    ; PTR TO INPUT LINE
  146.     INR    H
  147.     SHLD    FCBT    ; PTR TO FCB TEMP
  148.     INR    H
  149.     SHLD    FCBS    ; PTR TO SOURCE FCB
  150.     INR    H
  151.     SHLD    FCBD    ; PTR TO DEST FCB
  152.     INR    H
  153.     SHLD    FREEBUF    ; FREE SPACE BUFFER
  154.  
  155. ;
  156. ;  SET DEFAULT FLAGS
  157. ;
  158.     CALL    GETQUIET    ; GET QUIET FLAG
  159.     STA    QUIET
  160.     LDA    DVERFLG    ; VERIFY
  161.     STA    VERFLG
  162.     LDA    DINSP    ; INSPECT
  163.     STA    INSP
  164.     LDA    DNCOPY    ; MULTIPLE COPIES
  165.     STA    NCOPY
  166.  
  167. ;
  168. ;  CHECK FOR BACKUP DIRECTORY AND ESTABLISH IT AS DEFAULT
  169. ;    IF NO BACKUP DIRECTORY, SELECT DEFAULT STORED
  170. ;
  171.     LXI    H,BACKDIR    ; PT TO DIRECTORY NAME
  172.     CALL    DIRTDU
  173.     JZ    DEFBACK        ; NAME NOT FOUND, SO SELECT DEFAULT
  174.     MOV    A,B    ; SET DEST DISK
  175.     STA    DDISK
  176.     MOV    A,C    ; SET DEST USER
  177.     STA    DUSER
  178.     JMP    BACKSET
  179. DEFBACK:
  180.     LDA    DDDISK    ; GET DEFAULT DEST DISK
  181.     STA    DDISK    ; SET DEST DISK
  182.     LDA    DDUSER    ; GET DEFAULT DEST USER
  183.     STA    DUSER    ; SET DEST USER
  184. ;
  185. ;  OBTAIN AND SAVE CURRENT USER AND DISK
  186. ;
  187. BACKSET:
  188.     CALL    PUTUD    ; SAVE POSITION
  189.     CALL    RETUD    ; GET USER/DISK
  190.     MOV    A,B    ; SAVE DISK
  191.     STA    CDISK
  192.     LHLD    INLINE    ; INPUT LINE SAVE BUFFER
  193.     XCHG        ; ... IN DE
  194.     LXI    H,BUFF+1    ; PT TO COMMAND LINE CHAR COUNT
  195.     MVI    B,128    ; SAVE 128 BYTES (ARBITRARY)
  196.     CALL    MOVEB
  197.     XCHG        ; HL PTS TO INPUT LINE
  198. ;
  199. ;  SET OTHER FLAGS
  200. ;
  201.     XRA    A    ; A=0
  202.     STA    EXIST    ; TURN OFF EXIST TEST
  203. ;
  204. ;  CHECK FOR EMPTY COMMAND LINE AND PROCESS COMMAND MODE IF SO
  205. ;    ON ENTRY, HL PTS TO FIRST CHAR OF STRING FROM CLINE
  206. ;
  207. START1:
  208.     MOV    A,M    ; GET CHAR
  209.     ORA    A    ; EOL?
  210.     JZ    MHELP    ; PRINT HELP MESSAGE IF NO INPUT
  211.     INX    H    ; PT TO NEXT
  212.     CPI    ' '    ; JUST SPACES?
  213.     JZ    START1
  214. ;
  215. ;  COMMAND LINE WAS NOT EMPTY -- CHECK FOR HELP REQUEST
  216. ;
  217.     DCX    H    ; PT TO FIRST CHAR
  218.     CPI    '/'    ; IF OPENING OPTION, MUST BE HELP
  219.     JZ    MHELP
  220. ;
  221. ;  SEE IF OPTIONS ARE AVAILABLE IN THE COMMAND LINE
  222. ;
  223.     SHLD    MFPTR    ; SET PTR TO FIRST CHAR OF FILE NAME SPECS
  224. ;
  225. ;  SKIP TO END OF FILE NAME SPECS
  226. ;
  227. START2:
  228.     MOV    A,M    ; SKIP TO <SP> OR EOL
  229.     INX    H    ; PT TO NEXT
  230.     CPI    ' '+1    ; <SP> OR LESS?
  231.     JNC    START2
  232.     ORA    A    ; AT EOL?
  233.     JZ    MCOPY0    ; PERFORM DEFAULT MCOPY FUNCTION IF AT EOL
  234. ;
  235. ;  SCAN FOR OPTION
  236. ;
  237. OPTION:
  238.     MOV    A,M    ; GET OPTION CHAR
  239.     ORA    A    ; EOL?
  240.     JZ    MCOPY0    ; DO MCOPY
  241.     INX    H    ; PT TO NEXT
  242.     PUSH    H    ; SAVE PTR
  243.     LXI    H,OPTTAB    ; PT TO OPTION TABLE
  244.     CALL    CMDER    ; PROCESS COMMAND
  245.     POP    H    ; GET PTR
  246.     JMP    OPTION
  247.  
  248. ;
  249. ;  COMMAND PROCESSOR -- COMMAND LETTER IN A, HL PTS TO TABLE
  250. ;
  251. CMDER:
  252.     PUSH    B    ; SAVE BC
  253.     MOV    B,A    ; COMMAND IN B
  254. CMDER1:
  255.     MOV    A,M    ; GET COMMAND LETTER
  256.     ORA    A    ; DONE?
  257.     JZ    CMDER2
  258.     CMP    B    ; MATCH?
  259.     JNZ    CMDER3
  260. CMDER2:
  261.     INX    H    ; PT TO ADDRESS
  262.     MOV    E,M    ; GET IT IN DE
  263.     INX    H
  264.     MOV    D,M
  265.     XCHG        ; HL PTS TO COMMAND ADDRESS
  266.     POP    B    ; RESTORE BC
  267.     PCHL        ; RUN COMMAND
  268. CMDER3:
  269.     INX    H    ; SKIP TO NEXT ENTRY IN TABLE
  270.     INX    H
  271.     INX    H
  272.     JMP    CMDER1
  273.  
  274. ;  OPTION COMMAND TABLE
  275. OPTTAB:
  276.     DB    ' '    ; DONE
  277.     DW    OPTS
  278.     DB    OPTC    ; SKIP OPTC
  279.     DW    OPTS
  280.     DB    'E'    ; EXIST TEST
  281.     DW    OPTE
  282.     DB    'I'    ; INSPECT
  283.     DW    OPTI
  284.     DB    'M'    ; MULTIPLE COPY
  285.     DW    OPTM
  286.     DB    'Q'    ; QUIET
  287.     DW    OPTQ
  288.     DB    'V'    ; VERIFY
  289.     DW    OPTV
  290.     DB    0    ; END OF TABLE
  291.     DW    OHELP
  292.  
  293. ;  INVALID OPTION CHAR -- CLEAR STACK (RET ADR AND HL) AND PRINT HELP
  294. OHELP:
  295.     POP    H    ; CLEAR RET ADR
  296.     POP    H    ; CLEAR HL
  297.  
  298. ;  PRINT HELP MESSAGE
  299. MHELP:
  300.     CALL    EPRINT
  301.     DB    CR,LF,'Syntax:'
  302.     DB    cr,lf,'  MCOPY dir:=dir:filename.typ,... o...'
  303.     db    cr,lf,'Options:'
  304.     DB    cr,lf,'  E -- Existence Test'
  305.     DB    cr,lf,'  I -- Inspect Files'
  306.     DB    cr,lf,'  M -- Multiple Copy'
  307.     DB    cr,lf,'  Q -- Toggle Quiet'
  308.     DB    cr,lf,'  V -- No Verify'
  309.     DB    0
  310.     RET        ; RETURN TO ZCPR3
  311.  
  312. ;  VERIFY FLAG TOGGLE OPTION
  313. OPTV:
  314.     LDA    VERFLG    ; GET FLAG
  315.     CMA        ; FLIP IT
  316.     STA    VERFLG    ; PUT FLAG
  317. ;  SKIP OPTION
  318. OPTS:
  319.     RET
  320.  
  321. ;  EXIST TEST TOGGLE OPTION
  322. OPTE:
  323.     LDA    EXIST    ; GET FLAG
  324.     CMA        ; FLIP IT
  325.     STA    EXIST    ; PUT FLAG
  326.     RET
  327.  
  328. ;  NCOPY FLAG TOGGLE OPTION
  329. OPTM:
  330.     LDA    NCOPY    ; GET FLAG
  331.     CMA        ; FLIP IT
  332.     STA    NCOPY    ; PUT FLAG
  333.     RET
  334.  
  335. ;  INSPECT FLAG TOGGLE OPTION
  336. OPTI:
  337.     LDA    INSP    ; GET FLAG
  338.     CMA        ; FLIP IT
  339.     STA    INSP    ; PUT FLAG
  340.     RET
  341.  
  342. ;  QUIET FLAG TOGGLE OPTION
  343. OPTQ:
  344.     LDA    QUIET    ; GET FLAG
  345.     CMA        ; FLIP IT
  346.     STA    QUIET    ; PUT FLAG
  347.     RET
  348.  
  349. ;
  350. ;  **** MCOPY of COMMAND LINE ****
  351. ;
  352. MCOPY0:
  353.     LHLD    FREEBUF    ; STACK RESET
  354.     SPHL
  355.     LDA    NCOPY    ; MULTIPLE COPIES?
  356.     ORA    A    ; 0=NO
  357.     JZ    NOPAUSE
  358.     CALL    SAKCHK    ; STRIKE ANY KEY CHECK
  359.     JZ    CPM    ; WARM BOOT IF ABORT
  360. NOPAUSE:
  361.     CALL    COPY    ; DO THE COPY
  362. CPM:
  363.     LHLD    STACK    ; RESET STACK
  364.     SPHL
  365.     RET        ; RETURN TO OPSYS
  366. CPMA:
  367.     CALL    EPRINT
  368.     DB    CR,LF,'Abort',0
  369.     JMP    CPM
  370.  
  371. ;
  372. ;  **** Begin Multiple Copy Procedure ****
  373. ;
  374. COPY:
  375.     LHLD    MFPTR    ; PT TO FIRST FILE NAME
  376.     SHLD    NXTPTR    ; SET PTR TO NEXT FILE NAME
  377.     XRA    A    ; A=0
  378.     STA    VERCNT    ; ZERO ERROR COUNT
  379.     LDA    EXIST    ; IF EXIST, THEN MUST NOT BE QUIET
  380.     ORA    A    ; 0=NO EXIST
  381.     JZ    MCOPY
  382.     XRA    A    ; SET NO QUIET
  383.     STA    QUIET
  384. ;
  385. ;  **** MAIN COPY LOOP ****
  386. ;
  387. MCOPY:
  388.     LHLD    NXTPTR    ; GET PTR TO NEXT FILE NAME
  389.     MOV    A,M    ; GET FIRST CHAR
  390.     CPI    ' '+1    ; DONE IF <SP> OR LESS
  391.     JNC    MCOPY1    ; CONTINUE WITH PROCEDURE
  392. ;
  393. ;  MCOPY OF FILE SPECS IS NOW DONE
  394. ;  DONE WITH COPY PROCEDURE -- CONTINUE?
  395. ;
  396. COPYT:
  397.     LDA    VERFLG    ; VERIFY?
  398.     ORA    A    ; 0=NO
  399.     JZ    COPYT1
  400.     CALL    CRLF    ; NEW LINE
  401.     LDA    VERCNT    ; GET ERROR COUNT
  402.     CALL    PADC    ; PRINT AS DECIMAL
  403.     CALL    EPRINT
  404.     DB    ' Errors',0
  405. COPYT1:
  406.     LDA    NCOPY    ; MULTIPLE COPIES?
  407.     ORA    A    ; 0=NO
  408.     RZ
  409.     CALL    SAKCHK    ; CHECK FOR STRIKE OF ANY KEY
  410.     RZ        ; RETURN IF ABORT
  411.     JMP    COPY    ; COPY AGAIN FROM THE BEGINNING
  412. ;
  413. ;  BEGIN COPY OF FILE GROUP
  414. ;
  415. MCOPY1:
  416.     CPI    ','    ; SKIP COMMA SEPARATOR IF THERE
  417.     JNZ    MCPY0
  418.     INX    H    ; PT TO CHAR AFTER COMMA
  419. MCPY0:
  420.     MOV    A,M    ; GET NEXT CHAR
  421.     CPI    ' '+1    ; CHECK FOR ERROR
  422.     JC    FORMERR
  423.     CALL    GETUD    ; RETURN HOME
  424.     LDED    FCBS    ; PT TO SOURCE FCB
  425.     MVI    A,0    ; DIR BEFORE DU
  426.     CALL    ZFNAME    ; EXTRACT FILE NAME DATA
  427.     CALL    DUCVRT    ; CONVERT DU INTO BC
  428.     MOV    A,M    ; GET DELIMITER
  429.     CPI    '='    ; IF '=', WE HAVE A NEW DISK/USER
  430.     JNZ    MCOPY2    ; FORM IS DIRS:FN.FT IF NO '='
  431. ;
  432. ;  FORM IS DIRD:=DIRS:FN.FT, SO SET DEST DISK/USER
  433. ;
  434.     MOV    A,B    ; GET DISK
  435.     STA    DDISK    ; SET NEW DEFAULT DISK
  436.     MOV    A,C    ; GET USER
  437.     STA    DUSER    ; SET NEW DEFAULT USER
  438. ;
  439. ;  NOW DERIVE DIRS:FN.FT FORM AFTER THE '='
  440. ;
  441. MCPY2:
  442.     INX    H    ; PT TO CHAR BEYOND '='
  443.     MOV    A,M    ; GET CHAR
  444.     CPI    ' '+1    ; FORMAT ERROR?
  445.     JC    FORMERR
  446.     LDED    FCBS    ; LOAD FCB
  447.     MVI    A,0    ; DIR BEFORE DU
  448.     CALL    ZFNAME    ; GET SOURCE NAME
  449.     CALL    DUCVRT    ; CONVERT TO DU IN BC
  450. ;
  451. ;  SAVE PTR TO NEXT CHAR AFTER DIRS:FN.FT, AND SET SOURCE DISK/USER
  452. ;
  453. MCOPY2:
  454.     SHLD    NXTPTR    ; SAVE PTR TO NEXT CHAR
  455.     MOV    A,B    ; GET DISK
  456.     STA    SDISK    ; SET NEW DEFAULT DISK
  457.     MOV    A,C    ; GET USER
  458.     STA    SUSER    ; SET NEW DEFAULT USER
  459. MCPY22:
  460.     LDA    DDISK    ; DEST DIR MUST NOT EQUAL SOURCE DIR
  461.     MOV    B,A
  462.     LDA    SDISK
  463.     CMP    B
  464.     JNZ    MCPYOK
  465.     LDA    DUSER
  466.     MOV    B,A
  467.     LDA    SUSER
  468.     CMP    B
  469.     JNZ    MCPYOK
  470.     CALL    EPRINT
  471.     DB    CR,LF,'Src=Dest Err',0
  472.     RET
  473. MCPYOK:
  474.     CALL    EPRINT
  475.     DB    CR,LF,'Copy ',0
  476.     LDA    SDISK    ; GET NUMBER
  477.     ADI    'A'    ; CONVERT TO LETTER
  478.     CALL    COUT    ; PRINT
  479.     LDA    SUSER    ; PRINT USER NUMBER
  480.     CALL    PADC
  481.     MVI    A,':'    ; SEPARATOR
  482.     CALL    COUT
  483.     MVI    A,' '
  484.     CALL    COUT
  485.     LHLD    FCBS    ; PRINT FILE SPEC
  486.     INX    H    ; PT TO FILE NAME
  487.     CALL    PRFN
  488.     CALL    EPRINT
  489.     DB    ' to ',0
  490.     LDA    DDISK    ; GET NUMBER
  491.     ADI    'A'    ; CONVERT TO LETTER
  492.     CALL    COUT    ; PRINT
  493.     LDA    DUSER    ; PRINT USER NUMBER
  494.     CALL    PADC
  495.     MVI    A,':'
  496.     CALL    COUT
  497.     MVI    C,13    ; RESET DISK SYSTEM
  498.     CALL    BDOS
  499.     CALL    LOGS    ; LOG IN SOURCE USER/DISK
  500.     LDED    FCBS    ; PT TO SOURCE FCB
  501.     CALL    INITFCB    ; INIT FCB
  502.     LHLD    FREEBUF    ; PT TO BUFFER AREA
  503.     MVI    A,0C0H    ; SELECT NON-SYS AND SYS FILES
  504.     CALL    DIRQ    ; LOAD DIR, SELECT FILES, SORT, ETC
  505.     JZ    TPAOVFL    ; TPA OVERFLOW ERROR?
  506.     LDA    INSP    ; INSPECT FILES?
  507.     ORA    A    ; 0=NO
  508.     CNZ    INSPF    ; INSPECT FILES IF OPTION SELECTED
  509.     MOV    A,B    ; CHECK FOR ANY FILES TO COPY
  510.     ORA    C    ; 0=NONE
  511.     JNZ    MCPY24
  512. MCPY23:
  513.     CALL    EPRINT
  514.     DB    CR,LF,' NO Files -- ^C to Abort ',0
  515.     CALL    CIN    ; GET RESPONSE
  516.     CPI    'C'-'@'    ; ABORT?
  517.     JZ    COPYT    ; END TEST
  518.     JMP    MCOPY    ; CONTINUE WITH NEXT
  519. MCPY24:
  520.     PUSH    H    ; SAVE PTR AND COUNT
  521.     PUSH    B
  522.     LXI    D,ESIZE    ; SKIP TO END OF LOADED FILES AND MARK BEGINNING OF
  523.             ;   WORK AREA
  524. MCPY25:
  525.     DAD    D    ; PT TO NEXT
  526.     DCX    B    ; COUNT DOWN
  527.     MOV    A,B    ; DONE?
  528.     ORA    C
  529.     JNZ    MCPY25
  530.     MVI    A,PLIM    ; SET PAGE LIMIT
  531.     STA    PAGLIM
  532.     SHLD    WORKBF    ; SAVE PTR TO BEGINNING OF WORK BUFFER
  533.     LDA    BDOSE+2    ; GET BASE PAGE OF BDOS
  534.     SUI    10    ; GET BELOW BASE PAGE OF CCP
  535.     SUB    H    ; COMPUTE SIZE OF BUFFER AREA
  536.     CPI    PLIM    ; PLIM PAGES LEFT?
  537.     JNC    PAGOK
  538.     STA    PAGLIM    ; SET PAGE LIMIT
  539. PAGOK:
  540.     POP    B    ; RESTORE PTRS
  541.     POP    H
  542. ;
  543. ;  MAIN COPYING LOOP
  544. ;    FILE NAMES ARE PTED TO BY HL AND BC=NUMBER OF FILES
  545. ;
  546. MCPY26:
  547.     PUSH    H    ; SAVE REGS
  548.     PUSH    B
  549.     CALL    ABORTCK    ; CHECK FOR ABORT
  550. MCPY27:
  551.     CALL    MCOPYX    ; COPY SOURCE (HL) TO DESTINATION USING WORK BUFFER
  552.     CALL    PRDONE    ; PRINT DONE MESSAGE
  553.     CALL    ABORTCK    ; CHECK FOR ABORT
  554.     LDA    LSTCPY    ; LAST FILE COPIED?
  555.     ORA    A    ; 0=NO
  556.     JZ    MCPY28
  557.     LDA    VERFLG    ; VERIFY?
  558.     ORA    A    ; 0=NO
  559.     CNZ    MCOPYV    ; DO VERIFY
  560. MCPY28:
  561.     POP    B    ; GET REGS
  562.     POP    H
  563.     LXI    D,ESIZE    ; PT TO NEXT FILE
  564.     DAD    D    ; HL PTS TO NEXT FILE
  565.     DCX    B    ; COUNT DOWN
  566.     MOV    A,B
  567.     ORA    C
  568.     JNZ    MCPY26
  569.     JMP    MCOPY    ; COPY NEXT FILE SPEC
  570. ;
  571. ;  CHECK FOR ABORT
  572. ;
  573. ABORTCK:
  574.     CALL    CONDIN    ; CONDITIONAL INPUT
  575.     RZ
  576.     CPI    CTRLC    ; ABORT?
  577.     JZ    CPMA
  578.     RET
  579. ;
  580. ;  PRINT DONE MESSAGE
  581. ;
  582. PRDONE:
  583.     LDA    QUIET    ; CHECK FOR QUIET
  584.     ORA    A    ; NZ=QUIET
  585.     RNZ
  586.     CALL    EPRINT
  587.     DB    ' Done',0
  588.     RET
  589. ;
  590. ;  COPY SOURCE FILE PTED TO BY HL TO DESTINATION
  591. ;
  592. MCOPYX:
  593.     XRA    A    ; SET NO COPY OF LAST FILE
  594.     STA    LSTCPY    ; SET FLAG
  595.     LDED    FCBS    ; SET SOURCE FCB
  596.     MVI    B,12    ; 12 BYTES
  597.     CALL    MOVEB
  598.     CALL    INITFCB    ; INIT SOURCE FCB
  599.     LDED    FCBD    ; SET DESTINATION FCB
  600.     MVI    B,12    ; 12 BYTES
  601.     CALL    MOVEB
  602.     CALL    DRW    ; CLEAR ATTRIBUTES IN FCB
  603.     CALL    INITFCB    ; INIT DESTINATION FCB
  604.     CALL    LOGD    ; LOG IN DESTINATION
  605.     CALL    EPRINT
  606.     DB    CR,LF,' File ',0
  607.     LHLD    FCBD    ; PRINT FILE NAME
  608.     INX    H    ; PT TO FILE NAME
  609.     CALL    PRFN
  610.     LDED    FCBD    ; PT TO FCB
  611.     CALL    F$EXIST    ; DOES DEST EXIST?
  612.     JZ    FNF    ; FILE NOT FOUND IF ZERO
  613.     LDA    QUIET    ; QUIET?
  614.     ORA    A    ; 0=NO
  615.     JNZ    FFND
  616.     CALL    EPRINT
  617.     DB    ' Replace',0
  618. FFND:
  619.     CALL    EATEST    ; EXIST APPROVED TEST?
  620.     RZ        ; NOT APPROVED, SO ABORT
  621.     CALL    DESTRW    ; MAKE DESTINATION R/W IF NOT ALREADY
  622.     CALL    F$DELETE    ; DELETE FILE
  623.     CALL    INITFCB        ; REINIT FCB
  624.     JMP    FNF1    ; CREATE NEW FILE AND CONTINUE
  625. FNF:
  626.     LDA    QUIET    ; QUIET?
  627.     ORA    A    ; 0=NO
  628.     JNZ    FNF1
  629.     CALL    EATEST    ; EXIST APPROVED?
  630.     RZ        ; NO?
  631. FNF1:
  632.     CALL    EPRINT
  633.     DB    ' ...',0
  634.     MVI    A,0FFH    ; SET COPY OF LAST FILE
  635.     STA    LSTCPY    ; SET FLAG
  636.     CALL    F$MAKE    ; CREATE NEW FILE
  637.     inr    a    ; check for full directory
  638.     jz    dirful    ; report it
  639. ;
  640. ;  OPEN SOURCE FILE IN PREP FOR COPY
  641. ;
  642.     CALL    CRCCLR    ; CLEAR CRC VALUE
  643.     CALL    LOGS    ; LOG IN SOURCE DISK
  644.     LDED    FCBS    ; INIT FCB
  645.     CALL    INITFCB
  646.     CALL    F$OPEN    ; OPEN FILE
  647. ;
  648. ;  THIS LOOP, WHICH STARTS AT MCPYX, COPIES THE FILE FROM SOURCE TO DEST
  649. ;
  650. MCPYX:
  651.     CALL    LOGS    ; LOG IN SOURCE
  652.     LDED    FCBS    ; PT TO SOURCE FCB
  653.     LHLD    WORKBF    ; PT TO BUFFER TO COPY INTO
  654.     CALL    LOAD    ; LOAD FILE INTO WORKBF
  655.     LDA    BCNT    ; IF COUNT=0, THEN DONE
  656.     ORA    A
  657.     JZ    MC2DONE
  658. ;
  659. ;  COPY TO DISK
  660. ;
  661. MCPYD:
  662.     CALL    LOGD    ; LOG IN DESTINATION
  663.     LHLD    WORKBF    ; PT TO BUFFER
  664. MCPYD1:
  665.     CALL    SETDMA    ; SET DMA ADDRESS PTED TO BY HL
  666.     LXI    D,128    ; INCR HL BY 128
  667.     DAD    D    ; HL PTS TO NEXT BLOCK
  668.     LDED    FCBD    ; WRITE TO DESTINATION FILE
  669.     CALL    F$WRITE
  670.     ORA    A    ; OK?
  671.     JNZ    MCPYDERR
  672.  
  673. ;  COUNT DOWN TO NEXT BLOCK
  674.     LDA    BCNT    ; GET BLOCK COUNT
  675.     DCR    A    ; COUNT DOWN
  676.     STA    BCNT
  677.     JNZ    MCPYD1
  678.     LDA    CONT    ; CONTINUE?
  679.     ORA    A    ; CONT IF NOT ZERO
  680.     JNZ    MCPYX
  681. ;
  682. ;  END OF COPY LOOP
  683. ;
  684. MC2DONE:
  685.     CALL    LOGS    ; LOG IN SOURCE
  686.     LDED    FCBS    ; CLOSE SOURCE
  687.     CALL    F$CLOSE
  688.     CALL    LOGD    ; LOG IN DESTINATION
  689.     LDED    FCBD    ; CLOSE DESTINATION
  690.     CALL    F$CLOSE
  691.     CALL    CRCDONE    ; GET CRCK VALUE
  692.     SHLD    CRCVAL    ; SAVE CRC VALUE
  693. ;
  694. ;  SET ATTRIBUTES OF DESTINATION TO BE THE SAME AS THOSE OF SOURCE
  695. ;
  696.     CALL    LOGS    ; LOG IN SOURCE DRIVE
  697.     LDED    FCBS    ; FIND SOURCE
  698.     MVI    C,17    ; SEARCH FOR FIRST
  699.     CALL    BDOS
  700.     RLC        ; MULTIPLY BY 32 TO GET OFFSET
  701.     RLC
  702.     RLC
  703.     RLC
  704.     RLC
  705.     ANI    0E0H    ; MASK OUT LSB
  706.     MOV    L,A    ; VALUE IN L
  707.     MVI    H,0
  708.     LXI    D,BUFF    ; ADD IN BUFFER BASE
  709.     DAD    D
  710.     XCHG        ; PT TO FCBT IN DE
  711.     LHLD    FCBT
  712.     XCHG
  713.     MVI    B,16    ; MOVE 16 BYTES
  714.     CALL    MOVEB
  715.     CALL    LOGD    ; LOG IN DESTINATION DRIVE
  716.     CALL    INITFCB    ; INIT FCB PTED TO BY DE (FCBT)
  717.     MVI    C,30    ; SET FILE ATTRIBUTES
  718.     CALL    BDOS
  719.     RET        ; MCOPYX RETURN
  720.  
  721. ;
  722. ;  CONVERT Z3 FCB DU INTO DU IN BC
  723. ;
  724. DUCVRT:
  725.     PUSH    H    ; SAVE REGS
  726.     PUSH    D
  727.     LDAX    D    ; GET DISK
  728.     ORA    A    ; CURRENT?
  729.     JNZ    DUCV1
  730.     LDA    CDISK    ; GET CURRENT
  731.     INR    A    ; ADD 1 FOR A=1
  732. DUCV1:
  733.     DCR    A    ; A=0
  734.     MOV    B,A
  735.     LXI    H,13    ; OFFSET TO USER
  736.     DAD    D
  737.     MOV    C,M    ; GET USER
  738.     POP    D    ; RESTORE REGS
  739.     POP    H
  740.     RET
  741.  
  742. ;  FORMAT ERROR
  743. FORMERR:
  744.     CALL    EPRINT
  745.     DB    CR,LF,' Error: ',0
  746.     CALL    EPSTR    ; PRINT ERROR
  747.     RET
  748.  
  749. ;  TPA OVERFLOW
  750. TPAOVFL:
  751.     CALL    EPRINT
  752.     DB    CR,LF,'TPA Ovfl',0
  753.     JMP    CPM
  754.  
  755. ;  WRITE ERROR
  756. MCPYDERR:
  757.     CALL    EPRINT
  758.     DB    CR,LF,'Disk Full',0
  759.     JMP    CPM
  760.  
  761. ;  Directory Full Error
  762. dirful:
  763.     call    eprint
  764.     db    cr,lf,'Directory Full',0
  765.     jmp    cpm
  766.  
  767. ;  TEST FOR EXISTENCE REQUIREMENT AND GET USER RESPONSE
  768. EATEST:
  769.     LDA    EXIST    ; EXISTENCE TEST ON?
  770.     ORA    A    ; 0=NO
  771.     JZ    EAT1
  772.     CALL    EPRINT
  773.     DB    ' -- (Y/N)? ',0
  774.     CALL    CIN    ; GET RESPONSE
  775.     CALL    CAPS
  776.     CPI    CR    ; YES?
  777.     JZ    EAT1    ; COPY IF SO
  778.     CALL    COUT
  779.     CPI    'N'    ; NO?
  780.     JNZ    EAT1    ; COPY IF NOT NO
  781.     XRA    A    ; ZERO FOR NOT APPROVED
  782.     RET
  783. EAT1:
  784.     MVI    A,0FFH    ; SET NZ FOR APPROVED
  785.     ORA    A    ; SET FLAGS
  786.     RET
  787. ;
  788. ;  MAKE DESTINATION FCB ENTRY R/W AND DIR
  789. ;
  790. DRW:
  791.     PUSH    D
  792.     LHLD    FCBD    ; CLEAR ATTRIBUTES OF DEST
  793.     LXI    D,9
  794.     DAD    D
  795.     POP    D
  796.     MOV    A,M    ; GET IT
  797.     ANI    7FH    ; CLEAR IT
  798.     MOV    M,A
  799.     INX    H    ; SAME TO NEXT
  800.     MOV    A,M    ; GET IT AND CLEAR IT
  801.     ANI    7FH
  802.     MOV    M,A
  803.     RET
  804. DESTRW:
  805.     CALL    DRW    ; MAKE ATTRIBUTES R/W AND NON-SYS
  806.     LDED    FCBD    ; SET ATTRIBUTES
  807.     MVI    C,30
  808.     CALL    BDOS
  809.     RET
  810.  
  811. ;
  812. ;  LOAD BUFFER PTED TO BY HL FROM FILE WHOSE FCB IS PTED TO BY DE
  813. ;    ON OUTPUT, BCNT=NUMBER OF BLOCKS LOADED (UP TO 128) AND
  814. ;    CONT=0 IF DONE OR 128 IF NOT DONE
  815. ;
  816. LOAD:
  817.     XRA    A    ; A=0
  818.     STA    BCNT    ; SET BLOCK COUNT
  819.     STA    CONT    ; TURN OFF CONTINUATION FLAG
  820.  
  821. ;  MAIN COPY LOOP
  822. MCPY:
  823.     CALL    SETDMA    ; SET DMA TO BLOCK PTED TO BY HL
  824.     CALL    F$READ    ; READ BLOCK
  825.     ORA    A    ; END OF FILE?
  826.     RNZ        ; RETURN
  827.     PUSH    D    ; SAVE PTR TO FCB
  828.     XCHG        ; SAVE PTR TO DESTINATION BUFFER IN DE
  829.     LHLD    BDOSE+1    ; GET TOP OF TPA
  830.     XCHG        ; ... IN DE, DEST IN HL
  831.     MOV    A,H    ; IF SAME PAGE, WE ARE IN OVERFLOW
  832.     CMP    D    ; D MUST BE > H
  833.     JNC    TPAOVFL    ; OVERFLOW IF D<=H
  834.     MVI    B,128    ; UPDATE CRC FOR 128 BYTES
  835. MCPYCRC:
  836.     MOV    A,M    ; GET BYTE
  837.     CALL    CRCUPD    ; UPDATE CRC
  838.     INX    H    ; PT TO NEXT
  839.     DCR    B    ; COUNT DOWN
  840.     JNZ    MCPYCRC
  841.     POP    D    ; GET PTR TO FCB
  842.     LDA    BCNT    ; GET BLOCK COUNT
  843.     INR    A    ; INCREMENT IT
  844.     STA    BCNT    ; SET IT
  845.     MOV    B,A    ; BLOCK COUNT IN B
  846.     LDA    PAGLIM    ; GET PAGE LIMIT
  847.     ADD    A    ; DOUBLE IT FOR BLOCKS
  848.     CMP    B    ; BUFFER FULL?
  849.     JNZ    MCPY
  850.     STA    CONT    ; SET CONTINUATION FLAG
  851.     RET
  852.  
  853. ;
  854. ;  SET DMA ADDRESS TO THAT PTED TO BY HL
  855. ;
  856. SETDMA:
  857.     PUSH    H    ; SAVE REGS
  858.     PUSH    D
  859.     PUSH    B
  860.     XCHG        ; ADDRESS IN DE
  861.     MVI    C,SDMA
  862.     CALL    BDOSE
  863.     POP    B    ; RESTORE REGS
  864.     POP    D
  865.     POP    H
  866.     RET
  867.  
  868. ;
  869. ;  VERIFY PHASE
  870. ;
  871. MCOPYV:
  872.     LDA    QUIET    ; CHECK FOR QUIET
  873.     ORA    A    ; NZ=QUIET
  874.     JNZ    MCPYV
  875.     CALL    EPRINT
  876.     DB    '  Verify ...',0
  877. MCPYV:
  878.     CALL    CRCCLR    ; CLEAR CRCK VALUE
  879.     CALL    LOGD    ; LOG IN DESTINATION
  880.     LDED    FCBD    ; CLEAR DESTINATION FCB
  881.     CALL    INITFCB    ; INIT FCB
  882.     CALL    F$OPEN    ; OPEN FILE
  883.  
  884. ;  **** MAIN VERIFY LOOP ****
  885. VERLOOP:
  886.     LHLD    WORKBF    ; LOAD INPUT BUFFER FROM DESTINATION
  887.     LDED    FCBD
  888.     CALL    LOAD    ; LOAD AND COMPUTE CRC VALUE
  889.     LDA    BCNT    ; DONE IF NO BYTES LOADED
  890.     ORA    A
  891.     JZ    VERCRC
  892.     LDA    CONT    ; CONTINUE?
  893.     ORA    A    ; 0=NO
  894.     JNZ    VERLOOP
  895. ;  VERIFY DONE
  896. VERCRC:
  897.     LHLD    CRCVAL    ; GET OLD CRC VALUE
  898.     XCHG        ; ... IN DE
  899.     CALL    CRCDONE    ; UPDATE COMPLETE
  900.     CALL    COMPHD    ; COMPARE HL TO DE
  901.     JZ    PRDONE    ; PRINT DONE MESSAGE OR FALL THRU TO ERROR MSG
  902.  
  903. ;  VERIFY ERROR
  904. VERERR:
  905.     LXI    H,VERCNT    ; INCREMENT ERROR COUNT
  906.     INR    M
  907.     CALL    EPRINT
  908.     DB    ' Error',0
  909.     RET
  910.  
  911. ;
  912. ;  **** MCOPY Utilities ****
  913. ;
  914.  
  915. ;
  916. ;  CHECK TO SEE IF USER WANTS TO CONTINUE
  917. ;
  918. SAKCHK:
  919.     CALL    EPRINT
  920.     DB    ' ^C to Quit - ',0
  921.     CALL    CIN    ; GET RESPONSE
  922.     CALL    CRLF    ; NEW LINE
  923.     CALL    CAPS    ; CAPITALIZE
  924.     CPI    'C'-'@'    ; ^C?
  925.     RET
  926. ;
  927. ;  ALLOW USER TO INSPECT FILES FOR COPY
  928. ;    FIRST FILE NAME PTED TO BY HL, BC = NUMBER OF FILES
  929. ;    ON EXIT, BC = NUMBER OF SELECTED FILES
  930. ;
  931. INSPF:
  932.     CALL    EPRINT
  933.     DB    CR,LF,' Inspect -- '
  934.     db    'Yes, No (def), Skip Rest'
  935.     db    0
  936.     PUSH    H    ; SAVE PTR TO FIRST FILE
  937.     PUSH    B    ; SAVE FILE COUNT
  938.     LXI    D,ESIZE    ; ENTRIES ARE ESIZE BYTES APART
  939. INSPF0:
  940.     MOV    A,M    ; MARK FILE FOR NO COPY
  941.     ANI    7FH    ; CLEAR MSB FOR NO COPY
  942.     MOV    M,A
  943.     DAD    D    ; PT TO NEXT
  944.     DCX    B    ; COUNT DOWN
  945.     MOV    A,B    ; DONE?
  946.     ORA    C
  947.     JNZ    INSPF0
  948.     POP    B    ; RESTORE AND SAVE AGAIN
  949.     POP    H
  950.     PUSH    H
  951.     PUSH    B
  952. INSPF1:
  953.     PUSH    H    ; SAVE PTR TO FILE
  954.     INX    H    ; PT TO FN
  955.     CALL    CRLF    ; NEW LINE
  956.     CALL    PRFN    ; PRINT IT
  957.     POP    H    ; GET PTR TO FILE
  958.     CALL    EPRINT
  959.     DB    ' - (Y/N/S)? ',0
  960.     CALL    CIN    ; GET RESPONSE
  961.     CALL    CAPS    ; CAPITALIZE
  962.     CALL    COUT    ; ECHO
  963.     CPI    'S'    ; SKIP?
  964.     JZ    INSPFA
  965.     CPI    'Y'    ; Yes?
  966.     JNZ    INSPF2
  967.     MOV    A,M    ; GET USER NUMBER
  968.     ORI    80H    ; MARK FILE
  969.     MOV    M,A    ; SET USER NUMBER
  970. INSPF2:
  971.     LXI    D,ESIZE    ; PT TO NEXT FILE
  972.     DAD    D
  973.     DCX    B    ; COUNT DOWN
  974.     MOV    A,B    ; DONE?
  975.     ORA    C
  976.     JNZ    INSPF1
  977. INSPFA:
  978.     POP    B    ; GET COUNT
  979.     POP    H    ; GET PTR TO FIRST FILE
  980.     JMP    DIRPACK    ; REPACK DIRECTORY
  981.  
  982. ;
  983. ;  LOG IN SOURCE USER/DISK
  984. ;
  985. LOGS:
  986.     LDA    SUSER    ; USER
  987.     MOV    C,A    ; ... IN C
  988.     LDA    SDISK    ; DISK
  989.     MOV    B,A    ; ... IN B
  990.     JMP    LOGUD    ; LOG IN USER/DISK
  991.  
  992. ;
  993. ;  LOG IN DESTINATION USER/DISK
  994. ;
  995. LOGD:
  996.     LDA    DUSER    ; USER
  997.     MOV    C,A    ; ... IN C
  998.     LDA    DDISK    ; DISK
  999.     MOV    B,A    ; ... IN B
  1000.     JMP    LOGUD    ; LOG IN USER/DISK
  1001.  
  1002. ;
  1003. ;  PRINT FILE NAME
  1004. ;
  1005. PRFN:
  1006.     PUSH    H    ; SAVE REGS
  1007.     PUSH    B
  1008.     MVI    B,8    ; PRINT 8 CHARS
  1009.     CALL    PRFN1
  1010.     MVI    A,'.'    ; DOT
  1011.     CALL    COUT
  1012.     MVI    B,3    ; PRINT 3 CHARS
  1013.     CALL    PRFN1
  1014.     POP    B    ; GET REGS
  1015.     POP    H
  1016.     RET
  1017. PRFN1:
  1018.     MOV    A,M    ; GET CHAR
  1019.     INX    H    ; PT TO NEXT
  1020.     CALL    COUT    ; PRINT IT
  1021.     DCR    B    ; COUNT DOWN
  1022.     JNZ    PRFN1
  1023.     RET
  1024.  
  1025. ;
  1026. ;  **** BUFFERS ****
  1027. ;
  1028.  
  1029. ;  POINTERS
  1030. MFPTR:    DS    2    ; PTR TO FIRST CHAR OF NEXT FN SPEC
  1031. NXTPTR:    DS    2    ; PTR TO NEXT FN SPEC IN LINE
  1032. WORKBF:    DS    2    ; PTR TO BEGINNING OF WORK BUFFER
  1033.  
  1034. ;  FLAGS COPIED FROM DEFAULTS
  1035. VERFLG:    DS    1    ; VERIFY
  1036. INSP:    DS    1    ; INSPECT
  1037. QUIET:    DS    1    ; QUIET
  1038. NCOPY:    DS    1    ; MULTIPLE COPY
  1039.  
  1040. ;  DISKS AND USERS
  1041. CDISK:    DS    1    ; CURRENT DISK
  1042. SDISK:    DS    1    ; SOURCE DISK
  1043. SUSER:    DS    1    ; SOURCE USER
  1044. DDISK:    DS    1    ; DESTINATION DISK
  1045. DUSER:    DS    1    ; DESTINATION USER
  1046.  
  1047. ;  CRC VALUE
  1048. CRCVAL:    DS    2    ; CRC CHECK VALUE
  1049.  
  1050. ;  FCBS
  1051. FCBS:    DS    2    ; SOURCE FCB
  1052. FCBD:    DS    2    ; DESTINATION FCB
  1053. FCBT:    DS    2    ; PTR TO TEMPORARY FCB FOR ATTRIBUTE SETTINGS
  1054.  
  1055. ;  COUNTS AND FLAGS
  1056. PAGLIM:    DS    1    ; MAX NUMBER OF PAGES IN WORK BUFFER
  1057. LSTCPY:    DS    1    ; LAST FILE WAS COPIED FLAG
  1058. EXIST:    DS    1    ; TEST FOR EXISTENCE FLAG
  1059. VERCNT:    DS    1    ; ERROR COUNT
  1060. BCNT:    DS    1    ; BLOCK COUNT
  1061. CONT:    DS    1    ; CONTINUE FLAG (0=NO, 0FFH=YES)
  1062.  
  1063. ;  DYNAMIC BUFFERS
  1064. INLINE:
  1065.     DS    2    ; INPUT LINE BUFFER
  1066. FREEBUF:
  1067.     DS    2    ; FREE SPACE BUFFER
  1068. STACK:
  1069.     DS    2    ; OPSYS STACK PTR
  1070.  
  1071.     END
  1072.