home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / sigm / vol281 / zdir.zq0 / ZDIR.Z80
Encoding:
Text File  |  1986-06-11  |  20.8 KB  |  1,274 lines

  1. ;
  2. ;
  3. ;                  "zdir"
  4. ;
  5. ;              (C)  P.F.Ridler 1982
  6. ;
  7. ;    Last change
  8. ;            29 Apr 84  d.d. blocks fixed
  9. ;             7 Apr 84  directory write flag added?
  10. ;            26 Jan 84  disc size generalised
  11. ;            20 Aug 82  disc name added
  12. ;    Original    10 Aug 82
  13. ;
  14. ;    Licence is freely granted only for non-commercial educational use.
  15. ;
  16. ;
  17. ;******************************************************************************
  18. ;
  19. ;   for NCR DM5 change    "E"  to ":"
  20. ;            "Y"  to "="
  21. ;            "K"  to " "  ???????? 
  22. ;             4   to  2
  23. ;
  24. clrch    equ    'E'    ;clear screen sequence is <esc>,"E"
  25. cposch    equ    'Y'    ;cursor posn  sequence is <esc>,"Y",row+32,col+32
  26. eeolch    equ    'K'    ;eeol sequence is <esc>,"K"
  27. maxdrv    equ    4    ;maximum no of drives in system.
  28. ;
  29. ;******************************************************************************
  30. ;
  31. warm    equ    0000H
  32. bdos    equ    0005H
  33. ;
  34. bel    equ     7
  35. tab    equ     9
  36. lf    equ    10
  37. cr    equ    13
  38. esc    equ    27
  39. ;
  40. ;
  41.     org    100H
  42. ;
  43. ;
  44. newdir    ld    sp,stack
  45.     call    init
  46. newdr1    call    getdrv        ;ask for drive name
  47. newdr2    call    rdvol
  48.     call    rddir
  49.     ld    a,(nnames)
  50.     or    a,a
  51.     jr    z,newdr3
  52.     call    sort
  53.     call    size
  54.     call    disply
  55.     jr    newdr4
  56. newdr3    call    empty
  57. newdr4    call    dspnxt
  58.     db    esc,cposch,23+32,0+32,esc,'K'
  59.     db    'Display, Rename, Erase, Name_disc or Quit => '
  60.     db    0
  61.     call    getch
  62.     and    5FH
  63.     cp    a,'D'        ;display directory
  64.     jr    z,newdr1
  65.     cp    a,'R'
  66.     jr    nz,newdr5    
  67.     call    rename        ;rename a file
  68.     jr    newdr2
  69. newdr5    cp    a,'E'
  70.     jr    nz,newdr6
  71.     call    erase        ;erase a file
  72.     jr    newdr2
  73. newdr6    cp    a,'N'
  74.     jr    nz,newdr7
  75.     call    namvol        ;name a disc volume
  76.     jr    newdr2
  77. newdr7    cp    a,'Q'
  78.     jp    z,exit        ;leave the program
  79.     call    warn
  80.     jr    newdr4
  81. ;
  82. ;
  83. exit    ld    a,(cdrive)    ;restore current drive
  84.     ld    (0004),a
  85.     jp    warm
  86. ;
  87. ;
  88. init    ld    a,(0004)    ;store current drive
  89.     ld    (cdrive),a
  90.     call    dspnxt
  91.     db    esc,clrch,0
  92.     call    dspnxt
  93.     db    esc,cposch,10+32,20+32
  94.     db    'Zimsoft directory utility'
  95.     db    esc,cposch,12+32,23+32
  96.     db    '(C) P.F.Ridler 1984',0
  97.     ret
  98. ;
  99. ;
  100. getdrv    push    af
  101. gtdrv1    call    dspnxt
  102.     db    esc,cposch,23+32,0+32,esc,eeolch
  103.     db    'Directory for which drive?  => '
  104.     db    0
  105.     call    getch        ;get drive letter
  106.     call    lctouc        ;turn into U/C
  107.     sub    a,'A'        ;A=0, B=1 etc
  108.     jr    c,gtdrv2    ;not letter
  109.     cp    a,maxdrv+1    ;see if in range
  110.     jr    c,gtdrv3    ;o.k.
  111. gtdrv2    call    warn        ;not in range
  112.     jr    gtdrv1
  113. gtdrv3    ld    (drive),a    ;select drive
  114.     ld    c,14
  115.     ld    e,a
  116.     call    bdos
  117.     ld    (0004),a    ;make selected drive the current one
  118.                 ;  to get correct dpb
  119.     call    gtdpar        ;get disc parameters
  120.     pop    af
  121.     ret
  122. ;
  123. ;
  124. rdvol    push    af        ;read volume name
  125.     push    hl
  126.     push    de
  127.     push    bc
  128.     call    ntfcb0        ;initialise fcb0
  129.     ld    c,26        ;set transfer address
  130.     ld    de,buffer
  131.     call    bdos
  132.     ld    c,17        ;search for file
  133.     ld    de,fcb0
  134.     call    bdos
  135.     cp    a,255
  136.     jr    nz,rdvol1
  137.     ld    hl,volnam
  138.     ld    (hl),0
  139.     jr    rdvol9
  140. rdvol1    add    a,a
  141.     add    a,a
  142.     add    a,a
  143.     add    a,a
  144.     add    a,a
  145.     ld    e,a
  146.     ld    d,0
  147.     ld    hl,buffer+1
  148.     add    hl,de
  149.     ld    de,volnam    ;transfer name from read buffer
  150.     ld    bc,11
  151.     ldir
  152. rdvol9    pop    bc
  153.     pop    de
  154.     pop    hl
  155.     pop    af
  156.     ret
  157. ;
  158. ;
  159. dspvol    push    af
  160.     push    hl
  161.     ld    hl,volnam    ;volume name
  162. dspvl1    ld    a,(hl)
  163.     inc    hl
  164.     or    a,a        ;name terminator
  165.     jr    z,dspvl2
  166.     call    dspch
  167.     jr    dspvl1
  168. dspvl2    pop    hl
  169.     pop    af
  170.     ret
  171. ;
  172. ;
  173. dspnam    push    af        ;debugging routine
  174.     push    hl
  175.     push    bc
  176.     call    crlf
  177.     ld    b,11
  178.     ld    hl,(dirptr)
  179.     inc    hl
  180. dspnm1    ld    a,(hl)
  181.     inc    hl
  182.     call    dspch
  183.     djnz    dspnm1
  184.     pop    bc
  185.     pop    hl
  186.     pop    af
  187.     ret
  188. ;
  189. ;
  190. ntfcb0    push    af
  191.     push    hl
  192.     push    bc
  193.     ld    a,'?'
  194.     ld    b,12
  195.     ld    hl,fcb0
  196. ntfcb1    ld    (hl),a
  197.     inc    hl
  198.     djnz    ntfcb1
  199.     ld    a,0
  200.     ld    b,24
  201. ntfcb2    ld    (hl),a
  202.     inc    hl
  203.     djnz    ntfcb2
  204.     pop    bc
  205.     pop    hl
  206.     pop    af
  207.     ret
  208. ;
  209. ;
  210. rddir    push    af
  211.     push    hl
  212.     push    de
  213.     push    bc
  214.     ld    hl,0
  215.     ld    (nnames),hl    ;no. of distinct names
  216.     ld    (nentry),hl    ;no. of directory entries
  217.     ld    de,dirbuf    ;start of sort buffer
  218.     ld    (dirptr),de
  219.     ld    ix,buffer    ;buffer for directory read
  220.     ld    c,26        ;set transfer address
  221.     ld    de,buffer    ;directory names
  222.     call    bdos
  223.     ld    c,17        ;search for name
  224.     ld    de,fcb0        ;fcb holds '????????????'
  225.     call    bdos
  226. rddir1    cp    a,255
  227.     jr    z,rddir9
  228.     ld    hl,buffer
  229.     ld    d,0
  230.     add    a,a
  231.     add    a,a
  232.     add    a,a
  233.     add    a,a
  234.     add    a,a
  235.     ld    e,a
  236.     add    hl,de        ;start of name in read buffer
  237.     push    hl
  238.     pop    ix
  239.     ld    a,(ix)        ;buffer[0]=E5 if deleted file
  240.     cp    a,0E5H        ;  if so, discard altogether
  241.     jr    z,rddir8
  242.     ld    a,(ix+12)    ;name[12]<=exm if first entry of name
  243.     ld    b,a
  244.     ld    a,(exm)
  245.     cp    a,b
  246.     jr    nc,rddir3
  247.     ld    (ix),0E4H
  248.     jr    rddir5
  249. rddir3    ld    a,(ix+10)    ;bit 7 of extn char 2 set if "SYS" file
  250.     and    a,80H        ;if so, mark it as well
  251.     jr    z,rddir4
  252.     ld    (ix),0E3H
  253.     jr    rddir5
  254. rddir4    ld    de,(nnames)    ;no. of names to display + 1
  255.     inc    de
  256.     ld    (nnames),de
  257. rddir5    ld    de,(dirptr)    ;fas in name buffer
  258.     ld    bc,32
  259.     ldir            ;transfer name to name buffer
  260.     ld    (dirptr),de
  261.     ld    de,(nentry)
  262.     inc    de
  263.     ld    (nentry),de
  264. rddir8    ld    c,18
  265.     ld    de,fcb0
  266.     call    bdos
  267.     jr    rddir1
  268. rddir9    pop    bc
  269.     pop    de
  270.     pop    hl
  271.     pop    af
  272.     ret
  273. ;
  274. ;
  275. empty    push    af
  276.     call    dspnxt
  277.     db    esc,clrch,esc,cposch,5+32,17+32
  278.     db    'Directory for "'
  279.     db    0
  280.     call    dspvol
  281.     call    dspnxt
  282.     db    '" on drive '
  283.     db    0
  284.     ld    a,(drive)
  285.     add    a,'A'
  286.     call    dspch 
  287.     call    dspnxt
  288.     db    ' empty'
  289.     db    0
  290.     pop    af
  291.     ret
  292. ;
  293. ;
  294. sort    push    af
  295.     push    hl
  296.     push    de
  297.     push    bc
  298.     ld    hl,index    ;set up index[*]
  299.     ld    de,dirbuf
  300.     ld    bc,32
  301.     ld    a,(nentry)    ;{Shell sort of all entries}
  302. sort0    ld    (hl),e        ;for i=0 to nentry-1 do
  303.     inc    hl        ;  index[i]=^name[index[i],0]
  304.     ld    (hl),d
  305.     inc    hl
  306.     ex    de,hl
  307.     add    hl,bc
  308.     ex    de,hl
  309.     dec    a
  310.     jr    nz,sort0
  311.     ld    a,(nentry)    ;  jump=nentry
  312.     ld    e,a
  313. sort11    ld    a,e        ;  while jump>1
  314.     cp    a,2
  315.     jr    c,sort15
  316.     srl    e        ;    jump=jump div 2
  317. sort12    xor    a,a        ;    repeat
  318.     ld    d,a        ;      done=true
  319.     ld    (low),a        ;      low=0
  320.     ld    a,(nentry)    ;      for low=0 to nnames-jump-1
  321.     sub    a,e        ;     {nnames-jump loops}
  322.     ld    b,a
  323. sort13    ld    a,(low)        ;        high=low+jump
  324.     add    a,e
  325.     ld    (high),a
  326.     call    compar        ;        if name[index[high]]<name[
  327.     jr    nc,sort14    ;              index[low]]
  328.     call    swop        ;         swop_indices
  329.     inc    d        ;         done=false
  330. sort14    ld    hl,low        ;       low=low+1
  331.     inc    (hl)
  332.     djnz    sort13
  333.     ld    a,d        ;     until done
  334.     or    a,a
  335.     jr    nz,sort12
  336.     jr    sort11
  337. sort15    pop    bc
  338.     pop    de
  339.     pop    hl
  340.     pop    af
  341.     ret
  342. ;
  343. ;
  344. debug    push    af
  345.     push    de
  346.     push    hl
  347.     ex    de,hl
  348.     call    dspnxt
  349.     db    'No. of blocks=',0
  350.     call    dspval
  351.     call    cont
  352.     pop    hl
  353.     pop    de
  354.     pop    af
  355.     ret
  356. ;
  357. ;
  358. gtdpar    exx
  359.     ld    c,31        ;find no. of non-system blocks
  360.     call    bdos
  361.     inc    hl
  362.     inc    hl
  363.     ld    a,(hl)        ;BSH
  364.     ld    (bsh),a        ;right shift to turn records into blocks
  365.     dec    a
  366.     dec    a
  367.     dec    a
  368.     ld    (kperbl),a
  369.     inc    hl
  370.     ld    a,(hl)        ;BLM
  371.     ld    (blm),a
  372.     inc    hl
  373.     ld    a,(hl)        ;***** EXM
  374.     ld    (exm),a        ;*****
  375.     inc    hl        ;HL<=^DSM
  376.     ld    e,(hl)
  377.     inc    hl
  378.     ld    d,(hl)
  379.     inc    hl
  380.     inc    de        ;DE<=no. of non-system blocks
  381.     ld    c,(hl)
  382.     inc    hl
  383.     ld    b,(hl)
  384.     inc    hl
  385.     ld    (drm),bc    ;max. no. of directory entries-1
  386.     ld    c,2        ;subtract directory blocks
  387. gtdpr1    ld    b,8
  388.     ld    a,(hl)        ;"all00" then "all01"
  389.     inc    hl
  390. gtdpr2    rlca            ;count bits set
  391.     jr    nc,gtdpr3
  392.     dec    de        ;subtract one block for each
  393. gtdpr3    djnz    gtdpr2
  394.     dec    c        ;get "all01"
  395.     jr    nz,gtdpr1
  396.     ld    (blocks),de
  397.     ld    a,(exm)
  398.     or    a,a
  399.     jr    z,gtdpr5
  400.     ld    b,a
  401.     xor    a,a
  402. gtdpr4    scf
  403.     rla
  404.     djnz    gtdpr4
  405. gtdpr5    ld    (extmsk),a
  406.     exx
  407.     ret
  408. ;
  409. ;
  410. size    push    af
  411.     push    hl
  412.     push    de
  413.     push    bc
  414.     ld    hl,(blocks)    ;no. of blocks left
  415.     ld    (left),hl
  416.     ld    a,(nnames)
  417.     ld    b,a
  418.     ld    a,(nentry)
  419.     sub    a,b
  420.     ld    (temp1),a
  421.     ld    hl,00        ;for ndx=0 to nnames-1 do
  422. size1    xor    a,a        ;  size=0
  423.     ld    (nblcks),a
  424.     call    indexi        ;  size=size+(name[index[ndx],15]+7) div 8
  425.     ld    (ndxndx),de
  426.     call    getsiz
  427.     push    hl
  428.     push    bc
  429.     ld    a,(temp1)    ;  for i=nnames to nentry-1 do
  430.     or    a,a
  431.     jr    z,size4
  432.     ld    b,a
  433.     ld    hl,(nnames)
  434. size2    call    indexi
  435.     call    same        ;    if name[index[i],*]=name[index[ndx],*]
  436.     jr    nz,size3    ;      size=size+name[index[i],15]+7) div 8
  437.     call    getsiz
  438. size3    inc    hl
  439.     djnz    size2
  440. size4    ld    a,(nblcks)    ;  name[index[ndx],13]=size
  441.     ld    ix,(ndxndx)
  442.     ld    (ix+13),a
  443.     ld    c,a
  444.     ld    hl,(left)    ;  left=left-size
  445.     ld    b,0
  446.     or    a,a
  447.     sbc    hl,bc
  448.     ld    (left),hl    ;remember to turn this into k later
  449.     pop    bc
  450.     pop    hl
  451.     inc    hl
  452.     djnz    size1
  453.     pop    bc
  454.     pop    de
  455.     pop    hl
  456.     pop    af
  457.     ret
  458. ;
  459. ;
  460. erase    call    dspnxt
  461.     db    cr,lf,lf,'Erase which file? => ',0
  462.     call    getbuf
  463.     ld    de,fcb1
  464.     call    makfcb
  465.     jr    z,erase2        ;invalid filename
  466.     call    exists
  467.     jr    z,erase1
  468.     call    dspnxt
  469.     db    cr,lf,lf,'Erase  ',0
  470.     call    dspbuf
  471.     call    dspnxt
  472.     db    '? (y/n) ',0
  473.     call    getch
  474.     cp    'Y'
  475.     jr    nz,erase3
  476.     ld    a,(stars)
  477.     cp    11H
  478.     jr    nz,eras05
  479.     call    dspnxt
  480.     db    '  EVERYTHING',0
  481.     call    dspnxt
  482.     db    '? (y/n) ',0
  483.     call    getch
  484.     cp    'Y'
  485.     jr    nz,erase3
  486. eras05    exx
  487.     ld    de,fcb1
  488.     ld    c,19            ;delete a file
  489.     call    bdos
  490.     exx
  491.     jr    erase3
  492. erase1    call    warn            ;filename not in directory
  493.     call    crlf
  494.     call    dspbuf
  495.     call    dspnxt
  496.     db    ' doesn''t exist',0
  497. erase2    call    cont
  498. erase3    ret
  499. ;
  500. ;
  501. rename    call    dspnxt
  502.     db    cr,lf,lf,'Original name? => ',0
  503.     call    getbuf
  504.     ld    de,fcb1
  505.     call    makfcb
  506.     jr    z,renam2
  507.     ld    a,(stars)
  508.     or    a
  509.     jr    nz,renm25
  510.     call    exists
  511.     jr    z,renam2
  512.     call    dspnxt
  513.     db    cr,lf,lf,'New name? => ',0
  514.     call    getbuf
  515.     ld    de,fcb2
  516.     call    makfcb
  517.     jr    z,renam2
  518.     ld    a,(stars)
  519.     or    a
  520.     jr    nz,renm25
  521.     call    exists
  522.     jr    nz,renm27
  523.     jp    renam3
  524. renam2    call    warn
  525.     call    crlf
  526.     call    dspbuf
  527.     call    dspnxt
  528.     db    '  doesn''t exist',0
  529.     jr    renm29
  530. renm25    call    warn
  531.     call    crlf
  532.     call    dspbuf
  533.     call    dspnxt
  534.     db    '  is ambiguous',0
  535.     jr    renm29
  536. renm27    call    warn
  537.     call    crlf
  538.     call    dspbuf
  539.     call    dspnxt
  540.     db    '  already exists',0
  541. renm29    call    cont
  542.     jr    renam4
  543. renam3    ld    de,fcb1
  544.     ld    c,23        ;rename it
  545.     call    bdos
  546. renam4    ret
  547. ;
  548. ;
  549. namvol    push    af
  550.     exx
  551.     call    dspnxt
  552.     db    cr,lf,lf,'Present disc name is "',0
  553.     call    dspvol
  554.     call    dspnxt
  555.     db    '"  Change? (y/n) ',0
  556.     call    getch
  557.     and    a,5FH
  558.     cp    a,'Y'
  559.     jr    nz,namvl9
  560.     ld    de,fcb1
  561.     ld    a,0
  562.     ld    (de),a
  563.     inc    de
  564.     ld    hl,volnam
  565.     ld    bc,11
  566.     ldir
  567.     ld    b,4
  568. namvl1    ld    (hl),a
  569.     inc    hl
  570.     djnz    namvl1
  571.     call    dspnxt
  572.     db    cr,lf,lf,'New name? ',0
  573.     call    getbuf
  574.     ld    de,fcb2
  575.     call    makfcb
  576.     ld    c,23
  577.     ld    de,fcb1
  578.     call    bdos
  579.     ld    hl,fcb2
  580.     ld    de,fcb1
  581.     ld    bc,12
  582.     ldir
  583.     ld    a,0
  584.     ld    b,22
  585. namvl2    ld    (hl),a
  586.     inc    hl
  587.     djnz    namvl2
  588.     ld    hl,fcb1+10
  589.     ld    a,(hl)
  590.     or     a,80H
  591.     ld    (hl),a
  592.     ld    c,30        ;set up as "sys" file
  593.     ld    de,fcb1
  594.     call    bdos
  595. namvl9    exx
  596.     pop    af
  597.     ret
  598. ;
  599. ;
  600. blktok    push    af
  601.     ld    a,(kperbl)
  602.     or    a,a
  603.     jr    z,blktk2
  604. blktk1    sla    l
  605.     rl    h
  606.     dec    a
  607.     jr    nz,blktk1
  608. blktk2    pop    af
  609.     ret
  610. ;
  611. ;
  612. disply    push    af
  613.     push    hl
  614.     call    dspnxt
  615.     db    esc,clrch,esc,cposch,2+32,21+32
  616.     db    'Directory for "',0
  617.     call    dspvol
  618.     call    dspnxt
  619.     db    '" on drive ',0
  620.     ld    a,(drive)
  621.     add    a,'A'
  622.     call    dspch
  623.     call    crlf
  624.     call    crlf
  625.     ld    a,(nnames)    ; diff=(nnames+3) div 4
  626.     add    a,3
  627.     srl    a
  628.     srl    a
  629.     ld    (diff),a
  630.     xor    a,a        ; count=0
  631.     ld    (count),a
  632.     ld    (row),a        ; row=0
  633.     ld    (ndx),a        ; ndx=row
  634.     ld    (nrow),a    ; nrow=0
  635. dsply1    ld    a,(ndx)        ; repeat
  636.     ld    hl,nnames    ;   if ndx<nnames then begin
  637.     cp    a,(hl)
  638.     jp    p,dsply0
  639.     call    wrtnam        ;     write(name[index[ndx]])
  640.     ld    hl,count    ;     count=count+1
  641.     inc    (hl)
  642.     ld    a,(nrow)    ;     nrow=nrow+1
  643.     inc    a
  644.     ld    (nrow),a    ;     if (nrow=4)or(ndx>=nnames) then begin
  645.     cp    a,4
  646.     jr    nz,dsply2
  647. dsply0    call    crlf        ;       writeln
  648.     ld    a,(row)        ;       row=row+1
  649.     inc    a
  650.     ld    (row),a
  651.     ld    (ndx),a        ;       ndx=row
  652.     xor    a,a        ;       nrow=0 end
  653.     ld    (nrow),a
  654.     jr    dsply3
  655. dsply2    call    dspnxt        ;     else begin
  656.     db    '  |  ',0    ;       write(' |  ')
  657.     ld    a,(ndx)        ;       ndx=ndx+diff end end
  658.     ld    hl,diff
  659.     add    a,(hl)
  660.     ld    (ndx),a
  661. dsply3    ld    a,(count)    ;   until count=nnames
  662.     ld    hl,nnames
  663.     cp    a,(hl)
  664.     jr    nz,dsply1
  665.     call    dspnxt
  666.     db    cr,lf,lf,'Space left = ',0
  667.     ld    hl,(left)
  668.     call    blktok
  669.     call    dspval
  670.     ld    a,'k'
  671.     call    dspch
  672.     pop    hl
  673.     pop    af
  674.     ret
  675. ;
  676. ;
  677. seldrv    exx            ;select the disc drive
  678.     ld    c,14
  679.     ld    a,(drive)
  680.     ld    e,a
  681.     call    bdos
  682.     exx
  683.     ret
  684. ;
  685. ;
  686. getch    exx            ;get a character from the keyboard
  687.     ld    c,1        ;  and return the U/C version
  688.     call    bdos
  689.     call    lctouc
  690.     exx
  691.     ret
  692. ;
  693. ;
  694. lctouc    cp    a,'a'
  695.     ret    c
  696.     cp    a,'z'+1
  697.     ret    nc
  698.     sub    a,20H
  699.     ret
  700. ;
  701. ;
  702. getbuf    exx
  703.     ld    de,inbuff
  704.     ld    c,10
  705.     call    bdos
  706.     ld    a,(inbuff+1)    ;character count
  707.     ld    b,a
  708.     ld    hl,inbuff+1    ;start of buffer
  709. getbf1    inc    hl        ;turn buffer into u/c
  710.     ld    a,(hl)
  711.     call    lctouc
  712.     ld    (hl),a
  713.     djnz    getbf1    
  714.     exx
  715.     ret
  716. ;
  717. ;
  718. dspch    push    af        ;send a character to the console
  719.     exx
  720.     ld    e,a
  721.     ld    c,2
  722.     call    bdos
  723.     exx
  724.     pop    af
  725.     ret
  726. ;
  727. ;
  728. dspnxt    ex    (sp),hl
  729.     push    af
  730. dspnx1    ld    a,(hl)
  731.     inc    hl
  732.     or    a,a
  733.     jr    z,dspnx2
  734.     call    dspch
  735.     jr    dspnx1
  736. dspnx2    pop    af
  737.     ex    (sp),hl
  738.     ret
  739. ;
  740. ;
  741. dspbuf    push    af
  742.     push    hl
  743.     push    de
  744.     push    bc
  745.     ld    a,(inbuff+1)
  746.     or    a
  747.     jr    z,dspb3
  748.     ld    b,a
  749.     ld    hl,inbuff+2
  750. dspb1    ld    a,(hl)
  751.     inc    hl
  752.     cp    ' '
  753.     jr    nc,dspb2
  754.     ld    a,'_'
  755. dspb2    call    dspch
  756.     djnz    dspb1
  757. dspb3    pop    bc
  758.     pop    de
  759.     pop    hl
  760.     pop    af
  761.     ret
  762. ;
  763. ;
  764. cont    push    af
  765.     call    dspnxt
  766.     db    cr,lf,'Press < > to continue',0
  767.     call    getch
  768.     pop    af
  769.     ret
  770. ;
  771. ;
  772. warn    push    af
  773.     ld    a,bel
  774.     call    dspch
  775.     pop    af
  776.     ret
  777. ;
  778. ;
  779. crlf    call    dspnxt
  780.     db    cr,lf,0
  781.     ret
  782. ;
  783. ;
  784. space    push    af
  785.     ld    a,' '
  786.     call    dspch
  787.     pop    af
  788.     ret
  789. ;
  790. ;
  791. getsiz    push    af
  792.     push    hl
  793.     push    de
  794.     push    bc
  795.     push    de
  796.     pop    ix
  797.     ld    a,(ix+12)    ;<ex>
  798.     ld    b,a
  799.     ld    a,(extmsk)
  800.     and    a,b        ;records in extent=<ex> mod (EXM+1)
  801.     ld    h,a        ;*256
  802.     ld    l,0
  803.     srl    h        ;/2
  804.     rr    l        ;128*[<ex> mod (EXM+1)]
  805.     ld    e,(ix+15)    ;+record count <rc>
  806.     ld    d,0
  807.     add    hl,de
  808.     ld    de,(blm)    ;+BLM
  809.     add    hl,de        ;total no. of records in entry
  810.     ld    a,(bsh)
  811.     ld    b,a
  812. getsz1    srl    h        ;records div 2**BSH
  813.     rr    l
  814.     djnz    getsz1
  815.     ld    de,(nblcks)
  816.     add    hl,de
  817.     ld    (nblcks),hl
  818.     pop    bc
  819.     pop    de
  820.     pop    hl
  821.     pop    af
  822.     ret
  823. ;
  824. ;
  825. same    push    hl        ;if name[index[high]=name[index[low]]
  826.     push    de        ;  returns Z set
  827.     push    bc
  828.     ld    hl,(ndxndx)
  829.     ld    b,11        ;compare name, type
  830. same1    inc    hl
  831.     inc    de
  832.     ld    a,(de)
  833.     cp    a,(hl)
  834.     jr    nz,same2
  835.     djnz    same1
  836. same2    pop    bc
  837.     pop    de
  838.     pop    hl
  839.     ret
  840. ;
  841. ;
  842. compar    push    hl        ;if name[index[high]<name[index[low]]
  843.     push    de        ;  returns carry set
  844.     push    bc
  845.     ld    hl,(low)    ;^name[index[low]]
  846.     call    indexi        
  847.     push    de
  848.     ld    hl,(high)    ;^name[index[high]]
  849.     call    indexi
  850.     pop    hl        ;^name[index[low]]
  851.     ld    b,13        ;compare 13 bytes."dr,name,typ,ext"
  852. compr1    ld    a,(de)        ;high
  853.     cp    a,(hl)
  854.     jr    c,compr2    ;high<low
  855.     jr    nz,compr2    ;high>low
  856.     inc    hl
  857.     inc    de
  858.     djnz    compr1
  859. compr2    pop    bc
  860.     pop    de
  861.     pop    hl
  862.     ret
  863. ;
  864. ;
  865. swop    push    af
  866.     push    hl
  867.     push    de
  868.     push    bc
  869.     ld    hl,(low)    ;temp1=index[low]
  870.     call    indexi
  871.     ld    (temp1),de
  872.     ld    hl,(high)    ;temp2=index[high]
  873.     call    indexi
  874.     ld    (temp2),de
  875.     ld    hl,(high)    ;index[high]=temp1
  876.     add    hl,hl
  877.     ld    bc,index
  878.     add    hl,bc
  879.     ld    de,(temp1)
  880.     ld    (hl),e
  881.     inc    hl
  882.     ld    (hl),d
  883.     ld    hl,(low)    ;index[low]=temp2
  884.     add    hl,hl
  885.     ld    bc,index
  886.     add    hl,bc
  887.     ld    de,(temp2)
  888.     ld    (hl),e
  889.     inc    hl
  890.     ld    (hl),d
  891.     pop    bc
  892.     pop    de
  893.     pop    hl
  894.     pop    af
  895.     ret    
  896. ;
  897. ;
  898. indexi    push    af
  899.     push    hl        ;given HL=i returns DE=index[i]
  900.     push    bc
  901.     add    hl,hl        ;^index[i]
  902.     ld    bc,index
  903.     add    hl,bc
  904.     ld    e,(hl)        ;^name[index[i]]
  905.     inc    hl
  906.     ld    d,(hl)
  907.     pop    bc
  908.     pop    hl
  909.     pop    af
  910.     ret
  911. ;
  912. ;
  913. fillch    ld    (de),a
  914.     inc    de
  915.     djnz    fillch
  916.     ret
  917. ;
  918. ;
  919. makfcb    ;makes a file control block at (DE)
  920.     ;
  921.     push    hl        ;save registers
  922.     push    de
  923.     push    bc        ;squeeze out any blanks in filename
  924.     ld    (fcbx),de    ;address of pseudo fcb
  925.     ld    hl,9
  926.     add    hl,de
  927.     ld    (fcbxx),hl    ;address of extension    
  928.     xor    a
  929.     ld    (stars),a    ;position of '*' in name and extension
  930.     ld    (ndots),a    ;number of '.'s in filename
  931.     ld    (lextn),a    ;assumed
  932.     ld    a,' '        ;initialise fcb[0..11]=' '
  933.     ld    b,12        ;           fcb[12..15]=0
  934. mkfc01    ld    (de),a
  935.     inc    de
  936.     djnz    mkfc01
  937.     ld    a,0
  938.     ld    b,4
  939. mkfc02    ld    (de),a
  940.     inc    de
  941.     djnz    mkfc02
  942.     ld    a,(inbuff+1)    ;character count for 'inbuff'
  943.     or    a
  944.     jp    z,mkfc13    ;error if name is null
  945.     ld    hl,inbuff+2    ;source pointer
  946.     ld    de,inbuff+2    ;destination pointer
  947.     ld    c,0        ;new character count
  948.     ld    b,a
  949. mkfcb1    ld    a,(hl)        ;get a character
  950.     inc    hl
  951.     cp    ' '
  952.     jr    z,mkfcb2
  953.     call    valid        ;returns Z set if invalid character
  954.     jp    z,mkfc13
  955.     ld    (de),a
  956.     inc    de
  957.     inc    c
  958. mkfcb2    djnz    mkfcb1
  959.     ld    a,c        ;put new character count into buffer
  960.     ld    (inbuff+1),a
  961.     ld    (lname),a    ;assuming no extension
  962.     xor    a,a        ;put a null at the end in case length=1
  963.     ld    (de),a
  964.     ld    a,c        ;new character count
  965.     or    a
  966.     jp    z,mkfc13    ;error if name was all spaces
  967.     ld    de,(fcbx)    ;destination pointer
  968.     ld    a,(drive)    ;get drive number and
  969.     inc    a
  970.     ld    (de),a        ;put it into fcb[0])
  971.     ld    hl,inbuff+3
  972.     ld    a,(hl)        ;look at 2nd character in buffer
  973.     cp    ':'
  974.     jr    nz,mkfcb3
  975.     dec    c        ;shift name left 2 characters
  976.     dec    c        ;alter character count
  977.     jp    z,mkfc13    ;no name if count now zero
  978.     ld    a,c
  979.     ld    (inbuff+1),a    ;new character count
  980.     ld    (lname),a    ;assuming no '.'
  981.     ld    hl,inbuff+4    ;source address
  982.     ld    de,inbuff+2    ;destination address
  983.     ld    b,0        ;for LDIR
  984.     ldir
  985. mkfcb3    ld    a,(lname)    ;get length of 'name'
  986.     ld    b,a
  987.     ld    d,0        ;counts length of name
  988.     ld    hl,inbuff+2    ;start of name
  989. mkfcb4    ld    a,(hl)
  990.     inc    hl
  991.     inc    d
  992.     cp    '.'        ;look for '.'
  993.     jr    nz,mkfcb5
  994.     ld    a,(ndots)    ;see how many we've had
  995.     cp    1
  996.     jp    z,mkfc13    ;shouldn't have more than one '.'
  997.     inc    a        ;count them
  998.     ld    (ndots),a
  999.     ld    a,d        ;length of name part
  1000.     dec    a        ;allow for '.'
  1001.     ld    (lname),a
  1002.     ld    e,a
  1003.     ld    a,(inbuff+1)
  1004.     sub    a,e
  1005.     dec    a        ;for '.'
  1006.     ld    (lextn),a    ;length of extension
  1007. mkfcb5    djnz    mkfcb4
  1008.     ld    a,(lname)    ;now check the lengths
  1009.     cp    8+1
  1010.     jp    nc,mkfc13
  1011.     ld    a,(lextn)
  1012.     cp    3+1
  1013.     jp    nc,mkfc13
  1014.     ld    hl,inbuff+2    ;see if there are any '*'s
  1015.     ld    b,c
  1016.     ld    d,0        ;position in filename
  1017. mkfcb6    ld    a,(hl)
  1018.     inc    hl
  1019.     inc    d
  1020.     cp    '*'
  1021.     jr    nz,mkfcb8
  1022.     ld    a,(lname)    ;see if we're in name or extension
  1023.     cp    d
  1024.     jr    c,mkfcb7
  1025.     ld    a,(lname)    ;in name. See if length is 1
  1026.     cp    1
  1027.     jp    nz,mkfc13    ;if not then it's an error
  1028.     ld    a,10H        ;if so set flag to 10H
  1029.     ld    (stars),a
  1030.     jr    mkfcb8            
  1031. mkfcb7    ld    a,(lextn)    ;we're in extension. see if length is 1
  1032.     cp    1
  1033.     jp    nz,mkfc13    ;if not then it's an error
  1034.     ld    a,(stars)    ;if so, add 01H to flag
  1035.     or    01H
  1036.     ld    (stars),a
  1037. mkfcb8    djnz    mkfcb6
  1038.     ld    hl,inbuff+2    ;now make up the fcb        
  1039.     ld    de,(fcbx)
  1040.     inc    de        ;allow for drive number
  1041.     ld    a,(stars)    ;look at '*' flags to see how to make up name
  1042.     and    10H        ;if (stars) is 1X then put in 7 '?'
  1043.     jr    z,mkfcb9
  1044.     ld    a,'?'
  1045.     ld    b,8
  1046.     call    fillch
  1047.     inc    hl        ;skip the '.' following
  1048.     jr    mkfc10
  1049. mkfcb9    ld    b,0        ;else transfer name from 'inbuff'
  1050.     ld    a,(lname)
  1051.     ld    c,a
  1052.     ldir
  1053. mkfc10    ld    a,(lextn)    ;see if extension exists
  1054.     or    a
  1055.     jr    z,mkfc14    ;no extension    
  1056.     inc    hl        ;skip '.' in name
  1057.     ld    de,(fcbxx)    ;pointer to extension
  1058.     ld    a,(stars)
  1059.     and    01H        ;if (stars) is X1 then put in 3 '?'
  1060.     jr    z,mkfc11    ;else transfer extension from 'inbuff'
  1061.     ld    a,'?'
  1062.     ld    b,3
  1063.     call    fillch
  1064.     jr    mkfc14
  1065. mkfc11    ld    b,0
  1066.     ld    a,(lextn)
  1067.     ld    c,a
  1068.     ldir
  1069.     jr    mkfc14        ;all done
  1070. mkfc13    call    crlf
  1071.     call    dspnxt
  1072.     db    cr,lf,'Invalid filename',cr,lf,0
  1073.     xor    a,a        ;return with Z set if error
  1074.     jr    mkfc15
  1075. mkfc14    xor    a
  1076.     inc    a
  1077. mkfc15    pop    bc
  1078.     pop    de
  1079.     pop    hl
  1080.     ret     
  1081. ;
  1082. ;
  1083. valid    cp    ','        ;returns Z set if A has valid character
  1084.     ret    z
  1085.     cp    ':'
  1086.     ret    z
  1087.     cp    ';'
  1088.     ret    z
  1089.     cp    '<'
  1090.     ret    z
  1091.     cp    '='
  1092.     ret    z
  1093.     cp    '>'
  1094.     ret    z
  1095.     cp    '['
  1096.     ret    z
  1097.     cp    ']'
  1098.     ret
  1099. ;
  1100. ;
  1101. exists    ;DE points to a pseudo fcb
  1102.     ;return Z set if error
  1103.     ;
  1104.     push    de
  1105.     exx
  1106.     pop    de
  1107.     ld    c,17        ;search for filename
  1108.     call    bdos
  1109.     cp    0FFH
  1110.     exx
  1111.     ret
  1112. ;
  1113. ;
  1114. wrtnam    push    af        ;write(name[index[ndx,*]])
  1115.     push    hl
  1116.     push    de
  1117.     push    bc
  1118.     ld    hl,(ndx)    ;^index[ndx]
  1119.     add    hl,hl
  1120.     ld    de,index
  1121.     add    hl,de
  1122.     ld    e,(hl)        ;name[index[ndx]]
  1123.     inc    hl
  1124.     ld    d,(hl)
  1125.     ex    de,hl
  1126.     inc    hl        ;skip "dr"
  1127.     ld    b,8
  1128. wrtnm1    ld    a,(hl)        ;name[index[ndx],i]
  1129.     inc    hl
  1130.     call    dspch
  1131.     djnz    wrtnm1
  1132.     ld    a,' '
  1133.     call    dspch
  1134.     ld    b,3        ;type
  1135. wrtnm2    ld    a,(hl)
  1136.     inc    hl
  1137.     call    dspch
  1138.     djnz    wrtnm2
  1139.     inc    hl        ;^length in blocks
  1140.     ld    l,(hl)
  1141.     ld    h,0
  1142.     call    blktok
  1143.     call    space
  1144.     call    dspval
  1145.     pop    bc
  1146.     pop    de
  1147.     pop    hl
  1148.     pop    af
  1149.     ret
  1150. ;
  1151. ;
  1152. dspval    push    af        ;display the 3-digit decimal value of 
  1153.     push    hl        ;  binary in HL
  1154.     push    de
  1155.     push    bc
  1156.     xor    a,a
  1157.     ld    (temp1),a    ;leading zero flag
  1158.     ld    c,a
  1159.     ld    de,100
  1160. dspv1    inc    c
  1161.     or    a,a
  1162.     sbc    hl,de
  1163.     jp    p,dspv1
  1164.     add    hl,de        ;restore
  1165.     dec    c
  1166.     jr    nz,dspv2
  1167.     call    space
  1168.     jr    dspv3
  1169. dspv2    ld    a,'0'
  1170.     add    a,c
  1171.     call    dspch
  1172.     ld    (temp1),a
  1173. dspv3    ld    c,0
  1174.     ld    de,10
  1175. dspv4    inc    c
  1176.     or    a,a
  1177.     sbc    hl,de
  1178.     jp    p,dspv4
  1179.     add    hl,de
  1180.     dec    c
  1181.     jr    nz,dspv5
  1182.     ld    a,(temp1)
  1183.     or    a,a
  1184.     jr    nz,dspv5
  1185.     call    space
  1186.     jr    dspv6
  1187. dspv5    ld    a,'0'
  1188.     add    a,c
  1189.     call    dspch
  1190. dspv6    ld    c,0
  1191.     ld    de,1
  1192. dspv7    inc    c
  1193.     or    a,a
  1194.     sbc    hl,de
  1195.     jp    p,dspv7
  1196.     dec    c
  1197.     ld    a,'0'
  1198.     add    a,c
  1199.     call    dspch
  1200.     pop    bc
  1201.     pop    de
  1202.     pop    hl
  1203.     pop    af
  1204.     ret
  1205. ;
  1206. ;
  1207. dspbyt    push    af
  1208.     push    bc
  1209.     ld    b,8
  1210.     ld    c,a
  1211. dspbt1    rl    c
  1212.     ld    a,'0'
  1213.     jr    nc,dspbt2
  1214.     ld    a,'1'
  1215. dspbt2    call    dspch
  1216.     djnz    dspbt1
  1217.     pop    bc
  1218.     pop    af
  1219.     ret
  1220. ;
  1221. ;
  1222. cdrive    ds    2        ;store for current drive
  1223. drive    dw    0        ;A=0, B=1 etc.
  1224. track    dw    0        ;track number
  1225. psect    dw    0        ;physical sector number
  1226. lsect    dw    0        ;logical setor number
  1227. secmap    dw    0
  1228. vlnmm2    db     16        ;buffer size
  1229. vlnmm1    db    0        ;char count
  1230. volnam    ds     12        ;volume name
  1231. buffer    ds    128
  1232. nnames    dw    0        ;no. of distinct directory names
  1233. nentry    dw    0        ;total no. of directory entries
  1234. bsh    dw      0        ;log2(block size/record size)
  1235. blm    dw     0        ;(block size/record size) -1
  1236. exm    dw    0        ;extents/directory entry -1
  1237. extmsk    dw    0
  1238. dsm    dw    0
  1239. drm    dw    0
  1240. kperbl    dw    0
  1241. blocks    dw    0
  1242. nblcks    dw    0
  1243. left    dw    0
  1244. row    dw    0
  1245. diff    dw    0
  1246. count    dw    0
  1247. ndx    dw    0
  1248. ndxndx    dw    0
  1249. nrow    dw    0
  1250. low    dw    0
  1251. high    dw    0
  1252. temp1    dw    0
  1253. temp2    dw    0
  1254. ;
  1255. inbuff    db    48
  1256.     ds    41
  1257. ndots    ds    1
  1258. stars    ds    1
  1259. lname    ds    1
  1260. lextn    ds    1
  1261. fcbx    ds    2
  1262. fcbxx    ds    2
  1263. fcb1    ds    16
  1264. fcb2    ds    16
  1265.     ds    4
  1266. fcb0    db    36
  1267. index    ds    128
  1268.     ds    100
  1269. stack    equ    $
  1270. dirptr    ds    2    ;dw 0
  1271. dirbuf    ds    1
  1272. ;
  1273.     end
  1274.