home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / UTILS / DIRUTL / DIRDIRS2.LBR / DIR.ZZ0 / DIR.Z80
Text File  |  2000-06-30  |  9KB  |  436 lines

  1. ;------------------------------------------------------------------------------
  2. ;
  3. ;        A simple DIR program (with some extra features)
  4. ;
  5. ;    Written to provide a substitute for the simple DIR and DIRSYS
  6. ;    commands not supported internally by  CCP103+.
  7. ;
  8. ;    dir {du:}{filespec}    or    dirsys {du:}{filespec}
  9. ;
  10. ;    du:     is optional and can be any combination of a valid drive
  11. ;         and/or user number, e.g. 13:, b:, b13:, 13b: or even 1b3:
  12. ;
  13. ;    filespec is also optional and is a standard ambiguous or unambiguous
  14. ;         file name.
  15. ;
  16. ;    Program automatically adjusts directory display to the size of the
  17. ;    host system's console screen.
  18. ;
  19. ;    Create two versions of this program, DIR.COM and DIRSYS.COM (or
  20. ;    DIRS.COM if you prefer the shorter form of the DIRSYS command).
  21. ;    Put the two commands in COMMAND.LBR if you wish, and rename the
  22. ;    standard DIR.COM to something else, e.g. XD.COM.
  23. ;
  24. ;    To create the two versions, alter the byte at label 'dirsys:'
  25. ;    appropriately and reassemble.  Alternatively you may patch the
  26. ;    fourth byte in the object code (103h) to zero for DIR or non-zero
  27. ;    for DIRSYS.
  28. ;
  29. ;    This program can be assembled with either Microsoft's M80 or the
  30. ;    ex-Cromemco public domain ZASM assembler without altering the source
  31. ;    code.  (Note the /z switch and the .z80 extension in the M80 case.)
  32. ;
  33. ;    For    M80/L80 :-        or    ZASM/PROLINK :-
  34. ;
  35. ;        m80 =dir.z80/z            zasm dir.@@z
  36. ;        l80 dir,dir/n/e            pl link dir;exit
  37. ;
  38. ;    Jon Saxton,
  39. ;    P.O. Box 242,
  40. ;    Dural, NSW 2158
  41. ;    Australia
  42. ;
  43. ;------------------------------------------------------------------------------
  44. ;
  45. ; 19 Apr 87 - JRS
  46. ;
  47. ;    Amended to sidestep an occasional weirdness which caused program
  48. ;    to erroneously report "Invalid drive/user".
  49. ;
  50. ;------------------------------------------------------------------------------
  51.  
  52. BS    equ    8
  53. HT    equ    9
  54. CR    equ    13
  55. LF    equ    10
  56.  
  57. BDOS    equ    5
  58.  
  59. CONIN    equ    1
  60. CONOUT    equ    2
  61. PRINT    equ    9
  62. SRCH1ST    equ    17
  63. SRCHNXT    equ    18
  64. GETDRV    equ    25
  65. GSUSER    equ    32
  66. GSSCB    equ    49
  67. PARSEFN    equ    152
  68.  
  69. PAGEMODE equ    2Ch        ;Index of page mode byte in SCB
  70. PAGELEN  equ    1Ch        ;Index of console page length in SCB
  71. CONWIDTH equ    1Ah        ;Index of console width in SCB
  72.  
  73.  
  74. ;begin:                ;Linker inserts jp setStack at the beginning
  75. ;    jp    setStack    ;of the object file (see 'end' statement)
  76.  
  77. dirsys:
  78.     defb    0        ;Set non-0 to display system files
  79. setStack:
  80.     ld    hl,(BDOS+1)    ;Set stack up under the BDOS
  81.     ld    l,0
  82.     ld    sp,hl
  83.     ld    a,(dirsys)    ;Normalise the DIRSYS flag to 0 or 80h
  84.     or    a
  85.     jr    z,getLPS
  86.     ld    a,80h
  87.     ld    (dirsys),a
  88. getLPS:
  89.     ld    de,scbpb    ;Get number of lines on screen
  90.     push    de
  91.     ld    a,PAGELEN
  92.     ld    (de),a
  93.     ld    c,GSSCB
  94.     call    cpm
  95.     dec    a        ;One less to allow for [more] prompt
  96.     ld    (lpp),a
  97.     ld    (lines),a
  98.     pop    de        ;Get console width
  99.     ld    a,CONWIDTH
  100.     ld    (de),a
  101.     ld    c,GSSCB
  102.     call    cpm
  103.     ld    b,8
  104.     ld    c,a
  105.     ld    a,15*8+1
  106. getNPL:                ;Calculate names per line (maximum 8)
  107.     cp    c
  108.     jr    c,setNPL
  109.     sub    15
  110.     djnz    getNPL
  111. setNPL:
  112.     ld    a,b
  113.     ld    (npl),a
  114.     ld    (count),a
  115.  
  116.     xor    a        ;Clear the user number
  117.     ld    ix,du
  118.     ld    (ix+1),a
  119.  
  120.     ld    c,GSUSER    ;Get current user number
  121.     ld    e,0FFh
  122.     call    cpm
  123.     ld    (curUsr),a    ;Store it as default
  124.  
  125.     ld    c,GETDRV    ;Get current disk
  126.     call    cpm
  127.     inc    a
  128.     ld    (ix+0),a    ;Store it as default
  129.  
  130.     ld    hl,80h        ;Look at command-line tail
  131. skipWs:
  132.     inc    hl
  133.     ld    a,(hl)        ;Get a character
  134.     cp    ' '        ;Skip leading white space
  135.     jr    z,skipWs
  136.     cp    HT
  137.     jr    z,skipWs
  138.  
  139.     ld    b,4        ;Colon must be in first 4 characters
  140.     push    hl
  141. findColon:
  142.     ld    a,(hl)        ;Fetch byte from command tail
  143.     or    a
  144.     jr    z,noColon    ;Exit [not found] if end of command tail
  145.     cp    ':'
  146.     jr    z,colon        ;Exit [found]
  147.     inc    hl        ;Step the pointer
  148.     djnz    findColon
  149. noColon:
  150.     inc    a
  151. colon:
  152.     pop    hl        ;Point back at command line
  153.     jr    nz,duDone    ;Skip if there wasn't a colon
  154.  
  155. ;If we get here then there was a colon in the command tail.  We will
  156. ;rescan that part of the command tail preceeding the colon and attempt
  157. ;to extract a drive/user specification.
  158.  
  159. nxtChr:
  160.     ld    a,(hl)        ;Pick up a byte from the command tail
  161.     inc    hl
  162.     cp    ':'        ;Test for colon terminator
  163.     jr    z,duDone    ;Exit if done
  164.     cp    '0'        ;Check for a digit
  165.     jr    c,chkDrv
  166.     cp    '9'+1
  167.     jr    nc,chkDrv
  168.     call    cnvUsr        ;Build user number
  169.     jr    nxtChr
  170. chkDrv:
  171.     cp    'A'        ;Check for A-P
  172.     jr    c,badDU        ;Error if out of range
  173.     cp    'Q'
  174.     jr    nc,badDU
  175.     sub    'A'-1        ;Convert A-P to 1-16
  176.     ld    (ix+0),a
  177.     jr    nxtChr
  178.  
  179. badDU:
  180.     ld    de,invDU
  181. prtXit:
  182.     ld    c,PRINT
  183.     call    cpm
  184.     rst    0
  185. cnvUsr:
  186.     sub    '0'
  187.     ld    c,a
  188.     ld    a,(ix+1)
  189.     add    a,a        ;x2
  190.     add    a,a        ;x4
  191.     add    a,(ix+1)    ;x5
  192.     add    a,a        ;x10
  193.     add    a,c
  194.     ld    (ix+1),a
  195.     ld    a,1
  196.     ld    (gotUsr),a
  197.     ret
  198.  
  199. duDone:
  200.     ld    a,(gotUsr)    ;Did we get user number from command line?
  201.     or    a
  202.     jr    z,noUsr
  203.     ld    a,(ix+1)
  204.     ld    e,a
  205.     ld    (curUsr),a
  206.     ld    c,GSUSER    ;Set user number to match command line
  207.     push    hl
  208.     call    cpm        ;Just a temporary change
  209.     pop    hl
  210. noUsr:
  211.  
  212. ; At this point we are in the correct user area for the DIR command,
  213. ; the byte at DU: holds the required disk drive number (or zero for
  214. ; current drive) and HL points at the beginning of the file spec.
  215.  
  216.     ld    a,(hl)        ;If file specification is empty then
  217.     or    a        ;we leave the default *.* alone
  218.     jr    z,setDrv
  219.  
  220.     ld    (pfcb),hl    ;Let CP/M 3 do all the hard work
  221.     ld    de,pfcb        ;in setting up the FCB for the
  222.     ld    c,PARSEFN    ;directory search
  223.     call    cpm
  224. setDrv:
  225.     ld    a,(ix+0)    ;Pick up drive number
  226.     ld    de,fcb
  227.     ld    (de),a        ;Plug into directory FCB
  228. getDir:
  229.     ld    hl,dirFn
  230.     ld    c,(hl)
  231.     ld    a,SRCHNXT
  232.     ld    (hl),a
  233.     call    cpm        ;Get directory data
  234.     cp    0FFh        ;Test for end
  235.     jr    z,others?
  236.     ld    de,81h        ;Offset to first byte of file name
  237.     rept    5        ;Build pointer to file name
  238.     add    a,a
  239.     endm
  240.     ld    l,a
  241.     ld    h,0
  242.     add    hl,de
  243.     push    hl        ;Save file name pointer
  244.     ld    de,9        ;Offset to T2 byte of file name [SYS|DIR]
  245.     add    hl,de
  246.     ld    a,(dirsys)
  247.     xor    (hl)
  248.     bit    7,a        ;Test if SYS or DIR matches dirsys
  249.     jr    z,printIt
  250.     ld    a,1
  251.     ld    (others),a
  252.     pop    hl
  253.     jr    getDir
  254. printIt:
  255.     ld    hl,npl
  256.     ld    a,(count)    ;Count files displayed on this line
  257.     cp    (hl)        ;At end of line?
  258.     call    z,newLine    ;Yes - start new line, ..
  259.     call    z,putDU        ;.. and print drive/user
  260.     call    nz,fence    ;No - print separator
  261.     inc    a        ;Increment count of files on this line
  262.     ld    (count),a    ;Store count for next time
  263.     pop    hl        ;Recover file name pointer
  264.     call    printFn        ;Display current file name
  265.     ld    a,1        ;Signal that we have displayed some files
  266.     ld    (some),a
  267.     jr    getDir
  268.  
  269. others?:
  270.     ld    a,(others)    ;See if we found ANY files at all
  271.     ld    b,a
  272.     ld    a,(some)
  273.     or    b
  274.     ld    de,noFiles
  275.     jp    z,prtXit    ;Tell user if none
  276.     xor    a
  277.     or    b        ;See if any undisplayed files
  278.     jp    z,0        ;Exit if none
  279.     ld    de,crlf        ;Start a new line
  280.     ld    c,PRINT
  281.     call    cpm
  282.     ld    de,s
  283.     ld    a,(dirsys)
  284.     or    a
  285.     jp    z,prtXit
  286.     ld    de,nonS
  287.     ld    c,PRINT
  288.     call    cpm
  289.     ld    de,ystem
  290.     jp    prtXit
  291.  
  292. newLine:
  293.     ld    a,(some)    ;Is this the first time through?
  294.     or    a
  295.     jr    z,noNL        ;Yes - do nothing
  296.     ld    de,crlf        ;No - start new line
  297.     ld    c,PRINT
  298.     call    cpm
  299.     ld    a,(lines)    ;Count number of lines displayed
  300.     dec    a
  301.     ld    (lines),a
  302.     jr    nz,noNL        ;Skip if not at end of screen
  303.     ld    c,GSSCB        ;Find out if console paging is in effect
  304.     ld    de,scbpb
  305.     ld    a,PAGEMODE
  306.     ld    (de),a
  307.     call    cpm
  308.     or    a
  309.     jr    nz,noNL        ;Skip if not paging
  310.     ld    de,more        ;Display  [more]  prompt
  311.     ld    c,PRINT
  312.     call    cpm
  313.     ld    c,CONIN        ;Wait for a keystroke
  314.     call    cpm
  315.     ld    de,backSpace    ;Backspace over the prompt and response
  316.     ld    c,PRINT
  317.     call    cpm
  318.     ld    a,(lpp)        ;Reset lines per page
  319.     ld    (lines),a
  320. noNL:
  321.     xor    a
  322.     ret
  323.  
  324. fence:                ;Display file name separator
  325.     push    af
  326.     ld    de,separator
  327.     ld    c,PRINT
  328.     call    cpm
  329.     pop    af
  330.     ret
  331.  
  332. printFn:            ;Display file name @HL
  333.     ld    b,8
  334.     call    outStr
  335.     push    hl
  336.     ld    e,'.'
  337.     call    outChr
  338.     pop    hl
  339.     ld    b,3
  340.     call    outStr
  341.     ret
  342.  
  343. outStr:                ;Print string @HL for B bytes
  344.     ld    e,(hl)
  345.     res    7,e
  346.     inc    hl
  347.     push    hl
  348.     push    bc
  349.     call    outChr
  350.     pop    bc
  351.     pop    hl
  352.     djnz    outStr
  353.     ret
  354.  
  355. outChr:                ;Print a single character from E register
  356.     ld    c,CONOUT
  357.     call    cpm
  358.     ret
  359.  
  360. putDU:
  361.     push    af
  362.     call    putDrv
  363.     call    putUsr
  364.     ld    e,':'
  365.     call    outChr
  366.     pop    af
  367.     ret
  368.  
  369. putDrv:                ;Display drive letter
  370.     ld    a,(ix+0)
  371.     add    a,'A'-1
  372.     ld    e,a
  373.     call    outChr
  374.     ret
  375.  
  376. putUsr:
  377.     ld    a,(curUsr)
  378.     cp    10        ;Two digits?
  379.     jr    c,uLow        ;No - just one
  380.     sub    10        ;Yes - output '1' and then the low-order digit
  381.     push    af
  382.     ld    e,'1'
  383.     call    outChr
  384.     pop    af
  385. uLow:
  386.     add    a,'0'
  387.     ld    e,a
  388.     call    outChr
  389.     ret
  390. cpm:
  391.     push    ix
  392.     call    BDOS
  393.     pop    ix
  394.     ret
  395.  
  396. ;----------------------------------------------
  397.  
  398. crlf:    defb    CR,LF,'$'
  399. separator:
  400.     defb    ' | $'
  401. count:    defs    1
  402. lines:    defs    1
  403. lpp:    defs    1
  404. npl:    defs    1
  405. some:    defb    0
  406. others:    defb    0
  407. dirFn:    defb    SRCH1ST
  408. du:    defw    0        ;Drive/user from command line
  409. curUsr:    defs    1        ;Current user number
  410. gotUsr:    defb    0        ;Flag for command-line user number
  411. fcb:    defb    0
  412.     defb    '????????'
  413.     defb    '???'
  414.     defw    0,0,0,0,0,0,0,0,0,0
  415. pfcb:    defw    0
  416.     defw    fcb
  417. scbpb:    defs    1
  418.     defb    0
  419.     defs    2
  420. invDU:    defb    'Illegal drive/user$'
  421. nonS:    defb    'Non-s$'
  422. S:    defb    'S'
  423. ystem:
  424.     defb    'ystem files exist$'
  425. noFiles:
  426.     defb    'No files found$'
  427.  
  428. more:
  429.     defb    '[more] $'
  430. backSpace:
  431.     rept    15
  432.     defb    BS
  433.     endm
  434.     defb    '$'
  435.     end    setStack
  436.