home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols200 / vol210 / put.aq6 / PUT.A86
Text File  |  1986-02-09  |  19KB  |  954 lines

  1.  
  2. ;****************************************************************
  3. ;                                *
  4. ;    A UTILITY PROGRAM TO FACILITATE COPYING FILES        *
  5. ;            BETWEEN USER AREAS                *
  6. ;                                *
  7. ;****************************************************************
  8. ;
  9.     TITLE    'BUFFERED INTER-USER COPY ROUTINE FOR CP/M-86'
  10. ;
  11. ;    Copyright (C) 1981,1982,1984 by
  12. ;
  13. ;    Angus Bliss        Bill Bolton
  14. ;    P.O. Box 293,        Software Tools RCPM
  15. ;    Hamilton,        P.O. Box 357,
  16. ;    NSW, 2303,        Kenmore,
  17. ;    AUSTRALIA        QLD, 4069,
  18. ;                AUSTRALIA
  19. ;
  20. ;    This program is made available for public distribution
  21. ;    for NON-COMMERCIAL use only. All commercial rights
  22. ;    retained by the authors.
  23. ;
  24. ;    ------------------------------------------------------
  25. ;
  26. ;    This program is built on the Intel small memory model
  27. ;    and uses the operating system 96 byte stack. It 
  28. ;    should be GENCMD with the following command line
  29. ;
  30. ;        GENCMD PUT DATA[M860]
  31. ;
  32. ;    ------------------------------------------------------
  33. ;
  34. ;    VERSION LIST, most recent version first
  35. ;    ---------------------------------------
  36. ;
  37. ;    1.8    Added code to close source file for
  38. ;        Concurrent DOS operation - Bill Bolton, 30/Oct/84
  39. ;
  40. ;    1.7    Translated to CP/M-86, buffer size fixed
  41. ;        at 32K (generally no lack of memory in
  42. ;        16 bit systems) - Bill Bolton 07/Aug/84
  43. ;
  44. ;    1.6    Fixed problem with zero length files writing
  45. ;        a file as large as buffer. Fixed problem of
  46. ;        large files being truncated to 32K in
  47. ;        some multifile transfers. Tidied up for
  48. ;        publication - Angus Bliss 29/Apr/82
  49. ;
  50. ;    1.5    Initial release version. Large file transfer
  51. ;        bug fixed and other minor internal changes
  52. ;        mode - Bill Bolton 3/Feb/82
  53. ;
  54. ;    1.4    Overwrite options added, user abort added,
  55. ;        filename show added and lots more comments
  56. ;        added - Bill Bolton 2/Feb/82
  57. ;
  58. ;    1.3    Transfer to $$$ file first then rename after
  59. ;        succesful close (like PIP) added - Bill Bolton
  60. ;        1/Feb/82
  61. ;
  62. ;    1.2    Wildcard file transfer added. - Bill Bolton
  63. ;        31/Jan/82
  64. ;
  65. ;    1.1    Converted to 8080 code for greater portability
  66. ;            (now that the Godbout 8085/8088 card has given
  67. ;        8080 code a new lease of life) and presentation-
  68. ;        tidied up. - Bill Bolton 30/Jan/82
  69. ;
  70. ;    1.0    Original code in Xitan Z80 source. - Angus Bliss
  71. ;        Aug/82
  72. ;
  73. VERSION    EQU    18            ;VERSION NUMBER
  74. ;
  75. CNTRLC    EQU    3            ;CP/M 'PANIC' CHARACTER
  76. ACR    EQU    0DH
  77. ALF    EQU    0AH
  78. ;
  79. WBOOT    EQU    0            ;CP/M WARM BOOT ENTRY
  80. BDOS    EQU    0005H            ;CP/M BDOS ENTRY POINT
  81. FCB    EQU    05CH            ;CP/M FILE CONTROL BLOCK
  82. FCB0    EQU    06CH
  83. TBUF    EQU    080H            ;CP/M COMMAND LINE BUFFER
  84. ;
  85. CI    EQU    1            ;BDOS CONSOLE IN
  86. CO    EQU    2            ;BDOS CONSOLE OUT
  87. DIRECT    EQU    6            ;BDOS DIRECT CONSOLE
  88. B_PRINT    EQU    9            ;BDOS CONSOLE MESSAGE
  89. VERS    EQU    12            ;BDOS RETURN VERSION NUMBER
  90. B_OPEN    EQU    15            ;BDOS OPEN FILE
  91. B_CLOSE    EQU    16            ;BDOS CLOSE FILE
  92. SRCH_1ST EQU    17            ;BDOS SEARCH FOR FILE
  93. SRCH_NXT EQU    18            ;BDOS SEARCH FOR NEXT (AMBIG) FILE
  94. DELET    EQU    19            ;BDOS DELETE FILE
  95. B_READ    EQU    20            ;BDOS SEQUENTIAL READ
  96. B_WRITE    EQU    21            ;BDOS SEQUENTIAL WRITE
  97. MAKE    EQU    22            ;BDOS CREATE NEW FILE
  98. REN    EQU    23            ;BDOS RENAME FILE
  99. DMA    EQU    26            ;BDOS SET NEW DMA
  100. ATTRIB    EQU    30            ;BDOS SET FILE ATTRIBUTES
  101. USER    EQU    32            ;BDOS SET/GET USER
  102. ;
  103. BUFSIZ    EQU    255            ;Disk buffer in sectors (32K)
  104. M    EQU    Byte Ptr 0[BX]
  105. ;
  106.     CSEG
  107.     ORG    0
  108. ;
  109. START:
  110.     MOV    DX,(Offset MSG1)
  111.     MOV    CL,B_PRINT
  112.     CALL    BDOSE            ;ANNOUNCE OURSELF
  113. ;    MOV    CL,VERS            ;CHECK VERSION
  114. ;    INT    224            ;USES BX REGISTER
  115. ;    MOV    AL,BL
  116. ;    CMP    AL,2
  117. ;    JNB    L_1    
  118. ;    JMP    ERROR3            ;WRONG CP/M VERSION
  119. ;L_1:
  120.     MOV    AL,Byte Ptr .TBUF    ;PARAMETER COUNT
  121.     CMP    AL,0            ;NO PARAMETER
  122.     JNZ    START_1    
  123.     JMP    ERROR1
  124. ;
  125. START_1:
  126.     MOV    BX,FCB-1        ;TAKE A COPY OF FCB
  127.     MOV    DX,(Offset FCB2)-1    ;_ TBUF
  128.     MOV    CX,33            ;LENGTH OF A FILENAME
  129. LDIR1:
  130.     INC    BX            ;ADJUST POINTERS
  131.     INC    DX
  132.     MOV    AL,M            ;GET A BYTE
  133.     MOV    SI,DX            ;PUT A BYTE
  134.     MOV    [SI],AL
  135.     DEC    CX            ;ADJUST COUNT
  136.     MOV    AL,CH
  137.     OR    AL,CL            ;ZERO YET
  138.     JNZ    LDIR1            ;NO    
  139.     MOV    BX,TBUF            ;YES
  140.     MOV    CH,0
  141.     MOV    CL,M            ;GET COUNT
  142.     INC    BX            ;STEP OVER ANY SOURCE
  143.     DEC    CL
  144.     INC    BX            ; DRIVE IDENTIFIER ON
  145.     DEC    CL
  146.     INC    BX            ; FILE NAME
  147.     DEC    CL
  148.     MOV    AL,':'            ;DRIVE DELIMITER
  149. CCIR1:
  150.     INC    BX
  151.     CMP    AL,M            ;MATCH
  152.     JZ    GO_ON1
  153.     DEC    CL
  154.     JZ    NOT_FOUND1        ;YES
  155.     JMPS    CCIR1
  156. ;
  157. GO_ON1:
  158.     DEC    BX            ;ADJUST PTR
  159.     MOV    AL,M
  160.     CMP    AL,'G'+1
  161.     JNB    NOT_FOUND1
  162.     CMP    AL,'A'
  163.     JB    NOT_FOUND1
  164.     AND    AL,7            ;MAKE 0 TO 7
  165.     MOV    Byte Ptr DEST_DRV,AL
  166.     MOV    Byte Ptr FCB2,AL
  167. NOT_FOUND1:
  168.     MOV    BX,FCB
  169.     MOV    CL,11            ;GET LENGTH OF FILE NAME
  170.     MOV    AL,'?'            ;WILDCARD
  171. CCIR2:
  172.     INC    BX            ;LOOP TO SEARCH FOR WILDCARD
  173.     CMP    AL,M
  174.     JZ    GO_ON2
  175.     DEC    CL
  176.     JZ    NOT_FOUND2
  177.     JMPS    CCIR2
  178. ;
  179. GO_ON2:
  180.     MOV    AL,0FFH
  181.     MOV    Byte Ptr WILD,AL    ;SET MULTIFILE FLAG
  182. NOT_FOUND2:
  183.     MOV    BX,TBUF            ;YES
  184.     MOV    CH,0
  185.     MOV    CL,M            ;GET COUNT
  186.     MOV    AL,'-'            ;OPTION SPECIFIER
  187. CCIR_3:
  188.     INC    BX            ;LOOP TO SEARCH FOR OPTIONS
  189.     CMP    AL,M
  190.     PUSH    BX
  191.     JNZ    CCIR_4    
  192.     CALL    OPTION
  193. CCIR_4:
  194.     POP    BX
  195.     DEC    CL
  196.     JNZ    CCIR_3
  197.     JMPS    NOT_FOUND3
  198. ;
  199. OPTION:
  200.     LAHF                ;FOUND THE FLAG
  201.     XCHG    AL,AH
  202.     PUSH    AX
  203. OPT_1:
  204.     INC    BX            ;NOW LOOK FOR AN OPTION
  205.     MOV    AL,M
  206.     CMP    AL,'W'
  207.     JZ    OVER_WRITE
  208.     CMP    AL,'N'
  209.     JZ    NO_QUERY
  210.     POP    AX
  211.     XCHG    AL,AH
  212.     SAHF
  213.     RET
  214. ;
  215. OVER_WRITE:
  216.     MOV    AL,0FFH
  217.     MOV    Byte Ptr O_W,AL
  218.     JMPS    OPT_1            ;LOOK FOR ANOTHER ONE
  219. ;
  220. NO_QUERY:
  221.     MOV    AL,0FFH
  222.     MOV    Byte Ptr N_Q,AL
  223.     JMPS    OPT_1            ;LOOK FOR ANOTHER ONE
  224. ;
  225. NOT_FOUND3:
  226.     MOV    BX,6DH            ;FROM USER
  227.     CALL    NSCAN            ;GET NUMBER
  228.     JNB    NF_4    
  229.     JMP    ERROR2            ;INVALID USER
  230. NF_4:
  231.     MOV    Byte Ptr FUSER,AL    ;FROM USER
  232.     MOV    BX,75H            ;TO USER
  233.     CALL    NSCAN
  234.     JNB    NF_5    
  235.     JMP    ERROR2
  236. NF_5:
  237.     MOV    Byte Ptr TUSER,AL    ;TO USER
  238.     MOV    DL,0FFH
  239.     MOV    CL,USER            ;GET CURRENT USER
  240.     CALL    BDOSE
  241.     MOV    Byte Ptr CUSER,AL    ;SAVE IT
  242.     MOV    AL,Byte Ptr FUSER    ;FROM USER
  243.     MOV    DL,AL            ;PUT IN E
  244.     MOV    CL,USER
  245.     CALL    BDOSE            ;SET THE USER
  246.     MOV    BX,FCB
  247.     MOV    AL,Byte Ptr WILD
  248.     OR    AL,AL            ;SINGLE FILE ONLY ?
  249.     JZ    COPY_FCB        ;YES
  250.     MOV    DX,FCB
  251.     MOV    CL,SRCH_1ST
  252.     CALL    BDOSE
  253.     CMP    AL,0FFH            ;FOUND?
  254.     JNZ    DIR_MATCH
  255.     JMP    ERROR4            ;NO
  256. ;
  257. DIR_MATCH:
  258.     ADD    AL,AL            ;MULTIPLY BY 5
  259.     ADD    AL,AL
  260.     ADD    AL,AL
  261.     ADD    AL,AL
  262.     ADD    AL,AL
  263.     MOV    BX,TBUF            ;POINT TO DIRECTORY BUFFER
  264.     MOV    DL,AL
  265.     MOV    DH,0
  266.     ADD    BX,DX            ;BX <--- POINTER TO MATCHED FILE
  267. COPY_FCB:
  268.     PUSH    BX
  269.     MOV    CL,12
  270.     MOV    DX,(Offset FCB1)
  271.     MOV    AL,Byte Ptr .FCB
  272.     MOV    M,AL            ;STUFF SRC DRIVE IDENT INTO FCB
  273. C_FCB_1:
  274.     MOV    AL,M            ;COPY FCB TO FCB1 (READ FCB)
  275.     MOV    SI,DX
  276.     MOV    [SI],AL
  277.     INC    BX
  278.     INC    DX
  279.     DEC    CL
  280.     JNZ    C_FCB_1
  281.     POP    BX
  282. C_FCB_2:
  283.     MOV    CL,11
  284.     MOV    DX,(Offset FCB2)
  285.     MOV    AL,Byte Ptr DEST_DRV
  286.     MOV    SI,DX            ;STUFF DEST DRIVE IDENT INTO FCB
  287.     MOV    [SI],AL
  288.     INC    BX
  289.     INC    DX
  290. C_FCB_3:
  291.     MOV    AL,M            ;COPY FCB TO FCB1 (WRITE FCB)
  292.     AND    AL,7FH            ;RESET ANY FILE ATTRIBUTES
  293.     MOV    SI,DX
  294.     MOV    [SI],AL
  295.     LAHF
  296.     INC    BX
  297.     SAHF
  298.     LAHF
  299.     INC    DX
  300.     SAHF
  301.     DEC    CL
  302.     JNZ    C_FCB_3
  303. READ_FILE:
  304.     MOV    BX,(Offset FCB1)
  305.     CALL    SHOW
  306.     MOV    DX,(Offset FCB1)    ;CP/M DEFAULT
  307.     MOV    CL,B_OPEN
  308.     CALL    BDOSE            ;OPEN OUR SOURCE
  309.     CMP    AL,255
  310.     JNZ    RD_FILE_1    
  311.     JMP    ERROR4            ;OPEN FAILURE
  312. ;
  313. RD_FILE_1:
  314.     XOR    AL,AL            ;INITIALISE REGISTER
  315.     MOV    Byte Ptr ACOUNT,AL    ;SECTOR COUNT
  316.     MOV    AL,BUFSIZ
  317.     MOV    CH,AL            ;SECTOR COUNT
  318. ;
  319. READ:
  320.     MOV    DX,(Offset BUFSTART)    ;CH HAS SECTOR CNT
  321. READ1:
  322.     MOV    CL,DMA
  323.     CALL    BDOSE            ;SET DMA ADDRESS
  324.     PUSH    DX            ;SAVE DMA ADDR.
  325.     MOV    DX,(Offset FCB1)
  326.     MOV    CL,B_READ
  327.     CALL    BDOSE            ;READ A SECTOR
  328.     POP    DX            ;RESTORE DMA
  329.     CMP    AL,1
  330.     JZ    FINISH
  331.     CMP    AL,0
  332.     JZ    READ2    
  333.     JMP    ERROR5            ;READ ERROR
  334. ;
  335. READ2:
  336.     MOV    AL,DL            ;BUMP POINTER
  337.     ADD    AL,80H
  338.     MOV    DL,AL
  339.     MOV    AL,0
  340.     ADC    AL,DH
  341.     MOV    DH,AL            ;BY 128 BYTES
  342.     MOV    AL,Byte Ptr ACOUNT
  343.     INC    AL
  344.     MOV    Byte Ptr ACOUNT,AL    ;SECTORS READ
  345.     DEC    CH            ;ADJUST COUNT
  346.     JNZ    READ1            ;NO
  347.     CALL    WRITE            ;FULL, SO EMPTY IT
  348.     XOR    AL,AL            ;RESET REGISTERS
  349.     MOV    Byte Ptr ACOUNT,AL    ;SECTOR COUNT
  350.     MOV    AL,BUFSIZ
  351.     MOV    CH,AL            ;SECTOR COUNT
  352.     JMPS    READ
  353. ;
  354. FINISH:
  355.     MOV    DX,(Offset FCB1)
  356.     MOV    CL,B_CLOSE        ;CLOSE SOURCE
  357.     CALL    BDOSE
  358.     MOV    AL,0FFH
  359.     MOV    Byte Ptr EOF,AL        ;FINISHED THIS FILE
  360.     MOV    AL,BUFSIZ
  361.     SUB    AL,CH
  362.     MOV    CH,AL
  363.     CALL    WRITE
  364.     MOV    DX,(Offset FCB2)
  365.     MOV    CL,B_CLOSE        ;CLOSE DESTINATION
  366.     CALL    BDOSE
  367.     CMP    AL,255
  368.     JNZ    FINI_1    
  369.     JMP    ERROR9            ;CLOSE FAILURE
  370. ;
  371. FINI_1:
  372.     CALL    RENAME            ;RENAME $$$ TO TYP
  373.     MOV    AL,Byte Ptr WILD
  374.     OR    AL,AL            ;MORE FILES?
  375.     JNZ    FINI_2    
  376.     JMP    DONE
  377. ;
  378. FINI_2:
  379.     MOV    BX,(Offset BUFSTART)
  380.     MOV    Word Ptr BUFPT,BX    ;RESET BUFFER POINTER
  381.     XOR    AL,AL
  382.     MOV    Byte Ptr OPEN,AL    ;RESET FILE OPEN FLAG
  383.     MOV    Byte Ptr EOF,AL        ;WON'T BE EOF ON NEXT FILE
  384.     MOV    BX,(Offset FCB1)    ;POINT TO INTERNAL FCBS
  385.     MOV    CL,64            ;LENGTH OF 2 * FCB
  386.     XOR    AL,AL
  387. FCB_FILL1:
  388.     MOV    M,AL            ;RESET MEMORY
  389.     LAHF                ;ADJUST POINTER
  390.     INC    BX
  391.     SAHF
  392.     DEC    CL            ;DONE ?
  393.     JNZ    FCB_FILL1        ;NO    
  394.     MOV    AL,Byte Ptr FUSER
  395.     MOV    DL,AL            ;SAVE DIRECTORY POINTER TIL LATER
  396.     MOV    CL,USER
  397.     CALL    BDOSE            ;RESET TO SOURCE USER
  398.     MOV    DX,TBUF            ;RESET DMA
  399.     MOV    CL,DMA
  400.     CALL    BDOSE
  401.     MOV    DX,FCB
  402.     MOV    CL,SRCH_1ST        ;START SEARCH FOR NEXT 
  403.     CALL    BDOSE            ; WILDCARD MATCH (TEDIOUS)
  404.     MOV    AL,Byte Ptr F_COUNT    ;NO FILES DONE SO FAR
  405.     INC    AL            ;JUST DONE ANOTHER ONE
  406.     MOV    Byte Ptr F_COUNT,AL    ;KEEP FOR NEXT TIME
  407.     MOV    Byte Ptr D_COUNT,AL    ;INITIALISE LOOP COUNTER
  408. SEARCH_LOOP:
  409.     MOV    DX,0
  410.     MOV    CL,SRCH_NXT        ;SEARCH FOR NEXT WILDCARD MATCH
  411.     CALL    BDOSE
  412.     MOV    Byte Ptr DIR_POINT,AL
  413.     CMP    AL,0FFH            ;NO MORE MATCH ?
  414.     JNZ    SRC_LP_1    
  415.     JMP    DONE            ;YES
  416.  
  417. SRC_LP_1:
  418.     MOV    AL,Byte Ptr D_COUNT    ;NO, GET LOOP COUNT
  419.     DEC    AL            ;ONE SEARCH DONE
  420.     MOV    Byte Ptr D_COUNT,AL
  421.     JNZ    SEARCH_LOOP        ;SEARCH AGAIN
  422.     MOV    CL,DIRECT
  423.     MOV    DL,0FFH
  424.     CALL    BDOSE
  425.     CMP    AL,CNTRLC        ;USER WANTS ABORT ?
  426.     JNZ    SRC_LP_2    
  427.     JMP    U_ABORT            ;YES
  428. ;
  429. SRC_LP_2:
  430.     MOV    AL,Byte Ptr DIR_POINT    ;NO, A = POINTER INTO DIR SECTOR
  431.     JMP    DIR_MATCH        ;FOUND THE ONE WE NEEDED
  432. ;
  433. WRITE:
  434.     MOV    AL,Byte Ptr TUSER
  435.     MOV    DL,AL
  436.     MOV    CL,USER
  437.     CALL    BDOSE            ;SET DESTINATION USER
  438.     MOV    AL,Byte Ptr OPEN
  439.     CMP    AL,0            ;FILE ALREADY OPEN ?
  440.     JZ    WRITE_M    
  441.     JMP    WRITE2            ;YES
  442. ;
  443. WRITE_M:
  444.     NOT    AL            ;NO
  445.     MOV    Byte Ptr OPEN,AL    ;INDICATE FILE OPEN
  446.     MOV    DX,(Offset FCB2)
  447.     MOV    CL,B_OPEN
  448.     CALL    BDOSE            ;ATTEMPT OPEN
  449.     CMP    AL,255
  450.     JZ    WRITE0            ;NOT PRESENT
  451.     MOV    AL,Byte Ptr FCB2+9    ;PRESENT, CHECK R/O
  452.     AND    AL,80H            ;ISOLATE BIT
  453.     RCL    AL,1            ;PUT IN CARRY
  454.     JNB    NOT_RO            ;NOT R/O
  455.     MOV    AL,Byte Ptr O_W
  456.     OR    AL,AL            ;OVER WRITE R/O FILE ?
  457.     JNZ    REMOVE_RO
  458.     JMP    ERR6A            ;IS R/O
  459. ;
  460. REMOVE_RO:
  461.     MOV    DX,(Offset FCB2)
  462.     MOV    CL,B_CLOSE
  463.     CALL    BDOSE            ;CLOSE FILE TO CHANGE ATTRIBUTES
  464.     MOV    BX,(Offset FCB2)+12    ;FCB2 HAS GROUP 'GARBAGE' 
  465.     XOR    AL,AL            ; FROM OPEN CALL WHICH
  466.     MOV    CL,21            ; NEEDS TO BE CLEANED OUT
  467.     CALL    FILL_BLOCK        ; FOR ATTRIBUTE CALL
  468.     MOV    BX,(Offset FCB2)
  469.     MOV    CL,12
  470. R_RO:
  471.     MOV    AL,M            ;RESET ATTRIBUTES IN FILE NAME
  472.     AND    AL,7FH
  473.     MOV    M,AL
  474.     LAHF
  475.     INC    BX
  476.     SAHF
  477.     DEC    CL
  478.     JNZ    R_RO
  479.     MOV    DX,(Offset FCB2)
  480.     MOV    CL,ATTRIB
  481.     CALL    BDOSE
  482.     CMP    AL,0FFH            ;THIS SHOULD NEVER HAPPEN
  483.     JNZ    OPEN_RW
  484.     JMP    ERROR11            ; BUT JUST IN CASE
  485. ;
  486. OPEN_RW:
  487.     MOV    DX,(Offset FCB2)
  488.     MOV    CL,B_OPEN
  489.     CALL    BDOSE            ;OPEN, we already know it exists
  490. NOT_RO:
  491.     MOV    AL,Byte Ptr N_Q
  492.     OR    AL,AL            ;NO FILE EXISTS QUERY?
  493.     JNZ    WRITE0            ;YES
  494.     CALL    ERROR6            ;CHECK BEFORE DELETE
  495.     CMP    AL,'Y'
  496.     JZ    WRITE1            ;CONTINUE
  497.     CMP    AL,'y'
  498.     JZ    WRITE1            ;CONTINUE
  499.     JMP    ABORT            ;ANSWER NOT 'Y' OR 'y'
  500. WRITE1:
  501.     CALL    CRLF
  502. WRITE0:
  503.     MOV    BX,(Offset FCB2)+9    ;POINT TO SECONDARY FILENAME
  504.     MOV    DX,(Offset F_TYPE)
  505.     MOV    CL,3            ;LENGTH OF SECONDARY FILENAME
  506.     MOV    CH,'$'            ;TEMPORARY FILE TYPE MARKER
  507. FILL_TYPE1:
  508.     MOV    AL,M            ;GET SECONDARY FILE NAME
  509.     MOV    SI,DX            ;SAVE IT FOR LATER
  510.     MOV    [SI],AL
  511.     MOV    M,CH            ;STUFF IN TEMP MARKERS
  512.     INC    BX
  513.     INC    DX
  514.     DEC    CL
  515.     JNZ    FILL_TYPE1
  516.     MOV    BX,(Offset FCB2)+12    ;ZERO FILL REST OF FCB
  517.     MOV    CL,24
  518.     XOR    AL,AL
  519.     CALL    FILL_BLOCK
  520.     MOV    DX,(Offset FCB2)
  521.     MOV    CL,MAKE
  522.     CALL    BDOSE            ;CREATE DESTINATION FILE
  523.     CMP    AL,255
  524.     JNZ    WRITE2
  525.     JMP    ERROR7            ;DIRECTORY FULL
  526. ;
  527. WRITE2:
  528.     MOV    AL,Byte Ptr ACOUNT
  529.     OR    AL,AL            ;ZERO LENGTH FILE?
  530.     JZ    ZEXIT            ;YES, DONT WRITE TO DESTINATION
  531.     MOV    CH,AL            ;ACTUAL SECTOR COUNT
  532.     PUSH    BX
  533.     MOV    BX,(Offset BUFSTART)
  534.     MOV    Word Ptr BUFPT,BX    ;SAVE BUFFER POINTER
  535.     POP    BX
  536. WRITE3:
  537.     PUSH    BX
  538.     MOV    BX,Word Ptr BUFPT    ;GET BUFFER POINTER
  539.     XCHG    BX,DX            ;DE <---- BUFFER POINTER
  540.     POP    BX
  541.     PUSH    DX
  542.     MOV    AL,DL
  543.     ADD    AL,80H
  544.     MOV    DL,AL
  545.     MOV    AL,0
  546.     ADC    AL,DH            ;16 BIT ADD OF 1 SECTOR
  547.     MOV    DH,AL
  548.     PUSH    BX
  549.     XCHG    BX,DX
  550.     MOV    Word Ptr BUFPT,BX    ;SAVE NEW BUFFER POINTER
  551.     POP    BX
  552.     POP    DX
  553.     MOV    CL,DMA
  554.     CALL    BDOSE            ;CHANGE DMA ADDRESS
  555.     MOV    DX,(Offset FCB2)
  556.     MOV    CL,B_WRITE
  557.     CALL    BDOSE            ;WRITE A SECTOR
  558.     CMP    AL,0
  559.     JZ    WRITE4    
  560.     JMP    ERROR8            ;WRITE ERROR
  561. ;
  562. WRITE4:
  563.     DEC    CH            ;DONE YET?
  564.     JNZ    WRITE3            ;NO
  565. ZEXIT:                    ;(COME IN HERE IF ZERO LENGTH FILE)
  566.     MOV    AL,Byte Ptr EOF
  567.     CMP    AL,0
  568.     JZ    ZEXIT_1    
  569.     RET                ;END
  570. ;
  571. ZEXIT_1:
  572.     MOV    AL,Byte Ptr FUSER
  573.     MOV    DL,AL
  574.     MOV    CL,USER            ;SET SOURCE USER
  575.     CALL    BDOSE
  576.     RET
  577. ;
  578. FILL_BLOCK:
  579.     MOV    M,AL            ;GENERAL BLOCK FILLER
  580.     LAHF                ; WITH A CONSTANT
  581.     INC    BX
  582.     SAHF
  583.     DEC    CL
  584.     JNZ    FILL_BLOCK
  585.     RET
  586. ;
  587. ;
  588. RENAME:
  589.     MOV    BX,(Offset FCB2)+9    ;START POINT
  590.     MOV    CL,27            ;LENGTH TO FILL
  591.     XOR    AL,AL            ;ZERO A
  592.     CALL    FILL_BLOCK
  593.     MOV    BX,(Offset F_TYPE)    ;POINT TO FILE TYPE
  594.     MOV    DX,(Offset FCB2)+9    ;SECONDARY FILE NAME
  595.     MOV    CL,3            ;LENGTH TO MOVE
  596. REN_LOOP1:
  597.     MOV    AL,M            ;STUFF FILE TYPE BACK INTO FCB
  598.     MOV    SI,DX
  599.     MOV    [SI],AL
  600.     LAHF
  601.     INC    BX
  602.     SAHF
  603.     LAHF
  604.     INC    DX
  605.     SAHF
  606.     DEC    CL
  607.     JNZ    REN_LOOP1
  608.     MOV    DX,(Offset FCB2)
  609.     MOV    CL,DELET
  610.     CALL    BDOSE            ;KILL ORIGINAL DESTINATION FILE
  611.     MOV    BX,(Offset FCB2)+9
  612.     MOV    CL,27
  613.     XOR    AL,AL
  614.     CALL    FILL_BLOCK        ;ZERO FILL WRITE FCB YET AGAIN    
  615.     MOV    BX,(Offset FCB2)
  616.     MOV    DX,(Offset FCB2)+16
  617.     MOV    CL,9
  618. REN_LOOP2:
  619.     MOV    AL,M            ;COPY WRITE FCB TO MAKE THE
  620.     MOV    SI,DX            ; SPECIAL RENAME FORMAT FCB
  621.     MOV    [SI],AL
  622.     LAHF
  623.     INC    BX
  624.     SAHF
  625.     LAHF
  626.     INC    DX
  627.     SAHF
  628.     DEC    CL
  629.     JNZ    REN_LOOP2
  630.     MOV    AL,'$'            ;HL = POINTER TO FCB2 +9
  631.     MOV    CL,3
  632. REN_LOOP3:
  633.     MOV    M,AL            ;STUFF TEMP FILE MARKERS IN
  634.     LAHF                ; THE 'FROM' PART OF FCB
  635.     INC    BX
  636.     SAHF
  637.     DEC    CL
  638.     JNZ    REN_LOOP3
  639.     MOV    BX,(Offset F_TYPE)    ;DE = FCB2+9+16
  640.     MOV    CL,3
  641. REN_LOOP4:
  642.     MOV    AL,M            ;STUFF FILE TYPE IN THE
  643.     MOV    SI,DX            ; 'TO' PART OF FCB
  644.     MOV    [SI],AL
  645.     LAHF
  646.     INC    BX
  647.     SAHF
  648.     LAHF
  649.     INC    DX
  650.     SAHF
  651.     DEC    CL
  652.     JNZ    REN_LOOP4
  653.     MOV    DX,(Offset FCB2)
  654.     MOV    CL,REN            ;DO THE RENAME
  655.     CALL    BDOSE
  656.     CMP    AL,0FFH            ;AGAIN, THIS SHOULD NEVER HAPPEN
  657.     JZ    ERROR10            ; BUT.......
  658.     RET
  659. ;
  660. ;ERROR AND MESSAGE HANDLING
  661. ;
  662. ERROR1:
  663.     MOV    DX,(Offset MSG3)
  664.     CALL    PRINT
  665.     MOV    DX,(Offset MSG2)
  666.     CALL    PRINT
  667.     JMP    ABORT
  668. ;
  669. ERROR2:
  670.     MOV    DX,(Offset MSG4)
  671.     CALL    PRINT
  672.     MOV    DX,(Offset MSG2)
  673.     CALL    PRINT
  674.     JMP    ABORT
  675. ;
  676. ERROR3:
  677.     MOV    DX,(Offset MSG5)
  678.     CALL    PRINT
  679.     JMPS    ABORT
  680. ;
  681. ERROR4:
  682.     MOV    DX,(Offset MSG6)
  683.     CALL    PRINT
  684.     JMPS    ABORT
  685. ;
  686. ERROR5:
  687.     MOV    DX,(Offset MSG7)
  688.     CALL    PRINT
  689.     JMPS    ABORT
  690. ;
  691. ERROR6:
  692.     MOV    DX,(Offset MSG8)
  693.     MOV    CL,B_PRINT
  694.     CALL    BDOSE            ;PROMPT QUESTION
  695.     MOV    CL,CI
  696.     CALL    BDOSE
  697.     RET                ;RETURN WITH INPUT
  698. ;
  699. ERR6A:
  700.     MOV    DX,(Offset MSG8A)
  701.     CALL    PRINT
  702.     JMPS    ABORT
  703. ;
  704. ERROR7:
  705.     MOV    DX,(Offset MSG9)
  706.     CALL    PRINT
  707.     MOV    DX,(Offset MSG10)
  708.     CALL    PRINT
  709.     JMPS    ABORT
  710. ;
  711. ERROR8:
  712.     MOV    DX,(Offset MSG11)
  713.     CALL    PRINT
  714.     JMPS    ABORT
  715. ;
  716. ERROR9:
  717.     MOV    DX,(Offset MSG12)
  718.     CALL    PRINT
  719.     JMPS    ABORT
  720. ;
  721. ERROR10:
  722.     MOV    DX,(Offset MSG16)
  723.     CALL    PRINT
  724.     JMPS    ABORT
  725. ;
  726. ERROR11:
  727.     MOV    DX,(Offset MSG17)
  728.     CALL    PRINT
  729.     JMPS    ABORT
  730. ;
  731. ;
  732. ;GENERAL PURPOSE SUBROUTINES
  733. ;
  734. PRINT:
  735.     PUSH    DX
  736.     CALL    CRLF
  737.     POP    DX
  738.     MOV    CL,B_PRINT
  739.     CALL    BDOSE            ;PRINT MESSAGE
  740.     RET
  741. ;
  742. U_ABORT:
  743.     MOV    DX,(Offset MSG18)
  744.     CALL    PRINT
  745.     JMPS    EOJ
  746. ;
  747. ABORT:
  748.     MOV    DX,(Offset MSG13)
  749.     CALL    PRINT
  750.     JMPS    EOJ
  751. ;
  752. CRLF:
  753.     MOV    DL,ACR
  754.     MOV    CL,CO
  755.     CALL    BDOSE
  756.     MOV    DL,ALF
  757.     MOV    CL,CO
  758.     CALL    BDOSE
  759.     RET
  760. ;
  761. DONE:
  762.     CALL    CRLF            ;NORMAL EOJ MSG
  763.     MOV    DX,(Offset MSG14)
  764.     MOV    CL,B_PRINT
  765.     CALL    BDOSE
  766. ;
  767. EOJ:
  768.     MOV    AL,Byte Ptr CUSER    ;RESET USER
  769.     MOV    DL,AL
  770.     MOV    CL,USER
  771.     CALL    BDOSE
  772.     MOV    CX,0
  773.     MOV    DX,0
  774.     INT    224
  775. ;
  776. SHOW:
  777.     CALL    CRLF
  778.     MOV    DX,(Offset MSG15)
  779.     MOV    CL,B_PRINT
  780.     CALL    BDOSE
  781.     MOV    DH,9
  782. SHOW1:                    ;DISPLAY FILENAME IN READ FCB
  783.     LAHF
  784.     INC    BX
  785.     SAHF
  786.     DEC    DH
  787.     JNZ    SHOW2
  788.     MOV    DL,'.'            ;PRINT THE SEPARATOR
  789.     MOV    CL,CO
  790.     CALL    BDOSE
  791. SHOW2:
  792.     MOV    AL,M
  793.     CMP    AL,0
  794.     JNZ    SHOW3
  795.     RET
  796. ;
  797. SHOW3:
  798.     CMP    AL,' '            ;SKIP BLANKS
  799.     JZ    SHOW1
  800.     MOV    DL,AL
  801.     MOV    CL,CO
  802.     CALL    BDOSE
  803.     JMPS    SHOW1
  804. ;
  805. ;
  806. BDOSE:
  807.     PUSH    CX            ;BDOS ENTRY
  808.     PUSH    DX
  809.     PUSH    BX
  810.     INT    224
  811.     POP    BX
  812.     POP    DX
  813.     POP    CX
  814.     RET
  815. ;
  816. NSCAN:
  817.     MOV    DX,0            ;CLEAR WORK    
  818.     MOV    AL,M            ;GET CHAR
  819.     CMP    AL,'9'+1        ;IS IT A DIGIT
  820.     JNB    NSCAN2            ;> 9
  821.     CMP    AL,'0'
  822.     JB    NSCAN2            ;< 0
  823. NSCAN0:
  824.     SUB    AL,'0'            ;REMOVE ASCII BIAS
  825.     PUSH    BX            ;SAVE PTR
  826.     XCHG    BX,DX            ;GET WORK IN BX
  827.     PUSH    BX
  828.     POP    DX
  829.     SHL    BX,1
  830.     SHL    BX,1
  831.     ADD    BX,DX
  832.     SHL    BX,1            ;BX = BX * 10
  833.     MOV    DH,0
  834.     MOV    DL,AL            ;NEW DIGIT
  835.     ADD    BX,DX            ;ADD IT IN
  836.     XCHG    BX,DX            ;PUT WORK BACK
  837.     POP    BX            ;RESTORE PTR
  838.     INC    BX            ;AND STEP IT
  839.     MOV    AL,M
  840.     CMP    AL,'9'+1
  841.     JNB    NSCAN1
  842.     CMP    AL,'0'
  843.     JB    NSCAN1
  844.     JMPS    NSCAN0            ;LOOP
  845. ;
  846. NSCAN1:    MOV    AL,DL            ;GET NUMBER
  847.     CMP    AL,16            ;<= 15
  848.     JNB    NSCAN2
  849.     OR    AL,AL            ;CLEAR CARRY
  850.     JMPS    NSCAN3
  851. ;
  852. NSCAN2:
  853.     STC                ;SET CARRY
  854. NSCAN3:
  855.     RET                ;EXIT HERE
  856. ;
  857.     DSEG
  858.     ORG    100H
  859. ;
  860. MSG1    DB    'PUT, CP/M-86 Version ',VERSION/10 + '0','.'
  861.     DB    VERSION MOD 10 + '0'
  862.     DB    ', by Angus Bliss and Bill Bolton',ACR,ALF,'$'
  863. ;
  864. MSG2    DB    'Usage:',ACR,ALF
  865.     DB    '    A>put [d:]filename f.t [d:] [-NW] <cr>'
  866.     DB    ACR,ALF
  867.     DB    'Where:',ACR,ALF
  868.     DB    '    filename - is any valid CP/M file '
  869.     DB    'specifier',ACR,ALF
  870.     DB    '     f     - is source user area',ACR,ALF
  871.     DB    '    t     - is destination user area'
  872.     DB    ACR,ALF
  873.     DB    '    d:     - is optional drive specifier'
  874.     DB    ACR,ALF
  875.     DB    '    -     - is an option flag',ACR,ALF
  876.     DB    '    N     - is no query to overwrite '
  877.     DB    'existing file',ACR,ALF
  878.     DB    '    W     - is force overwrite of R/O '
  879.     DB    'file',ACR,ALF,ALF
  880.     DB    '    Will prompt if destination '
  881.     DB    'file is already present',ACR,ALF,'$'
  882. ;
  883. MSG3    DB    'No parameters given',ACR,ALF,'$'
  884. ;
  885. MSG4    DB    'Invalid user number(s)',ACR,ALF,'$'
  886. ;
  887. MSG5    DB    'Sorry - you need CP/M 2.x',ACR,ALF,'$'
  888. ;
  889. MSG6    DB    'Open fail on source file.',ACR,ALF,'$'
  890. ;
  891. MSG7    DB    'Read failure on source file.',ACR,ALF,'$'
  892. ;
  893. MSG8    DB    '  Destination file is present.',ACR,ALF
  894.     DB    '    Continue (y) or Abort (n)?$'
  895. ;
  896. MSG8A    DB    'Destination is present and R/O.$'
  897. ;
  898. MSG9    DB    'Open failure on destination file.$'
  899. ;
  900. MSG10    DB    'Destination directory probably full.$'
  901. ;
  902. MSG11    DB    'Write error on destination.$'
  903. ;
  904. MSG12    DB    'Close fail on destination.$'
  905. ;
  906. MSG13    DB    'ABORT - returning to CP/M.',ACR,ALF,'$'
  907. ;
  908. MSG14    DB    '**** Normal end-of-job ****',ACR,ALF,'$'
  909. ;
  910. MSG15    DB    '    Putting file : $'
  911. ;
  912. MSG16    DB    'Rename error on destination.$'
  913. ;
  914. MSG17    DB    'Rename error on R/O file.$'
  915. ;
  916. MSG18    DB    'ABORT, Control C typed at console - '
  917.     DB    'returning to CP/M',ACR,ALF,'$'
  918. ;
  919. CUSER    DB    0            ;INITIATING USER
  920. FUSER    DB    0            ;FILE FROM USER
  921. TUSER    DB    0            ;FILE TO USER
  922. SIZEB    DW    0            ;BUFFER IN BYTES
  923. BUFPT    DW    0            ;DMA POINTER
  924. ACOUNT    DB    0            ;ACTUAL SECTOR COUNT
  925. OPEN    DB    0            ;FILE OPEN SWITCH
  926. EOF    DB    0            ;END OF SOURCE SWITCH
  927. WILD    DB    0            ;WILDCARD SWITCH
  928. O_W    DB    0            ;OVER WRITE SWITCH    
  929. N_Q    DB    0            ;NO QUERY SWITCH
  930. DEST_DRV DB    0            ;DESTINATION DRIVE
  931. F_COUNT    DB    0            ;FILES TRANSFERED COUNTER
  932. D_COUNT    DB    0            ;FILES TO SEARCH COUNTER
  933. DIR_POINT DB    0            ;TEMP STORAGE FOR SEARCH NEXT
  934. ;
  935. F_TYPE    DB    '   '            ;SECONDARY FILE TYPE
  936. ;
  937. ; FOR RENAME AFTER WRITE
  938. ;
  939. FCB1    DB    0,0,0,0,0,0,0,0,0    ;SOURCE FCB
  940.     DB    0,0,0,0,0,0,0,0,0
  941.     DB    0,0,0,0,0,0,0,0,0
  942.     DB    0,0,0,0,0,0,0,0,0
  943. ;
  944. FCB2    DB    0,0,0,0,0,0,0,0,0    ;Destination FCB
  945.     DB    0,0,0,0,0,0,0,0,0
  946.     DB    0,0,0,0,0,0,0,0,0
  947.     DB    0,0,0,0,0,0,0,0,0
  948. ;
  949. BUFSTART RB    (BUFSIZ + 1) * 128    ;Disk buffer
  950. ;
  951. BUFEND    EQU    $            ;Generate symbol for SID
  952. ;
  953.     END
  954.