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

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