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 / BEEHIVE / UTILITYS / PACK10.ARC / PACK.Z80 < prev   
Text File  |  1991-03-10  |  29KB  |  1,465 lines

  1.     .title    'Pack Disk'
  2.  
  3. ;     FDC, 29 August 1987
  4.  
  5. version    equ    10
  6.  
  7. fcb1:    equ    5ch
  8. fcb2:    equ    6ch
  9. buff:    equ    80h
  10.  
  11. lf:    equ    10
  12. cr:    equ    13
  13. ctrlz:    equ    26
  14.  
  15. MAXLIN:    equ    128        ; maximum input line length
  16.  
  17.     extrn    print,cout,cin,condin,crlf,pfn2,pa2hc,phlfdc,phl4hc
  18.     extrn    caps,issp,sksp,compb,getcrt,getmdisk
  19.     extrn    z3init,z3log,getwhl,getefcb,retud,dnscan
  20.     extrn    f$open,f$read,f$close,bdos,bios
  21.     extrn    mulhd,divhd
  22.     public    $memry
  23.  
  24. start:    jp    pack
  25.     db    'Z3ENV'
  26.     db    1        ; external environment
  27. z3eadr    dw    0f000h        ; environment address
  28.  
  29. dirflg:    db    0        ; always set C=1 on directory writes if non-zero
  30.  
  31. pack:    ld    hl,(z3eadr)
  32.     call    z3init        ; initialise z3lib routines
  33.     call    assign        ; assign data areas
  34.     ld    c,12        ; get cp/m version number
  35.     call    bdos
  36.     ld    a,h
  37.     or    a
  38.     jr    nz,badver
  39.     ld    a,l
  40.     cp    22h
  41.     jr    z,chkwhl
  42. badver:    call    pname
  43.     call    print
  44.     db    ' requires CP/M 2.2 (or ZRDOS)',cr,lf,0
  45. quit:    rst    0
  46. chkwhl:    call    getwhl        ; priviledged?
  47.     jr    z,quit        ; silently deny access if not
  48.     ld    a,(fcb1+1)    ; help requested?
  49.     cp    '/'
  50.     jr    z,ghelp
  51.     cp    ' '
  52.     jr    nz,pack1
  53. ghelp:    call    help
  54.     rst    0        ; warm boot
  55.  
  56. pack1:    call    options        ; process options
  57.     call    gnames        ; read input file and build name tables
  58.     xor    a
  59.     ld    (fixmob),a
  60.     ld    hl,wild
  61.     call    fnam        ; terminate mobile list with *:*.*
  62.     ld    de,fcb1
  63.     call    f$close
  64.     call    quitif        ; quit if errors
  65.     ld    a,(verbose)
  66.     or    a
  67.     call    nz,showlist
  68.     call    maktab        ; make group table
  69.     call    quitif        ; quit if errors
  70.     ld    a,(verbose)
  71.     or    a
  72.     call    nz,showtab
  73.     ld    hl,0
  74.     ld    (rdcnt),hl    ; clear counters
  75.     ld    (wrcnt),hl
  76.     ld    a,(stats)    ; just statistics?
  77.     or    a
  78.     jr    nz,pack5
  79.     ld    a,(blshf)
  80.     ld    b,a
  81.     ld    hl,128
  82. pack2:    add    hl,hl        ; find group size
  83.     djnz    pack2
  84.     ex    de,hl
  85.     call    getheap        ; reserve 2 buffers
  86.     ld    (grp1),hl
  87.     call    getheap
  88.     ld    (grp2),hl
  89.     call    chkro        ; check for read only disk
  90.     call    print
  91.     db    'Ready to pack disk ',0
  92.     ld    a,(disk)
  93.     add    'A'
  94.     call    cout
  95.     call    print
  96.     db    cr,lf,'Are you sure you wish to proceed? (y/n) - ',0
  97. pack3:    call    cin
  98.     and    5fh
  99.     cp    'Y'
  100.     jr    z,pack4
  101.     cp    'N'
  102.     jr    nz,pack3
  103.     rst    0
  104. pack4:    call    cout
  105.     call    crlf
  106. pack5:    call    sort        ; sort groups
  107.     ld    a,(stats)
  108.     or    a
  109.     jr    nz,pack6
  110.     call    fixdir        ; fix directory
  111.     call    resdrv        ; reset drive
  112.     call    print
  113.     db    'Disk packed',cr,lf,0
  114.     rst    0
  115. pack6:    ld    hl,(rdcnt)
  116.     call    phlfdc
  117.     call    print
  118.     db    ' group reads and ',0
  119.     ld    hl,(wrcnt)
  120.     call    phlfdc
  121.     call    print
  122.     db    ' group writes required to pack disk.',cr,lf,0
  123.     rst    0
  124.  
  125. assign:    pop    bc        ; return address
  126.     ld    hl,($memry)
  127.     ld    de,128        ; stack size
  128.     add    hl,de
  129.     ld    sp,hl        ; assign stack above program
  130.     push    bc
  131.     ld    (inline),hl    ; input line buffer
  132.     ld    de,MAXLIN
  133.     add    hl,de
  134.     ld    (heap),hl    ; set top of heap
  135.     ret
  136.  
  137. ; Read input file and build fixed and mobile name tables
  138. gnames:    ld    hl,0
  139.     ld    (errors),hl    ; no errors yet
  140.     ld    de,fcb1
  141.     call    z3log        ; log in to file DU
  142.     call    f$open        ; open it
  143.     jr    z,opok
  144.     call    print        ; report file missing
  145.     db    'Can''t find ',0
  146.     inc    de
  147.     call    pfn2
  148.     call    crlf
  149.     rst    0        ; and quit
  150. opok:    xor    a
  151.     ld    (fixmob),a    ; initially expect mobile names
  152.     ld    h,a
  153.     ld    l,a
  154.     ld    (fixcnt),hl    ; no fixed or
  155.     ld    (mobcnt),hl    ;  mobile files yet
  156.     ld    hl,(heap)
  157.     ld    (fixpnt),hl    ; this is where they go
  158.     ld    (mobpnt),hl
  159.     ld    hl,0
  160.     ld    (linnum),hl    ; line number
  161.     ld    (bufcnt),a    ; no bytes in buffer
  162. gnam1:    call    getlin        ; get next input line
  163.     ret    z        ; all done
  164.     ld    hl,(inline)    ; point to line
  165.     call    sksp        ; skip spaces
  166.     ld    a,(hl)
  167.     or    a        ; empty line?
  168.     jr    z,gnam1        ; ignore
  169.     cp    ';'        ; fixed / mobile spec?
  170.     jr    nz,gnam2
  171.     call    cmd        ; process fixed / mobile spec
  172.     jr    gnam1
  173. gnam2:    call    fnam        ; process filename
  174.     jr    gnam1
  175.  
  176. ; Process command line
  177. cmd:    inc    hl        ; skip over ';'
  178.     call    sksp        ; and spaces
  179.     ld    de,fixstr    ; 'FIXED'
  180.     ld    b,5
  181.     call    compb
  182.     ld    a,1        ; flag if fixed
  183.     jr    z,cmd1
  184.     ld    de,mobstr    ; 'MOBILE'
  185.     ld    b,6
  186.     call    compb
  187.     ld    a,0        ; flag if mobile
  188.     ret    nz
  189. cmd1:    ld    (fixmob),a    ; set new flag value
  190.     ret
  191.  
  192. ; Extract filename from input line
  193. fnam:    call    gdir        ; get directory
  194.     ret    nz        ; ignore if error
  195.     push    hl        ; save pointer to start of name
  196.     push    bc        ;  and user number
  197.     ld    de,16
  198.     call    getheap        ; extend heap
  199.     ld    hl,(mobcnt)
  200.     add    hl,hl        ; x 2
  201.     add    hl,hl        ; x 4
  202.     add    hl,hl        ; x 8
  203.     add    hl,hl        ; x 16 (size of mobile list)
  204.     ld    a,(fixmob)
  205.     or    a        ; fixed or mobile?
  206.     jr    z,fnam2
  207.     ld    a,h
  208.     or    l        ; empty?
  209.     jr    z,fnam1
  210.     ld    b,h
  211.     ld    c,l
  212.     ld    hl,(mobpnt)
  213.     dec    hl
  214.     add    hl,bc        ; last byte of current location
  215.     ld    de,16        ; offset
  216.     ex    de,hl
  217.     add    hl,de
  218.     ex    de,hl
  219.     lddr            ; make space to expand fixed list
  220. fnam1:    ld    hl,(fixcnt)
  221.     inc    hl        ; increment number of fixed files
  222.     ld    (fixcnt),hl
  223.     ld    hl,(mobpnt)
  224.     ld    de,16
  225.     ex    de,hl
  226.     add    hl,de        ; shift mobile base up
  227.     ld    (mobpnt),hl
  228.     ex    de,hl        ; address of next fixed entry in hl
  229.     jr    fnam3
  230. fnam2:    ld    de,(mobpnt)
  231.     add    hl,de        ; address of next mobile entry
  232.     push    hl
  233.     ld    hl,(mobcnt)
  234.     inc    hl
  235.     ld    (mobcnt),hl
  236.     op    ck1a,lhl        ; xld    ╨2*.blnotenvgh(mobchl
  237.     a,hld,fticjr    f4obil╨chkwnoteosequitile eentr wi; tes8<mobcntexgn teld    b,h    eqc,p        ; r    ; f    fnam5
  238. :    ld    b,call    c    ; f    sp        ; blank typ
  239. fnam5:    ld    b,call    c    <m?        ; any extents
  240.     ld    a,(de)        ; valid end?
  241.     or    a
  242.     ret    z
  243.     cp    ' '
  244.     ret    z
  245.     call    plnum
  246.     call    print
  247.     db    ': invalid filename',cr,lf,0
  248. incerr:    ld    hl,(errors)
  249.     inc    hl        ; increment error count
  250.     ld    (errors),hl
  251.     ret
  252.  
  253. ; co8< part of filename from (de) to (hl), max b bytes
  254. c    ; f    n:    ld    a,)
  255.     or    a
  256.     jr    z,cp<mspexg'
  257.     jr    z,c    ; f    sp
  258.     cp    ' '    z,c    <msp
  259.     e
  260.     cp    '*'
  261.     jr    z,c    ; f    ?
  262.     ld    (hl),atict    hl
  263.     djnz    cp<    ret
  264. cp<sp:    ld    a,' '
  265.     jr    cp<lp
  266. c    ; f    ?:    ld    a,'?'
  267. cp<lp:    ld    (gh(a
  268.     inc    hl
  269.     djnz    cp<lp
  270.     ret
  271.  
  272. ; Analyse direcxtey specified in file name
  273.  
  274. ; Possibilities are:
  275. ;    none        - use default DU (as input file or option spec)
  276. ;    *: or ?:    - all users on default D
  277. ;    D:        - default DU, D must match default
  278. ;    D*: or D?:    - all *.bs on D (must be default)
  279. ;    DU:        - DU, D must match default
  280. ;    DIR:        - corresponding DU, D must match default
  281.  
  282. ; Entry: hl points to start of filespec
  283. ; Exit:  hl ╨nts to start of filename
  284. ;        c  contains *.b (0..31 or '?')
  285. ;     nz  means error detected (discard line)
  286. gdir:    ld    bc,9*256    ; char and wildcard count
  287.     ld    de,dnbuf    ; copy possible direcxtey spec to buf
  288.     push    hl
  289. gdir1:    ld    a,(hl)tict    hl
  290.     cp    ':'
  291.     jr    z,gdirld    (de),a
  292.     inc    de
  293.     cp    '?'
  294.     jr    z,gdir2
  295.     cp    '*'
  296.     jr    nz,gdir3
  297. gdir2:    inc    c        ; count wildcards
  298. gdir3:    djnz    gdir1
  299.     ld    a,(*.b)    ; no dir specifc
  300.     ld    c,a
  301.     op    o    hl
  302.     xor    a musjurn with Z (ok)
  303.     ret
  304. gdir4:    xor    a
  305.     ld    (de),a
  306.     ld    de,dnbuf
  307.     ld    a,(de)
  308.     or    a
  309.     jp    z,baddn        ; null - no good
  310.     ld    a,c        ; any wildcards *sec,pc    or    a
  311.     jr    z,gdir8
  312.     ld    a,(d on e
  313.     sub    'A'        ; disk specde)ed?
  314.     jr    c,gdir5
  315.     cp    'P'-'A'+1
  316.     jr    nc,gdir5
  317.     e
  318.     push    hl
  319.     ld    hl,disk
  320.     cp    (hl)        ; does disk match?
  321. gdirahl        ; xhcl
  322.     jr    z,gdir5
  323.     call    plnum
  324.     call    print
  325.     db    ' specdfies disk ',0
  326.     add    a,'A'
  327.     call    cout
  328.     call    print
  329.     db    ', (',0
  330.     ld    a,(disk)
  331.     add    'A'
  332.     call    cout
  333.     call    print
  334.     db    ' expected)',cr,lf,0
  335.     op    o    hl
  336.     jp    incerr
  337. gdir5:    ld    a, poi)
  338.     cp    '*'tec    z,gdir6        ; expecx just 1 wild card
  339.     cp    '?'
  340.     jr    nz,baddn
  341. gdir6:nc    ll -    d    a,(de)
  342.     or    atec    nz,baddn
  343.     ld    c,'?'        ; wildcard user
  344. gdir7    pop    af        ; discard start pointer
  345.     xor    a    ld    lturn with Z (ok)
  346.     ret
  347. gdir8:    ex    de,hl        ; directory pointer to hl
  348.     xor    a        ; DU before DIR
  349.     call    dnscan
  350.     ex    de,hl
  351.     jr    z,baddn
  352.     ld    a,b
  353.     push    hl
  354.     ld    hl,disk
  355.     cp    (hl)        ; does disk match?
  356.     jr    nz,gdir4a
  357.     oop    hl
  358.     jr    gdir7
  359. baddn:    call    plnum
  360.     call    print
  361.     db    ': can''hl
  362.     a,nterpret direcxory specdfication',cr,lf,0
  363.     pocl
  364.     jp    incerr
  365.  
  366. ; get a line from the input file
  367. getlin:    ld    hl,(linnum)tict    hl
  368.     ld    (linnum),hl    ; increment line count
  369.     ld    hl,(inline)    ; start of line
  370.     ld    bc,MAXLIN-1    ; space left
  371.     call    getch        ; get first input character
  372.     cp    ctrlz        ; end of file?
  373.     ret    z
  374. getl1:    cp    ctrlz
  375.     jr    nz,getl2
  376.     ld    a,lf        ; simulate eol
  377. getl2:    ld    (gh(atict    hl
  378.     cp    lf        ; end of line?
  379.     jr    z,getl.3dec    bc
  380.     ld    a,b
  381.     or    c
  382.     jr    z,getl
  383.     call    dcall    getch        ; get next character
  384.     jr    getl1
  385. getl3:    ld    (gh(0        ; terminate line
  386.     dec    hl
  387.     ld    a,hl)t
  388.     call    issp        ; eliminate trailing whitespace
  389.     jr    z,getl.3or    1    ld    lturn with NZ
  390.     ret
  391. getl4:    call    plnum        ; print line 
  392.     pushner
  393.     call    print
  394.     db    ' too long: truncated.',cr,lf,0
  395. getl5:    call    getch        ; skip rest of line
  396.     cp    lf
  397.     jr    z,getl.
  398.     cp    ctrlz
  399.     jr    z,getl.3jr    getl5
  400.  
  401. ; Get next input character
  402. getch:    push    hl
  403.     push    de
  404.     push    bc
  405.     ld    hl,bufcnt
  406.     ld    a,(hl)t
  407.     or    a        ; anything lefhl
  408.     a,n buffer?
  409.     jr    nz,getch1
  410.     ld    de,fcb1
  411.     call    f$read        ; read sector
  412.     or    a        ; end of file?
  413.     jr    nz,geteof
  414.     ld    a,128
  415.     ld    (gh(a        ; 128 bytes available now
  416. getch1:    dec    (hl)        ; decrement count
  417.     neg            ; convert to address
  418.     ld    e,a
  419.     ld    d,0
  420.     ld    a,de)        ; pick up character
  421.     and    7fh
  422.     call    caps        ; capitalize it
  423.     cp    ctrlz        ; end of file?
  424.     jr    nz,getch2
  425. geteof:    ld    (gl),80h    ; stick at eof
  426.     ld    a,ctrlz
  427.     ld    (80h),at
  428. getch2hl        ; xh    bc
  429.     phl)te
  430.     op    o    hl
  431.     ret
  432.     
  433.  
  434. ; Display input line umber
  435. plnum:    push    hl
  436.     push    de
  437.     push    bc
  438.     push    af
  439.     call    print
  440.     db    'Line ',0
  441.     ld    hl,(linnum)
  442.     call    phlfdc
  443.     po    af<mp    bc
  444.     po    de
  445.     pop    hl
  446.     ret
  447.  
  448. ; Make table of group 
  449.     pushners
  450. ; Table format is:
  451. ;
  452. ;        +----------------+----------------+
  453. ;    Index -> 0 | Current 
  454.     pushner | Position where |
  455. ;               | of group which | group which is |
  456. ;               | should go at   | currently here |
  457. ;               | this position  | should go      |
  458. ;               | on the disk    |                |
  459. ;               |                |                |
  460. ;                      :                 :
  461. ;           dsm |                |                |
  462. ;               +----------------+----------------+
  463.  
  464. maktab:    ld    a, disk)
  465.     ld    e,a
  466.     ld    c,14        ; selecx disk via bdos
  467.     call    bdos
  468.     ld    c,e
  469.     ld    b,0
  470.     ld    a,9        ; select disk via bios (to get dph)
  471.     call    bios
  472.     ld    e,(hl)t
  473.     inc    hl
  474.     ld    d,(hl)        ; pick up secxte table address
  475.     ld    (secxab),ll -    d    de,9        ; offset to dpb address
  476.     add    hl,de
  477.     ld    e,(hl)t
  478.     inc    hl
  479.     ld    d,(hl)
  480.     ex    de,hl        ; dpb address in hl
  481.     ld    de,dpb- unc,15
  482.     ldir            ; make a local co8< of disk de);ams
  483.     ld    hl,(dsm)
  484.     inc    hl
  485.     add    hl,hl        ; table size is 4 * (dsm+1)
  486.     add    hl,hl
  487.     ex    de,hl
  488.     push    de),    ; save size
  489.     call    getheap        ; get space for it
  490.     ld    (grptab),hl    ; save base of group table<mp    bc        ; size of table<
  491. mtab1:    ld    (gl),-1        ; clear table<
  492. nc,M
  493.     dec    bc
  494.     ld    a,b
  495.     or    c
  496.     jr    nz,mtab1
  497.     ld    hl,(alloc)    ; initial allocation
  498.     ld    a,h
  499.     ld    h,l
  500.     ld    l,a        ; get in right order
  501.     ld    de,0        ; group umber
  502. mtab2:    ld    a,h
  503.     or    l
  504.     jr    z,mtab.3call    fixgrp        ; fix direcxtey grouptict    de),    ; next groupt
  505.     add    hl,hl        ; shift a bit outtec    mtab2
  506. mtab.:    ld    hl,fixgrp
  507.     ld    (proc),hl    ; what to do for each groupt
  508.     ld    hl,(heap)
  509.     ld    (mark),hl    ; remember top of heap
  510.     ld    hl,(fixpnt)    ; fixed file table<
  511. ld    bc,(fixcnt)    ; how many
  512. mtab4:    ld    a,b
  513.     or    c
  514.     jr    z,mtab5
  515.     call    dofile        ; do it for these files
  516.     ld    de,16        ; size of file entry
  517.     add    hl,de
  518.     dec    bc
  519.     jr    mtab4
  520. mtab5:    ld    hl,-1
  521.     ld    (group),hl    ; last group allocated
  522.     ld    hl,nxtgrp    ; what to do for each groupt
  523.     ld    (proc),hl
  524.     ld    hl,(mobpnt)    ; mobile file table<
  525. ld    bc,(mobcnt)    ; how many
  526. mtab6:ld    a,b
  527.     or    c
  528.     jr    z,mtab7
  529.     call    dofile
  530.     ld    de,16
  531.     add    hl,de
  532.     dec    bc
  533.     jr    mtab6
  534. mtab7:    ld    hl,(mark)envgeap),hl    ; reset heap
  535.     ret
  536.  
  537. ; Do proc for each group allocated to the files matching
  538. ; the afn hl)t╨nted to by hl
  539. dofile:    push    bc
  540.     push    de
  541.     push    hl
  542.     ex    de,hl- unc,0        ; first direcxory slot
  543. dof0:    call    getdir        ; get next entry
  544.     jr    nz,dofendtict    bc
  545.     call    match    k)eeck),hl    ; w
  546.     jr    nz,dof0
  547.     push     allo; save slot number
  548.     push    de),    ; and afn pointer
  549.     ld    de,1ocat offset to group map
  550.     add    hl,de
  551.     ld    b,16        ; size of map in bytes
  552. dof1:    ld    e,(hl)
  553.     ld    d,0
  554.     inc    hl
  555.     ld    a,(dsm+1)    ; high byte of disk size
  556.     or    a
  557.     jr    z,dof2        ; 1 byte group 
  558.     pushners
  559.     ld    d,(hl)t
  560.     inc,M
  561.     dec    b
  562. dof2:    ld    a,d
  563.     or    e        ; assigned?
  564.     jr    z,dof.3push    hl
  565.     ld    hl,(proc)
  566.     call    ihl        ; do procedure on this groupt
  567.     op    o    hl
  568. dof3:    djnz    dof1<mp    de),    ; afn<mp     allo; slot 
  569.     pushner
  570.     jr    dof0plaofendhl        ; xh    hl
  571.     op    o    rst dp    bc
  572.     ret
  573.  
  574. ; Indirecx jump to (hl)
  575. ihl:    jp    (hl)t
  576.  
  577. ; Get direcxory entry for slot bc
  578. ; Return hl)t╨ntl        ; o *.in hl or nz if no more entr44s
  579. getdir:    ld    hl,(drm)    ; last  direcxy entry
  580.     or    a
  581.     sp    (hhl,bc
  582.     ret    c        ; past end of  direcxy
  583.     push    ll -    d    h,b
  584.     ld    l,c
  585.     srl    h
  586.     rr    l
  587.     srl    h
  588.     rr    l    ld    lquired secxetl.umber
  589.     ld    (secxor),hl
  590.     ld    hl,(heap)    ; how many secxors are cachec,pc    ld    de,(mar
  591.     n
  592.     xor    a
  593.     istc    hl,de        ; bytes on heap
  594.     sla    l
  595.     rl    h
  596.     rla
  597.     ld    e,h
  598.     ld    d,a        ; divide by 128
  599.     ld    hl,(secxor)
  600.     istc    hl,de
  601.     jr    nc,getd
  602.     ld    l,c must read if not (yet) on heap
  603.     ld    hl,(secxor)
  604.     xor    a
  605.     srl    h
  606.     rr    l
  607.     ld    h,l
  608.     rra
  609.     ld    l,a        ; multiply by 128
  610.     ld    de,(mark)
  611.     add    hl,de
  612.     jr    getd4
  613. getd1:    ld    hl,(heap)
  614.     ld    de,80h
  615.     add    hl,de
  616.     ex    de,hl
  617.     ld    hl,(6)
  618.     or    at    istc    hl,de        ; enough space on heap?
  619.     jr    nc,getdy sed    hl,buff        ; use temp buffer
  620.     jr    getdentr4etd2:    ld    de,
  621.     call    dca
  622.     call    getheap
  623.     push    ld3:    ld    a,c        ; is it first slot in secxor?
  624.     and    is icou,getd
  625.     call    dpush    hl
  626.     ex    de,hl
  627.     jr    z,dtsec    ld    lad secxor<mp    hl
  628.     jr    z,getd
  629.     call    dcall    print
  630.     db    'Can''h read direcxtey',cr,lf,0
  631.     rst    0
  632.     push    ld4:    ld    a,c
  633.     and    3        ; weduh slot?
  634.     rrca
  635.     rrN'
  636.     rrN'
  637.     add    l
  638.     ld    l,asp
  639.     adc    h
  640.     ld    hdisk vi; hl)t╨nt to  direcxy entrytict    hl
  641.     ld    a,(hl)        ; 1st byte of filename
  642.     dec    hl
  643.     ohl)te
  644.     cp    0e5
  645.     ld    (i; ever usec,pc    jr    z,getd5
  646.     xor    a
  647.     ret
  648.     push    ld5:    or    a
  649.     ret
  650.  
  651. ; Check if  direcxy *.matches afn pattern
  652. tryt:    push    hl
  653.     push    de
  654.     push    bc
  655.     ld    b,16        ; length to compare
  656.     ld    a,(hl)
  657.     cp    0; sa
  658.     ld    (i; erased?
  659.     jr    nz,tryt1
  660.     or    a
  661.     jr    match3    ld    ljecx it
  662. match1:    ld    a,(de)
  663.     cp    '?'        ; wild card?
  664.     jr    z,tryty sed    c,a
  665.     ld    a,(hl)
  666.     and    7f
  667.     ld    (i; mask off atjr    f4butes
  668.     cp    c
  669.     jr    nz,tryt3
  670. tryt2:    inc    hl
  671.     rre
  672.     djnz    match1
  673. match3:    op    o    bc
  674.     etue
  675.     oop    hl
  676.     ret
  677.  
  678. ; Fix group position by setting up a 1-1 mappetde
  679.     add    hlumber is in de
  680. fixgrp:    push      m,d
  681.     ld    l,e
  682.     call    makent        ; make 1-1 entry<mp    hl
  683.     ret
  684.  
  685. ; Allocate the next free groupctrlzhe one in de
  686. nxtgrp:    push    hl
  687.     push    bc
  688.     call    getnew        ; has it already been given a position?
  689.     inc    hl
  690.     ld    a,h
  691.     or    l
  692.     jr    nzeck)grpe
  693.     oush    de
  694. ngrp2:    ld    de,(group)    ; where to start looketde for a space
  695. ngrp3:    ld    hl,(dsm)
  696.     or    a
  697.     istc    hl,de        ; end of disk?
  698.     jr    nz,ngrp leoll    print
  699.     db    'Disk overflum)t(can''t happen!)',cr,lf,0
  700.     rst    0
  701. ngrp4:    rre
  702.     call    chkfre
  703.     jcou,ngrp(dsex    de,hl
  704.     ld    (group),hl    ; rememhl)t╨ntlwhere we got toh
  705.     lde
  706.     call    makent        ; make table entry to move de -> hl
  707. ngrpehl        ; xh     allo; group already dealt with
  708.     op    o    hl
  709.     ret
  710.  
  711. ; Ma    l    lan entry in the group table<
  712. ; de is current 
  713.     add    hlumber, hl is desired group number
  714. to at:    push    af
  715.     push    de
  716.     push    hl
  717.     jr    z,dtadr        ; desired group as indexenvgl),e
  718.     inc    hl
  719.     ld    (gl),l        ; assign current groupt
  720.     ex    de,hl
  721.     jr    z,dtadr        ; current group as indextict    hl
  722. mber,    hl
  723.     etue
  724.     ld    (hl),obilnc    hl
  725.     ld    (gh(d        ; assign dessibed group
  726.     ex    de,hlh
  727.     lde<mp    af
  728.     ret
  729.  
  730. ; Get disk groups into the red    7ed order
  731. sort:    ld    hl,-1
  732.     ld    (group),hl    ; scan from start of disk
  733.     xor    a
  734.     ld    (grpsel),a    ; initialise selector switch
  735.     ld    (dirwr),a    ; not writing  direcxy yet
  736. sort1:    call    ctrlc?    k)eeck for *.b interrupt
  737.     jp    z,abort
  738.     ld    hl,(group)tict    hl        ; next group
  739.     ld    (group),hl
  740.     ex    de,hl
  741.     ld    hl,(dsml
  742.     ld    l
  743.     istc    hl,de        ; end of disk?
  744.     ret    c
  745.     jr    z,dtold        ; what should go here?
  746.     inc    hl
  747.     ld    a,h
  748.     or    l        ; free?
  749.     ret    z        ; done if so
  750.     dec,M
  751.     ex    de,hl
  752.     push    hl
  753.     istc    hlwhat     ; here already?<mp    hl
  754.     jr    z,sort1
  755.     call    getgrp        ; gehl
  756.     a,hl
  757.     a,nto memory
  758.     jp    nz,s intrt
  759. sort2:    call    flip        ; swap buffers
  760.     ex    de,hl
  761.     jr    z,dtnewead    ere should present contents go?
  762.     inc    hl
  763.     l    ; w
  764.     or    l
  765.     dec    hl
  766.     oush    af
  767.     jr    z,sorte si; not needed?
  768.     php    af
  769.     ex    de,hl
  770.     push    hl
  771.     call    getold
  772.     or    a
  773.     ory erst dp    hl
  774.     ex    de,hlde
  775. ngaf
  776.     call    nz,get,ddnif not already there
  777. sord    a,h:    call    z,putb
  778.     oput if no read errsecxorde
  779. ngaf        ; save error flags
  780.     push      m,d        ; le
  781.     jr    z,dtadrenvgl),e        ; adjust table to reflngrpeisk cont    ; end tict    hl
  782.     ld    (gh(d
  783.     po    hl
  784.     oop    af
  785.     jp0
  786. cs intrtld    lad/write error?
  787.     op    o    af
  788.     jr    z,sortte e; end of chain?
  789.     jr    sort2
  790.  
  791. ; Maked    a,(hory correspond to new order of groups on disk
  792. fixdir:    xor    a
  793.     ld    (grpsel),a    ; initialise selector
  794.     ld    a,(dirflg)    ; be pessimistic on dir writes?
  795.     or    a
  796.     ld    a,1
  797.     jr    z,fixd0
  798.     inc    a
  799. fixd0ocatdirwrendt    ld    bc,(drm)    ; direcxory size
  800.     ld    de,-1        ; group 
  801.     pushner
  802. fixor t:    ld    a,b
  803.     or    c
  804.     ret    z        ; finished?
  805. mber,    de),    ; next dir group
  806.     call    getgrp
  807.     push    bc
  808.     ld    a,(blshf)    ; block shifh factapp    ld    b,a
  809.     ld    a,4
  810. fixd2:    add    a,a        ; calculate entr44s per groupt
  811.     djnz    fixd2<mp    bc
  812.     push    af
  813.     ld    hl,(grp1)    ; data location
  814. fixd3:    Indixent        ; fix entry
  815. tict    bfixd4        ; finishec,pc    op    o    af
  816.     dec    a
  817.     oush    af
  818.     jr    nz,fixd3
  819. fixd4hl        ; xh    af
  820.     call    flip
  821.     call    putgrp        ; write back
  822.     call    flip
  823.     jr    fixd1
  824.  
  825. ; F  ca s wntry
  826. fixent:    ld    a,if        r    c
  827.     ret    z        ; any more?
  828.     inc    hl
  829.     ld    a,(hl)t
  830.     dec    hl
  831.     cp    0e5
  832.     ld    (i; totrytyf used area?
  833.     jr    nz,fixe0
  834.     ld    bc,0
  835.     ret
  836. fixe0:    dec    bc
  837.     ld    a,(hl)
  838.     push    bc
  839.     push    de
  840.     ld    b,16        ; size of map
  841.     ld    de,16
  842.     add    hlwhat     t soint to group map
  843.     cp    0e5
  844.     ld    (i; erased entry?
  845.     jr    nz,fixe1
  846.     add    hl,de),    ; skip it
  847.     jr    fixe4
  848. fixe1:    ld    d,0
  849.     ld    e,(hl)
  850.     ld    a,(dsm+1)    ; 2 byte 
  851.     pushners?
  852.     or    aor    a
  853.     l    z,fixe2
  854.     inc    hl
  855.     ld    d,(hl)
  856.     dec    hl
  857. fixe2:    push    hl
  858.     call    gete?    ; ld    b,his 
  859.     add    hlow?
  860.     ex    de,hl
  861.     php    hl
  862.     ld    (glyst toc,am+1)
  863.     or    aor    a
  864.     l    z,fixe(dsld    (gl),lt todec    b
  865. fixe3:    djnz    fixe1
  866. fixe4hl        ; xh     coubc
  867.     or    1
  868.     ret
  869.  
  870. ; Use hl as index into group table<
  871. getadr:    add    hl,hl
  872.     add    hl,hl
  873.     pul.e
  874.     ld    de,(grptab)
  875.     add    hl, coude
  876.     ret
  877.  
  878. ; Check if entry for group in de is free
  879. ; Z - yes, NZ - no
  880. chkfre:    push    hl
  881.     call    getoldt told    a,h
  882.     or    l<mp    hl
  883.     ret
  884.  
  885. ; Translate old  poi) group numbl        ; o new (hl)t
  886. get    af<:    push    de
  887.     ex    de,hl
  888.     call    get.*
  889.     ld    e,(hl)
  890.     inc    hl
  891.     ld    d,(hl)
  892.     ex    de,hl
  893.     php    de
  894.     ret
  895.  
  896. ; Translate new  poi) group numbl        ; o     af< (hl)
  897. getnew:    push    de
  898.     ex    de,hl
  899.     jr    z,dt.*
  900. mber,    hl
  901.     inc    hl
  902.     ld    e,(hl)
  903.     i    l<2:    i(hl)
  904.     ex    de,hlor o
  905.     ret
  906.  
  907. ; Flip groupf
  908.     cers
  909. flip:    push    af
  910.     push      ml,grpsel
  911.     ld    a,te ecall    flip p
  912.     rs
  913.     xor    (hl)
  914.     ld    (gl),a
  915.     po    hl
  916.     pop    af
  917.     ret
  918.  
  919. ; Get group de
  920. getgrp:    push    hl
  921.     pul.e
  922.     push    bc
  923.     ld    hl,(rdcnt)
  924.     inc    hl        ; increment counter
  925.     ld    (rdcnt),hl
  926.     ld    hl,(grp1)
  927.     ld    a,(grpsel)    ; which ased?
  928.     or    a
  929.     jr    z,ggrp1
  930.     ld    hl,(grp2)
  931. ggrp1:    ld    a,(stats)    ; statistics only?
  932.     or    a
  933.     jr    nz,ggrp
  934.     call    dex    de,hl
  935.     ld    a,(blshf)    ; bloc(dsdhifh factappet.a
  936. ggrp2:    add    hl,hl        ; convert group to secxoblbumber
  937.     djnz    ggrp2
  938.     ld    (secxor),hl
  939.     ld    a,(blmsk)    ; b
  940.     ld    d, mask
  941. mber,    a        ; number of secxors in groupt
  942.     ld    b,a
  943. ggrp3:    call    getsec
  944.     jr    nz,ggrp5    ; error?
  945.     ld    hl,128
  946.     add    hl,de
  947.     ex    de,hl
  948.     djnz    ggrpentr4ow?:    xor    a
  949. ggrp5INc
  950.     etue
  951.     oop    hl
  952.     ret
  953.  
  954. ; Put group de
  955. putgrp:    push    hlde
  956. ngde
  957.     push    bc
  958.     ld    hl,(wrcnt)tict    hl        ; increment counter
  959.     ld    (wrcnt),hl
  960.     ld    hl,(grp1)
  961.     ld    a,(mobc(l)    ; whichf
  962.     cer?
  963.     or    a
  964.     jcou,pgrp1
  965.     ld    hl,(grp2)
  966. pgrpx    d,(stats)redtistics only?
  967.     or    aor    a
  968.     l    nz,pow?
  969.     ex    de,hl
  970.     ld    a,(blshf)    ; bloc,(stdhift factor
  971.     ld    b,a
  972. pgrp2Andd    hl,hl        ; convert group to secxetl.umber
  973.     djnz    c 
  974. mat
  975.     ld    c,2        ; write unallocated data
  976.     ld    (sector),hl
  977.     ld    a,(blmsk)x    d,ck ma    ; skinc    a        ; number of secxors in groupt
  978.     ld    b,a
  979. c  input c:    ld    a, dird    a,(ho
  980.     cp    2        ; pessimistic about dir writes?
  981.     jr    nz,c  input c0
  982.     ld    c,1
  983. c  input c0:    call    putsecor    a
  984.     l    nz,pgrp5    ; error?
  985.     ld    c,0        ; normal writes for rest of groupt
  986.     ld    a,(dird    a,(ho    ; writing to direcxory?
  987.     or    a
  988.     jr    z,c  input ca
  989.     ld    a,b
  990.     cp    2        ; last secxor of directory groupk)eecntsa
  991.     ld    c,1        ; signal5:    callocwrite
  992. c  input ca:    ld    hl,128
  993.     add    hl,de
  994.     ex    de,hl
  995.     djnz    pnts
  996. pow?:    xor    a
  997. c rp5:    op    o    bc
  998.     phl)tedex
  999.     ret
  1000.  
  1001. ; Read secxappgetsec:    push    bcde
  1002. ngde
  1003.     pet)
  1004.     ld    a,y sed    (curopendt    call    setor m    ld    a,1,(stcall    bios
  1005.     or    adex
  1006. tryt:e
  1007.     oop    bc
  1008.     ret
  1009.  
  1010. ; Write secxappputsec:    pusentr4o    push    de
  1011.     oet)
  1012.     ld    a,,(stld    (; tpendt    call    setor m    ld    a,1 leoll    bios
  1013.     pop    hl
  1014.     php    de
  1015.     oop    bc
  1016.     or    a
  1017.     ret
  1018.  
  1019. ; Prede);e for secxor read/write.  Data address is in de.
  1020. snzec:    push    hl
  1021.     pul.e
  1022.     push    bc
  1023.     push    af- un,d
  1024.     ld    c,e
  1025.     ld    a,12        ; se
  1026.     omanotedrt 
  1027.  
  1028.     call    bios
  1029.     ld    hl,(secxoto c    xouired secxapp    ld    de,(spt)    ; secxors pl        ; rack
  1030.     call    divhd        ; get relative track in hl
  1031.     oet)
  1032.     ld    de,(toff)    ; track offset
  1033.     add    hl,de        ; absolute track e,hldl
  1034.     ld    b,h
  1035.     ld    c,l
  1036.     ld    a,10        ; shecrack
  1037.     call    bios
  1038.     pop    hl
  1039.     ld    de,(spt)
  1040.     call    mulhd        ; sector atrst    0art of this track
  1041.     ex    de,hl
  1042.     ld    hl,(secxoto ctict    hl        ; inc?
  1043.     jr    nz,ct fetl.ext time
  1044.     ld    (secxoto c,hl
  1045.     dec    hl
  1046.     or    a
  1047.     ory ede),    ; relative secxor on track
  1048. et.h
  1049.     ld    c,l
  1050.     ld    de,(secxab)
  1051.     ld    a,d
  1052.     or    e        ; table definec,pc    jr    z,ssec1
  1053.     ld    veocat translate logical to physical secxor
  1054.     call    bios
  1055.     ld    e
  1056.     ca
  1057.     ld    c,l
  1058. ssec        ; ma1te e; set secxor
  1059.     call    bios
  1060.     pop    af
  1061.     op    o    c,pc    jp     couhl
  1062.     ret
  1063.  
  1064. ; Prematurely terminate disk sort
  1065. s intrt:    ld    a, ; tp)    ; reason for s intrt
  1066.     ld    (whyab),a
  1067.     ld    hl,(secxoto c    bioctor if it was read/write
  1068.     dec    hl        ; correcld    lthr pre-increment
  1069.     ld    (badsec),hl
  1070.     ld    a,(stats)
  1071.     or    aor    a
  1072.     l    nz,ab0
  1073.     Indixtab        ; make table reflecx ld    b,hwe reached
  1074.     call    fixdir        ; update directory
  1075.     call    resdrv        ; reset drive
  1076. ab0:    call    pname
  1077.     ld    a,(whyck1ngrp(c    a        ; console interrupt?
  1078.     jr    nz,ab1
  1079.     call    print
  1080.     db    ' interrupted )    ; w*.b1:    ld    a,0
  1081.     rst    0
  1082. aor    a
  1083. c:    dec    a        bioctor read?
  1084.     jr    nz,ab2
  1085.     call    print
  1086.     db    ' read',0
  1087.     jr    ab3
  1088. ),lt:    call    print        ; must be write
  1089.     db    ' write',0
  1090. ab3:    call    print
  1091.     db    ' error at group ',0
  1092.     ld    hl,(badsec)
  1093.     ld    a,(blshf)
  1094. ab4:    srl    
  1095.     ld    (i; convert secxor to group
  1096.     rr morngrp(c    a
  1097.     jcou,ab4
  1098.     call    phl4hc        ; displma    groupt
  1099.     ld    a,':'
  1100.     call    csm+    ld    a,badsec)
  1101.     ld    b,a
  1102.     ld    a,(
  1103.     osk)
  1104.     and    b
  1105.     call    pa2hc        ; and secxor within g
  1106.     call    ca
  1107.     call    crlf
  1108.     rst    0
  1109.  
  1110. ; Restore consistancy  between two halves of group table<
  1111. fixtab:    ld    de,0        ; first groupt
  1112. fixt1:    ld    hl,(dsml
  1113.     ld    l
  1114.     to c    be        call    finiz        ; ?
  1115.     ret    c
  1116.     call    get    af<ead    at were we going to move here?
  1117.     push    hl
  1118.     or    a
  1119.     to c    be
  1120.     oooing
  1121.     i
  1122.     dje
  1123.     jr    z,fixtte e; no action if 1-1 
  1124.     extrlready moved
  1125.     push    de
  1126.     ld    d,h
  1127.     ld    e,l
  1128.     call    getadrfluable address of group whichtict    hl        ;  not been movedt told    (gl),e        ; ihl
  1129.     a,s still ld    b,hit startedt toupdd
  1130. tryt:e
  1131.     jr    fixt1
  1132.  
  1133. ; Expand heap and check for overflow
  1134. ; entry: de is 
  1135.     pushner of bytes needed
  1136. ; exit:rig is old to
  1137.     call    dca
  1138.  heap (start of new spac on e
  1139. getheap: op    aeap)
  1140.     push    hl
  1141.     oush    de
  1142.     
  1143.     call    nzenvgeap),hl
  1144.     ex    de,hl
  1145.     ld    hl,(6l
  1146.     ld    l
  1147.     to c    be
  1148.     oo
  1149.     ld    a,10e
  1150.     oooing
  1151.     ret    nc
  1152.     call    print
  1153.     db    'Out of memorytt0
  1154.     rst    0
  1155.  
  1156. ; Proc
  1157. aooptions
  1158. options: xor    a
  1159.     ld    (stats),a    ; clear statistics option
  1160.     ld    (verbose),a    ;  and verbose flag
  1161.     call    retud        ; get defaul
  1162.     oisk
  1163.     ld    (*.b),bc
  1164.     ld    a,(fcb1)    ; input file on default disk?
  1165.     or    a
  1166.     jr    z,opt1
  1167.     dec    a
  1168.     ld    b,a        ; defose) to specde)ed disk
  1169. opt1:    ld    a,b
  1170.     ?    kisk),a    ; defaul
  1171.     oi    ; skld    hl,fcb2+1    ; hl)t╨nt to option stretde
  1172. opt2:    ld    a,(hl)t
  1173.     inld    (gl)
  1174.     cp    ' '+1        ; any left?
  1175.     rll    h    cp    'S'
  1176.     jr    z,opts
  1177.     cp    'V'
  1178.     jr    z,optv
  1179.     cp    'D'7fptd
  1180.     cp    '/'        ; ignore /7fpt2
  1181. opterr:    call    print
  1182.     db    'Option not recognized: ',0
  1183. opter1:    call    cout
  1184.     call    crlf
  1185.     rst    0
  1186. opts:    ld    a,1
  1187.     ld    (statsendt    jr    opt2
  1188. optv:    ld    a,1
  1189.     ld    (ssige),a
  1190. 1:    ld    a,pt2
  1191. optd:    call    getmdisk    ; whatall    primax available disk?
  1192.     l
  1193. poa
  1194.     ld    a,(hl)        ; ge
  1195.     add    hlok
  1196. mber,    hl
  1197.     cp    ' '        ; se
  1198.     cpfiec,pc    jr    z,optdn
  1199.     sub    'A'
  1200.     jr    c,optde),    ; in range ?
  1201.     cp    b
  1202.     jr    nc,optde
  1203.     ld    (diskendt1:    ld    a,pt2
  1204. optde:    call    print
  1205.     db    'No such disk: ',0
  1206.     add    a,'A'or    a
  1207.     l    opter1
  1208. optdn:    call    print
  1209.     db    'Disk specde)cation missetdett0
  1210.     rst    0
  1211.  
  1212. ; quit if erriteshave occurrlon
  1213. quitif    ld    (gerrors)
  1214.     ld    ashf    or    l        ; any errors?
  1215.     ret    zld    b,hit    0
  1216.  
  1217. ; Get vector bit correspondetde to disk into de
  1218.     push    lbit:    ld    de,1
  1219.     ld    a,(disk)
  1220. gbit1:    or    a
  1221.     ret    z
  1222.     dec    a
  1223.     ex    de,hl
  1224.     add    hlto mox    de,hl
  1225.     jr    gbit1
  1226.  
  1227. ; Is disk set to read only?
  1228. chkro:    ld    c,2l.e; get r/o vector
  1229.     call    bdosonltbit        ; get our disk's vector bit
  1230.     ld    a,d
  1231.     and    
  1232.     ld    (i; are we r/o?
  1233.     jr    nz,isro
  1234.     ld    a,?
  1235.     jr    snd    l
  1236.     ret    z
  1237. isro:    call    ps pe
  1238.     call    print
  1239.     dl,as Disk ',0
  1240.     ld    a,(disk)
  1241.     add    'A'; det
  1242.     call    print
  1243.     db    'all    priset read onlytt0
  1244.     rst    0        ; abort
  1245.  
  1246. ; Reset the drive we just packlon
  1247. resdrv:    call    pritbit
  1248.     ld    c,37        ; reset drive
  1249.     jp    bdos
  1250.  
  1251. ; Check for ^C at console
  1252. ctrlc?:    xor    a
  1253. nt ondin
  1254.     cp    r    z,oret    nz
  1255.     ld    a,1
  1256.     ld    (; tpendt    ret
  1257.  
  1258. ; Show terns
  1259. showtern:
  1260.     call    print
  1261.     db    cr,lf,    de,ixed?
  1262.     ppecs:',cr,lf,0
  1263.     ld    hl,(fixpnt)
  1264.     ld    bc,(fixcnt)
  1265.     call    showl
  1266.     call    print
  1267.     db    cr,lf,'Mobile filespecs:',cr,lf,0
  1268.     ld    hl,(mobpnt)- unc,(mob  ca
  1269.     call    showl
  1270.     jp    crlf
  1271.  
  1272. showl:    ld    a,if        r    c
  1273.     ret    z
  1274.     push    bc
  1275.     ld    b,0
  1276.     ld    a,(hl)        ; *.b number
  1277.     inc    hl
  1278.     cp    '?'
  1279.     jr    nz,showl1
  1280.     y leecxa    jr    showl4
  1281. showl1:    cp    10or    a
  1282.     l    c,showl2tict    b
  1283.     sub    10or    a
  1284.     l    showl1
  1285. showl2:    push    af
  1286.     ld    a,b
  1287.     add    '0'
  1288.     cp    '0jez,showlr    z,old    a,' '
  1289. slip p3:    call    csm+    po    af
  1290.     add    '0'
  1291. showl4:    call    cout
  1292.     ld    a,':'
  1293.     call    csm+et.fer
  1294. slip p5:    ld    a,(hl)t
  1295.     inld    (gl)
  1296.     cempecxa    djnz    showlsubll    crlwhichtop    bc
  1297.     dec    bc
  1298.     jr    showl
  1299.  
  1300. ; Show 
  1301.     add    hlumber table
  1302. showtab: call    getcrt
  1303.     ld    a,(hl)        ; crt width
  1304.     and    0f0h
  1305.     6lt    
  1306.     call    drrca            ; divide by 16
  1307.     endm
  1308.     ld    c,a        ; groupsC,r line
  1309. mber,    hl
  1310.     inc    hl
  1311.     l
  1312. po(hl)        ; text lines per screen
  1313.     push    bc
  1314.     ld    de,0        ; start at the beginning
  1315. showt1:    call    getplm    ; get entryt told    a,h
  1316.     or    l        ; free
  1317.     or    aoshowt
  1318.     call    ddec    hl
  1319.     push    hl
  1320.     or    a
  1321.     to c    be        ; 1 to 1makenop    hl
  1322. tict    bshowFI
  1323.     call    phl4hl2tall    print
  1324.     db    ' --> ',0
  1325.     ex    de,hl
  1326.     call    pde),ahc
  1327.     ex    de,hl
  1328.     dec    c
  1329.     jr    cp    chowty sed    a,'ident sm+nt sm+nt sm+    jr    showt4
  1330. showt2:    call    crlfngrp(c    b
  1331.     jr    nz,showd    a,h
  1332.     push    hl
  1333.     call    print
  1334.     db    '[pause]',0
  1335.     call    cin
  1336.     cp    is ip    z,quit
  1337.     call    pettb    cr,'       ',cr,0
  1338.     op    o    hl
  1339.     php    bc
  1340.     push    bc
  1341.     jr    showb
  1342.     s
  1343. showd    a,h:    ld    a,b
  1344.         call    sec
  1345.     push    bc
  1346.     ld    b,a
  1347. showFI    ld    (gdsml
  1348.     ld    l
  1349.     to c    bobil
  1350.     dje
  1351.     jcou,showt1
  1352.     ld    a,c
  1353.         call    sel2tp    c
  1354.     ret    z
  1355.     call    crlf
  1356.     ret
  1357.  
  1358. ; Display help info
  1359. help:    call    crlf
  1360.     call    pname        ; print program name
  1361.     call    print
  1362.     db    ' v',[version/10]+'0','.',[version mod 10]+'0'
  1363.     on DDDD--    Sort and pack disk allocation groupsttlf,0
  1364.     call    pname
  1365.     call    print
  1366.     on D<tern> <s>disk?f
  1367.     db    ' ovist> is a file specifyetde efoiles and the dessibed 1:    ld    a
  1368.     db    'orld    (gl)
  1369.     ce of mobile fileso v If the option Sall    prigiven, 1:    ld    a
  1370.     db    'statistics on the state of dispecs:er of the disk entr4    1:    ld    a
  1371.     db    'produced, but no groups are moved.' N,0
  1372.     ret
  1373.  
  1374. ; Dis
  1375. dy program name from efcb
  1376. pname:    push    awhichtet)line
  1377. mefcb
  1378.     jr    z,pname3    ; no efcb (not expected)
  1379.     ld    noten        ; max length
  1380. pname1:    inc    hl
  1381.     ld    a,(hl)t
  1382.     cp    'idetict    bpname2
  1383.     clt t
  1384.     djnz    pname1
  1385. pname2:    op    o    hl
  1386.     po    af
  1387.     ret
  1388. pname3:    call    print
  1389.     db    'PACK',0    ; defose)a,(d
  1390.     jr    pname2
  1391.     
  1392. fixstr:    db    'F        ; weED'
  1393. mobstr:    db    'MOBILE'
  1394. wild:    db    '*:*.
  1395.     jr    nz,s
  1396. proc    ds    2        ; routine to do for each g
  1397.     call    ca
  1398. errors:    ds    2        ; error count while analysing file tern
  1399. dnbuf:    ds    l.e1 tace for dn spec
  1400. *.b:    ds    te e; dptd:ult user 
  1401.     pushner
  1402. disk*.i        ; disk to be packlon
  1403. group:    ds    2        ; laby roup to b
  1404.     ld    a,?llocated
  1405. secxabaddn:        ; pointl        ; o secxor translation table
  1406.  
  1407. dpb:    equ    $        ; disk de);ameters
  1408. sptaddn:        ; sectort er track
  1409. blshf*.i    x    d,ck shifh factapp
  1410.     oskng
  1411. ; block mask
  1412. exms
  1413.     call    s    ds    te e; extent mask
  1414. dsmaddn:        ; disk sizeplarmaddn:        ; directory size
  1415. allocaddn:        ; initial gh(atation
  1416. chks:    ds    2    k)eecked  direcxy secxors
  1417. toffaddn:        ; track offset
  1418.  
  1419. inlineaddn:        ; input linenotedrt 
  1420.  
  1421. linnumaddn:        ; line umber in input file
  1422. bufcntng
  1423. ; bytes lefh in input ased
  1424. stats:    ds    1        ; just dis
  1425. dyrst    0atistics if <> 0
  1426. ssige: ds    te e; distbidebuggetde info
  1427. fixmobng
  1428. call    fixed?
  1429.     p if <> 0
  1430. fixcnt:    ds    2        ; fixed file count
  1431. fixpntaddn:        ; base of efoile ersi
  1432. mobcntaddn:        ; mobile file count:    ds    2obpntaddn:        ; base of mobile file ersi
  1433. grptsit    ds    2        ; base of group table<
  1434. secxoraddn:    ld    llative secxetl.umber for getsec/putor mdirwrng
  1435. ; digdir8:ory write flag
  1436. grp1:    ds    2        ; group ased 1noteroup ass
  1437. grp2:    ds    2        ; groupf
  1438.     cer 2 address
  1439. grpselng
  1440. ; =0 : get to 1, istfrom 2
  1441.                 ; <>0: get to 2b    'Put from 1
  1442. rdcnt:    *.b)    ; groups read
  1443. wrcnt:    *.b)    ; groups written
  1444. ; tpng
  1445. ; current operation in case of s intrt
  1446. whyse ofy/        ; reason for s intrt
  1447.                 ;  1 - ^C
  1448.                 ;  2 - secxor read error
  1449.                 ;  3 - secxor write error
  1450. badsec:    ds    te ebioctor in error
  1451.  
  1452. mar
  1453.     call    s    ds    2        ; heap mark
  1454. heap:    ds    2        ; tstr:    of heap
  1455. $memryaddn:        ; end of program address (supplactec by linketo c
  1456.  
  1457.     end
  1458. app
  1459. mar
  1460.     call    s    ds    2        ; heap mark
  1461. heapaddn:    d gcall    crlca
  1462.  heap
  1463. $memb
  1464.             ds    2    ',[of pro