home *** CD-ROM | disk | FTP | other *** search
/ Oakland CPM Archive / oakcpm.iso / cpmug / cpmug024.ark / XDIR.ASM < prev    next >
Encoding:
Assembly Source File  |  1984-04-29  |  10.4 KB  |  448 lines

  1. ;            -  XDIR -
  2. ;                    BY S J SINGER
  3. ;
  4. ;    XDIR IS A CPM UTILITY THAT DISPLAYS A DISK DIRECTORY IN A MORE
  5. ;READABLE FORM. THE DIRECTORY IS READ FROM THE SPECIFIED DISK, SORTED
  6. ;THEN DISPLAYED IN A 3 COLUMN FORMAT. BOTH THE FILE NAMES AND FILE SIZES 
  7. ;IN 1 K GROUPS ARE DISPLAYED.
  8. ;    THE PRESENT VERSION OF XDIR HAS CERTAIN MINOR LIMITATIONS WHICH
  9. ;MAY BE EASILY REMOVED IF THEY CAUSE PROBLEMS.
  10. ;
  11. ;    1.  ONLY 48 FILES ARE DISPLAYED. THIS LIMIT IS SUFFICIENT FOR
  12. ;        ALMOST ALL DISKS AND LEAVES ROOM ON THE SCREEN FOR EDITING.
  13. ;        TO CHANGE THE NO OF LINES DISPLAYED, CHANGE THE LINES VARIABLE
  14. ;        IN THE DATA ALLOCATION SECTION OF THE PROGRAM. FOR EXAMPLE
  15. ;        TO DISPLAY A MAXIMUM OF 54 FILES CHANGE LINES TO 18.
  16. ;    2.  THE PRESENT VERSION READS GROUPS 0 AND 1 DIRECTLY FOR SPEED.
  17. ;        IF A DISK IS SET UP FOR MORE THAN 64 FILES OR THE BLOCK FORMAT
  18. ;        IS CHANGED THE READ ROUTINE WILL HAVE TO BE MODIFIED.
  19. ;
  20. ;    OCCASIONALLY THE FILE NAMES WILL BE DISPLAYED WITH THE FORMAT
  21. ;SCRAMBLED OR THE SPACE REMAINING ON THE DISK WILL NOT AGREE WITH THAT REPORTED
  22. ;BY THE STAT UTILITY. THIS ALMOST ALWAYS MEANS THE DISK DIRECTORY HAS BEEN
  23. ;MESSED UP SOMEHOW. USUALLY THE PROBLEM CAN BE CORRECTED BY COPYING ALL THE
  24. ;FILES TO ANOTHER DISK USING PIP.
  25. ;    XDIR WAS ASSEMBLED USING THE NEW CP/M MACRO ASSEMBLER AND USES A LARGE
  26. ;NUMBER OF MACROS. THESE ARE CONTAINED IN A LIBRARY CALLED MACRO.LIB WHICH
  27. ;IS REQUIRED IF THE PROGRAM IS TO BE REASSEMBLED.
  28. ;
  29. ;
  30. ;        COMMAND FORMAT
  31. ;
  32. ;    XDIR            DISPLAY DIRECTORY OF LOGGED DISK
  33. ;    XDIR A:            DISPLAY DIRECTORY OF DISK A
  34. ;    XDIR B:            DISPLAY DIRECTORY OF DISK B
  35. ;
  36. ;
  37.     MACLIB    MACRO        ;INCLUDE MACRO LIBRARY
  38.     ORG    100H        ;SET PROG START
  39.     LXI    H,0
  40.     DAD    SP        ;GET OLD STACK POINTER
  41.     SHLD    OLDSTK        ;SAVE IT
  42.     LXI    SP,NEWSTK    ;LOAD NEW STACK POINTER
  43.     JMP    DIR
  44. ;
  45. ;   GRPTS  CONVERT CPM GROUP AND SECTOR NUMBER TO TRK AND SEC
  46. ;
  47. GRPTS:    MVI    H,0        ;ZERO H
  48.     LDA    G        ;GROUP NO
  49.     MOV    L,A        ;TO L
  50.     MOV    D,H        ;ZERO    D
  51.     DAD    H
  52.     DAD    H
  53.     DAD    H        ;SHIFT LEFT 3
  54.     LDA    S        ;GET SECTOR NO
  55.     MOV    E,A        ;TO DE
  56.     DAD    D        ;HL HAS G*8+S
  57.     LXI    D,-26        ;DIVISOR
  58.     MVI    A,1        ;CONTAINS DIVIDEND
  59. DIV:    DAD    D        ;SUB 26
  60.     INR    A
  61.     JC    DIV        ;LOOP TILL MINUS
  62.     LXI    D,TABLE+26    ;INDEX INTO TABLE
  63.     DAD    D
  64.     STA    TRACK        ;STORE TRACK NO
  65.     MOV    A,M        ;GET SECTOR NO
  66.     STA    BSEC        ;SAVE IN BEGINNING SECTOR
  67.     STA    ESEC        ;SAVE IN END SECTOR TOO
  68.     RET
  69. ;
  70. ;    START OF DIRECTORY ROUTINE READ IN GROUPS 0 AND 1 AND STORE
  71. ;    DIRECTORY FILE NAMES NOT FLAGGED E5.  IF EXTENT NOT ZERO STORE
  72. ;    OVER PREVIOUS FILE NAME. TABLE OF POINTERS WILL BE BUILT IN PDIR
  73. ;
  74. DIR:    DISKIO    ?DRIVE
  75.     STA    NEWDRV
  76.     LDA    81H
  77.     ORA    A        ;CHECK IF INPUT BUFFER EMPTY
  78.     JZ    DDD
  79.     LDA    82H        ;CHECK NEW DRIVE
  80.     CPI    'A'
  81.     JNZ    DX1
  82.     XRA    A
  83.     STA    NEWDRV        ;SELECT DRIVE A
  84.     JMP    DDD
  85. DX1:    CPI    'B'
  86.     JNZ    DSKERR
  87.     MVI    A,1
  88.     STA    NEWDRV
  89. DDD:    PRINT    <CR,LF,LF,'                        DIRECTORY DRIVE - '>
  90.     LDA    NEWDRV        ;LOGGED DISK
  91.     ORA    A
  92.     JNZ    BDIR
  93.     PRINT    <'A',CR,LF,LF>
  94.     JMP    DIR2
  95. BDIR:    PRINT    <'B',CR,LF,LF>
  96.     CALL    FIXB        ;RESTORE DRIVE B
  97. DIR2:    XRA    A
  98.     STA    S        ;SECTOR COUNT
  99.     STA    G        ;GROUP 0 = DIRECTORY
  100.     STA    COUNT        ;COUNT OF DIRECTORY ENTRIES
  101.     FILL    PDIR,PDIR+130    ;ZERO DIRECTORY POINTER TABLE
  102.     LXI    H,DIRBUF    ;POINTS TO DIRECTORY BUFFER
  103.     SHLD    OUTB
  104.     LXI    H,PDIR        ;POINTER TABLE
  105.     SHLD    IPOINT
  106.     LDA    NEWDRV
  107.     MOV    E,A
  108.     DISKIO    LOGIN        ;LOG IN NEW DRIVE NO
  109. DIR4:    LXI    H,80H        ;POINTS TO INPUT BUFFER
  110.     SHLD    INB
  111.     CALL    GRPTS        ;COMPUTE TRACK AND SECTOR NO FROM G AND S
  112.     SETSEC    BSEC        ;SET SECTOR
  113.     SETTRK    TRACK        ;SET TRACK
  114.     CALLBIOS DREAD        ;READ DIRECT
  115. DIR6:    LHLD    OUTB        ;LOAD DESTINATION POINTER
  116.     XCHG            ;PUT IT IN DE
  117.     LHLD    INB        ;LOAD SOURCE POINTER
  118.     MVI    A,0E5H        ;FLAG BYTE
  119.     CMP    M        ;TEST FIRST BYTE
  120.     JNZ    DIR8
  121.     INX    H
  122.     CMP    M        ;TEST SECOND BYTE
  123.     JZ    SORT        ;SORT DIRECTORY
  124.     JMP    DIR12
  125. DIR8:    INX    H
  126.     SAVE    H,D
  127.     LXI    D,11        ;EXTENSION OFFSET
  128.     DAD    D
  129.     MOV    A,M
  130.     ORA    A
  131.     JZ    DIR10        ;IF EXTENT ZERO CONTINUE
  132.     LXI    H,0        ;ELSE, SEARCH FOR SAME NAME AND SWITCH
  133.     SHLD    J        ;INITIALIZE INDEX
  134. DIR9:    DLOAD    PDIR,J
  135.     MOV    A,H
  136.     ORA    L
  137.     JZ    DIR10        ;ERROR TABLE EMPTY
  138.     XCHG
  139.     LHLD    INB        ;POINTER TO NEW DIR ENTRY
  140.     SAVE    D,H
  141.     INX    H
  142.     MATCH    ,,11        ;COMPARE 11 CHARAACTERS
  143.     RESTORE    H,D
  144.     JZ    SWITCH        ;STORE NEW ENTRY OVER OLD
  145.     INDEX    J,2        ;INCR INDEX BY 2
  146.     JMP    DIR9
  147. SWITCH:    INX    H
  148.     MOVE    ,,15        ;OVERWRITE OLD ENTRY
  149.     RESTORE    H
  150.     JMP    DIR12
  151. DIR10:    RESTORE    D,H
  152.     MOVE    ,,15        ;MOVE THE DIRECTORY ENTRY
  153.     LDA    COUNT
  154.     INR    A
  155.     STA    COUNT        ;INCR COUNT OF DIRECTORY ENTRIES
  156.     LHLD    OUTB
  157.     DSTORE    0,IPOINT    ;INDEXED STORE HL
  158.     INDEX    OUTB,16
  159.     INDEX    IPOINT,2
  160. DIR12:    INDEX    INB,32        ;INCR POINTERS
  161.     LXI    D,100H
  162.     CPHL            ;LIMIT OF 4 ENTRIES
  163.     JNZ    DIR6
  164.     LDA    S
  165.     INR    A
  166.     STA    S        ;INCR DIRECTORY SECTOR COUNT
  167.     JMP    DIR4        ;READ ANOTHER BLOCK FROM DIRECTORY
  168. ;
  169. ;    THIS ROUTINE PRINTS THE DIRECTORY IN 3 COLUMNS. NO OF LINES
  170. ;    PRINTED IS CONTROLED BY VARIABLE LINES. ALL DIRECTORY NAMES
  171. ;    ARE PRESENT IN TABLE BUT ONLY A MAXIMUM OF 3*LINES WILL BE
  172. ;    PRINTED.
  173. ;
  174. DIR14:    LXI    H,0
  175.     SHLD    W        ;INITIALIZE ALLOCATION
  176.     SHLD    I        ;INITIALIZE INDEX
  177. DIR16:    DLOAD    PDIR,I        ;INDEX LOAD POINTER
  178.     DJZ    ENDFIL        ;EXIT IF POINTER ZERO
  179.     CALL    DIR20        ;CALL PRINT ROUTINE
  180.     PRINT    '         '
  181.     DLOAD    PDIR+LINES*2,I    ;POINTER COL 2
  182.     DJZ    DIR18        ;NO PRINT IF ZERO
  183.     CALL    DIR20        ;PRINT IT
  184.     PRINT    '         '
  185.     DLOAD    PDIR+LINES*4,I    ;POINTER COL 3
  186.     DJZ    DIR18
  187.     CALL    DIR20        ;CALL PRINT ROUTINE
  188. DIR18:    PRINT    CRLF,$
  189.     INDEX    I,2        ;INCR INDEX BY 2
  190.     LXI    D,LINES*2    ;CHECK INDEX LIMIT
  191.     CPHL
  192.     JZ    ENDFIL        ;EXIT WHEN INDEX 32
  193.     JMP    DIR16        ;PRINT SOME MORE
  194. ;
  195. ;    SUBROUTINE TO PRINT A SINGLE DIRECTORY ENTRY
  196. ;
  197. DIR20:    MVI    C,11        ;NAME LENGTH
  198. DIR22:    SAVE    B,H        ;SAVE REGISTERS
  199.     MVI    C,2
  200.     MOV    E,M        ;CHAR TO BE PRINTER
  201.     CALL    5        ;CALL BDOS
  202.     RESTORE    H,B        ;RESTORE THE REGISTERS
  203.     INX    H        ;INCR NAME POINTER
  204.     DCR    C        ;DECR CHAR COUNT
  205.     JZ    DIR24        ;PRINT SIZE
  206.     JMP    DIR22        ;LOOP TILL COUNT 0
  207. DIR24:    MOV    A,M        ;EXTENSION TO A
  208.     ADD    A
  209.     ADD    A
  210.     ADD    A
  211.     ADD    A        ;MULTIPLY BY 16
  212.     MOV    B,A        ;SAVE IN B
  213.     INX    H
  214.     INX    H
  215.     INX    H        ;ADD 3
  216.     MOV    A,M        ;GET RECORD COUNT
  217.     RRC
  218.     RRC
  219.     RRC            ;SHIFT RIGHT 3
  220.     PUSH    PSW
  221.     ANI    1FH        ;EXTRACT
  222.     LXI    H,0
  223.     MOV    L,A        ;NO TO HL TO PRINT
  224.     POP    PSW
  225.     ANI    0E0H        ;EXTRACT
  226.     JZ    DIR26
  227.     INX    H
  228. DIR26:    MOV    A,L
  229.     ADD    B
  230.     MOV    L,A
  231.     SAVE    H
  232.     LXI    D,10
  233.     CPHL
  234.     JM    DIR28
  235.     PRINT    '  '
  236.     JMP    DIR30
  237. DIR28:    PRINT    '   '
  238. DIR30:    POP    H
  239.     PUSH    H
  240.     XCHG
  241.     LHLD    W
  242.     DAD    D
  243.     SHLD    W
  244.     POP    H
  245.     DECOUT
  246.     PRINT    'K'
  247.     RET
  248. ;
  249. ;
  250. ;    THIS ROUTINE RESTORES DRIVE B
  251. ;
  252. FIXB:    LDA    NEWDRV        ;CHECK DRIVE NO
  253.     ORA    A
  254.     RZ            ;RETURN IF DRIVE A
  255.     LDA    NEWDRV        ;SELECT DRIVE B
  256.     MOV    E,A
  257.     DISKIO    LOGIN
  258.     XRA    A
  259.     STA    TNUM        ;SELECT TRACK ZERO
  260.     INR    A        ;SELECT SECTOR 1
  261.     STA    SNUM
  262.     SETSEC    SNUM
  263.     SETTRK    TNUM
  264.     CALLBIOS DHOME        ;HOME DRIVES
  265.     CALLBIOS DREAD        ;READ TRACK ZERO DIRECT
  266.     RET
  267. ;
  268. ;    THIS IS THE EXIT POINT FROM THE PROGRAM. PRINT NO OF FILES AND
  269. ;    SPACE REMAINING, RELOAD OLD STACK POINTER AND RETURN BACK TO CCP.
  270. ;
  271. ENDFIL:    PRINT    <CR,LF,'                '>
  272.     LXI    H,0
  273.     LDA    COUNT
  274.     MOV    L,A
  275.     DECOUT
  276.     PRINT    ' FILES    '
  277.     LHLD    W
  278.     MOV    A,L
  279.     CMA
  280.     INR    A        ;NEGATE
  281.     ADI    240
  282.     MOV    L,A
  283.     DECOUT
  284.     PRINT    <'K BYTES REMAINING ON DISK',CR,LF>
  285. EF1:    LHLD    OLDSTK
  286.     SPHL            ;RELOAD OLD STACK POINTER
  287.     RET            ;RETURN TO CCP WITHOUT REBOOT
  288. ;
  289. DSKERR:    PRINT    <CR,LF,'ERROR - SELECT DRIVE A OR B'>
  290.     JMP    EF1        ;EXIT
  291. ;
  292. ;    THIS SECTION DOES THE ACTUAL SORTING OF THE DIRECTORY. DURING THE
  293. ;    INPUT OF THE DIRECTORY NAMES, A TABLE OF ADDRESS POINTERS PDIR
  294. ;    WAS CONSTRUCTED. THE SORT ROUTINE SORTS THE ADDRESS POINTERS
  295. ;    RATHER THAN THE ACTUAL DIRECTORY. 
  296. ;    THIS IS AN IMPLEMENTATION OF C. A. R. HOARE'S QUICKSORT ALGORITHM.
  297. ;    THE ALGORITHM IS VERY FAST AND GENERALLY USEFUL, HOWEVER CAUTION
  298. ;    SHOULD BE USED WITH LARGE FILES. THE ALGORITHM IS RECURSIVE AND
  299. ;    THE STACK SPACE REQUIRED IS PROPORTIONAL TO THE NO OF ITEMS TO BE
  300. ;    SORTED.
  301. ;
  302. SORT:    LDA    COUNT        ;NO OF ENTRIES IN DIR
  303.     ORA    A
  304.     JZ    ENDFIL        ;EXIT IF DIRECTORY EMPTY
  305.     DCR    A
  306.     LXI    H,0        ;ZERO HL
  307.     MOV    L,A
  308.     DAD    H
  309.     SHLD    LAST        ;END OF ARRAY
  310.     LXI    H,0
  311.     SHLD    FIRST        ;START OF ARRAY
  312.     LXI    H,0FFFFH
  313.     PUSH    H        ;FLAG FOR STACK EMPTY
  314.     LHLD    FIRST
  315.     PUSH    H
  316.     LHLD    LAST
  317.     PUSH    H        ;STACK CONTAINS FIRST AND LAST INDICES
  318. ;
  319. ;    NOW POP STACK AND KEEP CALLING SPLIT RECURSIVELY TILL STACK EMPTY
  320. ;
  321. SORT2:    POP    H
  322.     MOV    A,H
  323.     CPI    0FFH
  324.     JZ    DIR14        ;GO TO PRINT ROUTINE
  325.     SHLD    J
  326.     SHLD    LAST
  327.     POP    H
  328.     SHLD    I
  329.     SHLD    FIRST
  330.     CALL    SPLIT
  331.     LHLD    I
  332.     XCHG
  333.     LHLD    FIRST
  334.     CPHL
  335.     JZ    SORT4
  336.     PUSH    H        ;I ON STACK
  337.     DCX    D
  338.     DCX    D
  339.     PUSH    D        ;J ON STACK
  340. SORT4:    LHLD    J
  341.     XCHG
  342.     LHLD    LAST
  343.     CPHL
  344.     JZ    SORT8
  345.     INX    D
  346.     INX    D
  347.     PUSH    D        ;NEW I ON STACK
  348.     PUSH    H        ;NEW J ON STACK
  349. SORT8:    JMP    SORT2
  350. ;
  351. ;    SPLIT SUBROUTINE DOES A SINGLE PARTITION ON AN ARRAY OF POINTERS
  352. ;
  353. SPLIT:    HALF    I
  354.     XCHG
  355.     HALF    J
  356.     DAD    D
  357.     MOV    A,L
  358.     ANI    0FEH
  359.     MOV    L,A
  360.     SHLD    K        ;K=I+J/2
  361.     DLOAD    PDIR,K
  362.     SHLD    W        ;W IS POINTER TO PARTITION ELEMENT OF PDIR
  363. SPLIT2:    DLOAD    PDIR,I        ;GET ITEM FROM LEFT
  364.     XCHG
  365.     LHLD    W        ;PARTITION ELEMENT
  366.     MATCH    ,,11        ;CONPARE KEYS
  367.     JP    SPLIT4
  368.     INDEX    I,2        ;INCR I
  369.     JMP    SPLIT2
  370. SPLIT4:    DLOAD    PDIR,J        ;GET ITEM FROM RIGHT
  371.     XCHG
  372.     LHLD    W        ;PARTITION ELEMENT
  373.     XCHG
  374.     MATCH    ,,11        ;COMPARE KEYS
  375.     JP    SPLIT6
  376.     INDEX    J,-2
  377.     JMP    SPLIT4        ;LOOP BACK
  378. SPLIT6:    LHLD    I
  379.     XCHG
  380.     LHLD    J
  381.     CPHL            ;COMPARE I AND J
  382.     RZ            ;RET IF I = J
  383.     DLOAD    PDIR,I        ;SWITCH POINTERS
  384.     SAVE    H
  385.     DLOAD    PDIR,J
  386.     DSTORE    PDIR,I
  387.     RESTORE    H
  388.     DSTORE    PDIR,J
  389.     JMP    SPLIT2
  390. ;
  391. ;   DATA ALLOCATIONS
  392. ;
  393. LINES    EQU    16        ;LINES PER PAGE ON DISPLAY
  394. SPACE:    DB    ' $'        ;ASCII SPACE
  395. CRLF:    DB    0DH,0AH,24H    ;ASCII CR LF
  396. I:    DW    0        ;PSEUDO INDEX REGISTER
  397. J:    DW    0        ;PSEUDO INDEX REGISTER
  398. K:    DW    0        ;PSEUDO INDEX REGISTER
  399. FIRST:    DW    0        ;START OF ARRAY
  400. LAST:    DW    0        ;END OF ARRAY
  401. W:    DW    0        ;STORAGE FOR PARTITION INDEX
  402. LINE:    DW    0        ;LINE NUMBER FOR LISTING
  403. IPOINT:    DW    00        ;VARIABLE BUFFER POINTER
  404. DRVNO:    DB    0        ;STORAGE FOR ORIGINALLY LOGGED DRIVE
  405. NEWDRV:    DB    0        ;STORAGE FOR NEW DRIVE NO
  406. TRACK:    DB    0        ;SELECTED TRACK
  407. BSEC:    DB    0        ;SELECTED BEGINNING SECTOR
  408. ESEC:    DB    0        ;SELECTED ENDING SECTOR
  409. TNUM:    DB    0        ;TRACK NUMBER
  410. SNUM:    DB    0        ;SECTOR NUMBER
  411. G:    DB    0        ;CPM GROUP NO
  412. S:    DB    0        ;SECTOR NO WITHIN GROUP G
  413. COUNT:    DB    0        ;COUNT OF DIRECTORY ENTRIES
  414. OLDSTK:    DW    0        ;STORAGE FOR OLD STACK POINTER
  415. ENDSTK:    DS    60        ;STORAGE FOR NEW STACK
  416. NEWSTK:    DW    0        ;NEW STACK
  417. INB:    DW    0        ;STORES POINTER TO INPUT BUFFER AREA
  418. OUTB:    DW    0        ;STORES POINTER TO DIRECTORY BUFFER AREA
  419. TABLE:    DB    01H        ;SECTOR LOOK UP TABLE
  420.     DB    07H
  421.     DB    0DH
  422.     DB    13H
  423.     DB    19H
  424.     DB    05H
  425.     DB    0BH
  426.     DB    11H
  427.     DB    17H
  428.     DB    03H
  429.     DB    09H
  430.     DB    0FH
  431.     DB    15H
  432.     DB    02H
  433.     DB    08H
  434.     DB    0EH
  435.     DB    14H
  436.     DB    1AH
  437.     DB    06H
  438.     DB    0CH
  439.     DB    12H
  440.     DB    18H
  441.     DB    04H
  442.     DB    0AH
  443.     DB    10H
  444.     DB    16H
  445. PDIR    DW    0        ;POINTER TABLE TO DIRECTORY (64 ENTRIES MAX)
  446. DIRBUF:    EQU    PDIR+130    ;START OF AREA USED TO STORE AND SORT DIRECTORY
  447.     END
  448.