home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / CPM / UTILS / DIRUTL / SD-22.ASM < prev    next >
Assembly Source File  |  2000-06-30  |  20KB  |  963 lines

  1. ;            SD.ASM ver 2.2
  2. ;           (revised 6/5/81)
  3. ;
  4. ;        SUPER DIRECTORY PROGRAM
  5. ;          by Bruce R. Ratoff
  6. ;
  7. ;Displays the directory of a CP/M disk, sorted alphabetically,
  8. ;with the file size in K, rounded to the nearest CP/M block size.
  9. ;
  10. ;This latest variation on a common theme will automatically adjust
  11. ;itself for any block size and directory length under CP/M 1.4 or 2.x
  12. ;or MP/M (any version).  If the screen fills, program will pause until
  13. ;a key is struck (see NPL and LPS equates below).  Total space used
  14. ;and number of files are printed at end.
  15. ;
  16. ;Command: SD FILENAME.FILETYPE or just SD
  17. ;
  18. ;Allows '*' or '?' type specifications.  Drive name may also be
  19. ;specified.  Ignores "SYS" files unless SOPT is TRUE and 'S' option
  20. ;is given (i.e., SD *.* S will print all files).
  21. ;
  22. ;==============================================================
  23. ;
  24. ;Fixes/updates (in reverse order to minimize reading time):
  25. ;
  26. ;06/05/81 Added PGPAWZ (page pause) conditional for remote
  27. ;      CP/M systems where pausing may not be wanted.
  28. ;      Setting PGPAWZ and REPSIZ to FALSE will result in
  29. ;      a display like DIR, but sorted and with the stat
  30. ;      of space remaining.  Rearranged equates to allow
  31. ;      15 lines per page when narrow display is chosen.
  32. ;      (KBP)
  33. ;
  34. ;06/01/81 Added version number, restored CTL-C break, added
  35. ;      CTL-C test to allow break at page pause, added
  36. ;      routine to gobble up any waiting console character
  37. ;      at EXIT, added conditional assembly to allow no
  38. ;      report of file sizes, added conditional assembly
  39. ;      for direct console I/O for remote CP/M systems
  40. ;      where phone line noise would garbage display.  (KBP)
  41. ;
  42. ;05/06/81 Corrected double printing of drive name in CALLB.
  43. ;      Error only occurred with narrow display when file
  44. ;      wasn't found. (Tim Nicholas)
  45. ;
  46. ;02/06/81 Changed sort to have odd gap (K+P say its faster)
  47. ;
  48. ;01/06/80 Changed sort from bubble sort to shell sort
  49. ;      for faster speed.
  50. ;
  51. ;12/24/80 Changed BIOS conout to BDOS conout to allow
  52. ;      printing of directory with CTL-P.  Also added
  53. ;      print of remaining space even if file not
  54. ;      found. (Steve Nossen)
  55. ;
  56. ;12/15/80 Added space suppression when printing file
  57. ;      totals.  (KBP)
  58. ;
  59. ;12/14/80 Added logic to print space remaining on disk.
  60. ;      Changed ^C test so that interrupting character is
  61. ;      not echoed (makes remote use cleaner).  (BRR)
  62. ;
  63. ;12/02/80 Fixed bug in print routine which compared last file
  64. ;      against garbage before printing. (BRR)
  65. ;
  66. ;11/29/80 Changed to allow printing 4 file names. (Ben Bronson
  67. ;      and Keith Petersen)
  68. ;
  69. ;11/22/80 Fixed bug in handling >256 files.  Changed abort test
  70. ;      in print routine to only abort on control-c.  (BRR)
  71. ;
  72. ;Based on 'DIRS' by Keith Petersen, W8SDZ
  73. ;
  74. ;NOTE: If you add improvements or otherwise update
  75. ;this program, please modem a copy of the new file
  76. ;to "TECHNICAL CBBS" in Dearborn, Michigan - phone
  77. ;313-846-6127 (110, 300, 450 or 600 baud).  Use the
  78. ;filename SD-NEW.NEW. (KBP)
  79. ;
  80. ;Set 'RMAC' TRUE to assemble with relocating assembler
  81. ;(requires link with PAGE 0 equates in separate file).
  82. ;
  83. ;==============================================================
  84. ;
  85. FALSE    EQU    0      ;DEFINE LOGICAL FALSE
  86. TRUE    EQU    NOT FALSE ;DEFINE LOGICAL TRUE
  87. ;
  88. ALTCPM    EQU    FALSE    ;PUT TRUE HERE FOR H8 OR TRS-80
  89. RMAC    EQU    FALSE    ;PUT TRUE HERE FOR ASSEMBLY BY RMAC
  90. SOPT    EQU    TRUE     ;PUT TRUE TO ALLOW 'SD *.* S' FORM
  91. WIDE    EQU    TRUE     ;PUT TRUE TO ALLOW 4 NAMES ACROSS
  92. REPSIZ    EQU    TRUE     ;PUT TRUE TO REPORT FILE SIZES
  93. PGPAWZ    EQU    TRUE     ;PUT TRUE FOR PAUSE AFTER EACH PAGE
  94. DIRCON    EQU    FALSE    ;PUT TRUE FOR DIRECT CONSOLE OUTPUT
  95. ;
  96. DELIM    EQU    ':'    ;FENCE (DELIMITER) CHARACTER
  97. ;
  98.     IF    WIDE
  99. NPL    EQU    4    ;NUMBER OF NAMES PER LINE
  100. LPS    EQU    23    ;NUMBER OF LINES PER SCREEN
  101.     ENDIF
  102. ;
  103.     IF    NOT WIDE
  104. NPL    EQU    3    ;NUMBER OF NAMES PER LINE
  105. LPS    EQU    15    ;NUMBER OF LINES PER SCREEN
  106.     ENDIF
  107. ;
  108.     IF    ALTCPM
  109. BASE    EQU    4200H
  110. TPA    EQU    4300H
  111.     ENDIF
  112. ;
  113.     IF    RMAC
  114.     EXTRN    BASE,FCB,BDOS    ;MAKE BASE EXTERNAL
  115.     ENDIF
  116. ;
  117.     IF    (NOT ALTCPM) AND (NOT RMAC)
  118. BASE    EQU    $    ;WILL DEFAULT TO 0 (OR 100H WITH MAC +R OPTION)
  119. TPA    EQU    100H
  120.     ENDIF
  121. ;
  122.     IF    NOT RMAC
  123. FCB    EQU    BASE+5CH
  124. BDOS    EQU    BASE+5
  125.     ENDIF
  126. ;
  127.     IF    NOT RMAC
  128.     ORG    TPA
  129.     ENDIF
  130. ;
  131. START:    LXI    H,0
  132.     DAD    SP    ;HL=OLD STACK
  133.     SHLD    STACK     ;SAVE IT
  134.     LXI    SP,STACK ;GET NEW STACK
  135. ;
  136.     IF    SOPT
  137.     LDA    FCB+17     ;SAVE S OPTION FLAG
  138.     STA    SOPFLG     ;(BLANK OR LETTER S)
  139.     ENDIF
  140. ;
  141.     SUB    A
  142.     STA    USERNO     ;DEFAULT TO USER 0
  143.     STA    LINCNT     ;CLEAR COUNT OF LINES ON SCREEN
  144.     MVI    C,12
  145.     CALL    BDOS     ;CHECK CP/M VERSION
  146.     SHLD    VERFLG     ;LO ORD >0 IF 2.x, HI ORD>0 IF MP/M
  147.     MOV    A,L     ;2.x?
  148.     ORA    A
  149.     JZ    CHKDRV     ;SKIP USER NUMBER STUFF IF 1.4
  150.     MVI    E,0FFH
  151.     MVI    C,CURUSR ;INTERROGATE USER NUMBER
  152.     CALL    BDOS
  153.     STA    USERNO
  154.     LDA    MPMFLG     ;MP/M?
  155.     ORA    A    ;IF SO, TYPE HEADING LINE
  156.     JZ    CHKDRV     ; ELSE SKIP IT
  157.     LXI    D,USRMSG ;DISPLAY IT
  158.     MVI    C,PRINT
  159.     CALL    BDOS     ;FIRST PART OF MESSAGE
  160.     LDA    USERNO
  161.     CPI    10    ;IF USER NO. > 9 PRINT LEADING 1
  162.     JC    DUX
  163.     MVI    A,'1'
  164.     CALL    TYPE
  165.     LDA    USERNO     ;PRINT LOW DIGIT OF USER NO.
  166.     SUI    10
  167. ;
  168. DUX:    ADI    '0'
  169.     CALL    TYPE
  170.     LXI    D,USRMS2 ;PRINT TAIL OF MESSAGE
  171.     MVI    C,PRINT
  172.     CALL    BDOS
  173.     MVI    A,1
  174.     STA    LINCNT    ;WE USED A LINE
  175. ;
  176. CHKDRV:    LXI    H,FCB
  177.     MOV    A,M    ;GET DRIVE NAME
  178.     ORA    A    ;ANY SPECIFIED?
  179.     JNZ    START2    ;YES SKIP NEXT ROUTINE
  180.     MVI    C,CURDSK
  181.     CALL    BDOS    ;GET CURRENT DISK NR
  182.     INR    A    ;MAKE A:=1
  183.     STA    FCB
  184. ;
  185. START2:    ADI    'A'-1    ;MAKE IT PRINTABLE
  186.     STA    DRNAM    ;SAVE FOR LATER
  187.     LXI    H,FCB+1    ;POINT TO NAME
  188.     MOV    A,M    ;ANY SPECIFIED?
  189.     CPI    ' '
  190.     JNZ    GOTFCB
  191. ;No FCB    - make FCB all '?'
  192.     MVI    B,11    ;FN+FT COUNT
  193. ;
  194. QLOOP:    MVI    M,'?'    ;STORE '?' IN FCB
  195.     INX    H
  196.     DCR    B
  197.     JNZ    QLOOP
  198. ;
  199. GOTFCB:    MVI    A,'?'    ;FORCE WILD EXTENT
  200.     STA    FCB+12
  201.     LDA    FCB    ;CHECK FOR EXPLICIT DRIVE
  202.     DCR    A
  203.     MOV    E,A    ;SELECT SPECIFIED DRIVE
  204.     MVI    C,SELDSK
  205.     CALL    BDOS
  206.     SUB    A    ;ZAP DRIVE NO. IN FCB SO SELECTED DRIVE IS USED
  207.     STA    FCB
  208.     LDA    VERFLG    ;CHECK VERS.
  209.     ORA    A
  210.     JZ    V14    ;PRE-2.x...GET PARAMS THE 1.4 WAY
  211. ;
  212.     MVI    C,CURDPB;IT'S 2.x OR MP/M...REQUEST DPB
  213.     CALL    BDOS
  214.     INX    H
  215.     INX    H
  216.     MOV    A,M    ;GET BLOCK SHIFT
  217.     STA    BLKSHF
  218.     INX    H    ;BUMP TO BLOCK MASK
  219.     MOV    A,M
  220.     STA    BLKMSK    ;GET IT
  221.     INX    H
  222.     INX    H
  223.     MOV    E,M    ;GET MAX BLOCK #
  224.     INX    H
  225.     MOV    D,M
  226.     XCHG
  227.     SHLD    BLKMAX    ;SAVE IT
  228.     XCHG
  229.     INX    H
  230.     MOV    E,M    ;GET DIRECTORY SIZE
  231.     INX    H
  232.     MOV    D,M
  233.     XCHG
  234.     SHLD    DIRMAX    ;SAVE IT
  235.     JMP    SETTBL    ;DONE...GO SET UP ORDER TABLE
  236. ;
  237. V14:    LHLD    BDOS+1    ;GET PARAMS 1.4 STYLE
  238.     MVI    L,3BH    ;POINT TO DIRECTORY SIZE
  239.     MOV    E,M    ;GET IT
  240.     MVI    D,0    ;FORCE HI ORD TO 0
  241.     PUSH    D    ;SAVE FOR LATER
  242.     INX    H    ;POINT TO BLOCK SHIFT
  243.     MOV    A,M    ;FETCH
  244.     STA    BLKSHF    ;SAVE
  245.     INX    H    ;POINT TO BLOCK MASK
  246.     MOV    A,M    ;FETCH IT
  247.     STA    BLKMSK    ;AND SAVE IT
  248.     INX    H
  249.     MOV    E,M    ;GET MAX. BLOCK NO.
  250.     MVI    D,0
  251.     XCHG
  252.     SHLD    BLKMAX    ;SAVE IT
  253.     POP    H    ;RESTORE DIRECTORY SIZE
  254.     SHLD    DIRMAX    ;SAVE IT
  255. ;
  256. SETTBL:    INX    H    ;DIRECTORY SIZE IS DIRMAX+1
  257.     DAD    H    ;DOUBLE DIRECTORY SIZE
  258.     LXI    D,ORDER    ;TO GET SIZE OF ORDER TABLE
  259.     DAD    D    ;ALLOCATE ORDER TABLE
  260.     SHLD    TBLOC    ;NAME TABLE BEGINS WHERE ORDER TABLE ENDS
  261.     SHLD    NEXTT
  262.     XCHG
  263.     LHLD    BDOS+1    ;MAKE SURE WE HAVE ROOM TO CONTINUE
  264.     MOV    A,E
  265.     SUB    L
  266.     MOV    A,D
  267.     SBB    H
  268.     JNC    OUTMEM
  269. ;
  270. ;Look up the FCB in the    directory
  271. SFIRST:    MVI    C,FSRCHF ;GET 'SEARCH FIRST' FNC
  272.     LXI    D,FCB
  273.     CALL    BDOS    ;READ FIRST
  274.     INR    A    ;WERE THERE ANY?
  275.     JNZ    SOME    ;GOT SOME
  276. ;
  277. NONE:    LXI    D,FNF    ;PREPARE MP/M ERROR MESSAGE
  278.     LDA    MPMFLG
  279.     ORA    A    ;USE IT IF REALLY MP/M
  280.     JNZ    ERXIT1
  281.     CALL    ERXIT    ;ELSE USE CP/M ERROR MESSAGE
  282.     DB    'NO FILE$'
  283. FNF:    DB    'File not found.$'
  284. ;
  285. USRMSG:    DB    'Directory for user $'
  286. USRMS2:    DB    ':',13,10,'$'
  287. ;
  288. ;Read more directory entries
  289. MORDIR:    MVI    C,FSRCHN ;SEARCH NEXT
  290.     LXI    D,FCB
  291.     CALL    BDOS    ;READ DIR ENTRY
  292.     INR    A    ;CHECK FOR END (0FFH)
  293.     JZ    SPRINT    ;NO MORE - SORT & PRINT
  294. ;
  295. ;Point to directory entry 
  296. SOME:    DCR    A    ;UNDO PREV 'INR A'
  297.     ANI    3    ;MAKE MODULUS 4
  298.     ADD    A    ;MULTIPLY...
  299.     ADD    A    ;..BY 32 BECAUSE
  300.     ADD    A    ;..EACH DIRECTORY
  301.     ADD    A    ;..ENTRY IS 32
  302.     ADD    A    ;..BYTES LONG
  303.     LXI    H,BASE+81H ;POINT TO BUFFER
  304.             ;(SKIP TO FN/FT)
  305.     ADD    L    ;POINT TO ENTRY
  306.     ADI    9    ;POINT TO SYS BYTE
  307.     MOV    L,A    ;SAVE (CAN'T CARRY TO H)
  308. ;
  309.     IF    SOPT
  310.     LDA    SOPFLG    ;DID USER REQUEST SYS FILES?
  311.     CPI    'S'
  312.     JZ    SYSFOK
  313.     ENDIF
  314. ;
  315.     MOV    A,M    ;GET SYS BYTE
  316.     ANI    80H    ;CHECK BIT 7
  317.     JNZ    MORDIR    ;SKIP THAT FILE
  318. ;
  319. SYSFOK:    MOV    A,L    ;GO BACK NOW
  320.     SUI    10    ;BACK TO USER NUMBER (ALLOC FLAG)
  321.     MOV    L,A    ;HL POINTS TO ENTRY NOW
  322. ;
  323.     LDA    USERNO    ;GET CURRENT USER
  324.     CMP    M
  325.     JNZ    MORDIR    ;IGNORE IF DIFFERENT
  326.     INX    H
  327. ;
  328. ;Move entry to table
  329.     XCHG        ;ENTRY TO DE
  330.     LHLD    NEXTT    ;NEXT TABLE ENTRY TO HL
  331.     MVI    B,12    ;ENTRY LENGTH (NAME, TYPE, EXTENT)
  332. ;
  333. TMOVE:    LDAX    D    ;GET ENTRY CHAR
  334.     ANI    7FH    ;REMOVE ATTRIBUTES
  335.     MOV    M,A    ;STORE IN TABLE
  336.     INX    D
  337.     INX    H
  338.     DCR    B    ;MORE?
  339.     JNZ    TMOVE
  340.     INX    D
  341.     INX    D    ;POINT TO SECTOR COUNT
  342.     LDAX    D    ; GET IT
  343.     MOV    M,A    ;STORE IN TABLE
  344.     INX    H
  345.     SHLD    NEXTT    ;SAVE UPDATED TABLE ADDR
  346.     XCHG
  347.     LHLD    COUNT    ;GET PREV COUNT
  348.     INX    H
  349.     SHLD    COUNT
  350.     LXI    H,13    ;SIZE OF NEXT ENTRY
  351.     DAD    D
  352.     XCHG        ;FUTURE NEXTT IS IN DE
  353.     LHLD    BDOS+1    ;PICK UP TPA END
  354.     MOV    A,E
  355.     SUB    L    ;COMPARE NEXTT-TPA END
  356.     MOV    A,D
  357.     SBB    H
  358.     JC    MORDIR    ;IF TPA END>NEXTT THEN LOOP BACK FOR MORE
  359. ;
  360. OUTMEM:    CALL    ERXIT
  361.     DB    'Out of memory.',13,10,'$'
  362. ;
  363. ;Sort and print
  364. SPRINT:    LHLD    COUNT    ;GET FILE NAME COUNT
  365.     MOV    A,L
  366.     ORA    H    ;ANY FOUND?
  367.     JZ    NONE    ;NO, EXIT
  368.     PUSH    H    ;SAVE FILE COUNT
  369. ;Init the order    table
  370.     LHLD    TBLOC    ;GET START OF NAME TABLE
  371.     XCHG        ;INTO DE
  372.     LXI    H,ORDER    ;POINT TO ORDER TABLE
  373.     LXI    B,13    ;ENTRY LENGTH
  374. ;
  375. BLDORD:    MOV    M,E    ;SAVE LO ORD ADDR
  376.     INX    H
  377.     MOV    M,D    ;SAVE HI ORD ADDR
  378.     INX    H
  379.     XCHG        ;TABLE ADDR TO HL
  380.     DAD    B    ;POINT TO NEXT ENTRY
  381.     XCHG
  382.     XTHL        ;SAVE TBL ADDR, FETCH LOOP COUNTER
  383.     DCX    H    ;COUNT DOWN LOOP
  384.     MOV    A,L
  385.     ORA    H    ;MORE?
  386.     XTHL        ;(RESTORE TBL ADDR, SAVE COUNTER)
  387.     JNZ    BLDORD    ;..YES, GO DO ANOTHER ONE
  388.     POP    H    ;CLEAN LOOP COUNTER OFF STACK
  389.     LHLD    COUNT    ;GET COUNT
  390.     SHLD    SCOUNT    ;SAVE AS # TO SORT
  391.     DCX    H    ;ONLY 1 ENTRY?
  392.     MOV    A,L
  393.     ORA    H
  394.     JZ    DONE    ;..YES, SO SKIP SORT
  395. ;
  396. ; THIS SORT ROUTINE IS ADAPTED FROM SOFTWARE TOOLS
  397. ; BY KERNIGAN AND PLAUGHER.
  398. ;
  399. SORT:    LHLD    SCOUNT    ;NUMBER OF ENTRIES
  400. ;
  401. L0:    ORA    A    ;CLEAR CARRY
  402.     MOV    A,H    ;GAP=GAP/2
  403.     RAR
  404.     MOV    H,A
  405.     MOV    A,L
  406.     RAR
  407.     MOV    L,A
  408.     ORA    H    ;IS IT ZERO?
  409.     JZ    DONE    ;THEN NONE LEFT
  410.     MOV    A,L    ;MAKE GAP ODD
  411.     ORI    01
  412.     MOV    L,A
  413.     SHLD    GAP
  414.     INX    H    ;I=GAP+1
  415. ;
  416. L2:    SHLD    I
  417.     XCHG
  418.     LHLD    GAP
  419.     MOV    A,E    ;J=I-GAP
  420.     SUB    L
  421.     MOV    L,A
  422.     MOV    A,D
  423.     SBB    H
  424.     MOV    H,A
  425. ;
  426. L3:    SHLD    J
  427.     XCHG
  428.     LHLD    GAP    ;JG=J+GAP
  429.     DAD    D
  430.     SHLD    JG
  431.     MVI    A,12    ;COMPARE 12 CHARS
  432.     CALL    COMPARE    ;COMPARE (J) AND (JG)
  433.     JP    L5    ;IF A(J)<=A(JG)
  434.     LHLD    J
  435.     XCHG
  436.     LHLD    JG
  437.     CALL    SWAP    ;EXCH A(J) AND A(JG)
  438.     LHLD    J    ;J=J-GAP
  439.     XCHG
  440.     LHLD    GAP
  441.     MOV    A,E
  442.     SUB    L
  443.     MOV    L,A
  444.     MOV    A,D
  445.     SBB    H
  446.     MOV    H,A
  447.     JM    L5    ;IF J>0 GOTO L3
  448.     ORA    L    ;CHECK FOR ZERO
  449.     JZ    L5
  450.     JMP    L3
  451. ;
  452. L5:    LHLD    SCOUNT    ;FOR LATER
  453.     XCHG
  454.     LHLD    I    ;I=I+1
  455.     INX    H
  456.     MOV    A,E    ;IF I<=N GOTO L2
  457.     SUB    L
  458.     MOV    A,D
  459.     SBB    H
  460.     JP    L2
  461.     LHLD    GAP
  462.     JMP    L0
  463. ;
  464. ;Sort is all done - print entries
  465. ;
  466. DONE:    LXI    H,ORDER
  467.     SHLD    NEXTT
  468. ;
  469.     IF    NOT WIDE
  470.     CALL    DRPRNT    ;PRINT DRIVE NAME
  471.     ENDIF
  472. ;
  473.     MVI    C,NPL    ;NR. OF NAMES PER LINE
  474.     LXI    H,0    ;ZERO OUT
  475.     SHLD    TOTSIZ    ; TOTAL K USED
  476.     SHLD    TOTFIL    ; AND TOTAL FILES
  477. ;
  478. ;Print an entry
  479. ENTRY:    LHLD    COUNT    ;CHECK COUNT OF REMAINING FILES
  480.     DCX    H    ;1 LEFT?
  481.     MOV    A,L    ;IF ONLY 1 LEFT, SKIP COMPARE WITH NEXT
  482.     ORA    H    ;  (SINCE THERE ISN'T ANY NEXT)
  483.     JZ    OKPRNT
  484.     PUSH    B
  485. ;
  486.     LHLD    BASE+1
  487.     MVI    L,6    ;CK STATUS OF KB
  488.     CALL    GOHL    ;ANY KEY PRESSED?
  489.     ORA    A
  490.     JZ    NOBRK    ;NO, CONTINUE
  491.     CALL    CINPUT    ;GET CHARACTER
  492.     CPI    'C'-40H    ;CTL-C?
  493.     JZ    EXIT    ;IF CTL-C THEN QUIT
  494.     CPI    'S'-40H    ;CTL-S?
  495.     JNZ    NOBRK    ;NO, CONTINUE
  496.     CALL    CINPUT    ;YES, WAIT FOR ANOTHER CHAR.
  497.     CPI    'C'-40H    ;MIGHT BE CTL-C
  498.     JZ    EXIT    ;EXIT IF CTL-C, ELSE FALL THRU AND CONTINUE
  499. ;
  500. NOBRK:    LHLD    NEXTT
  501.     MVI    A,11
  502.     CALL    COMPR    ;DOES THIS ENTRY MATCH NEXT ONE?
  503.     POP    B
  504.     JNZ    OKPRNT    ;NO, PRINT IT
  505.     INX    H
  506.     INX    H    ;SKIP, SINCE HIGHEST EXTENT COMES LAST IN LIST
  507.     SHLD    NEXTT
  508.     LHLD    COUNT
  509.     DCX    H
  510.     SHLD    COUNT    ;COUNT DOWN
  511.     JMP    ENTRY    ;GO GET    NEXT
  512. ;
  513. GOHL:    PCHL        ;KLUDGE TO ALLOW CALL TO ADDRESS IN HL
  514. ;
  515. OKPRNT:    IF    NOT WIDE
  516.     CALL    FENCE    ;PRINT FENCE CHAR AND SPACE
  517.     ENDIF
  518. ;
  519.     LHLD    NEXTT    ;GET ORDER TABLE POINTER
  520.     MOV    E,M    ;GET LO ADDR
  521.     INX    H
  522.     MOV    D,M    ;GET HI ADDR
  523.     INX    H
  524.     SHLD    NEXTT    ;SAVE UPDATED TABLE POINTER
  525.     XCHG        ;TABLE ENTRY TO HL
  526.     MVI    B,8    ;FILE NAME LENGTH
  527.     CALL    TYPEIT    ;TYPE FILENAME
  528.     MVI    A,'.'    ;PERIOD AFTER FN
  529.     CALL    TYPE
  530.     MVI    B,3    ;GET THE FILETYPE
  531.     CALL    TYPEIT
  532.     MOV    E,M    ;GET EXTENT #
  533.     MVI    D,0
  534.     INX    H
  535.     MOV    A,M    ;GET SECTOR COUNT OF LAST EXTENT
  536.     XCHG
  537.     DAD    H    ;# OF EXTENTS TIMES 16K
  538.     DAD    H
  539.     DAD    H
  540.     DAD    H
  541.     XCHG        ;SAVE IN DE
  542.     LXI    H,BLKMSK
  543.     ADD    M    ;ROUND LAST EXTENT TO BLOCK SIZE
  544.     RRC
  545.     RRC        ;CONVERT FROM SECTORS TO K
  546.     RRC
  547.     ANI    1FH
  548.     MOV    L,A    ;ADD TO TOTAL K
  549.     MVI    H,0
  550.     DAD    D
  551.     LDA    BLKMSK    ;GET SECTORS/BLK-1
  552.     RRC
  553.     RRC        ;CONVERT TO K/BLK
  554.     RRC
  555.     ANI    1FH
  556.     CMA        ;USE TO FINISH ROUNDING
  557.     ANA    L
  558.     MOV    L,A
  559.     XCHG        ;SAVE FILE SIZE IN DE
  560.     LHLD    TOTSIZ
  561.     DAD    D    ;ADD TO TOTAL USED
  562.     SHLD    TOTSIZ
  563.     LHLD    TOTFIL    ;INCREMENT FILE COUNT
  564.     INX    H
  565.     SHLD    TOTFIL
  566.     XCHG        ;GET BACK FILE SIZE
  567. ;
  568.     IF    REPSIZ    ;FILE SIZE REPORT WANTED
  569.     CALL    DECPRT    ; AND PRINT IT
  570.     MVI    A,'k'    ;FOLLOW WITH K
  571.     CALL    TYPE
  572.     ENDIF
  573. ;
  574.     IF    NOT WIDE
  575.     CALL    SPACE
  576.     ENDIF
  577. ;
  578. ;See if    more entries
  579.     LHLD    COUNT    ;COUNT DOWN ENTRIES
  580.     DCX    H
  581.     MOV    A,L
  582.     ORA    H
  583.     JZ    PRTOTL    ;IF OUT OF FILES, PRINT TOTALS
  584.     SHLD    COUNT
  585.     DCR    C    ;ONE LESS ON THIS LINE
  586. ;
  587.     IF    WIDE
  588.     PUSH    PSW
  589.     CNZ    FENCE    ;NO CR-LF NEEDED, DO FENCE
  590.     POP    PSW
  591.     ENDIF
  592. ;
  593.     CZ    CRLF    ;CR-LF NEEDED
  594.     JMP    ENTRY
  595. ;
  596. ;Print HL in decimal with leading zero suppression
  597. ;
  598. DECPRT:    SUB    A    ;CLEAR LEADING ZERO FLAG
  599.     STA    LZFLG
  600.     LXI    D,-1000    ;PRINT 1000'S DIGIT
  601.     CALL    DIGIT
  602.     LXI    D,-100    ;ETC
  603.     CALL    DIGIT
  604.     LXI    D,-10
  605.     CALL    DIGIT
  606.     MVI    A,'0'    ;GET 1'S DIGIT
  607.     ADD    L
  608.     JMP    TYPE
  609. ;
  610. DIGIT:    MVI    B,'0'    ;START OFF WITH ASCII 0
  611. ;
  612. DIGLP:    PUSH    H    ;SAVE CURRENT REMAINDER
  613.     DAD    D    ;SUBTRACT
  614.     JNC    DIGEX    ;QUIT ON OVERFLOW
  615.     POP    PSW    ;THROW AWAY REMAINDER
  616.     INR    B    ;BUMP DIGIT
  617.     JMP    DIGLP    ;LOOP BACK
  618. ;
  619. DIGEX:    POP    H    ;RESTORE POINTER
  620.     MOV    A,B
  621.     CPI    '0'    ;ZERO DIGIT?
  622.     JNZ    DIGNZ    ;NO, TYPE IT
  623.     LDA    LZFLG    ;LEADING ZERO?
  624.     ORA    A
  625.     MVI    A,'0'
  626.     JNZ    TYPE    ;PRINT DIGIT
  627.     LDA    SUPSPC    ;GET SPACE SUPPRESSION FLAG
  628.     ORA    A    ;SEE IF PRINTING FILE TOTALS
  629.     RZ        ;YES, DON'T GIVE LEADING SPACES
  630.     JMP    SPACE    ;LEADING ZERO...PRINT SPACE
  631. ;
  632. DIGNZ:    STA    LZFLG    ;SET LEADING ZERO FLAG SO NEXT ZERO PRINTS
  633.     JMP    TYPE    ;AND PRINT DIGIT
  634. ;
  635. ;Show total space and files used
  636. ;
  637. PRTOTL:    XRA    A    ;GET A ZERO TO...
  638.     STA    SUPSPC    ;SUPPRESS LEADING SPACES IN TOTALS
  639.     CALL    CRLF    ;NEW LINE (WITH PAUSE IF NECESSARY)
  640. ;
  641.     IF    WIDE
  642.     LXI    D,TOTMS1 ;PRINT FIRST PART OF TOTAL MESSAGE
  643.     ENDIF
  644. ;
  645.     IF    NOT WIDE
  646.     LXI    D,TOTMS1+1 ;PRINT FIRST PART OF TOTAL MESSAGE
  647.     ENDIF
  648. ;
  649.     MVI    C,PRINT
  650.     CALL    BDOS
  651.     LHLD    TOTSIZ     ;PRINT TOTAL K USED
  652.     CALL    DECPRT
  653.     LXI    D,TOTMS2 ;NEXT PART OF MESSAGE
  654.     MVI    C,PRINT
  655.     CALL    BDOS
  656.     LHLD    TOTFIL     ;PRINT COUNT OF FILES
  657.     CALL    DECPRT
  658.     LXI    D,TOTMS3 ;TAIL OF MESSAGE
  659.     MVI    C,PRINT
  660.     CALL    BDOS
  661. ;
  662. PRT1:    MVI    C,GALLOC ;GET ADDRESS OF ALLOCATION VECTOR
  663.     CALL    BDOS
  664.     XCHG
  665.     LHLD    BLKMAX    ;GET ITS LENGTH
  666.     INX    H
  667.     LXI    B,0    ;INIT BLOCK COUNT TO 0
  668. ;
  669. GSPBYT:    PUSH    D    ;SAVE ALLOC ADDRESS
  670.     LDAX    D
  671.     MVI    E,8    ;SET TO PROCESS 8 BLOCKS
  672. ;
  673. GSPLUP:    RAL        ;TEST BIT
  674.     JC    NOTFRE
  675.     INX    B
  676. ;
  677. NOTFRE:    MOV    D,A    ;SAVE BITS
  678.     DCX    H    ;COUNT DOWN BLOCKS
  679.     MOV    A,L
  680.     ORA    H
  681.     JZ    ENDALC    ;QUIT IF OUT OF BLOCKS
  682.     MOV    A,D    ;RESTORE BITS
  683.     DCR    E    ;COUNT DOWN 8 BITS
  684.     JNZ    GSPLUP    ;DO ANOTHER BIT
  685.     POP    D    ;BUMP TO NEXT BYTE
  686.     INX    D    ;OF ALLOC. VECTOR
  687.     JMP    GSPBYT    ;PROCESS IT
  688. ;
  689. ENDALC:    MOV    L,C    ;COPY BLOCKS TO HL
  690.     MOV    H,B
  691.     LDA    BLKSHF    ;GET BLOCK SHIFT FACTOR
  692.     SUI    3    ;CONVERT FROM SECTORS TO K
  693.     JZ    PRTFRE    ;SKIP SHIFTS IF 1K BLOCKS
  694. ;
  695. FREKLP:    DAD    H    ;MULT BLKS BY K/BLK
  696.     DCR    A
  697.     JNZ    FREKLP
  698. ;
  699. PRTFRE:    CALL    DECPRT    ;PRINT K FREE
  700.     LXI    D,TOTMS4
  701.     MVI    C,PRINT
  702.     CALL    BDOS
  703.     JMP    EXIT    ;ALL DONE...RETURN TO CP/M
  704. ;
  705. DRNAM    EQU    $    ;SAVE DRIVE NAME HERE
  706. TOTMS1:    DB    ' : Total of $'
  707. TOTMS2: DB    'k in $'
  708. TOTMS3: DB    ' files with $'
  709. TOTMS4: DB    'k space remaining.$'
  710. ;
  711. FENCE:    IF    WIDE
  712.     CALL    SPACE
  713.     ENDIF
  714. ;
  715.     IF    NOT REPSIZ
  716.     CALL    SPACE    ;PRINT AN EXTRA SPACE
  717.     ENDIF
  718. ;
  719.     MVI    A,DELIM    ;FENCE CHARACTER
  720.     CALL    TYPE    ;PRINT IT, FALL INTO SPACE
  721. ;
  722.     IF    NOT REPSIZ
  723.     CALL    SPACE    ;PRINT ANOTHER SPACE
  724.     ENDIF
  725. ;
  726. SPACE:    MVI    A,' '
  727. ;
  728. ;Type character    in A
  729. ;
  730.     IF    DIRCON    ;DIRECT CONSOLE OUTPUT
  731. TYPE:    PUSH    B
  732.     PUSH    D
  733.     PUSH    H
  734.     LHLD    BASE+1
  735.     MVI    L,12
  736.     MOV    C,A
  737.     CALL    GOHL
  738.     POP    H
  739.     POP     D
  740.     POP    B
  741.     RET
  742.     ENDIF        ;DIRCON
  743. ;
  744.     IF    NOT DIRCON ;USE BDOS CONSOLE OUTPUT
  745. TYPE:    PUSH    B
  746.     PUSH    D
  747.     PUSH    H
  748.     MOV    E,A
  749.     MVI    C,WRCHR    ;CHAR TO CONSOLE
  750.     CALL    BDOS
  751.     POP    H
  752.     POP    D
  753.     POP    B
  754.     RET
  755.     ENDIF        ;NOT DIRCON
  756. ;
  757. TYPEIT:    MOV    A,M
  758.     CALL    TYPE
  759.     INX    H
  760.     DCR    B
  761.     JNZ    TYPEIT
  762.     RET
  763. ;
  764. ;Fetch character from console (without echo)
  765. ;
  766. CINPUT:    LHLD    BASE+1
  767.     MVI    L,9
  768.     CALL    GOHL
  769.     ANI    7FH
  770.     RET
  771. ;
  772. CRLF:    LDA    LINCNT    ;CHECK FOR END OF SCREEN
  773.     INR    A
  774. ;
  775.     IF    PGPAWZ    ;PAUSE AFTER EACH PAGE
  776.     CPI    LPS
  777.     JC    NOTEOS     ;SKIP MESSAGE IF MORE LINES LEFT ON SCREEN
  778.     LXI    D,EOSMSG ;SAY WE'RE PAUSING FOR INPUT
  779.     MVI    C,PRINT
  780.     CALL    BDOS
  781.     CALL    CINPUT    ;WAIT FOR CHAR.
  782.     CPI    'C'-40H    ;CTL-C ?
  783.     JZ    EXIT
  784.     SUB    A    ;SET UP TO ZERO LINE COUNT
  785.     ENDIF        ;PGPAWZ
  786. ;
  787. NOTEOS:    STA    LINCNT    ;SAVE NEW LINE COUNT
  788.     MVI    A,13    ;PRINT CR
  789.     CALL    TYPE
  790.     MVI    A,10    ;LF
  791.     CALL    TYPE
  792. ;
  793.     IF    NOT WIDE
  794.     CALL    DRPRNT    ;DRIVE NAME
  795.     ENDIF
  796. ;
  797.     MVI    C,NPL    ;RESET NUMBER OF NAMES PER LINE
  798.     RET
  799. ;
  800. EOSMSG:    DB    13,10,'(Strike any key to continue)$'
  801. ;
  802.     IF    NOT WIDE
  803. DRPRNT:    LDA    DRNAM
  804.     JMP    TYPE
  805.     ENDIF
  806. ;
  807. ;Compare routine for sort
  808. ;
  809. COMPR:    PUSH    H    ;SAVE TABLE ADDR
  810.     MOV    E,M    ;LOAD LO
  811.     INX    H
  812.     MOV    D,M    ;LOAD HI
  813.     INX    H
  814.     MOV    C,M
  815.     INX    H
  816.     MOV    B,M
  817. ;BC, DE now point to entries to be compared
  818.     XCHG
  819.     MOV    E,A    ;GET COUNT
  820. ;
  821. CMPLP:    LDAX    B
  822.     CMP    M
  823.     INX    H
  824.     INX    B
  825.     JNZ    NOTEQL    ;QUIT ON MISMATCH
  826.     DCR    E    ;OR END OF COUNT
  827.     JNZ    CMPLP
  828. ;
  829. NOTEQL:    POP    H
  830.     RET        ;COND CODE TELLS ALL
  831. ;
  832. ;Swap entries in the order table
  833. ;
  834. SWAP:    LXI    B,ORDER-2 ;TABLE BASE
  835.     DAD    H    ;*2
  836.     DAD    B    ;+ BASE
  837.     XCHG
  838.     DAD    H    ;*2
  839.     DAD    B    ;+ BASE
  840.     MOV    C,M
  841.     LDAX    D
  842.     XCHG
  843.     MOV    M,C
  844.     STAX    D
  845.     INX    H
  846.     INX    D
  847.     MOV    C,M
  848.     LDAX    D
  849.     XCHG
  850.     MOV    M,C
  851.     STAX    D
  852.     RET
  853. ;
  854. ;New compare routine
  855. ;
  856. COMPARE:LXI    B,ORDER-2
  857.     DAD    H
  858.     DAD    B
  859.     XCHG
  860.     DAD    H
  861.     DAD    B
  862.     XCHG
  863.     MOV    C,M
  864.     INX    H
  865.     MOV    B,M
  866.     XCHG
  867.     MOV    E,M
  868.     INX    H
  869.     MOV    D,M
  870.     XCHG
  871.     MOV    E,A    ;COUNT
  872. ;
  873. CMPLPE:    LDAX    B
  874.     CMP    M
  875.     INX    B
  876.     INX    H
  877.     RNZ
  878.     DCR    E
  879.     JNZ    CMPLPE
  880.     RET
  881. ;
  882. ;Error exit
  883. ;
  884. ERXIT:    POP    D    ;GET MSG
  885. ;
  886. ERXIT1:    MVI    C,PRINT
  887.     CALL    BDOS
  888.     CALL    CRLF
  889. ;
  890.     IF    WIDE
  891.     LXI    D,TOTMS1
  892.     ENDIF
  893. ;
  894.     IF    NOT WIDE
  895.     LXI    D,TOTMS1+1 ;SKIP PRINTING DRIVE NAME
  896.     ENDIF
  897. ;
  898.     MVI    C,PRINT
  899.     CALL    BDOS
  900.     XRA    A
  901.     STA    SUPSPC    ;SUPPRESS LEADING ZEROS
  902.     JMP    PRT1    ;PRINT SPACE REMAINING
  903. ;
  904. ;Exit -    all done, restore stack
  905. ;
  906. EXIT:    MVI    C,CONST    ;CHECK CONSOLE STATUS
  907.     CALL    BDOS
  908.     ORA    A    ;CHAR WAITING?
  909.     MVI    C,RDCHR
  910.     CNZ    BDOS    ;GOBBLE UP CHAR
  911.     LHLD    STACK    ;GET OLD STACK
  912.     SPHL        ;MOVE TO STACK
  913.     RET        ;..AND RETURN
  914. ;
  915. ;Temporary storage area
  916. ;
  917. I    DW    0
  918. J    DW    0
  919. JG    DW    0
  920. GAP    DW    0
  921. ;
  922. BLKSHF    DB    0    ;# SHIFTS TO MULT BY SEC/BLK
  923. BLKMSK    DB    0    ;SEC/BLK - 1
  924. BLKMAX    DW    0    ;HIGHEST BLOCK # ON DRIVE
  925. DIRMAX    DW    0    ;HIGHEST FILE # IN DIRECTORY
  926. TOTSIZ    DW    0    ;TOTAL SIZE OF ALL FILES
  927. TOTFIL    DW    0    ;TOTAL NUMBER OF FILES
  928. LINCNT    DB    0    ;COUNT OF LINES ON SCREEN
  929. TBLOC    DW    0    ;POINTER TO START OF NAME TABLE
  930. NEXTT    DW    0    ;NEXT TABLE ENTRY
  931. COUNT    DW    0    ;ENTRY COUNT
  932. SCOUNT    DW    0    ;# TO SORT
  933. SWITCH    DB    0    ;SWAP SWITCH FOR SORT
  934. SUPSPC    DB    0FFH    ;LEADING SPACE FLAG FOR DECIMAL RTN.
  935. BUFAD    DW    BASE+80H ;OUTPUT ADDR
  936. SOPFLG    DS    1    ;SET TO 'S' TO ALLOW SYS FILES TO PRINT
  937. USERNO    DS    1    ;CONTAINS CURRENT USER NUMBER
  938. TEMP    DS    2    ;SAVE DIR ENTRY
  939. VERFLG    DS    1    ;VERSION FLAG
  940. MPMFLG    DS    1    ;MP/M FLAG
  941. LZFLG    DS    1    ;0 WHEN PRINTING LEADING ZEROS
  942.     DS    60    ;STACK AREA
  943. STACK    DS    2    ;SAVE OLD STACK HERE
  944. ORDER    EQU    $    ;ORDER TABLE STARTS HERE
  945. ;
  946. ;BDOS equates
  947. ;
  948. RDCHR    EQU    1    ;READ CHAR FROM CONSOLE
  949. WRCHR    EQU    2    ;WRITE CHR TO CONSOLE
  950. PRINT    EQU    9    ;PRINT CONSOLE BUFF
  951. CONST    EQU    11    ;CHECK CONS STAT
  952. SELDSK    EQU    14    ;SELECT DISK
  953. FOPEN    EQU    15    ;0FFH=NOT FOUND
  954. FCLOSE    EQU    16    ;   "    "
  955. FSRCHF    EQU    17    ;   "    "
  956. FSRCHN    EQU    18    ;   "    "
  957. CURDSK    EQU    25    ;GET CURRENTLY LOGGED DISK NAME
  958. GALLOC    EQU    27    ;GET ADDRESS OF ALLOCATION VECTOR
  959. CURDPB    EQU    31    ;GET CURRENT DISK PARAMETERS
  960. CURUSR    EQU    32    ;GET CURRENTLY LOGGED USER NUMBER (2.x ONLY)
  961. ;
  962.     END
  963.