home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / lambda / soundpot / a / cu20.lbr / CU20.AZM / CU20.ASM
Encoding:
Assembly Source File  |  1993-10-26  |  16.3 KB  |  718 lines

  1. ;CU.ASM - A PROGRAM TO MOVE FILES FROM ONE USER NUMBER TO ANOTHER
  2. ;
  3. ;CU v2.0   06/23/87    Richard Brewster
  4. ;            R.D. 1  Box 46
  5. ;            Brackney, PA 18812
  6. ;
  7. ;CHANGES:    1)  Altered command syntax to require a period instead
  8. ;        of a comma between source and destination user (e.g.
  9. ;        3.0 instead of 3,0).  This allows proper operation
  10. ;        under ZCPR, which does not format FCB2 (6CH) correctly
  11. ;        using a comma as the delimiter.  The second parameter 
  12. ;        which gives the source and dest user numbers now looks
  13. ;        like a filespec, and should work under any CCP.
  14. ;
  15. ;        2)  Added initialization of variables so that ZCPR
  16. ;        GO [parameters] command can be used.
  17. ;
  18. ;        3)  Added code to check for an existing file of the
  19. ;        same name in the destination user area.  If the file
  20. ;        exists and is R/W, it is automatically deleted.  If
  21. ;        it exists and is R/O, the change operation is skipped.
  22. ;        Appropriate messages are displayed.
  23. ;
  24. ;        4)  Corrected display of the filename attributes of
  25. ;        the source files.
  26. ;
  27. ;        5)  Modified messages.
  28. ;
  29. ;        6)  Moved video attributes into first sector for easy
  30. ;        patching with DDT, EDFILE, SUPERZAP, etc.
  31. ;
  32. ;---------------------------------------------------------------
  33. ;
  34. ;CU    original documentation
  35. ;
  36. ;From an idea by Aubrey Hutchinson of Pompano Beach, Florida
  37. ;published in Dr. Dobbs Journal, March 1983.
  38. ;See: Dr. Dobbs Clinic, page 82.
  39. ;
  40. ;Written by:    Robert Wilcox
  41. ;        920 N. Washington
  42. ;        Owosso, MI  48867
  43. ;Date written:    2 Mar 83
  44. ;Rewritten   : 25 Mar 85 to show filenames as they are changed
  45. ;              and allow for operator to be asked before each
  46. ;              file operation.  This revision was patterned
  47. ;              after ERAQ, from which much of the code was
  48. ;              borrowed.
  49. ;
  50. ;OPERATION:       CU [dr:]FILENAME.TYPE s,d [/N]
  51. ;
  52. ;Where dr: is the drive designator (optional),
  53. ;        s is the source user number, and
  54. ;        d is the destination user number.
  55. ;        N means don't ask before changing each file.
  56. ;
  57. ;Filename.typ may be ambiguous, same as with the ERA command.
  58. ;
  59. ;EXAMPLE:
  60. ;                 CU *.ASM 0,3 /N
  61. ;
  62. ;This would transfer all files of type ASM from user 0 to user 3
  63. ;without asking before each transfer.
  64. ;
  65. ;CAUTION: If a file already exists in the destination user area,
  66. ;it is possible with this program to create another one with
  67. ;the same name.  Using the ERA command will then erase BOTH
  68. ;of them.
  69. ;
  70. ;NOTE: R/O files will be R/W after the transfer.
  71. ;
  72. ;*********************************************************************
  73. ;
  74. ;CP/M LOCATIONS
  75. BOOT    EQU    00000H
  76. BDOS    EQU    00005H
  77. FCB1    EQU    0005CH
  78. FCB2    EQU    0006CH
  79. ;
  80. ;CP/M FUNCTIONS
  81. CONIN    EQU    1        ; Console in function
  82. TYPE    EQU    2        ; Console type function
  83. PRINTF    EQU    9        ; Print string function
  84. STATUS    EQU    11        ; Console status function
  85. SEARCHF    EQU    17        ; Search for first file
  86. SEARCHN    EQU    18        ; Search for next file
  87. DELETE    EQU    19        ; Delete file function
  88. CDISK    EQU    25        ; Get current disk function
  89. SETDMA    EQU    26        ; Set DMA function
  90. SETFIL    EQU    30        ; Set file attributes
  91. USERF    EQU    32        ; Get/set user
  92. ;
  93. ;ASCII EQUATES
  94. CTRLC    EQU    3        ; Control - C
  95. TAB    EQU    9
  96. CR    EQU    13
  97. LF    EQU    10
  98. ESC    EQU    27
  99. ;
  100. MAXUSR:    EQU    15        ; Highest valid user - can be
  101.                 ; made higher to 'hide' files
  102.  
  103.     ORG    100H
  104. START:    JMP    GO        ;skip over video codes
  105. ;
  106. ;    VIDEO ATTRIBUTE STRINGS
  107. ; Strings for video attributes are stored here, each ending with '$'
  108. ;  for BDOS function 9.  These can be patched using DDT, EDFILE, or
  109. ;  SUPERZAP, using up to six chars each.  The string MUST end with '$'!
  110. ;
  111. CLSMSG:    DB    '$$$$$$$'    ; Clear screen
  112. ONSTR:    DB    '$$$$$$$'    ; Reverse video start tag
  113. OFFSTR:    DB    '$$$$$$$'    ; Reverse video end tag
  114. NITSTR:    DB    '$$$$$$$'    ; Initialize scrn for reverse video
  115. ;
  116. GO:    LXI    H,PRTFLG    ; dynamic itialization of storage area
  117.     XRA    A
  118.     MVI    B,17        ; number of bytes in storage area
  119.     DCX    H
  120. DOINIT:    INX    H
  121.     MOV    M,A
  122.     DCR    B
  123.     JNZ    DOINIT
  124.     LXI    H,BUFFER    ; Initialize BUFPTR
  125.     SHLD    BUFPTR
  126. ;
  127. GETRDY:    LHLD    1        ; get warm start entry point
  128.     LXI    D,-654H
  129.     DAD    D        ; subtract 654h bytes
  130.     SHLD    LOCE5        ; save address for later
  131.     MOV    A,M        ; check to see that byte there
  132.     CPI    0E5H        ; is E5
  133.     JZ    GETSET        ; jump if it's there,
  134.     LHLD    6        ; otherwise search thru
  135. FIND:    INX    H        ; memory looking for
  136.     MOV    A,H        ; the code for MVI M,E5, MVI C,xx
  137.     CPI    0        ; If H=0 we have
  138.     JZ    BAD        ;        gone too far...
  139.     MOV    A,M        ; Otherwise keep searching
  140.     CPI    36H
  141.     JNZ    FIND
  142.     INX    H
  143.     SHLD    LOCE5
  144.     MOV    A,M
  145.     CPI    0E5H
  146.     JNZ    FIND
  147.     INX    H
  148.     MOV    A,M
  149.     CPI    0EH
  150.     JZ    GETSET
  151.     JMP    FIND
  152. ;
  153. BAD:    LXI    D,BADMSG    ; print bad system msg
  154.     CALL    PRTSTR        ; and return to CCP....
  155.     RET
  156. ;
  157. GETSET:    CALL    INIT        ; Initialize terminal if needed
  158.     LDA    FCB1+1
  159.     CPI    ' '
  160.     JNZ    NOWGO        ; Jump if something was typed
  161.     CALL    CLRSCR        ; No file spec'd, print help msg
  162.     CALL    REVON        ;       Reverse video on
  163.     LXI    D,PGMNAM    ;       Show the program name
  164.     CALL    PRTSTR
  165.     CALL    REVOFF        ;       Reverse video off
  166.     LXI    D,HLPMSG    ;       Help message
  167.     CALL    PRTSTR
  168.     RET            ; and return to CCP
  169.  
  170. NOWGO:    LXI    H,FCB2+1    ; get source user #
  171.     CALL    GETNUM
  172.     JC    GOMORE        ; if ok...
  173. BADNUM:    LXI    D,BADNR        ; otherwise print bad number msg
  174.     CALL    PRTSTR        ; and return to CCP
  175.     JMP    ABORT
  176. GOMORE:    STA    SOURCE        ; save source user #
  177.     MVI    E,0FFH        ; get current user #
  178.     MVI    C,USERF
  179.     CALL    BDOS
  180.     STA    USRNR        ; save it
  181.     LXI    H,FCB2+9    ; look at file type for dest user
  182.     MOV    A,M
  183.     CPI    ' '        ; if nothing there
  184.     JNZ    GETDES
  185.     LDA    USRNR        ; dest = current user
  186.     JMP    GOTDES
  187. GETDES:    CALL    GETNUM        ; get dest user #
  188.     JNC    BADNUM        ; quit if bad number...
  189. GOTDES:    STA    DEST
  190.     MOV    E,A        ; otherwise dest to E
  191.     LDA    SOURCE        ; get source # and quit if same as
  192.     CMP    E        ; dest.
  193.     JZ    BADNUM        ; otherwise...
  194.     PUSH    D
  195.     PUSH    PSW
  196.     LDA    FCB1        ; get drive designation
  197.     ANA    A
  198.     JNZ    GOTDRV
  199.     MVI    C,CDISK        ; get default drive    
  200.     CALL    BDOS        ; returns 0 for drive A
  201.     INR    A        ; fix it so 1 = drive A...
  202. GOTDRV:    ADI    '@'        ; convert drive to ASCII
  203.     STA    DRIVE        ; save it
  204.     LHLD    LOCE5        ; point to location of e5h in CCP.
  205.     POP    PSW
  206.     POP    D
  207.     MOV    M,E        ; replace the e5h with the dest user #
  208.     MOV    E,A        ; source to E for bdos call
  209.     MVI    C,USERF
  210.     CALL    BDOS        ; set user to source
  211.     LXI    H,80H
  212.     MOV    B,M
  213.     MOV    A,B
  214.     ORA    A
  215.     JZ    NOTN        ; Skip if no characters typed
  216. FINDN:    INX    H        ; else check each character
  217.     MOV    A,M
  218.     CPI    '/'        ; Was it "/"?
  219.     JNZ    FINDLP
  220.     DCR    B
  221.     JZ    NOTN
  222.     INX    H
  223.     MOV    A,M
  224.     CPI    'N'
  225.     JZ    YESN
  226. FINDLP:    DCR    B
  227.     JNZ    FINDN
  228.     JMP    NOTN
  229. YESN:    STA    NAFLG
  230. NOTN:    LXI    D,DBUF
  231.     MVI    C,SETDMA
  232.     CALL    BDOS
  233.     LXI    D,FCB1
  234.     MVI    C,SEARCHF
  235.     CALL    BDOS
  236.     INR    A
  237.     JZ    FINIS
  238. GETFN:    DCR    A        ; Adjust Accum to point to filename
  239.     ADD    A        ; A=A*32
  240.     ADD    A
  241.     ADD    A
  242.     ADD    A
  243.     ADD    A
  244.     LXI    H,DBUF        ; Point to disk buffer
  245.     MVI    D,0        ; Add in
  246.     MOV    E,A        ;  offset for
  247.     DAD    D        ;   this file
  248.     XCHG            ; DE points to filename in disk buffer
  249.     LHLD    BUFPTR        ; Point HL to buffer
  250.     MVI    C,32        ; # of bytes to move
  251. MOVE:    LDAX    D        ; Move filename from disk buffer
  252.     MOV    M,A        ;  to main buffer
  253.     INX    H
  254.     INX    D
  255.     DCR    C
  256.     JNZ    MOVE
  257.     SHLD    BUFPTR        ; Update pointer
  258.     LDA    FCOUNT        ; Add 1 to file count
  259.     INR    A
  260.     STA    FCOUNT
  261.     LXI    D,FCB1
  262.     MVI    C,SEARCHN    ; Look for more files
  263.     CALL    BDOS
  264.     INR    A
  265.     JNZ    GETFN        ; Get next filename
  266.     LXI    H,BUFFER    ; All found, point to first one
  267.     SHLD    BUFPTR
  268. ;
  269. ;SEE IF WE TYPED "/N", IF YES, SAY "^C TO QUIT"
  270.     LDA    NAFLG
  271.     CPI    'N'
  272.     JNZ    PRTFN
  273.     CALL    REVON
  274.     LXI    D,CTCMSG    ; "^C" message
  275.     CALL    PRTSTR
  276.     CALL    REVOFF
  277. ;
  278. ;PRINT THE FILE SPECS
  279. PRTFN:    CALL    CRLF
  280.     MVI    A,8        ; Print 8 char's
  281.     PUSH    H
  282.     INX    H
  283.     CALL    TYPEA
  284.     PUSH    H
  285.     MVI    E,'.'        ; Print a period
  286.     CALL    PCHAR
  287.     POP    H
  288.     MVI    A,3        ; Print file type
  289.     CALL    TYPEA
  290.     MVI    E,' '        ; And a couple of spaces
  291.     CALL    PCHAR
  292.     MVI    E,' '
  293.     CALL    PCHAR
  294.     POP    H
  295.     LXI    D,9        ; Look at
  296.     DAD    D        ;  the
  297.     MOV    A,M        ;   R/O bit
  298.     RLC
  299.     JNC    NOTRO        ; Skip if not R/O, else
  300.     MVI    A,0FFH        ;   set R/O flag
  301.     STA    ROFLG
  302. NOTRO:    INX    H        ; Look at SYS bit
  303.     MOV    A,M
  304.     RLC
  305.     JNC    NOTSYS        ; Skip if not SYS, else
  306.     MVI    A,0FFH        ;   set SYS flag
  307.     STA    SYSFLG
  308. NOTSYS:    LDA    ROFLG
  309.     MOV    B,A
  310.     LDA    SYSFLG
  311.     ORA    B
  312.     JNZ    PRTATR        ; Jump if file is R/O or SYS
  313.     JMP    DOIT
  314. ;
  315. PRTATR:    
  316.     MVI    E,'('        ; Print file attributes
  317.     CALL    PCHAR
  318.     LDA    ROFLG
  319.     ORA    A
  320.     JZ    SKPRO        ; Skip if not R/O
  321.     LXI    D,ROMSG        ; "R/O"
  322.     CALL    PRTSTR
  323. SKPRO:    LDA    ROFLG
  324.     MOV    B,A
  325.     LDA    SYSFLG
  326.     ANA    B
  327.     JZ    SKPCOM        ; print ',' if both 'R/O' and 'SYS'
  328.     MVI    E,','
  329.     CALL    PCHAR
  330. SKPCOM:    LDA    SYSFLG
  331.     ORA    A
  332.     JZ    SKPSYS
  333.     LXI    D,SYSMSG    ; "SYS"
  334.     CALL    PRTSTR
  335. SKPSYS:    MVI    E,')'
  336.     CALL    PCHAR
  337. DOIT:    MVI    E,' '
  338.     CALL    PCHAR
  339.     MVI    E,' '
  340.     CALL     PCHAR
  341.     CALL    CHANGE
  342.     MVI    C,STATUS    ; Check if anything typed
  343.     CALL    BDOS        ;   on keyboard
  344.     ANA    A
  345.     JZ    CONT        ; Continue if not, else
  346.     MVI    C,CONIN        ;   get character
  347.     CALL    BDOS
  348.     CPI    CTRLC        ; Abort if it was ^C
  349.     JZ    FINIS
  350. CONT:    MVI    A,0        ; Reset the flags
  351.     STA    ROFLG
  352.     STA    SYSFLG
  353.     STA    ASKFLG
  354.     LDA    FCOUNT        ; Count down
  355.     DCR    A
  356.     STA    FCOUNT
  357.     JZ    FINIS        ; If no more
  358.     LHLD    BUFPTR
  359.     LXI    D,32        ; Move to next filename
  360.     DAD    D
  361.     SHLD    BUFPTR
  362.     JMP    PRTFN
  363. ;
  364. ;SUBROUTINE ASK RETURNS Z IF OK TO CHANGE
  365. ASK:    LDA    NAFLG        ; See if must ask to change file
  366.     CPI    'N'        ; 'N' = no ask
  367.     RZ            ; return if don't have to ask
  368.     LDA    ASKFLG        ; check if asking to delete existing file
  369.     INR    A
  370.     RZ            ; if so, we've already asked - it's OK
  371.     LXI    D,QUERY        ; Move this file?
  372.     CALL    PRTSTR
  373.     MVI    C,CONIN        ; Get response
  374.     CALL    BDOS
  375.     ANI    05FH        ; Make upper case
  376.     CPI    CTRLC        ; ^C to quit
  377.     JZ    FINIS
  378.     CPI    'Y'        ; Y to move the file
  379.     RET
  380. ;
  381. CHANGE:    LHLD    BUFPTR        ; Get drive and
  382.     LDA    FCB1        ;  move it to buffer
  383.     MOV    M,A
  384.  
  385. ;CHECK TO SEE IF A FILE OF THE SAME NAME EXISTS IN THE DEST USER AREA
  386. RWOK:    PUSH    H        ;FCB
  387.     LDA    DEST        ;get destination user
  388.     MOV    E,A
  389.     MVI    C,USERF
  390.     CALL    BDOS        ;set user to destination
  391.     POP    D        ;FCB
  392.     PUSH    D
  393.     MVI    C,SEARCHF    ;search for file of same name
  394.     CALL    BDOS
  395.     INR    A
  396.     JZ    CHANG2        ;no file, so OK to change
  397. ;
  398. ;WE HAVE FOUND AN EXISTING FILE
  399.     DCR    A        ;now check for R/O status
  400.     ADD    A        ;compute index to name
  401.     ADD    A
  402.     ADD    A
  403.     ADD    A
  404.     ADD    A
  405.     ADI    9        ;point to R/O bit
  406.     LXI    H,DBUF
  407.     MVI    D,0
  408.     MOV    E,A
  409.     DAD    D
  410.     MOV    A,M        ;get it
  411.     RLC
  412.     JNC    DDEST        ;if it is R/W, continue
  413. ;
  414.     CALL    REVON
  415.     LXI    D,NODELE    ;else print message and DO NOT change
  416.     CALL    PRTSTR
  417.     CALL    REVOFF
  418.     POP    H        ;clean stack
  419.     RET
  420. ;
  421. DDEST:    CALL    REVON
  422.     LXI    D,DELMSG
  423.     CALL    PRTSTR
  424.     CALL    REVOFF
  425.     CALL    ASK
  426.     JZ    DELOK
  427.     POP    H
  428.     RET
  429. ;
  430. DELOK:    MVI    A,0FFH        ;set flag for ASK routine
  431.     STA    ASKFLG
  432.     LHLD    LOCE5        ;have to put E5 back for real delete
  433.     MVI    M,0E5H
  434.     POP    D
  435.     PUSH    D
  436.     PUSH    H
  437.     MVI    C,DELETE
  438.     CALL    BDOS
  439.     LDA    NAFLG
  440.     CPI    'N'
  441.     JNZ    HADASK        ;if not querying, say that the file
  442.     MVI    E,' '        ; has been deleted
  443.     CALL    PCHAR
  444.     CALL    REVON        
  445.     LXI    D,KILMSG
  446.     CALL    PRTSTR
  447.     CALL    REVOFF
  448. HADASK:    POP    H        ;get back LOCE5
  449.     LDA    DEST        ;and replace destination user
  450.     MOV    M,A
  451.  
  452. ;CHANGE THE FILE'S USER BY CALLING THE DELETE FUNCTION
  453. CHANG2:    LDA    SOURCE        ;restore source user
  454.     MOV    E,A
  455.     MVI    C,USERF
  456.     CALL    BDOS
  457.     CALL    ASK        ; Now query if requested
  458.     JZ    CHANG3
  459.     POP    H        ; Do not change
  460.     RET
  461. CHANG3:    POP    H        ;FCB
  462.     PUSH    H
  463.     LDA    ROFLG        
  464.     ORA    A        ; If source file is not R/O
  465.     JZ    CHNOW        ;  skip, else
  466.     LXI    D,9             ;  set it to R/W
  467.     DAD    D
  468.     MOV    A,M
  469.     ANI    7FH
  470.     MOV    M,A
  471.     POP    D
  472.     PUSH    D
  473.     MVI    C,SETFIL
  474.     CALL    BDOS
  475. CHNOW:    POP    D        ;FCB
  476.     MVI    C,DELETE
  477.     CALL    BDOS
  478.     LDA    CHGCNT
  479.     INR    A
  480.     STA    CHGCNT
  481.     RET
  482. ;
  483. ;PRINT THE NUMBER OF FILES CHANGED AND RETURN TO CCP
  484. ;(IF ABORTING, PRINT ABORT MSG FIRST)
  485. FINIS:    CPI    CTRLC
  486.     CZ    ABORT
  487.     CALL    CRLF
  488.     CALL    CRLF
  489.     CALL    REVON
  490.     MVI    E,TAB
  491.     CALL    PCHAR
  492.     LDA    CHGCNT
  493.     MVI    H,0
  494.     MOV    L,A
  495.     CALL    PT3DEC        ; Print H/L as 3 decimal digits
  496.     LXI    D,REPORT    ; "FILES CHANGED "
  497.     CALL    PRTSTR
  498.     LDA    CHGCNT        ; See if any files were changed
  499.     ANA    A        ; Skip if none changed, otherwise
  500.     JZ    FINIS1        ; show 'from here to there' message
  501.     LXI    D,FRMMSG    ; "FROM "
  502.     CALL    PRTSTR
  503.     LDA    DRIVE
  504.     MOV    E,A
  505.     CALL    PCHAR
  506.     XRA    A
  507.     STA    PRTFLG
  508.     LDA    SOURCE
  509.     MVI    H,0
  510.     MOV    L,A
  511.     CALL    PT2DEC
  512.     LXI    D,TOMSG        ; " TO "
  513.     CALL    PRTSTR
  514.     LDA    DRIVE
  515.     MOV    E,A
  516.     CALL    PCHAR
  517.     XRA    A
  518.     STA    PRTFLG
  519.     LDA    DEST
  520.     MVI    H,0
  521.     MOV    L,A
  522.     CALL    PT2DEC
  523. FINIS1:    MVI    E,TAB
  524.     CALL    PCHAR
  525.     MVI    E,TAB
  526.     CALL    PCHAR
  527.     CALL    REVOFF
  528.     CALL    CRLF
  529. ;RESTORE ORIGINAL USER AND REPLACE E5 ERASE CODE
  530.     LHLD    LOCE5
  531.     MVI    M,0E5H
  532.     LDA    USRNR
  533.     MOV    E,A
  534.     MVI    C,USERF
  535.     CALL    BDOS
  536.     JMP    BOOT
  537. ;
  538. ABORT:    LXI    D,ABTMSG    ; "PROGRAM ABORTED"
  539.     CALL    PRTSTR
  540.     RET
  541. ;
  542. ;Print H/L as 3 decimal digits
  543. PT3DEC:    LXI    B,-100        ; Divide by 100
  544.     CALL    DIVIDE
  545.     MOV    A,E        ; Result to A
  546.     STA     PRTFLG        ; Save it for later
  547.     CPI    0        ; Suppress leading 0
  548.     JZ    PT2DEC
  549.     CALL    PRTDIG
  550. PT2DEC:    LXI    B,-10        ; Divide by 10
  551.     CALL    DIVIDE
  552.     LDA    PRTFLG        ; Have we printed a char?
  553.     ANA    A
  554.     MOV    A,E
  555.     JNZ    NOSKIP        ; Yes, then don't skip a 0
  556.     CPI    0
  557.     JZ    LSTDIG
  558. NOSKIP:    CALL    PRTDIG
  559. LSTDIG:    MOV    A,L
  560.     CALL    PRTDIG
  561.     RET
  562. ;
  563. ;GETNUM - GETS NUMBER FROM COMMAND LINE - QUITS AT NON-NUMERIC CHAR.
  564. ;         RETURNS WITH CARRY SET IF VALID USER.
  565. ;
  566. GETNUM:    MVI    E,0        ; clear accumulation
  567. GNLOOP:    MOV    A,M        ; get the character
  568.     INX    H        ; point to next one
  569.     CALL    CKNR        ; conv. to binary & check if valid #
  570.     JC    GNDONE        ; if not 0-9
  571.     MOV    D,A        ; save present digit of user #
  572.     MOV    A,E        ; get prev. accumulation
  573.     CALL    X10        ; and mult it X 10
  574.     ADD    D        ; add in present digit
  575.     MOV    E,A        ; save the accumulated value
  576.     JMP    GNLOOP        ; get next char.
  577. GNDONE:    MOV    A,E        ; retrieve the digit
  578.     CPI    MAXUSR+1    ; see if valid - ret w/carry set if ok
  579.     SHLD    POINTR        ; remember where we left off
  580.     RET
  581. ;
  582. ;CKNR - Returns carry set if A is not a valid ASCII digit between 0 and 9
  583. ;       otherwise returns carry=0 and A converted to the binary value of
  584. ;       the digit
  585. ;
  586. CKNR:    SUI    '0'
  587.     RC
  588.     CPI    10
  589.     CMC
  590.     RET
  591. ;
  592. X10:    ADD    A        ; A=A*2
  593.     MOV    B,A
  594.     ADD    A        ; A=A*4
  595.     ADD    A        ; A=A*8
  596.     ADD    B        ; A=A*10
  597.     RET
  598. ;
  599. ;TYPE NUMBER OF CHAR'S IN A REG
  600. TYPEA:    PUSH    PSW
  601.     PUSH    H
  602.     MOV    A,M
  603.     ANI    7FH        ;clear parity bit
  604.     MOV    E,A
  605.     CALL    PCHAR
  606.     POP    H
  607.     POP    PSW
  608.     INX    H
  609.     DCR    A
  610.     JNZ    TYPEA
  611.     RET
  612. ;
  613. ;Divide HL/BC, returns quotient in E, remainder in L
  614. DIVIDE:    MVI    E,0FFH
  615. DVLOOP:    INR    E
  616.     DAD    B
  617.     JC    DVLOOP
  618.     MOV    A,B
  619.     CMA
  620.     MOV    B,A
  621.     MOV    A,C
  622.     CMA
  623.     MOV    C,A
  624.     INX    B
  625.     DAD    B
  626.     RET
  627. ;
  628. ;PRINT VALUE IN ACCUM AS ASCII DIGIT
  629. PRTDIG:    ADI    030H
  630.     PUSH    H
  631.     MOV    E,A
  632.     CALL    PCHAR
  633.     POP    H
  634.     RET
  635. ;
  636. ;SEND CARRIAGE RETURN, LINEFEED TO CRT
  637. CRLF:    MVI    E,CR
  638.     CALL    PCHAR
  639.     MVI    E,LF
  640. PCHAR:    PUSH    H
  641.     MVI    C,TYPE
  642.     CALL    BDOS
  643.     POP    H
  644.     RET
  645. ;
  646. ;CLEAR CRT SCREEN
  647. CLRSCR:    LXI    D,CLSMSG
  648.     JMP    PRTSTR
  649. ;
  650. INIT:    LXI    D,NITSTR    ; Initialize CRT for reverse video
  651.     JMP    PRTSTR
  652. ;
  653. REVOFF:    LXI    D,OFFSTR    ; Reverse video off
  654.     JMP    PRTSTR
  655. ;
  656. REVON:    LXI    D,ONSTR        ; Reverse video on
  657. ;
  658. PRTSTR:    PUSH    H
  659.     PUSH    D
  660.     MVI    C,PRINTF
  661.     CALL    BDOS
  662.     POP    D
  663.     POP    H
  664.     RET
  665. ;
  666. ;MESSAGES -
  667. CTCMSG:    DB    CR,LF,TAB,'Use ^C to quit',TAB,TAB,CR,LF,'$'
  668. QUERY:    DB    ' Change? $'
  669. ABTMSG:    DB    CR,LF,TAB,'Program aborted',TAB,TAB,CR,LF,'$'
  670. REPORT:    DB    ' file(s) changed $'
  671. FRMMSG:    DB    'from $'
  672. TOMSG:    DB    ' to $'
  673. PGMNAM:    DB    TAB,TAB,'Change User v2.0  6/23/87',TAB,TAB,'$'
  674. HLPMSG:    DB    CR,LF,LF
  675.     DB    'Usage:'
  676.     DB    TAB,TAB,'CU [d:]filespec s[.d] [/N]',CR,LF,LF
  677.     DB    TAB,'d: = optional drive',CR,LF
  678.     DB    TAB,'s = source user number (required)',CR,LF
  679.     DB    TAB,'d = optional destination user number',CR,LF
  680.     DB    TAB,'filespec may be ambiguous',CR,LF
  681.     DB    TAB,'optional /N for no query before each change',CR,LF,LF
  682.     DB    TAB,TAB,'CU *.ASM 0.3',CR,LF,LF
  683.     DB    TAB,'Changes all .ASM files '
  684.     DB    'from user 0 to user 3.',CR,LF,LF
  685.     DB    TAB,TAB,'CU TEXT.FIL 5 /N',CR,LF,LF
  686.     DB    TAB,'Changes TEXT.FIL from user 5 to the current',CR,LF
  687.     DB    TAB,'user area, without query.',CR,LF,LF
  688.     DB    TAB,'Can delete an existing R/W file of the',CR,LF
  689.     DB    TAB,'same name in the destination user area.',CR,LF,'$'
  690. BADMSG:    DB    CR,LF,'CU cannot run on this system.',CR,LF,'$'
  691. BADNR:    DB    CR,LF,TAB,'Bad user number',CR,LF,TAB,'$'
  692. ROMSG:    DB    'R/O$'
  693. SYSMSG:    DB    'SYS$'
  694. NODELE:    DB    ' NOT CHANGED - R/O destination file $'
  695. DELMSG:    DB    ' EXISTING R/W DESTINATION FILE $'
  696. KILMSG:    DB    ' DELETED $'
  697. ;
  698. ;STORAGE AREA    This area is dynamically initialized.
  699. ;
  700. PRTFLG:    DB    0        ; Flag for decimal print routine
  701. DRIVE:    DB    'A'        ; Drive letter for messages
  702. SOURCE:    DB    0        ; temp storage for source #
  703. DEST:    DB    0        ; temp storage for destination #
  704. POINTR:    DW    0        ; pointer to next character for dest user #
  705. LOCE5:    DW    0        ; location of e5h in CCP
  706. USRNR:    DB    0        ; Current user
  707. BUFPTR:    DW    BUFFER        ; Buffer pointer storage
  708. FCOUNT:    DB    0        ; File counter storage
  709. CHGCNT:    DB    0        ; Changed file counter storage
  710. ROFLG:    DB    0        ; Read-only flag (FF=R/O)
  711. SYSFLG:    DB    0        ; SYSTEM flag (FF=SYS)
  712. NAFLG:    DB    0        ; No ask flag (0=ask)
  713. ASKFLG:    DB    0        ; FF if query concerns existing file
  714. DBUF:    DS    128        ; Disk buffer
  715. BUFFER:    DB    0        ; File name storage starts here
  716. ;
  717.     END    START
  718.