home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols000 / vol009 / cpyfil15.asm < prev    next >
Assembly Source File  |  1984-04-29  |  10KB  |  410 lines

  1. ;
  2. ;           COPYFILE.ASM ver 1.5
  3. ;         by Keith Petersen, W8SDZ
  4. ;                  (revised 10/18/80)
  5. ;
  6. ;This program will copy files of any length from one drive to
  7. ;another, with up to 16k buffering.  It was created for very
  8. ;long files (megabyte length), which are not properly handled
  9. ;by CP/M 2.x PIP.  This version offers selective copying of
  10. ;files - something not available with PIP.  The destination
  11. ;files will have NO attributes set, which is useful for
  12. ;copying from CP/M 2.x to 1.4 disks.
  13. ;
  14. ;10/18/80 Modified to strip attributes from file name before
  15. ;      creating new file (to eliminate BDOS error on R/O
  16. ;      files on CP/M 2.x).  Corrected error in stack
  17. ;      location.  (KBP)
  18. ;
  19. ;10/10/80 Modified to make compatible with CP/M 1.4 or 2.x.
  20. ;      Added: echo to prompt input, allow upper or lower
  21. ;      case answer, reask if improper answer, more comments
  22. ;      to file. (KBP)
  23. ;
  24. ;10/09/80 Modified to allow operator to scan and select which
  25. ;      files will be transfered if wildcard options are used.
  26. ;      This will allow transfer of selected file from a full
  27. ;      disk without having to transfer all files and then
  28. ;      erase the ones that were not to be transfered.  Also
  29. ;      modified to have transfers default to DIR files only
  30. ;      and if files with SYS attribute are to be transfered the
  31. ;      use of the /S option is required. (by Robert Arrington)
  32. ;
  33. ;COMMANDS:
  34. ;    COPYFILE [drive:]<filename.filetype> <destination drive:>[/S]
  35. ;
  36. ;    Requires the use of the /S option if transfer
  37. ;    of files with SYS attribute is wanted.
  38. ;
  39. ;EXAMPLES:
  40. ;    COPYFILE MYFILE.ASM B:
  41. ;        gets MYFILE.ASM from default disk and copies to B:
  42. ;    COPYFILE A:MYFILE.ASM B:
  43. ;        gets MYFILE.ASM from A: and copies to B:
  44. ;    COPYFILE B:*.* A:
  45. ;        gets all files from B: and copies to A:
  46. ;        
  47. ;All normal ambiguous file names are allowed.
  48. ;
  49. ;DEFINE WRITE BUFFER SIZE
  50. ;    (presently set for 16k.  If you have less space
  51. ;    available in the TPA, reduce accordingly).
  52. ;
  53. BSIZE    EQU    16*1024    ;<--NOW SET FOR 16k
  54. ;
  55. ;BDOS/CBIOS EQUATES
  56. ;
  57. WBOOT    EQU    0    ;WARM BOOT ENTRY ADRS
  58. RDCON    EQU    1    ;READ CONSOLE (WITH ECHO)
  59. WRCON    EQU    2    ;WRITE CHARACTER TO CONSOLE
  60. BDOS    EQU    5    ;CP/M BDOS ENTRY ADRS
  61. PRINT    EQU    9    ;PRINT STRING (DE) UNTIL '$'
  62. OPEN    EQU    15    ;OPEN DISK FILE
  63. SRCHF    EQU    17    ;SEARCH DIR FOR FIRST OCCUR.
  64. SRCHN    EQU    18    ;SEARCH DIR FOR NEXT OCCUR.
  65. READ    EQU    20    ;READ SEQUENTIAL FILE
  66. CDISK    EQU    25    ;RETURN CURRENT DISK
  67. STDMA    EQU    26    ;SET DMA ADDRESS
  68. FCB    EQU    5CH    ;DEFAULT FILE CONTROL BLOCK
  69. FCBEXT    EQU    FCB+12    ;EXTENT BYTE IN FCB
  70. FCBRNO    EQU    FCB+32    ;RECORD NUMBER IN FCB
  71. FCB2    EQU    6CH    ;DEFAULT 2ND FILE CONTROL BLOCK
  72. ;
  73. ;    Program starts here
  74. ;
  75.     ORG    100H
  76. ;
  77.     MACLIB    SEQIO    ;NAME OF MACRO LIBRARY USED
  78. ;
  79. START:    LDA    FCB+1
  80.     CPI    ' '    ;SEE IF FILENAME THERE
  81.     JNZ    SIGNON
  82.     CALL    ILPRT    ;PRINT:
  83.     DB    CR,LF,'++NO FILE NAME SPECIFIED++',0
  84.     RET        ;EXIT TO CP/M
  85. ;
  86. SIGNON:    LXI    SP,STACK  ;SET STACK POINTER
  87.     CALL    ILPRT    ;PRINT:
  88.     DB    CR,LF,'COPYFILE ver 1.5',CR,LF
  89.     DB    'multiple file copy program',CR,LF,0
  90.     LDA    FCB    ;GET DRIVE NAME
  91.     ORA    A    ;SEE IF DEFAULT DRIVE
  92.     CZ    GETDRV    ;IF DEFAULT, GET DRIVE NAME
  93.     STA    SRCDRV    ;SAVE FOR LATER
  94.     MOV    B,A    ;SAVE FOR LATER COMPARE
  95.     LDA    FCB2+2    ;GET OPTION REQUEST
  96.     CPI    'S'    ;SYS FILES WANTED?
  97.     JNZ    SNDDRV    ;NO, SKIP SYS FLAG SET
  98.     STA    SYS    ;SET SYS FLAG
  99. ;
  100. SNDDRV:    LDA    FCB2    ;GET SECOND DRIVE NAME
  101.     STA    DESTDR    ;SAVE IT FOR LATER
  102.     ORA    A    ;SEE IF DEFAULT DRIVE
  103.     JZ    ABORT    ;DEFAULT NOT ALLOWED
  104.     CMP    B    ;SEE IF DRIVE NAMES THE SAME
  105.     JNZ    MORE    ;NOT THE SAME, CONTINUE
  106. ;
  107. ABORT:    CALL    EXIT
  108.     DB    '++DRIVE NAME ERROR++$'
  109. ;
  110. GETDRV:    MVI    C,CDISK    ;CURRENT DISK NAME REQUEST
  111.     CALL    BDOS    ;GET IT
  112.     INR    A    ;ADJUST FOR USE IN FCB
  113.     RET
  114. ;
  115. ;Get file name from directory and put in FCB
  116. ;
  117. MORE:    CALL    MFNAME    ;SEE IF FILE IS IN DIRECTORY
  118.     JNC    SYSTST    ;ANOTHER FILE FOUND, GET IT
  119.     LDA    MFFLG1    ;NOTHING FOUND, CHECK...
  120.     ORA    A    ;... FIRST TIME FLAG
  121.     JZ    DONE    ;AT LEAST ONE WAS FOUND
  122.     CALL    EXIT
  123.     DB    '++FILE NOT FOUND++$'
  124. ;
  125. DONE:    CALL    EXIT
  126.     DB    CR,LF,'DONE$'
  127. ;
  128. ;Check if SYS files wanted
  129. ;
  130. SYSTST:    LDA    SYS    ;GET SAVED SYS FLAG
  131.     CPI    'S'    ;SYS WANTED?
  132.     JZ    MOVNAM    ;YES, CONTINUE
  133.     LDA    SYSAT    ;GET SYS ATTRIBUTE
  134.     ANI    80H    ;ISOLATE ATTR BIT
  135.     JNZ    MORE    ;IT'S SYS, IGNORE IT
  136. ;
  137. ;Move filename from FCB to FNAME and print it
  138. ;
  139. MOVNAM:    LXI    H,FCB+1
  140.     LXI    D,FNAME
  141.     MVI    B,8    ;8 CHARS IN FILE NAME
  142.     CALL    MOVER
  143.     LXI    H,FCB+9
  144.     LXI    D,FNAME+9
  145.     MVI    B,3    ;3 CHARS IN FILE TYPE
  146.     CALL    MOVER
  147.     CALL    ILPRT    ;PRINT:
  148.     DB    CR,LF,'--> FILE: '
  149. FNAME:    DB    'XXXXXXXX.XXX',CR,LF,0
  150.     LDA    CFLAG    ;GET CONTINUOUS MODE FLAG
  151.     CPI    'C'    ;IS IT SET?
  152.     JZ    DCOUT    ;YES, SKIP OPTION REQUEST
  153. ;
  154. ;Ask for options
  155. ;
  156. REASK:    CALL    ASK    ;PRINT:
  157.     DB    '(T)ransfer, (S)kip, (Q)uit, (C)ontinuous ? $'
  158. ;
  159. ASK:    POP    D    ;GET MSG ADRS
  160.     MVI    C,PRINT
  161.     CALL    BDOS    ;PRINT MSG
  162.     MVI    C,RDCON    ;GET ANSWER AND ECHO IT
  163.     CALL    BDOS
  164.     PUSH    PSW    ;SAVE IT
  165.     CALL    CRLF    ;TURN UP A NEW LINE
  166.     POP    PSW    ;GET ANSWER BACK
  167.     ANI    5FH    ;MAKE IT UPPER CASE
  168.     CPI    'T'    ;TRANSFER?
  169.     JZ    DCOUT    ;YES, GO DO ONE
  170.     CPI    'S'    ;SKIP?
  171.     JZ    MORE    ;YES, IGNORE THIS FILE
  172.     CPI    'C'    ;CONTINUOUS?
  173.     JZ    SETCM    ;YES, SET CONTINOUS MODE
  174.     CPI    'Q'    ;QUIT?
  175.     JNZ    REASK    ;NONE OF ABOVE, ASK AGAIN
  176.     CALL    EXIT
  177.     DB    '++QUITTING++$'
  178. ;
  179. ;Set continuous mode
  180. ;
  181. SETCM:    STA    CFLAG    ;SAVE CONTINUOUS REQUEST
  182. ;
  183. ;'Declare' output file using FCB2
  184. ;
  185. DCOUT    FILE    OUTFILE,DESTINATION,,2,,BSIZE
  186.     CALL    ILPRT    ;PRINT:
  187.     DB    'File open on destination disk',0
  188. ;
  189. ;Open source file
  190. ;
  191.     LXI    D,FCB
  192.     MVI    C,OPEN
  193.     CALL    BDOS
  194.     INR    A    ;CHECK FOR NO OPEN
  195.     JNZ    READLP    ;NO ERROR, CONTINUE
  196.     CALL    ERXIT
  197.     DB    '++CAN''T OPEN SOURCE FILE++$'
  198. ;
  199. ;Read sector from source disk
  200. ;
  201. READLP:    LXI    D,80H
  202.     MVI    C,STDMA
  203.     CALL    BDOS
  204.     LXI    D,FCB
  205.     MVI    C,READ
  206.     CALL    BDOS
  207.     ORA    A    ;READ OK?
  208.     JZ    WRDISK    ;YES, SEND IT TO DESTINATION
  209.     CPI    1    ;END-OF-FILE?
  210.     JZ    TDONE    ;TRANSFER DONE, CLOSE, EXIT
  211.     CALL    ERXIT
  212.     DB    '++FILE READ ERROR++$'
  213. ;
  214. ;Write sector to destination disk (with buffering)
  215. ;
  216. WRDISK:    LXI    H,80H    ;READ BUFFER ADRS
  217. ;
  218. WRDLOP:    MOV    A,M    ;GET BYTE FROM READ BUFFER
  219.     PUSH    H
  220.     PUT    DESTINATION ;SEND TO DISK WRITE BUFFER
  221.     POP    H
  222.     INR    L    ;DONE WITH SECTOR?
  223.     JNZ    WRDLOP    ;NO, GET ANOTHER BYTE
  224.     JMP    READLP    ;GO GET ANOTHER SECTOR
  225. ;
  226. ;Transfer is done - close destination file,
  227. ;then go look for more files
  228. ;
  229. TDONE:    FINIS    DESTINATION ;FLUSH BUFFERS, CLOSE
  230.     CALL    ILPRT    ;PRINT:
  231.     DB    'File closed on destination disk now',0
  232.     JMP    MORE    ;GET ANOTHER FILE
  233. ;
  234. ;Erase the incomplete output file, then exit
  235. ;
  236. ERXIT:    ERASE    DESTINATION
  237. ;
  238. ;Print message then exit to CP/M warm boot
  239. ;
  240. EXIT:    POP    D    ;GET MSG ADRS
  241.     MVI    C,PRINT    ;PRINT MESSAGE
  242.     CALL    BDOS
  243.     CALL    CRLF    ;PRINT CRLF
  244.     JMP    WBOOT
  245. ;
  246. ;Inline print routine - prints string pointed to
  247. ;by stack until a zero is found.  Returns to caller
  248. ;at next address after the zero terminator.
  249. ;
  250. ILPRT:    XTHL        ;SAVE HL, GET MSG ADRS
  251. ;
  252. ILPLP:    MOV    A,M    ;GET CHAR
  253.     CALL    TYPE    ;OUTPUT IT
  254.     INX    H    ;POINT TO NEXT
  255.     MOV    A,M    ;TEST
  256.     ORA    A    ;..FOR END
  257.     JNZ    ILPLP
  258.     CALL    CRLF    ;TURN UP A NEW LINE
  259.     XTHL        ;RESTORE HL, RET ADDR
  260.     RET        ;RET PAST MSG
  261. ;
  262. ;Turn up a new line
  263. ;
  264. CRLF:    MVI    A,CR    ;CARRIAGE RETURN
  265.     CALL    TYPE
  266.     MVI    A,LF    ;LINE FEED, FALL INTO 'TYPE'
  267. ;
  268. ;Send character in A register to console
  269. ;
  270. TYPE:    PUSH    B
  271.     PUSH    D
  272.     PUSH    H
  273.     MOV    E,A    ;CHAR TO E FOR CP/M
  274.     MVI    C,WRCON    ;WRITE TO CONSOLE
  275.     CALL    BDOS
  276.     POP    H
  277.     POP    D
  278.     POP    B
  279.     RET
  280. ;
  281. ;Multi-file access subroutine.  Allows processing
  282. ;of multiple files (i.e. *.ASM) from disk.  This
  283. ;routine builds the proper name in the FCB each
  284. ;time it is called. Carry is set if no more names
  285. ;can be found. The routine is commented in Pseudo
  286. ;code, each Pseudo code statement is in <<...>>
  287. ;
  288. MFNAME:    ;<<init DMA address and FCB>>
  289.     MVI    C,STDMA
  290.     LXI    D,80H
  291.     CALL    BDOS
  292.     XRA    A
  293.     STA    FCBEXT
  294.     STA    FCBRNO
  295. ;<<if first time>>
  296.     LDA    MFFLG1
  297.     ORA    A
  298.     JZ    MFN01
  299. ;<<save the requested name>>
  300. ;Save original request
  301.     LXI    H,FCB
  302.     LXI    D,MFREQ
  303.     MVI    B,12
  304.     CALL    MOVER
  305.     LDA    FCB
  306.     STA    MFCUR    ;SAVE DISK IN CURR FCB
  307. ;<<SRCHF requested name>>
  308.     MVI    C,SRCHF
  309.     LXI    D,FCB
  310.     CALL    BDOS
  311. ;<<else>>
  312.     JMP    MFN02
  313. ;
  314. MFN01:    ;<<SRCHF current name>>
  315.     LXI    H,MFCUR
  316.     LXI    D,FCB
  317.     MVI    B,12
  318.     CALL    MOVER
  319.     MVI    C,SRCHF
  320.     LXI    D,FCB
  321.     CALL    BDOS
  322. ;<<SRCHN requested name>>
  323.     LXI    H,MFREQ
  324.     LXI    D,FCB
  325.     MVI    B,12
  326.     CALL    MOVER
  327.     MVI    C,SRCHN
  328.     LXI    D,FCB
  329.     CALL    BDOS
  330. ;<<endif>>
  331. MFN02:    ;<<return carry if not found>>
  332.     INR    A
  333.     STC
  334.     RZ
  335. ;<<move name found to CURR>>
  336.     DCR    A
  337.     ANI    3
  338.     ADD    A
  339.     ADD    A
  340.     ADD    A
  341.     ADD    A
  342.     ADD    A
  343.     ADI    81H
  344.     MOV    L,A
  345.     MVI    H,0
  346.     PUSH    H    ;SAVE NAME POINTER
  347.     LXI    D,9    ;READY TO ADD 9 TO...
  348.     DAD    D    ;...POINT TO SYS ATTR
  349.     MOV    A,M    ;GET IT
  350.     STA    SYSAT    ;SAVE FOR LATER
  351.     POP    H    ;GET NAME POINTER BACK
  352.     PUSH    H    ;SAVE IT AGAIN
  353.     LXI    D,MFCUR+1
  354.     MVI    B,11
  355.     CALL    MOVER
  356. ;<<move name found to FCB>>
  357.     POP    H
  358.     LXI    D,FCB+1
  359.     MVI    B,11
  360.     CALL    MOVER
  361. ;<<make copy of name found to FCB2>>
  362.     LXI    H,FCB+1
  363.     LXI    D,FCB2+1
  364.     MVI    B,11
  365.     CALL    MOVER
  366. ;<<setup FCB>>
  367.     XRA    A
  368.     STA    FCBRNO    ;ZERO RECORD NUMBER
  369.     STA    FCBEXT    ;ZERO EXTENT NUMBER
  370.     STA    MFFLG1    ;TURN OFF 1ST TIME SW
  371.     LDA    SRCDRV    ;GET SOURCE DRIVE NAME
  372.     STA    FCB    ;PUT IT IN FCB1
  373.     LDA    DESTDR    ;GET DESTINATION DRIVE NAME
  374.     STA    FCB2    ;PUT IT IN FCB2
  375. ;<<return>>
  376.     RET
  377. ;------------------------------------------------
  378. ;
  379. ;Move subroutine - move (B) bytes from (HL) to (DE)
  380. ;
  381. MOVER:    MOV    A,M
  382.     ANI    7FH    ;STRIP ATTRIBUTES
  383.     STAX    D
  384.     INX    H
  385.     INX    D
  386.     DCR    B
  387.     JNZ    MOVER
  388.     RET
  389. ;
  390. CFLAG:    DB    0    ;CONTINUOUS TRANSFER FLAG
  391. SYS:    DB    0    ;SYS FILE FLAG
  392. SYSAT:    DB    0    ;FILE SYS ATTRIBUTE STORED HERE
  393. SRCDRV:    DB    0    ;SOURCE DRIVE NAME SAVED HERE
  394. DESTDR:    DB    0    ;AND DESTINATION DRIVE NAME HERE
  395. ;
  396. ;Multi-file access work area
  397. ;
  398. MFFLG1:    DB    1    ;1ST TIME SW
  399. MFREQ:    DS    12    ;REQ NAME
  400. MFCUR:    DS    12    ;CURR NAME
  401. ;
  402.     DS    100    ;ROOM FOR STACK
  403. STACK:    EQU    $    ;STACK POINTER SET HERE
  404. ;
  405. ;Org write buffer to even page boundry
  406.     ORG    ($+255) AND 0FF00H
  407. BUFFERS:EQU    $    ;WRITE BUFFER STARTS HERE
  408. ;
  409.     END
  410.