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 / RCPM / LUX80.ARK / LUXDIR12.MAC < prev    next >
Text File  |  1987-02-02  |  13KB  |  607 lines

  1. ;    LUXDIR12.MAC    LUX Utility DIR transient        01-23-84
  2. ;
  3. ;  Copyright 1983 by Steven R. Holtzclaw and entered into the public domain.
  4. ;
  5. ;    Modification history in reverse order:
  6. ;
  7. ; 01-23-84    Small formatting changes - Added documentation header.
  8. ; LUXDIR12    Mark Howard
  9. ;
  10. ; 11-26-83    Original version ??
  11. ; LUXDIR11
  12. ;
  13. ;
  14.       .Z80
  15.     ASEG
  16.     ORG    100H
  17. ;
  18. CR    EQU    0DH
  19. LF    EQU    0AH
  20. ;
  21. DBUF    EQU    80H        ; default buffer
  22. FCB    EQU    05CH        ; default fcb
  23. FCB2    EQU    06CH
  24. MAXCOL    EQU    4        ; number of dir columns
  25. FENCE    EQU    '|'        ; fence character
  26. ;
  27. BEGIN:    LD    HL,0
  28.     ADD    HL,SP
  29.     LD    (STAKER+1),HL    
  30.     LD    A,(FCB2+1)    ; any files specified ?
  31.     CP    020H        ; space?
  32.     JR    NZ,BEGN2    ; ...no - continue
  33.     LD    HL,FCB2+1    ; index fcb2 filename
  34.     LD    A,'?'        ; wildcard
  35.     LD    B,11        ; 11 bytes to fill
  36. BEGN1:    LD    (HL),A        ; put a byte
  37.     INC    HL        ; next byte
  38.     DJNZ    BEGN1        ; do all 11 bytes
  39. ;
  40. BEGN2:    LD    HL,FCB
  41.     LD    DE,FCB1
  42.     LD    BC,12
  43.     LDIR            ; move to local fcb
  44.     LD    DE,DBUF        ; set default dma address
  45.     LD    C,26
  46.     CALL    5
  47.     LD    DE,FCB1        ; index .fcb for search
  48.     LD    C,17
  49.     CALL    5        ; search for first
  50.     INC    A
  51.     JP    Z,NOFILE    ; barf if not found
  52.     LD    DE,FCB1        ; index fcb for open
  53.     LD    C,15
  54.     CALL    5        ; open the file for input
  55.     XOR    A
  56.     LD    (DIRS),A    ; set dir sector count = 0
  57.     LD    (COL),A        ; set column count to 0
  58.     LD    HL,(6)        ; get bdos location
  59.     LD    DE,ORDER    ; get end of our program
  60.     SBC    HL,DE        ; available free memory
  61. ;
  62. ; calculate the approximate max number of directory entries
  63. ;
  64.     LD    B,4        ; loop here 4 times
  65. DIVLOP:    SRL    H
  66.     RR    L        ; * 2
  67.     DJNZ    DIVLOP        ; hl=hl/16
  68.     LD    (MAXDIR),HL    ; set the max number of dirs
  69.     ADD    HL,HL
  70.     LD    DE,ORDER
  71.     ADD    HL,DE        ; calculate the start of name table
  72.     LD    (NAMBUF),HL    ; base location for name table
  73.     LD    (TBLOC),HL    ; dito
  74.     CALL    ILPRT
  75.     DEFB    13,10
  76.     DEFB    'LBR directory for ',0
  77.     CALL    PFLNAM        ; print the file name
  78.     CALL    ILPRT
  79.     DEFB    13,10,10,0
  80. GETLP:    CALL    RDBLOK        ; get a block
  81.     LD    A,(DIRS)    ; increment
  82.     INC    A        ; directory
  83.     LD    (DIRS),A    ; and sector count
  84.     LD    HL,DBUF        ; point to first entry
  85.     LD    A,(HL)        ; get status byte
  86.     OR    A
  87.     JP    Z,STATOK    ; skip if active
  88. ;
  89. ; the first entry of this sector is inactive.
  90. ; if its not sector 1, all's well.  if it is,
  91. ; we dont have a lbr file!
  92. ;
  93.     LD    A,(DIRS)
  94.     DEC    A
  95.     JP    NZ,ENT2        ; skip if not first sector
  96.     CALL    ILPRT
  97.     DEFB    CR,LF
  98.     DEFB    'Directory error in ',0
  99.     CALL    PFLNAM        ; print the filename
  100.     CALL    ILPRT
  101.     DEFB    13,10,0
  102.     JP    EXIT
  103. ;
  104. STATOK:    LD    A,(DIRS)    ; check if first entry
  105.     DEC    A
  106.     JP    NZ,NOTD        ; skip if not 1st sector
  107.     LD    HL,DBUF+14    ; get lbr directory size...
  108.     LD    A,(HL)        ; ...into a
  109.     LD    (DIRSIZ),A    ; save dir size...
  110.     JP    ENT2        ; ...and skip
  111. ;
  112. NOTD:    LD    HL,DBUF+00H
  113.     CALL    ADDBUF
  114. ENT2:    LD    HL,DBUF+20H    ; point to second entry
  115.     CALL    ADDBUF        ; process it
  116. ENT3:    LD    HL,DBUF+40H    ; third entry
  117.     CALL    ADDBUF
  118. ENT4:    LD    HL,DBUF+60H    ; last entry for this sector
  119.     CALL    ADDBUF
  120.     LD    A,(DIRS)    ; get # of sectors done
  121.     LD    HL,DIRSIZ    ; compare with...
  122.     CP    (HL)        ; ...total directory size
  123.     JP    NZ,GETLP    ; loop if not finished...
  124.     JP    SPRINT        ; ...else sort and print the directory
  125. ;
  126. ; add a member name to nambuf names queue
  127. ;
  128. ADDBUF:    LD    A,(HL)        ; get status
  129.     OR    A
  130.     RET    NZ        ; skip if empty/inactive
  131.     INC    HL
  132.     LD    A,(HL)        ; get first byte of member name
  133.     OR    A
  134.     RET    Z        ; skip if a null entry
  135.     PUSH    HL        ; save dbuff pointer
  136.     LD    DE,FCB2+1    ; index 
  137.     LD    B,11        ; 11 characters to compare
  138. ADDBU1:    LD    A,(DE)        ; get character from fcb2
  139.     CP    '?'        ; '?' matches all
  140.     JR    Z,ADDBU2
  141.     CP    (HL)        ; same a command line
  142.     JR    NZ,ADDBU3    ; ...no - skip this entry
  143. ADDBU2:    INC    HL
  144.     INC    DE
  145.     DJNZ    ADDBU1        ; loop for 11 character compares
  146.     POP    HL
  147.     LD    BC,(COUNT)    ; dump entry counter
  148.     INC    BC
  149.     LD    (COUNT),BC
  150.     LD    DE,(NAMBUF)    ; get destination of move
  151.     LD    BC,11        ; 11 character file name
  152.     LDIR            ; move it
  153.     INC    HL        ; point to file size
  154.     INC    HL
  155.     LD    BC,2        ; 2 byte file size
  156.     LDIR            ; move it
  157.     LD    (NAMBUF),DE    ; save destination of next move
  158.     RET
  159. ADDBU3:    POP    HL        ; balance stack
  160.     RET
  161. ; sort and print
  162. SPRINT:    LD    HL,(COUNT)    ; get file name count
  163.     LD    (MAXNUM),HL    ; set number of times to print
  164.     LD    (MEMBRS),HL    ; set total number of members
  165.     LD    A,L
  166.     OR    H        ; any found?
  167.     JP    Z,DONE        ; exit if no files found
  168.     PUSH    HL        ; save file count
  169.     LD    (SUPSPC),A    ; enable leading zero suppression
  170. ; initialize the order table
  171.     LD    HL,(TBLOC)    ; get start of name table
  172.     EX    DE,HL        ; into de
  173.     LD    HL,ORDER    ; point to order table
  174.     LD    BC,13        ; entry length
  175. BLDORD:    LD    (HL),E        ; save low order address
  176.     INC    HL
  177.     LD    (HL),D        ; save high order address
  178.     INC    HL
  179.     EX    DE,HL        ; table addr to hl
  180.     ADD    HL,BC        ; point to next entry
  181.     EX    DE,HL
  182.     EX    (SP),HL        ; save tbl addr, fetch loop counter
  183.     DEC    HL        ; count down loop
  184.     LD    A,L
  185.     OR    H        ; more?
  186.     EX    (SP),HL        ; (restore tbl addr, save counter)
  187.     JP    NZ,BLDORD    ; yes, go do another one
  188.     POP    HL        ; clean loop counter off stack
  189.     LD    HL,(COUNT)    ; get count
  190.     LD    (SCOUNT),HL    ; save as # to sort
  191.     DEC    HL        ; only 1 entry?
  192.     LD    A,L
  193.     OR    H
  194.     JP    Z,DONE        ; yes, so skip sort
  195. ; this sort routine is adapted from software tools by kernigan and
  196. ; plaugher.
  197. SORT:    LD    HL,(SCOUNT)    ; number of entries
  198. SORT0:    OR    A        ; clear carry
  199.     LD    A,H        ; gap=gap/2
  200.     RRA    
  201.     LD    H,A
  202.     LD    A,L
  203.     RRA    
  204.     LD    L,A
  205.     OR    H        ; is it zero?
  206.     JP    Z,DONE        ; then none left
  207.     LD    A,L        ; make gap odd
  208.     OR    1
  209.     LD    L,A
  210.     LD    (GAP),HL
  211.     INC    HL        ; i=gap+1
  212. SORT2:    LD    (VARI),HL
  213.     EX    DE,HL
  214.     LD    HL,(GAP)
  215.     LD    A,E        ; varj=i-gap
  216.     SUB    L
  217.     LD    L,A
  218.     LD    A,D
  219.     SBC    A,H
  220.     LD    H,A
  221. SORT3:    LD    (VARJ),HL
  222.     EX    DE,HL
  223.     LD    HL,(GAP)    ; jg=varj+gap
  224.     ADD    HL,DE
  225.     LD    (VARJG),HL
  226.     LD    A,12        ; compare 12 chars
  227.     CALL    COMPARE        ; compare (varj) and (jg)
  228.     JP    P,SORT5        ; if a(varj)<=a(jg)
  229.     LD    HL,(VARJ)
  230.     EX    DE,HL
  231.     LD    HL,(VARJG)
  232.     CALL    SWAP        ; exchange a(varj) and a(jg)
  233.     LD    HL,(VARJ)    ; varj=varj-gap
  234.     EX    DE,HL
  235.     LD    HL,(GAP)
  236.     LD    A,E
  237.     SUB    L
  238.     LD    L,A
  239.     LD    A,D
  240.     SBC    A,H
  241.     LD    H,A
  242.     JP    M,SORT5        ; if varj>0    goto l3
  243.     OR    L        ; check for zero
  244.     JP    Z,SORT5
  245.     JP    SORT3
  246. SORT5:    LD    HL,(SCOUNT)    ; for later
  247.     EX    DE,HL
  248.     LD    HL,(VARI)    ; i=i+1
  249.     INC    HL
  250.     LD    A,E        ; if i<=n goto l2
  251.     SUB    L
  252.     LD    A,D
  253.     SBC    A,H
  254.     JP    P,SORT2
  255.     LD    HL,(GAP)
  256.     JP    SORT0
  257. ; new compare routine
  258. COMPARE:
  259.     LD    BC,ORDER-2
  260.     ADD    HL,HL
  261.     ADD    HL,BC
  262.     EX    DE,HL
  263.     ADD    HL,HL
  264.     ADD    HL,BC
  265.     EX    DE,HL
  266.     LD    C,(HL)
  267.     INC    HL
  268.     LD    B,(HL)
  269.     EX    DE,HL
  270.     LD    E,(HL)
  271.     INC    HL
  272.     LD    D,(HL)
  273.     EX    DE,HL
  274.     LD    E,A        ; count
  275. CMPLPE:    LD    A,(HL)
  276.     AND    7FH
  277.     LD    D,A
  278.     LD    A,(BC)
  279.     AND    7FH
  280.     CP    D
  281.     INC    BC
  282.     INC    HL
  283.     RET    NZ
  284.     DEC    E
  285.     JP    NZ,CMPLPE
  286.     RET    
  287. ; swap entries in the order table
  288. SWAP:    LD    BC,ORDER-2    ; table base
  289.     ADD    HL,HL        ; *2
  290.     ADD    HL,BC        ; + base
  291.     EX    DE,HL
  292.     ADD    HL,HL        ; *2
  293.     ADD    HL,BC        ; + base
  294.     LD    C,(HL)
  295.     LD    A,(DE)
  296.     EX    DE,HL
  297.     LD    (HL),C
  298.     LD    (DE),A
  299.     INC    HL
  300.     INC    DE
  301.     LD    C,(HL)
  302.     LD    A,(DE)
  303.     EX    DE,HL
  304.     LD    (HL),C
  305.     LD    (DE),A
  306.     RET    
  307. ; sort is all done - print entries
  308. DONE:
  309. PLOOP:    LD    HL,(MAXNUM)    ; get number of entries to print
  310.     LD    A,H
  311.     OR    L
  312.     JP    Z,PLOOP6    ; if all done
  313. ;
  314. PLOOP1:    LD    HL,ORDER    ; index order
  315.     LD    E,(HL)        ; get entry lsb
  316.     INC    HL        ; next
  317.     LD    D,(HL)        ; get entry msb
  318.     INC    HL        ; next
  319.     LD    (PLOOP1+1),HL    ; set next order address
  320.     EX    DE,HL        ; hl scans the entry
  321. ;
  322.     LD    B,8        ; 8 character file name
  323. PLOOP2:    LD    A,(HL)        ; get a byte
  324.     CALL    CTYPE        ; print it
  325.     INC    HL        ; next character
  326.     DJNZ    PLOOP2        ; do 8 characters
  327.     LD    A,'.'
  328.     CALL    CTYPE        ; print the seperator
  329.     LD    B,3        ; 3 character file name
  330. PLOOP3:    LD    A,(HL)        ; get a byte
  331.     CALL    CTYPE        ; print it
  332.     INC    HL        ; next character
  333.     DJNZ    PLOOP3        ; do 3 characters
  334.     LD    E,(HL)        ; get the number of sectors into de
  335.     INC    HL
  336.     LD    D,(HL)
  337.     EX    DE,HL        ; put number into hl
  338.     CALL    ADDTOT        ; add to total sectors
  339.     LD    B,3
  340. PLOOP4:    SRL    H
  341.     RR    L
  342.     DJNZ    PLOOP4
  343.     INC    HL        ; round up to nearest k
  344.     CALL    PNUMB1        ; print hl as 5-digit decimal
  345.     CALL    ILPRT        ; print the "s" in "sectors"
  346.     DEFB    'k',0
  347.     LD    C,6        ; bdos direct function call
  348.     LD    E,0FFH
  349.     CALL    5        ; get keyboard character
  350.     CP    3        ; control c?
  351.     JP    Z,EXIT        ; ...yes - abort
  352.     LD    HL,(MAXNUM)
  353.     DEC    HL
  354.     LD    (MAXNUM),HL    ; bump counter down
  355.     LD    A,(COL)        ; increment...
  356.     INC    A        ; ...column count
  357.     LD    (COL),A
  358.     CP    MAXCOL        ; reached max column?
  359.     JR    NZ,PLOOP5    ; not yet - back to caller
  360.     XOR    A        ; reached max column...
  361.     LD    (COL),A        ; ...set it to zero...
  362.     CALL    CRLF        ; ...and start a new line
  363.     JP    PLOOP
  364. PLOOP5:    LD    A,L
  365.     OR    H
  366.     JP    Z,PLOOP
  367.     CALL    ILPRT
  368.     DEFB    ' ',FENCE,' ',0
  369.     JP    PLOOP
  370. ;
  371. PLOOP6:    LD    HL,(SECTRS)    ; get sector count
  372.     LD    A,L
  373.     OR    H        ; test for no files
  374.     JR    NZ,PLOO6A    ; ...if there are any sectors in .lbr
  375.     CALL    ILPRT
  376.     DEFB    'No file(s)',0
  377.     JP    EXIT
  378. ;
  379. PLOO6A:    CALL    ILPRT
  380.     DEFB    13,10,13,10,'This file contains ',0
  381.     LD    HL,(MEMBRS)
  382.     CALL    PNUMB0
  383.     CALL    ILPRT
  384.     DEFB    ' members in ',0
  385.     LD    HL,(SECTRS)
  386.     CALL    PNUMB0
  387.     CALL    ILPRT
  388.     DEFB    ' active sectors for a total of ',0
  389.     LD    HL,(SECTRS)
  390.     LD    B,3
  391. PLOOP7:    SRL    H
  392.     RR    L
  393.     DJNZ    PLOOP7
  394.     INC    HL
  395.     CALL    PNUMB0
  396.     CALL    ILPRT
  397.     DEFB    'k',13,10,0
  398.     JP    EXIT
  399. ;
  400. RDBLOK:    LD    DE,DBUF
  401.     LD    C,26
  402.     CALL    5
  403.     LD    DE,FCB1        ; point to our fcb
  404.     LD    C,20
  405.     CALL    5
  406.     OR    A
  407.     RET    Z
  408.     CALL    ILPRT
  409.     DEFB    13,10,'Premature eof in file',13,10,0
  410.     JP    EXIT        ; abort
  411. ;
  412. ADDTOT:    PUSH    HL        ; save sector count
  413.     EX    DE,HL        ; keep sector count in 'DE' for the add
  414.     LD    HL,(SECTRS)
  415.     ADD    HL,DE
  416.     LD    (SECTRS),HL    ; put number back
  417.     JR    NC,ADDTO1    ; if no overflow
  418.     LD    A,(SECTRS+2)    ; get sectors msb
  419.     INC    A        ; + 1
  420.     LD    (SECTRS+2),A    ; put ot back
  421. ADDTO1:    POP    HL        ; restore sector count
  422.     RET            ; return to caller
  423.     
  424. ;
  425. NOFILE:    CALL    ILPRT
  426.     DEFB    CR,LF
  427.     DEFB    'No such file on disk',CR,LF,0
  428.     JP    EXIT
  429. ;
  430. EXIT:
  431. STAKER:    LD    SP,STACK
  432.     RET
  433. ;
  434. PFLNAM:    LD    HL,FCB1+1
  435.     LD    B,8        ; 8 character file name
  436. PFLNA1:    LD    A,(HL)        ; get character
  437.     CP    020H        ; space ?
  438.     CALL    NZ,CTYPE    ; no - print the character
  439.     INC    HL        ; next character
  440.     DJNZ    PFLNA1        ; do 8 characters
  441.     LD    A,'.'
  442.     CALL    CTYPE
  443.     LD    B,3        ; 3 character file type
  444. PFLNA2:    LD    A,(HL)        ; get character
  445.     CP    020H        ; space ?
  446.     CALL    NZ,CTYPE    ; no - print the character
  447.     INC    HL        ; next character
  448.     DJNZ    PFLNA2        ; do 3 characters
  449.     RET
  450. ;
  451. ; write a string of characters to the crt
  452. ;
  453. ILPRT:    EX    (SP),HL        ; save return address/get character pointer
  454. ILPRT1:    LD    A,(HL)        ; get a byte
  455.     OR    A        ; test it
  456.     JR    Z,ILPRT2    ; null - end of string
  457.     CALL    CTYPE        ; else type the character
  458.     INC    HL        ; next character
  459.     JR    ILPRT1        ; loop for more
  460. ILPRT2:    EX    (SP),HL        ; restore return address
  461.     RET            ; return to caller
  462. ;
  463. CTYPE:    PUSH    AF        ; save all registers
  464.     PUSH    BC
  465.     PUSH    DE
  466.     PUSH    HL
  467.     AND    07FH        ; be sure its ascii
  468.     LD    E,A        ; into 'E'
  469.     LD    C,6        ; cpm direct console function
  470.     CALL    5
  471.     POP    HL        ; restore all registers
  472.     POP    DE
  473.     POP    BC
  474.     POP    AF
  475.     RET            ; return to caller
  476. ;
  477. CRLF:    LD    A,13
  478.     CALL    CTYPE
  479.     LD    A,10
  480.     JR    CTYPE
  481. ;
  482. PUTRG    MACRO    
  483.     PUSH    BC        ; save bc, de, hl
  484.     PUSH    DE
  485.     PUSH    HL
  486.     ENDM    
  487. GETRG    MACRO    
  488.     POP    HL        ; restore hl, de, bc
  489.     POP    DE
  490.     POP    BC
  491.     ENDM    
  492. ;
  493. PNUMB0:
  494.     PUSH    AF        ; save all regs
  495.     PUTRG    
  496.     LD    A,1        ; a=1
  497.     LD    (LSFLG0),A    ; turn on leading <sp>
  498.     LD    (SPCFLG),A
  499.     JR    PHDC
  500. ;
  501. ;
  502. ;    print hl as decimal characters w/leading spaces in 5-char field
  503. ;
  504. PNUMB1:    PUSH    AF        ; save all regs
  505.     PUTRG    
  506.     LD    A,1        ; a=1
  507.     LD    (LSFLG0),A    ; turn on leading <sp>
  508.     LD    A,0
  509.     LD    (SPCFLG),A
  510. ;
  511. PHDC:    LD    DE,1000        ; print 1000'S
  512.     CALL    PHDC1
  513.     LD    DE,100        ; print 100'S
  514.     CALL    PHDC1
  515.     LD    DE,10        ; print 10'S
  516.     CALL    PHDC1
  517.     LD    A,L        ; print 1'S
  518.     ADD    A,'0'        ; convert to ascii
  519.     CALL    CTYPE
  520.     GETRG            ; restore all regs
  521.     POP    AF
  522.     RET    
  523. ;
  524. LSFLG0:    DEFS    1        ; leading <sp> flag
  525. ;    
  526. ;  divide hl by de and print quotient with leading <sp>s
  527. ;
  528. PHDC1:    LD    C,0        ; set count
  529. PHDC2:    LD    A,L        ; sub e from l
  530.     SUB    E
  531.     LD    L,A        ; result in l
  532.     LD    A,H        ; sub d from h w/borrow
  533.     SBC    A,D
  534.     LD    H,A        ; result in h
  535.     JP    C,PHDC3        ; done if carry set (further borrow)
  536.     INC    C        ; incr count
  537.     JP    PHDC2
  538. PHDC3:    LD    A,L        ; add e to l
  539.     ADD    A,E
  540.     LD    L,A        ; result in l
  541.     LD    A,H        ; add d to h w/carry
  542.     ADC    A,D
  543.     LD    H,A        ; result in h
  544.     LD    A,C        ; get result
  545.     OR    A        ; check for zero
  546.     JP    NZ,PHDC4
  547.     LD    A,(LSFLG0)    ; check for leading <sp>
  548.     OR    A        ; print value if not (a=0)
  549.     JP    Z,PHDC4
  550.     LD    A,(SPCFLG)
  551.     OR    A
  552.     RET    NZ
  553.     LD    A,' '        ; print <sp>
  554.     CALL    CTYPE
  555.     RET    
  556. PHDC4:    XOR    A        ; turn off leading <sp>
  557.     LD    (LSFLG0),A
  558.     LD    A,C        ; get value
  559.     ADD    A,'0'        ; convert to ascii
  560.     CALL    CTYPE
  561.     RET    
  562. ;
  563. SPCFLG:    DEFB    0
  564. SECTRS:    DEFB    0,0,0
  565. MAXNUM:    DEFW    0
  566. MAXDIR:    DEFW    0
  567. NAMBUF:    DEFW    0
  568. MEMBRS:    DEFW    0
  569. DIRS:    DEFB    0        ; # of dir sectors processed
  570. DIRSIZ:    DEFB    0        ; # of total dir sectors
  571. COL:    DEFB    0        ; column count
  572. SUPSPC:    DEFB    0
  573. TBLOC:    DEFW    0
  574. COUNT:    DEFW    0
  575. SCOUNT:    DEFW    0
  576. GAP:    DEFW    0
  577. VARI:    DEFW    0
  578. VARJ:    DEFW    0
  579. VARJG:    DEFW    0
  580. FCB1:    DEFS    36
  581.     DEFS    50        ; 25 level stack
  582. STACK:    DEFW    0        ; save cp/m stack pointer here
  583. ORDER    EQU    $
  584. ;
  585.     END
  586.