home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / jsage / znode3 / uploads / zf11src.lbr / ZFCMDS2.ZZ0 / ZFCMDS2.Z80
Encoding:
Text File  |  1992-10-03  |  34.1 KB  |  1,484 lines

  1. .printx    Reading ZFCMDS2.Z80
  2. ;===========================================================================
  3. ;
  4. ; ZFCMDS2.Z80 - Print and View Commands and Code (P, V)
  5. ;        Copy Command and Unsqueeze Code (C)
  6. ;        Move, Delete, Rename Files (M, D, R)
  7. ;
  8. ;===========================================================================
  9.  
  10. ; * * * COMMAND: V
  11.  
  12. ; Type file to console with pagination set to 'lps' from ENV
  13. ;    <space>        single-line scroll using
  14. ;    <ctrl-S>    pause screen output
  15. ;    <ctrl-C>    cancel operation
  16. ;    <ctrl-X>    go to next file
  17. ;    other        scroll one page
  18.  
  19. fview:
  20.     xor    a        ; Set flags
  21.     ld    (first$m),a    ; First view
  22.     ld    (mflag),a    ; Not a mass view
  23.     call    view        ; View file at ringpos
  24.     jp    runsh4        ; Rebuild screen and continue user input
  25.  
  26.  
  27. ;  VIEW - View file at RINGPOS
  28.  
  29. view:
  30.     call    cls
  31.     ld    a,1        ; Initialize..
  32.     ld    (lpscnt),a    ; Lines-per-screen counter
  33.     ld    a,swcon        ; Console output switch value for SOUT routine
  34.     jr    current        ; To common i/o processing
  35.  
  36.  
  37. ; * * * COMMAND: P
  38.  
  39. ; Send file to logical list device (any keypress cancels)
  40.  
  41. flist:
  42.     xor    a        ; Set flags
  43.     ld    (first$m),a    ; Set for prompt for print
  44.     ld    (mflag),a    ; Not a mass print
  45.     call    lstfile        ; Print file at ringpos
  46.     call    erclr        ; Clear error message line.
  47.     jp    loop        ; Return for next command.
  48.  
  49.  
  50. ; LISTFILE - Print file at RINGPOS
  51.  
  52. lstfile:
  53.     ld    a,(first$m)    ; Bypass prompt if already issued.
  54.     or    a
  55.     jr    nz,lstskip
  56.  
  57.     ld    hl,msg55    ; "Print (Y/N)? "
  58.     call    cprmptyn
  59.     call    keyin        ; Get response
  60.     call    testyn        ; Test for YES/NO answer
  61.     jr    z,lstf1        ; Proceed if YES
  62.     jp    loop        ; ..else refresh screen & continue
  63. lstf1:
  64.     ld    (first$m),a    ; Bypass prompt next file print.
  65.  
  66. lstskip:
  67.     ld    hl,0        ; Initialize page number
  68.     ld    (pagenum),hl
  69.     ld    hl,msg56    ; "Printing "
  70.     call    ermsg2
  71.     ld    hl,(ringpos)    ; Pt to file name
  72.     inc    hl
  73.     call    prfnskip    ; Print it
  74.     xor    a
  75.     ld    (eoflag),a    ; File not completed yet.
  76.     ld    a,2        ; Initialize lines-per-page counter
  77.     ld    (lpscnt),a
  78.     ld    a,swlst        ; Printer output switch flag for SOUT routine
  79.  
  80. ; output character for console/list processing
  81.  
  82. current:
  83.     ld    (sctlfl),a    ; Set output switch for SOUT routine
  84.     xor    a        ; Clear the skip-to-end-of-file flag
  85.     ld    (skipfl),a
  86.  
  87. ; output file to console/list
  88.  
  89.     call    ringfcb        ; Position name to 'fcb'
  90.     call    fi0$close    ; Close input file if previously opened.
  91.     ld    de,s$fcb    ; Get fcb with file id.
  92.     call    fi0$open    ; Open file for byte i/o.
  93.     jr    z,zerocr    ; If okay, bypass error message.
  94.  
  95. endfnf:
  96.     cp    4        ; See if fi0$open end-of-file.
  97.     jr    nz,fnf        ; Br if not. assume file not found.
  98.  
  99. ;  Empty File Error
  100.  
  101. endf:
  102.     call    endf1        ; Print 'empty file' message.
  103.     jr    fnfxit        ; Exit after user prompt.
  104.  
  105. ;  File Not Found Error
  106.  
  107. fnf:
  108.     call    fnf1        ; Print 'file not found' message
  109. fnfxit:
  110.     call    bottom0        ; Wait for user to respond.
  111.     ld    a,(mflag)    ; Mass operation?
  112.     or    a
  113.     ret    nz        ; Group operation - continue.
  114.     jp    runsh4a        ; Single file - refresh screen & continue
  115.  
  116. ;  Print File Not Found Message
  117.  
  118. fnf1:
  119.     ld    hl,msg57    ; "File NOT Found"
  120.     jp    ermsg2
  121.  
  122. ;  Print Empty File Message
  123.  
  124. endf1:
  125.     ld    hl,msg58    ; "Empty File"
  126.     jp    ermsg2
  127.  
  128. ; Continue
  129.  
  130. zerocr:
  131.     xor    a
  132.     ld    (s$fcb+32),a    ; Zero file 'current record' field
  133.      if    exptab
  134.     ld    (charcnt),a    ; Zero char count for tabbing
  135.      endif
  136.      if    unsqz
  137.     call    usqhdr        ; Check for squeezed file.
  138.      endif
  139.     call    phead        ; Print heading
  140.  
  141. readlp:        ; Get next character (squeezed or not)
  142.  
  143.      if    unsqz
  144.     ld    a,(usqflg)    ; Squeezed file?
  145.     or    a
  146.     jr    nz,rdlp1    ; Br if not.
  147.     call    usqnxt        ; Unsqueeze next char.
  148.     jr    rdlp2        ; Continue.
  149.      endif    ;unsqz
  150. rdlp1:
  151.     call    f0$get        ; Get a character
  152.  
  153. rdlp2:
  154.     jr    nz,curdone    ; Finished on physical eof.
  155.  
  156.     and    7fh        ; Force to ascii
  157.     cp    eofchar        ; See if end-of-file
  158.     jr    z,curdone    ; Back to ring loop if 'eof'
  159.  
  160.     call    dspchr        ; Output to list/console (char in E on return)
  161.     call    pager        ; Check for 'lf'.
  162.     call    condin        ; See if user entered a character
  163.     and    7fh        ; If character there, then abort..
  164.     call    nz,canview    ; Already got char
  165.     jr    readlp        ; If not, continue with next character.
  166.  
  167. ; EOF reached (if 'view', wait for user before returning to command mode)
  168.  
  169. curdone:
  170.     ld    a,(sctlfl)    ; Console output?
  171.     cp    swcon
  172.     jp    z,bottom    ; If so, prompt user
  173.     ld    (eoflag),a    ; Force final form feed
  174.     jp    formfd        ; Complete processing this file.
  175.  
  176. ; Test for end of page and prompt for continuation if so
  177.  
  178.      if    usedseg
  179.     dseg
  180.      endif
  181.  
  182. skipfl:    ds    1        ; Skip-to-end-of-file flag
  183.  
  184.      if    usedseg
  185.     cseg
  186.      endif
  187.  
  188. pager:
  189.     ld    a,e        ; (character in e-reg)
  190.     cp    lf
  191.     ret    nz
  192.      if    exptab
  193.     xor    a        ; Zero char count
  194.     ld    (charcnt),a
  195.      endif
  196.     ld    a,(sctlfl)    ; Check switch flag for printer output
  197.     cp    swlst
  198.     jr    z,pagep        ; Branch if outputting to printer
  199.  
  200.     ld    a,(skipfl)    ; If skip-to-end-of-file is active
  201.     or    a        ; ..then return to displaying
  202.     ret    nz        ; ..the file
  203.  
  204.     ld    b,22        ; Lines per screen
  205.     ld    a,(lpscnt)    ; Check for lines-per-screen limit
  206.     inc    a
  207.     ld    (lpscnt),a
  208.     cp    b
  209.     ret    c        ; If not, return
  210.     xor    a        ; Else, initialize for next screenful
  211.     ld    (lpscnt),a
  212.     ld    hl,msg59    ; " [sp=line cr=screen ^x=file..."
  213.     call    pstri
  214.     call    dkeyin        ; Wait for keyboard input
  215.     push    af        ; Save it while clearing the prompt
  216.     ld    b,60
  217.     call    ereol        ; Clear to End of Line
  218.     ld    a,cr
  219.     call    cout
  220.     pop    af        ; Get character back
  221.     cp    skipch        ; See if skip-to-end character
  222.     jr    nz,pager1    ; If not, continue
  223.     ld    a,0ffh        ; Set skip flag
  224.     ld    (skipfl),a
  225.     ret            ; Back to displaying file
  226. pager1:
  227.     cp    ' '        ; See if <space> bar..
  228.     jr    nz,canview    ; If not, see if cancel.
  229.     ld    a,22        ; Set for single line
  230.     dec    a
  231.     ld    (lpscnt),a    ; Scroll and..
  232.     ret            ; Return for one more line.
  233.  
  234. ; Check for new page on printer
  235.  
  236. pagep:
  237.     ld    a,(ltpp)    ; Get number of lines of text per page
  238.     ld    b,a        ; ..in B
  239.     ld    a,(lpscnt)    ; Is counter at limit of lines-per-page
  240.     inc    a
  241.     ld    (lpscnt),a
  242.     cp    b
  243.     ret    c        ; If not, return; else, fall thru to formfd
  244.  
  245. ; Print Form Feed
  246.  
  247. formfd:
  248.     ld    a,(lpscnt)    ; Get lines printed already into B
  249.     ld    b,a
  250.     ld    a,(lppp)    ; Get total lines per physical page
  251.     sub    b        ; Compute lines to skip
  252.     ret    z        ; If zero, we are done already
  253.     ld    b,a        ; Else, move count into B
  254.     ld    a,2        ; Reinitialize lines-per-screen counter
  255.     ld    (lpscnt),a
  256.     ld    a,(lffeed)    ; Form feed available?
  257.     or    a        ; 0=no
  258.     jr    nz,prfeed
  259.  
  260.         ; No formfeed capability available in printer
  261.  
  262.     ld    c,list        ; Lst output
  263. pagelst:
  264.     call    lcrlf        ; New line on lst
  265.     djnz    pagelst
  266.     jr    ffhdrck        ; Print heading and continue.
  267.  
  268.         ; Printer has formfeed capability
  269.  
  270. prfeed:
  271.     call    lcrlf        ; New line
  272.     ld    a,ff        ; Send form feed char
  273.     call    lout
  274.  
  275. ffhdrck:
  276.     ld    a,(eoflag)    ; End of current file?
  277.     or    a
  278.     ret    nz        ; No heading after final form feed.
  279.     jr    phead        ; Print header and done
  280.  
  281. canview:
  282.     cp    ctrlc        ; ^c?
  283.     jp    z,runsh4    ; Quit to command prompt
  284.     cp    ctrlx        ; Cancel this file?
  285.     jr    z,canview1    ; Branch if so
  286.     cp    ctrls        ; Pause request?
  287.     ret    nz        ; If not, continue display
  288.     call    dkeyin        ; If so, wait for another key
  289.     cp    ctrls        ; If not another control-s
  290.     jr    nz,canview    ; ..test again for control-c or control-x
  291.     ret            ; Otherwise, resume
  292. canview1:
  293.     pop    bc        ; Yes. return one level higher
  294.     ret
  295.  
  296. ;    Print Heading
  297.  
  298. phead:
  299.     ld    hl,headmsg    ; Pt to heading
  300.     ld    b,6        ; Get length.
  301.     call    phead3a        ; Print string.
  302.  
  303.     ld    hl,s$fcb+1    ; Pt to file name
  304.     call    pheadfn        ; Print file name in heading
  305.  
  306.      if    unsqz
  307.     ld    a,(usqflg)    ; Squeezed file?
  308.     or    a
  309.     jr    nz,phead2    ; Br if not.
  310.  
  311.     ld    hl,usqsep    ; Pt to usq file name separator.
  312.     ld    b,5        ; Get length.
  313.     call    phead3a        ; Print string.
  314.  
  315.     ld    hl,d$fcb+1    ; Pt to original file name
  316.     call    pheadfn        ; Print file name in heading
  317.      endif    ;unsqz
  318. phead2:
  319.     ld    a,(sctlfl)    ; Check for printer output switch
  320.     cp    swlst
  321.     jr    nz,phead2a    ; If not printing, skip page number display
  322.  
  323.     ld    hl,pagehdr    ; Print 'Page' header
  324.     ld    b,8
  325.     call    phead3a
  326.     ld    hl,(pagenum)    ; Get last page number
  327.     inc    hl        ; Increment to current page
  328.     ld    (pagenum),hl    ; Save it
  329.     call    shlfdc        ; Print current page number
  330.  
  331. phead2a:
  332.     ld    hl,headskp    ; New line, blank line
  333.     ld    b,4        ; 4 chars
  334.  
  335. phead3a:
  336.     ld    c,0        ; Display all chars
  337.     jr    phead3
  338. phead3b:
  339.     ld    c,' '        ; Skip spaces
  340. phead3:
  341.     ld    a,(hl)        ; Get char
  342.     push    bc
  343.     cp    c        ; Is it char to skip?
  344.     call    nz,dspchr    ; If not, output to list/console
  345.     pop    bc        ; Restore regs.
  346.     inc    hl        ; Pt to next
  347.     djnz    phead3
  348.  
  349.      if    exptab
  350.     xor    a        ; Reset character counter
  351.     ld    (charcnt),a    ; ..after header has been printed
  352.      endif    ; exptab
  353.  
  354.     ret
  355.  
  356. ; Print a file name in heading, suppressing imbedded spaces.  Called with
  357. ; HL pointing to name in FCB.
  358.  
  359. pheadfn:
  360.     ld    b,8        ; 8 chars
  361.     call    phead3b
  362.     ld    a,'.'        ; Dot
  363.     call    dspchr
  364.     ld    b,3        ; 3 more chars
  365.     jr    phead3b
  366.  
  367. ; Output character to list/console (return character in E register,
  368. ; preserve HL)
  369.  
  370. dspchr:
  371.     push    hl
  372.     ld    e,a        ; Save character in E
  373.     push    de
  374.  
  375.      if    exptab
  376.  
  377.     ld    a,e        ; Check for tab character
  378.     and    7fh
  379.     cp    tab
  380.     jr    nz,notab    ; Skip if not
  381.  
  382.     ld    e,' '        ; Output space characters
  383. tabl:
  384.     ld    a,e
  385.     call    sout        ; Switched output
  386.     ld    hl,charcnt    ; Increment char count
  387.     inc    (hl)
  388.     ld    a,(hl)        ; Get new count
  389.     and    7        ; Check for done at every 8
  390.     jr    nz,tabl
  391.     jr    tabdn
  392.  
  393. notab:
  394.     call    vwchar        ; Output character
  395. ;    call    sout        ; Switched output library routine
  396.     ld    hl,charcnt    ; Increment char count
  397.     inc    (hl)
  398. tabdn:
  399.     pop    de        ; Get char in e in case pager is called
  400.     pop    hl
  401.     ret
  402.  
  403.      else    ; not exptab
  404.  
  405.     call    vwchar        ; Output viewable char
  406. ;    call    sout        ; Switched output library routine
  407.     pop    de        ; Get char in e in case pager is called
  408.     pop    hl
  409.     ret
  410.  
  411.      endif    ; exptab
  412.  
  413. ; Filter output per FILTFLA setting
  414. ; If filter, remove high bit and only output CR and LF controls.
  415. ;   Char in A
  416.  
  417. vwchar:
  418.     ex    af,af'        ; Save char
  419.     ld    a,(filtfla)    ; Filter?
  420.     or    a
  421.     jr    z,vwchar1    ; No
  422.     ex    af,af'        ; Recover char
  423.     and    7fh        ; Remove high bit
  424.     cp    7fh
  425.     ret    z        ; DEL
  426.     cp    20h        ; First printable char
  427.     jr    nc,vwchar2    ; Alpha, send it
  428.     cp    cr
  429.     jr    z,vwchar2
  430.     cp    lf
  431.     jr    z,vwchar2
  432.      iff exptab    ; not exptab
  433.     cp    tab
  434.     jr    z,vwchar2
  435.      endif        ; not exptab
  436.     ret
  437.  
  438. vwchar1:
  439.     ex    af,af'        ; Recover char
  440. vwchar2:
  441.     jp    sout        ; Switched output
  442.  
  443. ; BOTTOM - Position at Bottom of Screen and Prompt for Continuation of Listing
  444. ;       by Entering ^X or ^C
  445.  
  446. bottom:
  447.     ld    hl,botadr    ; Position cursor
  448.     call    gotoxy
  449.     call    vprint
  450.     db    ' EOF ',0
  451. bottom0:
  452.     ld    hl,botadr+5
  453.     call    gotoxy
  454.     ld    hl,msg60    ; "[^x:next ^c:abort] "
  455.     call    pstri
  456. bottom1:
  457.     call    dkeyin
  458.     cp    ctrlx
  459.     ret    z        ; If control-x, return and continue
  460.     cp    ctrlc
  461.     jr    nz,bottom1    ; If not control-c, loop until one of the two
  462.     ld    a,(mflag)    ; Mass operation?
  463.     or    a
  464.     call    nz,stag        ; If so, soft-tag the file just viewed
  465.     jp    runsh4        ; If control-c, start over at command level
  466.  
  467.  
  468. ; * * * COMMAND: C
  469.  
  470. ; Copy source file at current 'ring' position to another drive.
  471. ; Set-up FCB's and buffer area and check for correct keyboard inputs.
  472. ; Contains auto-CRC file copy verification.
  473.  
  474. fcopy:
  475.  
  476. ; Set Flags for First Time Thru and No Mass Copy
  477.  
  478.     xor    a        ; A=0
  479.     ld    (first$m),a    ; Set for prompt for destination
  480.     ld    (mflag),a    ; Not a mass copy
  481.  
  482. ; Do Copy
  483.  
  484.     ld    hl,msg61    ; "Copy File"
  485.     call    ermsg2
  486.     call    copy        ; Do copy of file at ringpos
  487.     call    erclr
  488.  
  489.     jp    loop        ; Return to Same File
  490.  
  491. ; Copy File at RINGPOS
  492.  
  493.      if    usedseg
  494.     dseg
  495.      endif
  496.  
  497. cflag:
  498.     ds    1        ; Copy-success flag (ff = good copy)
  499. tattrfl:
  500.     ds    1        ; Temporary set attributes option flag
  501. tdestfl:
  502.     ds    1        ; Temporary use destination attributes flag
  503. tarcfl:
  504.     ds    1        ; Temporary always set archive attribute flag
  505.  
  506.      if    usedseg
  507.     cseg
  508.      endif
  509.  
  510. copy:
  511.     ld    hl,attrfla    ; Source of attribute control flags
  512.  
  513. copym:                ; Entry point for copy part of move cmd
  514.     ld    de,tattrfl    ; Destination for flags
  515.     ld    b,3        ; Copy three flags
  516.     call    movec
  517.     xor    a        ; Initialize copy flag
  518.     ld    (cflag),a
  519.  
  520.      if    datestamp
  521.     ld    (gotstp),a    ; Initialize got stamp flag
  522.      endif    ;datestamp
  523.  
  524.     ld    hl,0        ; Initialize storage for..
  525.     ld    (crcval),hl    ; 'crc' working value.
  526.     call    ringfcb        ; Move from 'ring' to 'sfcb' with attributes
  527.     ld    b,32        ; Copy source 'fcb' to destination 'fcb'
  528.     ld    hl,s$fcb+1    ; From point..
  529.     ld    de,d$fcb+1    ; To point..
  530.     call    movea        ; Copy, stripping attributes
  531.     ld    de,s$fcb    ; Open file for reading
  532.     ld    c,open        ; Open function
  533.     call    bdosptr
  534.  
  535.      if    datestamp
  536.     ld    (ssector),de    ; Save source sector number
  537.     ld    (sindex),a    ; ..and directory offset
  538.      endif    ;datestamp
  539.  
  540.     inc    a        ; 0ffh --> 00h if bad open
  541.     jp    z,fnf        ; File not found
  542.  
  543. ; Source File is Open
  544.  
  545. copy2:
  546.     ld    de,s$fcb+1    ; Save attributes of source
  547.     call    saveattr    
  548.     ld    a,(first$m)    ; If not first time through
  549.     or    a        ; ..skip getting destination directory
  550.     jr    nz,copy3m    ; ..and resetting disk system
  551.     dec    a        ; A=0ffh
  552.     ld    (first$m),a    ; Set not first time any more
  553.     ld    hl,msg62    ; "to Dir: "
  554.     call    cprmpt2        ; Prompt for drive selection
  555.     call    cpy$d$u
  556.     ld    a,(vflag)    ; Copy default verify flag into temporary flag
  557.     ld    (tvflag),a
  558.     ld    a,(qryvfya)    ; See if verify option is set
  559.     or    a
  560.     call    nz,vfyreq
  561.  
  562. ; Check to ensure that either drives or user areas are different
  563.  
  564.     ld    hl,(du$req)    ; Get requested du
  565.     ld    de,(du$dest)    ; And destination du
  566.     call    cmpdehl        ; Compare..
  567.     jr    nz,copy3    ; Branch if different
  568.     ld    hl,msg63    ; "Src Dir = Dest Dir"
  569.     call    ermsg2        ; If not, show error condition:
  570.     jp    loop        ; Try again?
  571.  
  572. ; First File Copy - Reset System
  573.  
  574. copy3:
  575.     call    reset        ; Make sure disk is read/write
  576.                 ; And return to source du:
  577.  
  578. ; Nth File Copy - Copy without Resetting System
  579.  
  580. copy3m:
  581.      if    datestamp
  582.     call    cpm3
  583.     jr    nc,notzs    ; Don't do it if Plus
  584.     ld    c,setdma    ; Set up for Get Stamp
  585.     ld    de,tdbuff
  586.     call    bdosptr
  587.     ld    de,s$fcb    ; ..of source
  588.     ld    c,getstp
  589.     call    bdosptr
  590.     ld    (gotstp),a    ; Save result for Set
  591. notzs:
  592.     call    resdma
  593.      endif    ;datestamp
  594.  
  595.     call    cufile        ; Make new file, erase old if required.
  596.  
  597. ; Perform Copy
  598.  
  599. copy6:
  600.     call    cprmpt        ; Clear prompt and position the cursor
  601.     ld    a,(massop)    ; Get letter of command requested
  602.     cp    'A'        ; Archiv?
  603.     jr    z,copy60b
  604.     cp    'M'        ; Move?
  605.     jr    z,copy60a
  606.     ld    hl,msg64    ; "Copying "
  607.     call    pstri        ; Must be normal copy
  608.     jr    copy60c
  609. copy60a:
  610.     ld    hl,msg65    ; "Moving "
  611.     call    pstri
  612.     jr    copy60c
  613. copy60b:
  614.     ld    hl,msg66    ; "Archiving "
  615.     call    pstri
  616. copy60c:
  617.     ld    hl,d$fcb+1    ; Print file name
  618.     call    prfnsx
  619.     ld    hl,msg67    ; " to "
  620.     call    pstri
  621.     ld    a,(du$dest+1)    ; Print dest du
  622.     add    a,'A'
  623.     call    cout        ; Print disk
  624.     ld    a,(du$dest)    ; Get user
  625.     call    pafdc        ; Print user
  626.     ld    a,':'
  627.     call    cout
  628.     xor    a        ; Clear 'eof' flag
  629.     ld    (eoflag),a
  630.  
  631. copy6a:
  632.     ld    bc,(du$req)    ; Get current du
  633.     call    logud        ; And set it up.
  634.     ld    hl,0        ; Clear current-record..
  635.     ld    (rec$cnt),hl    ; Counter.
  636.     ld    hl,(bufstart)    ; Set buffer start pointer..
  637.     ld    (buf$pt),hl    ; To begin pointer.
  638.  
  639. ; read source file -- fill buffer memory or stop on 'EOF'
  640. ;           -- update 'CRC' on-the-fly
  641.  
  642. copy7:
  643.     ld    hl,(buf$pt)    ; Set dma address to buffer pointer
  644.     ex    de,hl        ; De --> dma address
  645.     ld    c,setdma
  646.     call    bdosptr
  647.     ld    de,s$fcb    ; Source 'fcb' for reading
  648.     ld    c,read        ; Record read function
  649.     call    bdosptr
  650.     or    a        ; 00h --> read okay
  651.     jr    z,s$rd$ok
  652.     dec    a        ; Eof?
  653.     jr    z,copy8        ; Yes, end-of-file, set 'eof' flag.
  654.     call    resdma        ; Reset dma address.
  655.     ld    hl,msg68    ; "Read Error"
  656.     call    ermsg2
  657.     jp    cankey        ; Cancel group operation
  658.  
  659. ; Read OK - Update CRC
  660.  
  661. s$rd$ok:
  662.     ld    a,(tvflag)
  663.     or    a
  664.     jr    z,copy7b    ; Don't bother if no verify
  665.  
  666.     ld    hl,(buf$pt)
  667.     ld    b,128
  668. copy7a:
  669.     ld    a,(hl)        ; Get character and..
  670.     call    updcrc        ; Add to 'crc' value.
  671.     inc    hl
  672.     djnz    copy7a        ; Loop 'till record read finished
  673. copy7b:
  674.  
  675. ; Update Buffer Ptr and Record Count
  676.  
  677.     ld    hl,(buf$pt)    ; Bump buffer pointer..
  678.     ld    de,128        ; By..
  679.     add    hl,de        ; One..
  680.     ld    (buf$pt),hl    ; Record.
  681.     ld    hl,(rec$cnt)    ; Bump buffer..
  682.     inc    hl        ; Record count and..
  683.     ld    (rec$cnt),hl    ; Store.
  684.     ex    de,hl        ; Ready to compare to..
  685.  
  686. ; Check for Full Buffer
  687.  
  688.     ld    hl,(rec$max)    ; Maximum record count (full-buffer).
  689.     call    cmpdehl        ; Compare
  690.     jr    nz,copy7    ; If not full, get next record.
  691.     jr    copy9        ; Full, start first write session.
  692.  
  693. ; Indicate end-of-file read
  694.  
  695. copy8:
  696.     ld    a,true        ; Set 'eof' flag
  697.     ld    (eoflag),a
  698.  
  699. ; Write source file from memory buffer to destination
  700.  
  701. copy9:
  702.     ld    hl,(bufstart)    ; Adjust buffer pointer..
  703.     ld    (buf$pt),hl    ; To start address.
  704.     call    cuwrite        ; Write buffer to disk.
  705.     jp    z,copy6a    ; Branch to read next buffer full
  706.     ld    a,(tvflag)    ; Verify?
  707.     or    a
  708.     jp    z,cua$log    ; No verify
  709.     jp    crc$cmp        ; Compare file crc's and return
  710.  
  711. ; Get Destination drive and user for Copy/Usq (full check of drive/user)
  712.  
  713. cpy$d$u:
  714.     call    getfspec    ; Get file specification from user
  715.     jr    z,nullin    ; Exit on null input line.
  716.     call    vfy$d$u        ; Resolve, verify du or dir access.
  717.     jr    z,edef_dir    ; Not defined?
  718.     jr    c,eacc_dir    ; Access error?
  719.     ld    (du$dest),bc    ; Return destination du
  720.     ret
  721. nullin:
  722.     call    erclr
  723.     jp    loop
  724.  
  725. edef_dir:
  726.     ld    hl,msg69    ; "Destination Dir Entry Invalid"
  727.     call    ermsg2
  728.     jp    loop
  729.  
  730. eacc_dir:
  731.     ld    hl,msg70    ; "Destination Dir Access Denied"
  732.     call    ermsg2
  733.     jp    loop
  734.  
  735.  
  736. ; Create New Destination Copy File
  737.  
  738. cufile:
  739.     ld    bc,(du$dest)    ; Get destination du
  740.     call    logud        ; And set it up.
  741.     ld    de,d$fcb    ; Search for duplicate
  742.     xor    a        ; Clear destination drive id.
  743.     ld    (de),a
  744.     ld    c,srchf        ; Search for file
  745.     call    bdosptr
  746.     inc    a        ; If not found, 0ffh --> 00h.  then..
  747.     jp    z,cufile2    ; Go to 'make' function for new file.
  748.  
  749.     call    chkpub        ; Check if dest. found via Public
  750.     jp    nz,cankey    ; Abort if so
  751.  
  752.         ; Destination exists -- handle attribute setting
  753.  
  754. ; Bug - DOS error if copy file to destination where r/o file already is
  755. ; Fix - d$fcb doesn't contain correct attributes is OPEN doesn't occur here
  756. ; <rdf>
  757.  
  758. ;    ld    a,(tattrfl)    ; See if attributes are to be set
  759. ;    or    a
  760. ;    jr    z,cufile0    ; If not, leave attributes as they are
  761.  
  762.     ld    de,d$fcb    ; Get dest attributes now.
  763.     ld    c,open
  764.     call    bdosptr
  765.  
  766.     ld    de,d$fcb+1    ; Prepare pointer to destination file name
  767.     ld    a,(tdestfl)    ; See if destination is to be used
  768.     or    a
  769.     call    nz,saveattr    ; ..and save them
  770.  
  771.         ; Check all the query possibilities
  772.  
  773. cufile0:
  774.     ld    a,(mflag)    ; See if single or multiple file operation
  775.     or    a
  776.     jr    z,single    ; Jump if single
  777.     ld    a,(massop)    ; Is it an archive copy
  778.     cp    'A'
  779.     jr    nz,multiple    ; If not, go to multiple file case
  780.     ld    a,(qryarca)    ; Check archive query flag
  781.     or    a
  782.     jr    z,cufile1    ; If not, get on with it
  783.     jr    query        ; Else query
  784. multiple:
  785.     ld    a,(qrygrpa)    ; Is group query option set
  786.     or    a
  787.     jr    z,cufile1    ; If not, get on with it
  788.     jr    query        ; Else, query for overwrite
  789. single:
  790.     ld    a,(qryrepa)    ; Is single file replace query option set
  791.     or    a
  792.     jr    z,cufile1    ; If not, get on with it
  793. query:
  794.     call    atcmd        ; Position cursor at command prompt
  795.  
  796.     ld    hl,(du$dest)    ; Destination drive/user
  797.     ld    a,h        ; Drive
  798.     add    a,'A'
  799.     call    cout
  800.     ld    a,l
  801.     call    pafdc
  802.     ld    a,':'
  803.     call    cout
  804.     ld    hl,d$fcb+1
  805.     call    prfnskip
  806.     ld    hl,msg71    ; " Exists. Erase (Y/N)? "
  807.     call    pstri
  808.     call    keyin        ; Get answer
  809.     cp    ctrlc
  810.     jp    z,cancel    ; Restart if Control C
  811.     call    testyn        ; Test for YES/NO answer
  812.     jr    z,cufile1    ; Proceed if YES
  813.     jr    cufile3        ; ..else skip delete and copy/usq ...
  814.  
  815. ; Erase destination file and proceed
  816.  
  817. cufile1:
  818.  
  819. ; Check destination R/O attribute and prompt if so for deletion.
  820.  
  821.     ld    hl,d$fcb    ; Pt to fcb
  822.     call    attrib        ; Clear bytes in fcb and set file r/w if needed
  823.     jr    z,cufile3    ; Return to caller if r/w not permitted
  824.  
  825. ; Delete old file at dest
  826.  
  827. cufile1a:
  828.     ld    de,d$fcb    ; Delete existing file
  829.     ld    c,erase        ; Erase function
  830.     call    bdosptr
  831.  
  832. ; Create new file at dest
  833.  
  834. cufile2:
  835.     ld    de,d$fcb    ; Create new file and open for writing
  836.     ld    c,make        ; Make function
  837.     call    bdosptr
  838.  
  839.      if    datestamp
  840.     ld    (dsector),de    ; Save destination sector number
  841.     ld    (dindex),a    ; ..and directory index
  842.      endif    ;datestamp
  843.  
  844.     inc    a        ; If directory full, 0ffh --> 00h.
  845.     ret    nz        ; If not, return.
  846.     ld    hl,msg72    ; "Dest Dir Full"
  847.     call    ermsg2
  848.     jp    cankey        ; Wait for keystroke
  849.  
  850. ; Existing file not deleted - return.
  851.  
  852. cufile3:
  853.     ld    bc,(du$req)    ; Else get current du
  854.     call    logud        ; And set it up.
  855.     pop    hl        ; And return 1 level higher.
  856.     ret
  857.  
  858.  
  859. ; Write Copy/Usq Memory buffer to Destination File
  860. ;
  861. ;    Parm:    BUFF$PT = start of buffer to be written
  862. ;        REC$CNT = # records to write.
  863. ;
  864. ;    Returns  Z if EOFLAG reset,
  865. ;         NZ if     "   set, file closed OK.
  866.  
  867. cuwrite:
  868.     ld    bc,(du$dest)    ; Get destination du
  869.     call    logud        ; And set it up.
  870. cuwrt1:
  871.     ld    hl,(rec$cnt)    ; Buffer empty?
  872.     ld    a,h
  873.     or    l
  874.     jr    z,cuwrt2    ; Buffer empty, check 'eof' flag.
  875.     dec    hl        ; Dec buffer record count for each write
  876.     ld    (rec$cnt),hl
  877.     ld    hl,(buf$pt)    ; Set up dma address
  878.     push    hl        ; Save for size bump
  879.     ex    de,hl        ; Pointer in de
  880.     ld    c,setdma
  881.     call    bdosptr
  882.     pop    hl
  883.     ld    de,128        ; Bump pointer one record length
  884.     add    hl,de
  885.     ld    (buf$pt),hl
  886.     ld    de,d$fcb    ; Destination file 'fcb'
  887.     ld    c,write        ; Write record function
  888.     call    bdosptr
  889.     or    a        ; 00h --> write okay
  890.     jr    z,cuwrt1    ; Okay, do next record.  else..
  891.     ld    hl,msg73    ; "Disk Full"
  892.     call    ermsg2        ; Say disk write error.
  893.     ld    c,close        ; <rdf> - free up disk space
  894.     call    bdosptr
  895.  
  896.  
  897. ; Error in Write -- Delete Destination File and Abort
  898.  
  899. c$era:
  900.     call    resdma        ; Reset dma address.
  901.     ld    de,d$fcb    ; Delete..
  902.     ld    c,erase        ; Partial..
  903.     call    bdosptr        ; From directory.
  904.     ld    bc,(du$req)    ; Source du:
  905.     call    logud        ; Log it in
  906.     jp    cankey        ; Back to ring
  907.  
  908. ; Destination Buffer Written - Check for End
  909.  
  910. cuwrt2:
  911.     ld    a,(eoflag)    ; Buffer all written, check for 'eof'.
  912.     or    a
  913.     ret    z        ; Return to read next buffer full
  914.     ld    de,d$fcb    ; Point at 'fcb' for file closure
  915.     ld    c,close
  916.     call    bdosptr
  917.     inc    a        ; If no-close-error then..
  918.     jr    nz,cuwrt3    ; Copy attributes
  919.     ld    hl,msg74    ; "Close Error"
  920.     call    ermsg2
  921.     jr    c$era
  922.  
  923. ; Copy attributes as required
  924.  
  925. cuwrt3:
  926.      if    datestamp
  927.     ld    a,(gotstp)    ; See if ZSDOS Get Stamp succeeded
  928.     dec    a        ; 1 means ok
  929.     jr    nz,cuwrt3a    ; No
  930.     ld    de,tdbuff    ; Point to stamp
  931.     ld    c,setdma
  932.     call    bdosptr
  933.     ld    de,d$fcb    ; Point to file
  934.     call    initfcb        ; SYSLIB (prepare for SetStp)
  935.     ld    c,setstp
  936.     call    bdosptr
  937. cuwrt3a:
  938.      endif    ;datestamp
  939.  
  940.     ld    a,(tattrfl)    ; Check option to set attributes
  941.     or    a
  942.     jr    z,cuwrt4    ; If not set, skip copying attributes
  943.  
  944.     ld    de,d$fcb+1    ; Pointer to destination file name
  945.     call    restattr    ; Get the saved attributes back
  946.  
  947. cuwrt4:
  948.     ld    a,(tarcfl)    ; Should destination be marked as archived?
  949.     or    a
  950.     jr    z,cuwrt5    ; No
  951.  
  952.     ld    hl,d$fcb+11    ; Point to archive attribute position
  953.     set    7,(hl)        ; Set high bit
  954.     jr    cuwrt6        ; ..and set attributes
  955.  
  956. cuwrt5:
  957.     ld    hl,(attribs)    ; Were any attributes saved?
  958.     ld    a,h
  959.     or    l
  960.     jr    z,cuwrt7    ; No, so skip set
  961. cuwrt6:
  962.     ld    de,d$fcb    ; Set attributes in directory
  963.     ld    c,attr
  964.     call    bdosptr
  965. cuwrt7:
  966.     or    255        ; Flag no error
  967.     ret
  968.  
  969. ; Read Destination File and Compare CRCs
  970.  
  971. crc$cmp:
  972.     ld    hl,(crcval)    ; Transfer 'crc' value to..
  973.     ld    (crcval2),hl    ; New storage area.
  974.     ld    hl,0        ; Clear working storage..
  975.     ld    (crcval),hl    ; To continue.
  976.     call    resdma        ; Reset dma address
  977.     ld    de,d$fcb
  978.     call    initfcb
  979.     ld    c,open
  980.     call    bdosptr
  981.     inc    a        ; 0ffh --> 00h if bad open
  982.     jr    z,badcrc    ; If bad open, just say 'bad-crc'.
  983.     xor    a        ; Zero 'fcb'..
  984.     ld    (d$fcb+32),a    ; 'cr' field.
  985.     ld    hl,msg75    ; "Vfy"
  986.     call    pstri
  987.  
  988. crcwf1:
  989.     ld    de,d$fcb
  990.     ld    c,read
  991.     call    bdosptr
  992.     or    a        ; Read okay?
  993.     jr    z,d$rd$ok    ; Yes, read more.
  994.     dec    a        ; Eof?
  995.     jr    z,fincrc    ; Yes, finish up and make 'crc' comparison.
  996.     ld    hl,msg76    ; "Verify Read Error"
  997.     call    ermsg2
  998.     jp    cankey        ; Wait for keystroke
  999.  
  1000. ; Block Read OK - Update CRC
  1001.  
  1002. d$rd$ok:
  1003.     ld    hl,tbuff
  1004.     ld    b,128
  1005. crcwf2:
  1006.     ld    a,(hl)        ; Get character to..
  1007.     call    updcrc        ; Add to 'crc' value.
  1008.     inc    hl
  1009.     djnz    crcwf2
  1010.     jr    crcwf1
  1011.  
  1012. ; Read Complete - Check CRCs
  1013.  
  1014. fincrc:
  1015.     ld    de,(crcval)    ; Put written-file 'crc' into de
  1016.     ld    hl,(crcval2)    ; Put read-file 'crc' and..
  1017.     call    cmpdehl        ; Compare 'de/hl' for equality.
  1018.     jr    nz,badcrc    ; If not zero, show copy-error message.
  1019.  
  1020. ; Log into Current User Area, Return to caller
  1021.  
  1022. cua$log:
  1023.     call    vprint
  1024.     db    ' OK ',0
  1025.     ld    a,0ffh        ; Show successful copy
  1026.     ld    (cflag),a
  1027.  
  1028.      if    datestamp
  1029.     ld    a,(gotstp)    ; If copied via ZSDOS?
  1030.     dec    a
  1031.     call    nz,copydate    ; No, copy via COPYDATE
  1032.      endif    ;datestamp
  1033.  
  1034.     call    resdma        ; Set default dmaadr
  1035.     ld    bc,(du$req)    ; Get current du
  1036.     jp    logud        ; Set it up, and return to caller.
  1037.  
  1038. ; Error on Copy
  1039.  
  1040. badcrc:
  1041.     call    cua$log        ; Return to current user
  1042.     ld    hl,msg77    ; " -- CRC Error"
  1043.     call    ermsg2
  1044.     jp    cankey
  1045.  
  1046.  
  1047. ; CHKPUB - Check for Public Conflicts
  1048. ;
  1049. ;    Entry: D$FCB holds FCB of opened file
  1050. ;    Exit:    (Z) if no conflict
  1051. ;        Message printed and (NZ) if conflict
  1052. chkpub:
  1053.     ld    ix,d$fcb
  1054.     bit    7,(ix+7)    ; File opened via ZSDOS path/public?
  1055.     ret    z        ; No conflicts
  1056.     ld    hl,msg78    ; "Public File Conflict"
  1057.     call    ermsg2
  1058.     or    0ffh
  1059.     ret
  1060.  
  1061.  
  1062. ; ATTRIB - Check for destination R/O file
  1063. ;
  1064. ; If destination is R/O, prompt for permission to erase it and, if granted,
  1065. ; set the file to R/W.    This routine is called by the C and D functions.
  1066. ;
  1067. ;    Return code:    0FFH (NZ) indicates OK to proceed
  1068. ;            0    (Z)  indicates abort
  1069. ;
  1070. ; Note - now assumes attributes of FCB at HL have been initialized with 
  1071. ;     File Open (copy) or from ring (delete).
  1072. ;
  1073. attrib:
  1074.     push    hl        ; Save d$fcb pointer
  1075.     push    hl
  1076.     pop    ix        ; Copy pointer
  1077.     bit    7,(ix+9)    ; Test file r/o
  1078.     jr    z,attrib1    ; r/w
  1079.  
  1080.     call    erclr        ; Position cursor to error line
  1081.     pop    hl        ; Get the fcb ptr again
  1082.     push    hl        ; And save it again
  1083.     inc    hl        ; Pt to file name
  1084.     call    prfnskip    ; Print file name
  1085.     ld    hl,msg79    ; " is R/O. Erase (Y/N)? "
  1086.     call    pstri        ; And query
  1087.     call    keyin        ; Get response
  1088.     push    af
  1089.     call    erclr        ; Clear error line
  1090.     pop    af
  1091.     cp    ctrlc
  1092.     jp    z,cancel    ; Restart if Control C
  1093.     call    testyn        ; Test for YES/NO answer
  1094.     jr    z,attrib1    ; Proceed if YES
  1095.     pop    hl        ; ..else clean up and
  1096.     xor    a        ; ..return error
  1097.     ret
  1098. ;
  1099. ; Reset all attributes in FCB for Make File.  If file is
  1100. ;    r/o, also reset on disk for Erase.
  1101. ; <rdf> changes
  1102. ;
  1103. attrib1:
  1104. ;    xor    a        ; Clear carry
  1105.     pop    ix        ; Get ptr to d$fcb
  1106.     bit    7,(ix+9)    ; Test r/o again
  1107. ;    jr    z,attrib2
  1108. ;    ccf            ; Set carry if r/o
  1109. attrib2:
  1110.     push    af        ; Save r/o test result <rdf>
  1111.     push    ix
  1112.     pop    hl        ; Get ptr to d$fcb
  1113.     push    hl        ; Save again
  1114.     inc    hl        ; Point to first character
  1115.     ld    b,11        ; 11 Bytes
  1116. attrib3:
  1117.     res    7,(hl)        ; Remove attributes
  1118.     inc    hl        ; Pt to next
  1119.     djnz    attrib3        ; Count down
  1120.     pop    de        ; Pt to d$fcb
  1121.     pop    af        ; Recover r/o test
  1122.     ld    c,attr
  1123. ;    call    c,bdosptr    ; Reset attributes on disk if r/o
  1124.     call    nz,bdosptr
  1125.     or    0ffh        ; No error return
  1126.     ret
  1127.  
  1128.  
  1129. ; SAVE and RESTORE ATTRIBUTES
  1130. ;
  1131. ; These routines save and restore the attributes of a file.  On entry DE
  1132. ; points to the file name in the FCB after the file has been opened so that
  1133. ; the attribute bits are set.
  1134.  
  1135.      if    usedseg
  1136.     dseg
  1137.      endif
  1138.  
  1139. attribs:
  1140.     ds    2            ; Place to keep the attribute bits
  1141.  
  1142.      if    usedseg
  1143.     cseg
  1144.      endif
  1145.  
  1146. saveattr:
  1147.     ld    hl,0            ; Initialize HL
  1148.     ld    b,16            ; Read 16 characters to fill HL
  1149. saveattr1:
  1150.     ld    a,(de)            ; Get character from file name
  1151.     inc    de            ; Point to next one
  1152.     rla                ; Move attribute bit into carry
  1153.     rl    l            ; Move it into L
  1154.     rl    h            ; Move carry from L into H
  1155.     djnz    saveattr1        ; Loop
  1156.     res    6,h            ; Always set dest. to "private"
  1157.     ld    (attribs),hl        ; Save the bits
  1158.     ret
  1159.  
  1160. restattr:
  1161.     ld    hl,(attribs)        ; Get stored attribute bits
  1162.     ex    de,hl            ; Now HL points to name in dest FCB
  1163.     ld    b,11            ; Attributes to copy
  1164. restattr1:
  1165.     xor    a            ; Initialize A
  1166.     rl    e            ; Shift a bit left out of DE into carry
  1167.     rl    d
  1168.     rra                ; Move it into high bit of A
  1169.     or    (hl)            ; Add in file name character
  1170.     ld    (hl),a            ; Put result back
  1171.     inc    hl            ; Point to next character
  1172.     djnz    restattr1        ; Loop
  1173.     ret
  1174.  
  1175.  
  1176. ; COMMAND: 'M' Move files
  1177.  
  1178. move:
  1179.     ld    hl,msg80    ; "Move File"
  1180.     call    ermsg2
  1181.     xor    a
  1182.     ld    (mflag),a    ; Not mass operation
  1183.     ld    (first$m),a    ; Ask destination
  1184.     call    copy
  1185.     ld    a,(cflag)    ; See if copy performed successfully
  1186.     or    a
  1187.     jr    nz,fdel0    ; If so, go delete source
  1188.     call    erclr        ; If not, clear 'Move File' message
  1189.     jp    loop
  1190.  
  1191.  
  1192. ; * * * COMMAND: D
  1193.  
  1194. fdel:
  1195.     xor    a        ; Set no mass operation
  1196.     ld    (mflag),a
  1197.     call    ringfcb        ; Get filename into s$fcb
  1198.     call    delprmpt    ; Prompt for deletion
  1199.     jp    nz,loop        ; If rejected, back to command loop
  1200. fdel0:
  1201.     call    delete        ; Delete file
  1202.  
  1203. ; Was Deletion Done?  Abort if Not
  1204.  
  1205.     ld    a,(delcode)    ; 0=not done
  1206.     or    a
  1207.     jp    z,loop        ; Abort if not
  1208.  
  1209. ; Check for deletion of All local files
  1210.  
  1211.     ld    hl,(locend)    ; Move in end
  1212.     ld    de,-eltsiz
  1213.     add    hl,de
  1214.     ld    de,(locbeg)    ; Erased all local files?
  1215.     call    cmpdehl
  1216.     jr    nz,fdel1    ; No - continue
  1217.     ld    (locend),hl    ; Yes - set new local end.
  1218.     jp    cmdloop        ; Start on first screen again.
  1219.  
  1220. ; Check for deletion with full screen of files remaining.
  1221.  
  1222. fdel1:
  1223.     ld    de,(ringend)    ; Last screen of files?
  1224.     call    cmpdehl
  1225.     jr    nz,fdel4    ; No. redisplay with new last file.
  1226.  
  1227. ; Check for Deletion of last file in ring.
  1228.  
  1229.     push    hl        ; Save new local end.
  1230.     ld    de,(ringpos)    ; Deleted file was last file in ring?
  1231.     call    cmpdehl
  1232.     jr    nz,fdel2    ; No? rebuild shorter display.
  1233.  
  1234. ; Last file in ring deleted - move back one position
  1235.  
  1236.     ld    de,-eltsiz    ; Reset position to new end.
  1237.     add    hl,de
  1238.     ld    (ringpos),hl
  1239.     call    psn$back    ; Back up cursor by one file
  1240.  
  1241. ; Erase file at previous last file position
  1242.  
  1243. fdel2:
  1244.     ld    hl,(curat)    ; Save current cursor position
  1245.     ld    (scurat),hl
  1246.     call    cur$last    ; Position to previous last file.
  1247.  
  1248.     ld    b,entsiz    ; Blank it
  1249.     ld    a,' '
  1250. fdel3:
  1251.     call    cout
  1252.     djnz    fdel3
  1253.  
  1254.     ld    hl,(scurat)    ; Restore current cursor position
  1255.     ld    (curat),hl
  1256.     pop    hl        ; Set new local end.
  1257.     ld    (locend),hl
  1258.  
  1259. ; Redisplay files starting at RINGPOS
  1260.  
  1261. fdel4:
  1262.     call    erclr        ; Clear error message line.
  1263.     jp    runsh5        ; Redisplay current files
  1264.  
  1265.  
  1266. ; DELETE - Delete filename at RINGPOS - entry point for Mass Delete
  1267.  
  1268. delete:
  1269.     xor    a
  1270.     ld    (delcode),a    ; Set deletion not done
  1271.     call    ringfcb        ; Get file name
  1272.     ld    a,(mflag)    ; Mass operation?
  1273.     or    a        ; 0=no
  1274.     jr    z,del1        ; Do delete
  1275.     ld    a,(massop)    ; Mass move?
  1276.     cp    'M'
  1277.     jr    z,del1        ; If so, perform as single delete
  1278.  
  1279. ; Test for Verify on Mass Delete
  1280.  
  1281.     ld    a,(mdflg)    ; Verify?
  1282.     cp    'V'
  1283.     jr    nz,del1        ; Delete without verify
  1284.  
  1285. ; Group Delete with Verify
  1286. ;    - Verify file deletion
  1287. ;    - Delete only if Approved
  1288.  
  1289.     call    delprmpt    ; Prompt for deletion of file
  1290.     ret    nz        ; Abort if not approved
  1291.  
  1292. ; Display File Deletion Message
  1293.  
  1294. del1:
  1295.     ld    hl,msg81    ; "Deleting "
  1296.     call    cprmpt2
  1297.     call    prfns
  1298.  
  1299. ; Delete File in S$FCB
  1300.  
  1301. del2:
  1302.     ld    hl,s$fcb    ; Check file R/W status
  1303.     call    attrib
  1304.     ret    z        ; Abort if R/O and delete not approved
  1305.     ld    de,s$fcb    ; Point at delete 'fcb'
  1306.     ld    c,erase        ; Erase function
  1307.     call    bdosptr
  1308.     inc    a
  1309.     jr    nz,delcl0    ; Branch if delete succeeded
  1310. fnf$msg:
  1311.     call    fnf1        ; Show error message
  1312.     jp    cankey        ; Abort
  1313.  
  1314. delcl0:    ld    a,0ffh
  1315.     ld    (delcode),a    ; Set deletion done
  1316.     ld    a,(mflag)
  1317.     or    a
  1318.     ret    nz        ; If mass operation, quit now
  1319.  
  1320.         ; Close up erased position
  1321.  
  1322.     ld    hl,(ringpos)    ; Prepare move up pointers
  1323.     push    hl
  1324.     ld    de,eltsiz    ; Eltsiz bytes/entry
  1325.     add    hl,de        ; De = 'to' location
  1326.     pop    de        ; Hl = 'from' location
  1327.  
  1328. ;  Move ELTSIZ-byte ring entries from HL to DE
  1329.  
  1330. movup:    ex    de,hl        ; Hl=dest
  1331.     push    hl        ; Check if at end
  1332.     ld    hl,(ringend)    ; Get old end pointer
  1333.     call    cmpdehl        ; Check against current end location
  1334.     pop    hl
  1335.     ex    de,hl        ; De=dest
  1336.     jr    z,movdone    ; Must be at end of ring
  1337.     ld    b,eltsiz    ; One name size
  1338.     call    movec        ; Move one name up
  1339.     jr    movup        ; Go check end parameters
  1340.  
  1341. ;  Move Complete
  1342.  
  1343. movdone:
  1344.     ld    (ringend),de    ; Set new ring end if all moved
  1345.     ld    hl,(ringcnt)    ; One less element in array.
  1346.     dec    hl
  1347.     ld    (ringcnt),hl
  1348.     ret
  1349.  
  1350.  
  1351. ; Prompt for deletion of file
  1352.  
  1353. delprmpt:
  1354.     call    erclr        ; Clear the error line
  1355.     ld    hl,msg82    ; "Delete "
  1356.     call    cprmpt2
  1357.     call    prfns        ; Print file name in s$fcb
  1358.     ld    hl,msgyn    ; ' (Y/N?)?' message
  1359.     call    pstri
  1360.     call    keyin
  1361.     push    af
  1362.     call    atcmd        ; Clear the command line
  1363.     pop    af
  1364.     cp    ctrlc
  1365.     jp    z,cancel    ; Restart if Control C
  1366.     jp    testyn        ; Test for YES/NO and return Z if YES
  1367.  
  1368.  
  1369. ; * * * COMMAND: R
  1370.  
  1371. ; Set-up to rename file at cursor position
  1372. ;    scan keyboard buffer and move filename to destination FCB (DFCB)
  1373.  
  1374. rename:
  1375.     ld    hl,(ringpos)    ; Point to the file in the ring
  1376.     ld    de,9        ; Offset to R/O byte
  1377.     add    hl,de        ; Point to it
  1378.     ld    a,128        ; Set bit 7 of A
  1379.     cp    (hl)        ; Set carry if R/O
  1380.     jr    nc,renam0    ; File is R/W
  1381.  
  1382.     call    atcmd        ; Cursor to command prompt
  1383.     ld    hl,(ringpos)    ; Get ring position
  1384.     inc    hl        ; Point to name
  1385.     call    prfnskip    ; Print file name
  1386.     ld    hl,msg83    ; " is R/O. Rename anyway (Y/N)? "
  1387.     call    pstri
  1388.     call    keyin
  1389.     call    testyn        ; Test for YES/NO answer
  1390.     jr    z,renam0    ; Proceed if YES
  1391.     jp    loop        ; ..else resume
  1392.  
  1393. renam0:
  1394.     call    erclr        ; Clear error line
  1395. renam0a:
  1396.     ld    hl,msg84    ; "Rename File to: "
  1397.     call    cprmpt2        ; New name prompt
  1398.     ld    de,d$fcb    ; Pt to fcb to fill
  1399.     call    filename    ; Get file name & init fcb.
  1400.  
  1401.     ld    hl,d$fcb+1    ; Check for any wild cards -- none permitted
  1402.     ld    b,11        ; 11 bytes
  1403. wildchk:
  1404.     ld    a,(hl)        ; Get char
  1405.     inc    hl        ; Pt to next
  1406.     cp    '?'        ; Wild?
  1407.     jr    z,wildfnd
  1408.     djnz    wildchk
  1409.  
  1410.     ld    de,d$fcb    ; Search to see if this file exists
  1411.     ld    c,srchf        ; Search first function
  1412.     call    bdosptr
  1413.     inc    a        ; 0ffh --> 00h if file not found
  1414.     jr    z,renam1    ; To rename, if duplicate doesn't exist.
  1415.  
  1416. ; File exists - warn user and abort
  1417.  
  1418.     call    chkpub        ; If found via ZSDOS Public, say so
  1419.     jr    nz,renam0a    ; ..and retry
  1420.     ld    hl,msg85    ; "File exists"
  1421.     call    ermsg2        ; File found in current directory
  1422.     jr    renam0a        ; Try again?
  1423.  
  1424. renam1:
  1425.     ld    hl,d$fcb    ; -> file id filled in by filename
  1426.     ld    de,d$fcb+16    ; -> to new file id field of fcb
  1427.     ld    b,12        ; Amount to move
  1428.     call    movec
  1429.  
  1430.     ld    hl,(ringpos)    ; Move old id from ring to rename 'fcb'
  1431.     push    hl
  1432.     ld    de,d$fcb    ; Place to move name
  1433.     push    de
  1434.     ld    b,12        ; Amount to move
  1435.     call    movea        ; Moves name and not attributes
  1436.     pop    de        ; Point to old name
  1437.     pop    ix        ; Point to ring name
  1438.     res    7,(ix+2)    ; Ensure new name Private
  1439.     bit    7,(ix+9)    ; See if old name r/o
  1440.     jr    z,renam1a    ; Not r/o
  1441.  
  1442.     ld    c,attr        ; R/O, so set r/w first
  1443.     push    de
  1444.     call    bdosptr        ; Clear attributes
  1445.     pop    de
  1446. renam1a:
  1447.     ld    c,ren        ; Rename file.
  1448.     call    bdosptr
  1449.  
  1450. ; Copy original drive and attribute settings to new name
  1451.  
  1452.     ld    de,(ringpos)    ; DE points to original file data
  1453.     ld    hl,d$fcb+16    ; HL points to new file data
  1454.     push    de        ; Save pointer for use below
  1455.     ld    b,11        ; Number of chars to scan for attributes
  1456. renam2:
  1457.     inc    hl        ; Advance pointers
  1458.     inc    de
  1459.     ld    a,(de)        ; Get char in original name
  1460.     and    80h        ; Isolate attribute bit
  1461.     or    (hl)        ; Merge with char in new name
  1462.     ld    (hl),a        ; Save result in FCB
  1463.     ld    (de),a        ; ..and in ring
  1464.     djnz    renam2        ; Loop through file name and type
  1465.  
  1466.     pop    ix
  1467.     bit    7,(ix+9)    ; If file was r/w
  1468.      jr    z,renam3    ; ..then attributes preserved on disk
  1469.  
  1470.     ld    de,d$fcb+16    ; Else restore attributes from FCB
  1471.     ld    c,attr
  1472.     call    bdosptr
  1473. renam3:
  1474.     jp    runsh5        ; Quit
  1475.  
  1476. ; Wild char found in file name -- error
  1477.  
  1478. wildfnd:
  1479.     ld    hl,msg86    ; "AFN NOT Allowed"
  1480.     call    ermsg2
  1481.     jp    renam0a        ; Try again
  1482.  
  1483. ; End of ZFCMDS2.Z80
  1484.