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 / ZSYS / SIMTEL20 / ZCPR3 / FINDF.MAC < prev    next >
Text File  |  2000-06-30  |  22KB  |  1,050 lines

  1. ; PROGRAM:  FINDF
  2. ; AUTHOR:  RICHARD CONN
  3. ; VERSION:  2.0
  4. ; DATE:  18 May 84
  5. ; PREVIOUS VERSIONS: 1.1 (25 July 83), 1.0 (24 JULY 83)
  6. ;
  7. VERS    EQU    20        ;version number
  8. z3env    SET    0f400h
  9.  
  10. ;
  11. ;    FINDF searches through all of the known disks for one or more
  12. ; files matching the passed file specification.  AFNs (Ambiguous File Names)
  13. ; are permitted.  FINDF is invoked by the following command line:
  14. ;        FINDF afn,afn,afn,... o
  15. ; where "afn" refers to the file sought and "o" is none or more of:
  16. ;        S - Include System Files
  17. ;
  18.  
  19. ;
  20. ; System equates:
  21. ;
  22. BOOT    EQU    0000H        ;CP/M WARM BOOT JUMP VECTOR
  23. BDOS    EQU    BOOT+05H    ;CP/M BDOS CALL JUMP VECTOR
  24. TBUFF    EQU    BOOT+80H    ;DISK I/O BUFFER
  25. FCB    EQU    BOOT+5CH    ;DEFAULT FILE CONTROL BLOCK
  26. CR    EQU    'M'-'@'        ;CTL-M FOR CARRIAGE RETURN
  27. LF    EQU    'J'-'@'        ;CTL-J FOR LINE FEED
  28. CTRLC    EQU    'C'-'@'        ;ABORT
  29. CTRLS    EQU    'S'-'@'        ;PAUSE
  30. ESIZE    EQU    12        ;12 BYTES/DIR ENTRY
  31.  
  32. ;
  33. ; SYSLIB and Z3LIB Routines
  34. ;
  35.     ext    z3init,codend
  36.     ext    cout,crlf,print,padc
  37.  
  38. ;
  39. ; Environment Definition
  40. ;
  41.     if    z3env ne 0
  42. ;
  43. ; External ZCPR3 Environment Descriptor
  44. ;
  45.     jmp    start
  46.     db    'Z3ENV'    ;This is a ZCPR3 Utility
  47.     db    1    ;External Environment Descriptor
  48. z3eadr:
  49.     dw    z3env
  50. start:
  51.     lhld    z3eadr    ;pt to ZCPR3 environment
  52. ;
  53.     else
  54. ;
  55. ; Internal ZCPR3 Environment Descriptor
  56. ;
  57.     MACLIB    Z3BASE.LIB
  58.     MACLIB    SYSENV.LIB
  59. z3eadr:
  60.     jmp    start
  61.     SYSENV
  62. start:
  63.     lxi    h,z3eadr    ;pt to ZCPR3 environment
  64.     endif
  65.  
  66. ;
  67. ; Start of Program -- Initialize ZCPR3 Environment
  68. ;
  69.     call    z3init    ;initialize the ZCPR3 Env and the VLIB Env
  70.     LXI    H,0        ;SAVE STACK PTR
  71.     DAD    SP
  72.     SHLD    STACK
  73.     CALL    CODEND        ;DETERMINE FREE SPACE
  74.     SHLD    FNTAB        ;FILE NAME TABLE
  75.     LXI    D,512        ;1/2 K SPACE
  76.     DAD    D
  77.     SHLD    SCRATCH        ;BEGINNING OF SCRATCH AREA
  78.     SPHL            ;AND TOP OF STACK
  79.     CALL    GTBIOS        ;GET BIOS JUMP TABLE
  80.     CALL     HELLO        ;SIGN ON MESSAGE
  81.     CALL    HELPCHK        ;CHECK FOR AND PRINT HELP MESSAGE
  82.     CALL    OPTCHK        ;BUILD FILE NAME TABLE AND PROCESS OPTIONS
  83.     CALL    CRLF        ;NEW LINE
  84.     CALL    FIND        ;DO THE SEARCHES
  85.     CALL    BYE        ;SIGN OFF MESSAGE
  86. RETURN:
  87.     LHLD    STACK        ;QUIET RETURN
  88.     SPHL
  89.     RET
  90. ;
  91. ; ** Main Routines **
  92. ;
  93.  
  94. ;
  95. ; SAY WHO WE ARE
  96. ;
  97. HELLO:
  98.     CALL    PRINT
  99.     DB    'FINDF, Version '
  100.     DB    (VERS/10)+'0','.',(VERS MOD 10)+'0'
  101.     DB    0
  102.     RET
  103. ;
  104. ;  CHECK FOR HELP REQUEST
  105. ;
  106. HELPCHK:
  107.     LDA    FCB+1        ;GET 1ST BYTE OF FILENAME
  108.     CPI    '/'        ;HELP?
  109.     JZ    HCK1
  110.     CPI    ' '        ;MAKE SURE IT IS NON-BLANK
  111.     RNZ            ;OK - KEEP GOING
  112. ;    
  113. ; IF NO FILE NAME IS SPECIFIED, ABORT WITH NOTICE
  114. ;
  115. HCK1:
  116.     CALL     PRINT
  117.     db    cr,lf,'Syntax:'
  118.     DB    CR,LF,'   FINDF afn,afn,afn,... o'
  119.     db    cr,lf,'Options:'
  120.     DB    CR,LF,'   S - Include System Files'
  121.     DB    0
  122.     JMP    RETURN
  123. ;
  124. ; CHECKS FOR S OPTION IN COMMAND LINE AND EXTRACTS FILE NAMES INTO TABLE
  125. ;
  126. OPTCHK:
  127.     XRA    A    ;TURN OFF FLAGS
  128.     STA    SYSTEM    ;NO SYSTEM FILES
  129.     STA    FFLAG    ;NO FILES FOUND
  130.     STA    ECOUNT    ;NO ENTRIES
  131.     STA    FNCOUNT    ;NO FILE NAMES
  132.     LHLD    FNTAB    ;PT TO TABLE
  133.     XCHG        ;... IN DE
  134.     LXI    H,TBUFF+1    ;SCAN THRU TBUFF, BUILDING A FILE NAME TABLE
  135.     CALL    SBLANK    ;SKIP BLANKS
  136. FNLOOP:
  137.     PUSH    D    ;SAVE TABLE PTR
  138.     CALL    GETFN    ;EXTRACT FILE NAME
  139.     POP    D
  140.     PUSH    H
  141.     LXI    H,11    ;PT TO NEXT TABLE ENTRY
  142.     DAD    D
  143.     XCHG
  144.     POP    H
  145.     LDA    FNCOUNT    ;INCREMENT COUNT
  146.     INR    A
  147.     STA    FNCOUNT
  148.     MOV    A,M    ;GET TERMINATING CHAR
  149.     INX    H    ;PT TO NEXT
  150.     CPI    ','    ;ANOTHER FOLLOWS?
  151.     JZ    FNLOOP
  152.     DCX    H    ;POINT BACK TO DELIM
  153.     CALL    SBLANK    ;SKIP TO NON-BLANK
  154. OPTCK1:
  155.     MOV    A,M    ;GET OPTION
  156.     CALL    DELCHK    ;DONE IF DELIM
  157.     RZ
  158.     CPI    'S'    ;SYSTEM?
  159.     JZ    OPTCKS
  160.     CALL    PRINT
  161.     DB    CR,LF,'Invalid Option -- ',0
  162.     MOV    A,M
  163.     CALL    COUT
  164.     JMP    HCK1
  165. OPTCKS:
  166.     MVI    A,0FFH    ;SET FLAG
  167.     STA    SYSTEM
  168.     INX    H
  169.     JMP    OPTCK1
  170. GETFN:
  171.     PUSH    D    ;FILL TARGET FCB
  172.     MVI    B,11    ;11 BYTES
  173.     MVI    A,' '    ;SPACE FILL
  174. GETFN0:
  175.     STAX    D    ;PUT SPACE
  176.     INX    D
  177.     DCR    B
  178.     JNZ    GETFN0
  179.     POP    D    ;PT TO ENTRY AGAIN
  180.     CALL    SCANCOL    ;SCAN FOR COLON
  181.     MVI    B,8    ;8 CHARS MAX
  182.     CALL    GETFN1    ;GET AND FILL ENTRY
  183.     MOV    A,M    ;GET CHAR
  184.     CPI    '.'    ;DELIM?
  185.     RNZ        ;DONE
  186.     INX    H    ;PT TO AFTER PERIOD
  187.     MVI    B,3    ;3 CHARS MAX AND DO IT AGAIN
  188. GETFN1:
  189.     MOV    A,M    ;GET CHAR
  190.     CPI    '.'    ;END OF FIELD?
  191.     JZ    GETFN3
  192.     CALL    DELCHK    ;CHECK DELIMITER
  193.     RZ
  194.     CPI    '*'    ;WILD?
  195.     JZ    GETFNQ
  196.     STAX    D    ;STORE CHAR
  197.     INX    H    ;PT TO NEXT
  198.     INX    D
  199.     DCR    B    ;COUNT DOWN
  200.     JNZ    GETFN1
  201. GETFN2:
  202.     MOV    A,M    ;FLUSH CHARS TO DELIM
  203.     CALL    DELCHK    ;CHECK FOR DELIMITER
  204.     RZ
  205.     INX    H    ;PT TO NEXT
  206.     JMP    GETFN2
  207. GETFN3:
  208.     INX    D    ;PT TO AFTER FIELD
  209.     DCR    B    ;COUNT DOWN
  210.     JNZ    GETFN3
  211.     RET
  212. GETFNQ:
  213.     MVI    A,'?'    ;FILL WITH QUESTION MARKS
  214.     STAX    D
  215.     INX    D
  216.     DCR    B
  217.     JNZ    GETFNQ
  218.     JMP    GETFN2    ;SKIP TO DELIM
  219. DELCHK:
  220.     ORA    A    ;END OF LINE?
  221.     RZ
  222.     CPI    '.'    ;END OF FIELD?
  223.     RZ
  224.     CPI    ','    ;END OF ENTRY?
  225.     RZ
  226.     CPI    ' '
  227.     RET
  228. SBLANK:
  229.     MOV    A,M    ;SKIP TO NON-BLANK
  230.     CPI    ' '
  231.     RNZ
  232.     INX    H
  233.     JMP    SBLANK
  234. SCANCOL:
  235.     PUSH    D    ;SAVE TABLE PTR
  236.     PUSH    H    ;SAVE PTR
  237. SCOL1:
  238.     MOV    A,M    ;GET CHAR
  239.     INX    H    ;PT TO NEXT
  240.     CPI    ':'    ;COLON?
  241.     JZ    SCOLX
  242.     CALL    DELCHK    ;CHECK FOR DELIMITER
  243.     JNZ    SCOL1
  244. SCOL2:
  245.     POP    H    ;RESTORE
  246.     POP    D
  247.     RET
  248. SCOLX:
  249.     XCHG        ;DE PTS TO AFTER COLON
  250.     POP    H    ;GET OLD PTR
  251.     XCHG        ;REPLACE IT
  252.     POP    D    ;GET TABLE PTR
  253.     RET
  254. ;
  255. ; LOOK THROUGH DIRECTORY
  256. ;
  257. FIND:
  258.     XRA    A        ;SELECT FIRST DISK
  259.     STA    FCB
  260.     CALL    NXTDISK        ;GET INFO THE FIRST TIME
  261. FIND1:
  262.     RZ            ;ABORT IF ERROR
  263. FIND2:
  264.     CALL    NXTSEC        ;GET A DIRECTORY SECTOR
  265.     JZ    FIND3        ;RETURNS ZERO FLAG IF NO MORE
  266.     CALL    CHKENT        ;CHECK IT OUT
  267.     JMP    FIND2        ;KEEP IT UP TILL DONE
  268. FIND3:
  269.     CALL    DIRALPHA    ;SORT ENTRIES
  270.     CALL    PRFILES        ;PRINT SORTED ENTRIES
  271.     LDA    FCB        ;NEXT DISK
  272.     INR    A
  273.     STA    FCB
  274.     CALL    NXTDISK        ;SELECT NEXT DISK
  275.     JMP    FIND1
  276.  
  277. ;
  278. ; SIGN OFF
  279. ;
  280. BYE:
  281.     MVI    C,13        ;RESET SYSTEM
  282.     CALL    BDOS
  283.     LDA    FFLAG        ;GET FILE FOUND FLAG
  284.     ORA    A        ;NO FILES FOUND?
  285.     JNZ    RETURN
  286.     CALL    PRINT
  287.     DB    CR,LF,'NO Files Found',0
  288.     JMP    RETURN
  289. ;
  290. ; CHECKS THE CURRENT 4 DIRECTORY ENTRIES AGAINST ARGUMENT
  291. ; IF MATCH, REWRITES SECTOR WITH REACTIVATED 1ST BYTES
  292. ;
  293. CHKENT:
  294.     MVI    B,4        ;NUMBER OF ENTRIES PER SECTOR
  295.     LXI     H,TBUFF        ;BEGINNING OF BUFFER
  296. CKLUP:
  297.     PUSH    B
  298.     MOV    A,M
  299.     CPI    0E5H        ;CHECK FOR UNUSED
  300.     JZ    CKINC
  301.     XRA    A        ;A=0
  302.     STA    CLPFLG        ;SET FLAG FOR NO ENTRIES FOUND
  303.     LDA    FNCOUNT        ;GET NUMBER OF FILE NAMES TO LOOK THRU
  304.     MOV    B,A        ;... IN B
  305.     PUSH    H
  306.     LHLD    FNTAB        ;PT TO TABLE
  307.     XCHG            ;... IN DE
  308.     POP    H
  309. CKLUP1:
  310.     PUSH    B        ;SAVE COUNT
  311.     PUSH     H        ;SAVE BEGINNING ADDRESS
  312.     PUSH    D
  313.     CALL    COMPAR        ;COMPARE WITH ARGUMENT AND SAVE IF MATCH
  314.     POP    D
  315.     LXI    H,11        ;PT TO NEXT ENTRY
  316.     DAD    D
  317.     XCHG
  318.     POP    H
  319.     POP    B
  320.     DCR    B        ;COUNT DOWN
  321.     JNZ    CKLUP1
  322. CKINC:
  323.     POP    B
  324.     LXI    D,32        ;LENGTH OF ENTRY
  325.     DAD    D
  326.     DCR    B
  327.     JNZ    CKLUP
  328.     LHLD    DIRMAX
  329.     DCX    H        ;REDUCE SECTORS LEFT
  330.     SHLD    DIRMAX
  331.     LHLD    SECTOR        ;POINT TO NEXT SECTOR
  332.     INX    H
  333.     SHLD    SECTOR
  334.     XCHG
  335.     LHLD    MAXSEC        ;REACHED LIMIT?
  336.     INX    H        ;ONE MORE
  337.     MOV    A,H        ;CHECK HIGH
  338.     CMP    D
  339.     RNZ
  340.     MOV    A,L        ;CHECK LOW
  341.     CMP    E
  342.     RNZ
  343.     LHLD    TRACK        ;NEXT TRACK
  344.     INX    H
  345.     SHLD    TRACK
  346.     LXI    H,1        ;FIRST SECTOR OF NEXT TRACK
  347.     SHLD    SECTOR
  348.     RET
  349. ;
  350. ; COMPARE 11 BYTES OF DIRECTORY ENTRY AGAINST ARGUMENT; RNZ IF NOT MATCHED
  351. ;  DE PTS TO TABLE ENTRY TO COMPARE TO
  352. ;
  353. COMPAR:
  354.     LDA    CLPFLG        ;GET FOUND FLAG
  355.     ORA    A        ;0=NO
  356.     RNZ
  357.     SHLD    TEMP        ;Hold pointer in case of match
  358.     INX    H
  359.     XCHG
  360.     MVI    B,11
  361. CMPR1:
  362.     LDAX    D        ;GET DIRECTORY ENTRY CHARACTER
  363.     ANI    7FH        ;STRIP ANY FLAGS
  364.     CMP    M
  365.     JZ    CMPR2
  366.     MOV    A,M
  367.     CPI    '?'
  368.     RNZ
  369. CMPR2:
  370.     INX    D
  371.     INX    H        ;BUMP TO NEXT CHARACTER
  372.     DCR    B
  373.     JNZ    CMPR1        ;LOOP FOR 11 CHARACTERS
  374.     PUSH    D        ;SAVE ENTRY PTR
  375.     LDAX    D        ;GET EXTENT IN B
  376.     MOV    B,A
  377.     LDA    EXTENT        ;GET EXTENT MASK
  378.     CMP    B
  379.     POP    D        ;GET ENTRY PTR
  380.     JC    CMPR4        ;NO MATCH
  381.     LDA    SYSTEM        ;INCLUDE SYSTEM FILES?
  382.     ORA    A        ;0=NO
  383.     JNZ    CMPR3
  384.     DCX    D        ;BACK UP 2 BYTES
  385.     DCX    D
  386.     LDAX    D        ;GET T2
  387.     ANI    80H        ;CHECK FOR SYS
  388.     RNZ
  389. CMPR3:
  390.     LHLD    TEMP        ;CHECK FOR USER LIMIT
  391.     MVI    A,31        ;MAX USER
  392.     CMP    M        ;BEYOND MAX?
  393.     JC    CMPR4
  394.     LHLD    FCOUNT        ;INCREMENT COUNT
  395.     INX    H
  396.     SHLD    FCOUNT
  397.     LHLD    DSTART        ;GET PTR TO NEXT ENTRY
  398.     XCHG
  399.     LHLD    TEMP
  400.     MVI    B,ESIZE        ;COPY ENTRY
  401.     CALL    MOVE
  402.     XCHG
  403.     SHLD    DSTART        ;PTR TO NEXT ENTRY
  404.     XCHG
  405.     LHLD    BDOS+1        ;CHECK FOR MEMORY OVERFLOW
  406.     MOV    A,H
  407.     SUI    10        ;BELOW CCP
  408.     CMP    D        ;PT BEYOND LIMIT?
  409.     JC    MOVFL
  410.     MVI    A,0FFH        ;SET FOUND FLAG
  411.     STA    FFLAG
  412.     XRA    A
  413.     RET            ;RETURNS 'ZERO' FLAG SET FOR MATCH
  414. CMPR4:
  415.     MVI    A,0FFH        ;NO MATCH
  416.     ORA    A
  417.     RET
  418. MOVFL:
  419.     CALL    PRINT
  420.     DB    CR,LF,'ABORT -- Not Enough Memory for Buffers',0
  421.     JMP    RETURN
  422. ;
  423. ;  ADVANCE TO NEXT DISK
  424. ;
  425. NXTDISK:
  426.     LXI    B,TBUFF        ;SET DMA ADDRESS
  427.     CALL    SETDMA
  428.     LDA    FCB
  429.     MOV    C,A
  430.     MVI    B,0
  431.     CALL    SELDSK        ;MAKE SURE DRIVE IS
  432.     MOV    A,H        ;  SELECTED
  433.     ORA    L
  434.     RZ            ;ERROR RETURN
  435.     SHLD    DPH        ;SAVE THE ADDRESS
  436.     LXI    D,10        ;PT TO DPB
  437.     DAD    D
  438.     MOV    E,M        ;GET DPB ADDRESS IN HL
  439.     INX    H
  440.     MOV    D,M
  441.     XCHG
  442.     MOV    E,M        ;NUMBER OF SECTORS/TRACK
  443.     INX    H        ;AS 2-BYTE QUANTITY IN DE
  444.     MOV    D,M
  445.     INX    H
  446.     XCHG
  447.     SHLD    MAXSEC        ;SET MAX SECTORS/TRACK
  448.     XCHG
  449.     INX    H
  450.     INX    H
  451.     MOV    A,M        ;GET EXM
  452.     STA    EXTENT
  453.     INX    H        ;PT TO DRM
  454.     INX    H
  455.     INX    H
  456.     MOV    E,M        ;GET NUMBER OF
  457.     INX    H        ;  DIRECTORY ENTRIES
  458.     MOV    D,M
  459.     XCHG
  460.     INX    H        ;ACCOUNT FOR - 1
  461.     SHLD    DSTART        ;SAVE NUMBER OF DIRECTORY ENTRIES
  462.     CALL    SHFHL2        ;SHIFT 'HL' RIGHT 2
  463.     SHLD    DIRMAX        ;SAVE NUMBER DIRECTORY SECTORS
  464.     LXI    H,5        ;NOW POINT TO SYSTEM
  465.     DAD    D        ;  TRACK OFFSET
  466.     MOV    A,M        ;PICK UP NUMBER OF
  467.     INX    H
  468.     MOV    H,M
  469.     MOV    L,A
  470.     SHLD    TRACK
  471.     LXI    H,1        ;SET SECTOR
  472.     SHLD    SECTOR
  473.     LDA    ECOUNT        ;LAST NEW LINE?
  474.     ANI    3
  475.     CNZ    CRLF
  476.     CALL    PRINT
  477.     DB    'Disk ',0
  478.     LDA    FCB
  479.     ADI    'A'
  480.     CALL    COUT
  481.     CALL    PRINT
  482.     DB    ' --',CR,LF,0
  483.     LHLD    SCRATCH        ;PT TO SCRATCH AREA
  484.     SHLD    ORDER        ;ADDRESS OF ORDER TABLE
  485.     XCHG
  486.     LHLD    DSTART        ;GET NUMBER OF DIRECTORY ENTRIES
  487.     DAD    H        ;DOUBLE FOR NUMBER OF BYTES IN ORDER TABLE
  488.     DAD    D        ;PT TO FIRST BYTE OF DIRBUF
  489.     SHLD    DIRBUF        ;SET PTR
  490.     SHLD    DSTART        ;SET LOOP PTR
  491.     LXI    H,0        ;SET FILE COUNT
  492.     SHLD    FCOUNT
  493.     XRA    A        ;SET COUNT
  494.     STA    ECOUNT
  495.     CMA            ;FLIP
  496.     ORA    A        ;OK TO CONTINUE
  497.     RET
  498. ;
  499. ; GET BIOS JUMPS VECTORS FOR EASY REFERENCE
  500. ;
  501. GTBIOS:
  502.     LHLD    BOOT+1        ;POINTS TO BIOS JUMP TABLE+3
  503.     LXI    D,WBOOT        ;WHERE WE WILL KEEP A COPY
  504.     MVI    B,16*3        ;MOVE 48 BYTES AND FALL THRU TO MOVE
  505. ;
  506. ; GENERAL PURPOSE MOVE ROUTINE
  507. ; FROM 'HL' TO 'DE' FOR COUNT OF 8
  508. ;
  509. MOVE:
  510.     MOV    A,M        ;GET A BYTE
  511.     STAX    D        ;PUT A BYTE
  512.     INX    D        ;INCREMENT TO NEXT
  513.     INX    H
  514.     DCR    B        ;COUNT DOWN
  515.     JNZ    MOVE
  516.     RET
  517. ;
  518. ; READS NEXT SECTOR (GROUP OF FOUR DIRECTORY ENTRIES)
  519. ; RETURNS WITH ZERO FLAG SET IF NO MORE
  520. ;
  521. NXTSEC:
  522.     LHLD    DIRMAX        ;SEE IF MORE SECTORS
  523.     MOV    A,H
  524.     ORA    L
  525.     RZ            ;RETURNS ZERO FLAG IF NO MORE
  526.     LHLD    TRACK        ;SET TRACK
  527.     MOV    B,H
  528.     MOV    C,L
  529.     CALL    SETTRK
  530.     LHLD    SECTOR        ;SET SECTOR
  531.     MOV    B,H
  532.     MOV    C,L
  533.     CALL    TRNSLT
  534.     CALL    SETSEC
  535.     CALL    READ        ;READ A SECTOR
  536.     ANI    1        ;REVERSE SENSE OF ERROR FLAG
  537.     XRI    1        ;RETURNS WITH ZERO FLAG SET
  538.     RET            ;IF BAD READ
  539. ;
  540. ; PRINT FILES IN DIRBUF
  541. ;
  542. PRFILES:
  543.     LHLD    FCOUNT        ;GET COUNT
  544.     MOV    A,H        ;ANY?
  545.     ORA    L
  546.     RZ
  547.     MOV    B,H        ;COUNT IN BC
  548.     MOV    C,L
  549.     LHLD    DIRBUF        ;PT TO FIRST ONE
  550. PRFLOOP:
  551.     PUSH    B        ;SAVE COUNT
  552.     PUSH    H        ;SAVE PTR
  553.     CALL    PRINTFCB    ;PRINT FCB
  554.     POP    H        ;GET REGS BACK
  555.     POP    B
  556.     LXI    D,ESIZE        ;PT TO NEXT
  557.     DAD    D
  558.     DCX    B        ;COUNT DOWN
  559.     MOV    A,B
  560.     ORA    C
  561.     JNZ    PRFLOOP
  562.     MVI    A,0FFH        ;SET OK
  563.     ORA    A
  564.     RET
  565. ;
  566. ; FCB PRINTING ROUTINE
  567. ;
  568. PRINTFCB:
  569.     CALL    PRINT        ;2 SPACES
  570.     DB    '  ',0
  571.     MOV    A,M        ;GET USER NUMBER
  572.     CALL    PADC        ;PRINT IT
  573.     MVI    A,':'
  574.     CALL    COUT
  575.     INX    H
  576. PR0:
  577.     MVI    B,8
  578.     CALL    PR1
  579.     MVI    A,'.'
  580.     CALL    COUT
  581.     MVI    B,3
  582.     CALL    PR1
  583.     LDA    ECOUNT        ;INCREMENT COUNT
  584.     INR    A
  585.     STA    ECOUNT
  586.     ANI    3        ;EVERY 4
  587.     CZ    CRLF        ;NEW LINE
  588.     RET
  589. PR1:
  590.     MOV    A,M
  591.     ANI    7FH
  592.     CALL    COUT
  593.     INX    H
  594.     DCR    B
  595.     JNZ    PR1    
  596.     RET
  597. ;
  598. ; SHIFT REGS 'HL' RIGHT 2 BITS LOGICAL
  599. ;
  600. SHFHL2:
  601.     CALL    SHFHL        ;ROTATE RIGHT 1 BIT AND FALL THRU
  602. SHFHL:
  603.     XRA    A        ;CLEAR CARRY
  604.     MOV    A,H
  605.     RAR            ;SHIFTED BIT IN CARRY
  606.     MOV    H,A
  607.     MOV    A,L
  608.     RAR
  609.     MOV    L,A
  610.     RET
  611. ;
  612. ; TRANSLATE REG 'BC' FROM LOGICAL TO PHYSICAL SECTOR NUMBER
  613. ;
  614. TRNSLT:
  615.     LHLD    DPH        ;GET PTR TO DPH
  616.     MOV    E,M        ;GET ADDRESS OF XLT
  617.     INX    H
  618.     MOV    D,M
  619.     CALL    SECTRAN        ;USE BIOS ROUTINE
  620.     MOV    C,L        ;RETURN VALUE IN BC
  621.     MOV    B,H
  622.     RET
  623.  
  624. ;
  625. ;  DIRALPHA -- ALPHABETIZES DIRECTORY PTED TO BY HL; BC CONTAINS
  626. ;    THE NUMBER OF FILES IN THE DIRECTORY
  627. ;
  628. DIRALPHA:
  629.     LHLD    FCOUNT    ; GET FILE COUNT
  630.     MOV    A,H    ; ANY FILES?
  631.     ORA    L
  632.     RZ
  633.     SHLD    N    ; SET "N"
  634.     MOV    B,H    ; BC=COUNT
  635.     MOV    C,L
  636.     LHLD    DIRBUF    ; PT TO DIRECTORY
  637. ;
  638. ;  SHELL SORT --
  639. ;    THIS SORT ROUTINE IS ADAPTED FROM "SOFTWARE TOOLS"
  640. ;    BY KERNIGAN AND PLAUGHER, PAGE 106.  COPYRIGHT, 1976, ADDISON-WESLEY.
  641. ;  ON ENTRY, BC=NUMBER OF ENTRIES AND HL=ADDRESS OF FIRST ENTRY
  642. ;
  643. SORT:
  644.     XCHG        ; POINTER TO DIRECTORY IN DE
  645.     LHLD    ORDER    ; PT TO ORDER TABLE
  646. ;
  647. ;  SET UP ORDER TABLE; HL PTS TO NEXT ENTRY IN ORDER TABLE, DE PTS TO NEXT
  648. ;    ENTRY IN DIRECTORY, BC = NUMBER OF ELEMENTS REMAINING
  649. ;
  650. SORT1:
  651.     MOV    M,E    ; STORE LOW-ORDER ADDRESS
  652.     INX    H    ; PT TO NEXT ORDER BYTE
  653.     MOV    M,D    ; STORE HIGH-ORDER ADDRESS
  654.     INX    H    ; PT TO NEXT ORDER ENTRY
  655.     PUSH    H    ; SAVE PTR
  656.     LXI    H,ESIZE    ; HL=NUMBER OF BYTES/ENTRY
  657.     DAD    D    ; PT TO NEXT DIR1 ENTRY
  658.     XCHG        ; DE PTS TO NEXT ENTRY
  659.     POP    H    ; GET PTR TO ORDER TABLE
  660.     DCX    B    ; COUNT DOWN
  661.     MOV    A,B    ; DONE?
  662.     ORA    C
  663.     JNZ    SORT1
  664. ;
  665. ;  THIS IS THE MAIN SORT LOOP FOR THE SHELL SORT IN "SOFTWARE TOOLS" BY K&P
  666. ;
  667.  
  668. ;
  669. ;  SHELL SORT FROM "SOFTWARE TOOLS" BY KERNINGHAN AND PLAUGER
  670. ;
  671.     LHLD    N    ; NUMBER OF ITEMS TO SORT
  672.     SHLD    GAP    ; SET INITIAL GAP TO N FOR FIRST DIVISION BY 2
  673.  
  674. ;  FOR (GAP = N/2; GAP > 0; GAP = GAP/2)
  675. SRTL0:
  676.     ORA    A    ; CLEAR CARRY
  677.     LHLD    GAP    ; GET PREVIOUS GAP
  678.     MOV    A,H    ; ROTATE RIGHT TO DIVIDE BY 2
  679.     RAR
  680.     MOV    H,A
  681.     MOV    A,L
  682.     RAR
  683.     MOV    L,A
  684.  
  685. ;  TEST FOR ZERO
  686.     ORA    H
  687.     JZ    SDONE    ; DONE WITH SORT IF GAP = 0
  688.  
  689.     SHLD    GAP    ; SET VALUE OF GAP
  690.     SHLD    I    ; SET I=GAP FOR FOLLOWING LOOP
  691.  
  692. ;  FOR (I = GAP + 1; I <= N; I = I + 1)
  693. SRTL1:
  694.     LHLD    I    ; ADD 1 TO I
  695.     INX    H
  696.     SHLD    I
  697.  
  698. ;  TEST FOR I <= N
  699.     XCHG        ; I IS IN DE
  700.     LHLD    N    ; GET N
  701.     MOV    A,L    ; COMPARE BY SUBTRACTION
  702.     SUB    E
  703.     MOV    A,H
  704.     SBB    D    ; CARRY SET MEANS I > N
  705.     JC    SRTL0    ; DON'T DO FOR LOOP IF I > N
  706.  
  707.     LHLD    I    ; SET J = I INITIALLY FOR FIRST SUBTRACTION OF GAP
  708.     SHLD    J
  709.  
  710. ;  FOR (J = I - GAP; J > 0; J = J - GAP)
  711. SRTL2:
  712.     LHLD    GAP    ; GET GAP
  713.     XCHG        ; ... IN DE
  714.     LHLD    J    ; GET J
  715.     MOV    A,L    ; COMPUTE J - GAP
  716.     SUB    E
  717.     MOV    L,A
  718.     MOV    A,H
  719.     SBB    D
  720.     MOV    H,A
  721.     SHLD    J    ; J = J - GAP
  722.     JC    SRTL1    ; IF CARRY FROM SUBTRACTIONS, J < 0 AND ABORT
  723.     MOV    A,H    ; J=0?
  724.     ORA    L
  725.     JZ    SRTL1    ; IF ZERO, J=0 AND ABORT
  726.  
  727. ;  SET JG = J + GAP
  728.     XCHG        ; J IN DE
  729.     LHLD    GAP    ; GET GAP
  730.     DAD    D    ; J + GAP
  731.     SHLD    JG    ; JG = J + GAP
  732.  
  733. ;  IF (V(J) <= V(JG))
  734.     CALL    ICOMPARE    ; J IN DE, JG IN HL
  735.  
  736. ;  ... THEN BREAK
  737.     JC    SRTL1
  738.  
  739. ;  ... ELSE EXCHANGE
  740.     LHLD    J    ; SWAP J, JG
  741.     XCHG
  742.     LHLD    JG
  743.     CALL    ISWAP    ; J IN DE, JG IN HL
  744.  
  745. ;  END OF INNER-MOST FOR LOOP
  746.     JMP    SRTL2
  747.  
  748. ;
  749. ;  SORT IS DONE -- RESTRUCTURE DIR1 IN SORTED ORDER IN PLACE
  750. ;
  751. SDONE:
  752.     LHLD    N    ; NUMBER OF ENTRIES
  753.     MOV    B,H    ; ... IN BC
  754.     MOV    C,L
  755.     LHLD    ORDER    ; PTR TO ORDERED POINTER TABLE
  756.     SHLD    PTPTR    ; SET PTR PTR
  757.     LHLD    DIRBUF    ; PTR TO UNORDERED DIRECTORY
  758.     SHLD    PTDIR    ; SET PTR DIR BUFFER
  759.  
  760. ;  FIND PTR TO NEXT DIR1 ENTRY
  761. SRTDN:
  762.     LHLD    PTPTR    ; PT TO REMAINING POINTERS
  763.     XCHG        ; ... IN DE
  764.     LHLD    PTDIR    ; HL PTS TO NEXT DIR ENTRY
  765.     PUSH    B    ; SAVE COUNT OF REMAINING ENTRIES
  766.  
  767. ;  FIND PTR TABLE ENTRY
  768. SRTDN1:
  769.     LDAX    D    ; GET CURRENT POINTER TABLE ENTRY VALUE
  770.     INX    D    ; PT TO HIGH-ORDER POINTER BYTE
  771.     CMP    L    ; COMPARE AGAINST DIR1 ADDRESS LOW
  772.     JNZ    SRTDN2    ; NOT FOUND YET
  773.     LDAX    D    ; LOW-ORDER BYTES MATCH -- GET HIGH-ORDER POINTER BYTE
  774.     CMP    H    ; COMPARE AGAINST DIR1 ADDRESS HIGH
  775.     JZ    SRTDN3    ; MATCH FOUND
  776. SRTDN2:
  777.     INX    D    ; PT TO NEXT PTR TABLE ENTRY
  778.     DCX    B    ; COUNT DOWN
  779.     MOV    A,C    ; END OF TABLE?
  780.     ORA    B
  781.     JNZ    SRTDN1    ; CONTINUE IF NOT
  782.  
  783. ;  FATAL ERROR -- INTERNAL ERROR; POINTER TABLE NOT CONSISTENT
  784. FERR$PTR:
  785.     CALL    PRINT
  786.     DB    0DH,0AH,'DIRALPHA -- Pointer Error',0
  787.     JMP    RETURN
  788.  
  789. ;  FOUND THE POINTER TABLE ENTRY WHICH POINTS TO THE NEXT UNORDERED DIR1 ENTRY
  790. ;    MAKE BOTH POINTERS (PTR TO NEXT, PTR TO CURRENT UNORDERED DIR1 ENTRY)
  791. ;    POINT TO SAME LOCATION (PTR TO NEXT DIR1 ENTRY TO BE ORDERED)
  792. SRTDN3:
  793.     LHLD    PTPTR    ; GET PTR TO NEXT ORDERED ENTRY
  794.     DCX    D    ; DE PTS TO LOW-ORDER POINTER ADDRESS
  795.     MOV    A,M    ; MAKE PTR TO NEXT UNORDERED DIR1 PT TO BUFFER FOR
  796.     STAX    D    ;   DIR1 ENTRY TO BE MOVED TO NEXT UNORDERED DIR1 POS
  797.     INX    H    ; PT TO NEXT PTR ADDRESS
  798.     INX    D
  799.     MOV    A,M    ; MAKE HIGH POINT SIMILARLY
  800.     STAX    D
  801.  
  802. ;  COPY NEXT UNORDERED DIR1 ENTRY TO HOLD BUFFER
  803.     MVI    B,ESIZE    ; B=NUMBER OF BYTES/ENTRY
  804.     LHLD    PTDIR    ; PT TO ENTRY
  805.     LXI    D,HOLD    ; PT TO HOLD BUFFER
  806.     PUSH    B    ; SAVE B=NUMBER OF BYTES/ENTRY
  807.     CALL    MOVE
  808.     POP    B
  809.  
  810. ;  COPY TO-BE-ORDERED DIR1 ENTRY TO NEXT ORDERED DIR1 POSITION
  811.     LHLD    PTPTR    ; POINT TO ITS POINTER
  812.     MOV    E,M    ; GET LOW-ADDRESS POINTER
  813.     INX    H
  814.     MOV    D,M    ; GET HIGH-ADDRESS POINTER
  815.     LHLD    PTDIR    ; DESTINATION ADDRESS FOR NEXT ORDERED DIR1 ENTRY
  816.     XCHG        ; HL PTS TO ENTRY TO BE MOVED, DE PTS TO DEST
  817.     PUSH    B    ; SAVE B=NUMBER OF BYTES/ENTRY
  818.     CALL    MOVE
  819.     POP    B
  820.     XCHG        ; HL PTS TO NEXT UNORDERED DIR1 ENTRY
  821.     SHLD    PTDIR    ; SET POINTER FOR NEXT LOOP
  822.  
  823. ;  COPY ENTRY IN HOLD BUFFER TO LOC PREVIOUSLY HELD BY LATEST ORDERED ENTRY
  824.     LHLD    PTPTR    ; GET PTR TO PTR TO THE DESTINATION
  825.     MOV    E,M    ; GET LOW-ADDRESS POINTER
  826.     INX    H
  827.     MOV    D,M    ; HIGH-ADDRESS POINTER
  828.     LXI    H,HOLD    ; HL PTS TO HOLD BUFFER, DE PTS TO ENTRY DEST
  829.     CALL    MOVE    ; B=NUMBER OF BYTES/ENTRY
  830.  
  831. ;  POINT TO NEXT ENTRY IN POINTER TABLE
  832.     LHLD    PTPTR    ; POINTER TO CURRENT ENTRY
  833.     INX    H    ; SKIP OVER IT
  834.     INX    H
  835.     SHLD    PTPTR
  836.  
  837. ;  COUNT DOWN
  838.     POP    B    ; GET COUNTER
  839.     DCX    B    ; COUNT DOWN
  840.     MOV    A,C    ; DONE?
  841.     ORA    B
  842.     JNZ    SRTDN
  843.     RET        ; DONE
  844.  
  845. ;
  846. ;  SWAP (Exchange) the pointers in the ORDER table whose indexes are in
  847. ;    HL and DE
  848. ;
  849. ISWAP:
  850.     PUSH    H        ; SAVE HL
  851.     LHLD    ORDER        ; ADDRESS OF ORDER TABLE - 2
  852.     MOV    B,H        ; ... IN BC
  853.     MOV    C,L
  854.     POP    H
  855.     DCX    H        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  856.     DAD    H        ; HL PTS TO OFFSET ADDRESS INDICATED BY INDEX
  857.                 ;   OF ORIGINAL HL (1, 2, ...)
  858.     DAD    B        ; HL NOW PTS TO POINTER INVOLVED
  859.     XCHG            ; DE NOW PTS TO POINTER INDEXED BY HL
  860.     DCX    H        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  861.     DAD    H        ; HL PTS TO OFFSET ADDRESS INDICATED BY INDEX
  862.                 ;   OF ORIGINAL DE (1, 2, ...)
  863.     DAD    B        ; HL NOW PTS TO POINTER INVOLVED
  864.     MOV    C,M        ; EXCHANGE POINTERS -- GET OLD (DE)
  865.     LDAX    D        ; -- GET OLD (HL)
  866.     XCHG            ; SWITCH
  867.     MOV    M,C        ; PUT NEW (HL)
  868.     STAX    D        ; PUT NEW (DE)
  869.     INX    H        ; PT TO NEXT BYTE OF POINTER
  870.     INX    D
  871.     MOV    C,M        ; GET OLD (HL)
  872.     LDAX    D        ; GET OLD (DE)
  873.     XCHG            ; SWITCH
  874.     MOV    M,C        ; PUT NEW (DE)
  875.     STAX    D        ; PUT NEW (HL)
  876.     RET
  877. ;
  878. ;  ICOMPARE compares the entry pointed to by the pointer pointed to by HL
  879. ;    with that pointed to by DE (1st level indirect addressing); on entry,
  880. ;    HL and DE contain the numbers of the elements to compare (1, 2, ...);
  881. ;    on exit, Carry Set means ((DE)) < ((HL)), Zero Set means ((HL)) = ((DE)),
  882. ;    and Non-Zero and No-Carry means ((DE)) > ((HL))
  883. ;
  884. ICOMPARE:
  885.     PUSH    H        ; SAVE HL
  886.     LHLD    ORDER        ; ADDRESS OF ORDER - 2
  887.     MOV    B,H        ; ... IN BC
  888.     MOV    C,L
  889.     POP    H
  890.     DCX    H        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  891.     DAD    H        ; DOUBLE THE ELEMENT NUMBER TO POINT TO THE PTR
  892.     DAD    B        ; ADD TO THIS THE BASE ADDRESS OF THE PTR TABLE
  893.     XCHG            ; RESULT IN DE
  894.     DCX    H        ; ADJUST INDEX TO 0...N-1 FROM 1...N
  895.     DAD    H        ; DO THE SAME WITH THE ORIGINAL DE
  896.     DAD    B
  897.     XCHG
  898.  
  899. ;
  900. ;  HL NOW POINTS TO THE POINTER WHOSE INDEX WAS IN HL TO BEGIN WITH
  901. ;  DE NOW POINTS TO THE POINTER WHOSE INDEX WAS IN DE TO BEGIN WITH
  902. ;    FOR EXAMPLE, IF DE=5 AND HL=4, DE NOW POINTS TO THE 5TH PTR AND HL
  903. ; TO THE 4TH POINTER
  904. ;
  905.     MOV    C,M        ; BC IS MADE TO POINT TO THE OBJECT INDEXED TO
  906.     INX    H        ; ... BY THE ORIGINAL HL
  907.     MOV    B,M
  908.     XCHG
  909.     MOV    E,M        ; DE IS MADE TO POINT TO THE OBJECT INDEXED TO
  910.     INX    H        ; ... BY THE ORIGINAL DE
  911.     MOV    D,M
  912.     MOV    H,B        ; SET HL = OBJECT PTED TO INDIRECTLY BY BC
  913.     MOV    L,C
  914.  
  915. ;
  916. ;  COMPARE DIR ENTRY PTED TO BY HL WITH THAT PTED TO BY DE;
  917. ;    NO NET EFFECT ON HL, DE; RET W/CARRY SET MEANS DE<HL
  918. ;    RET W/ZERO SET MEANS DE=HL
  919. ;
  920. CMP$ENTRY:
  921. ;
  922. ;  COMPARE BY FILE NAME, FILE TYPE, EXTENSION, AND USER NUM (IN THAT ORDER)
  923. ;
  924.     PUSH    H
  925.     PUSH    D
  926.     INX    H    ; PT TO FN
  927.     INX    D
  928.     MVI    B,11    ; COMPARE FN, FT
  929.     CALL    COMP
  930.     POP    D
  931.     POP    H
  932.     RNZ
  933.     LDAX    D    ; COMPARE USER NUMBER
  934.     CMP    M
  935.     RET
  936. ;
  937. ;  COMP COMPARES DE W/HL FOR B BYTES; RET W/CARRY IF DE<HL
  938. ;    MSB IS DISREGARDED
  939. ;
  940. COMP:
  941.     MOV    A,M    ; GET (HL)
  942.     ANI    7FH    ; MASK MSB
  943.     MOV    C,A    ; ... IN C
  944.     LDAX    D    ; COMPARE
  945.     ANI    7FH    ; MASK MSB
  946.     CMP    C
  947.     RNZ
  948.     INX    H    ; PT TO NEXT
  949.     INX    D
  950.     DCR    B    ; COUNT DOWN
  951.     JNZ    COMP
  952.     RET
  953. ;
  954. ;  AS COMP, BUT MATCH ON '?' PTED TO BY HL
  955. ;
  956. COMP2:
  957.     MOV    A,M    ; GET (HL)
  958.     ANI    7FH    ; MASK MSB
  959.     CPI    '?'    ; MATCH '?'
  960.     JZ    COMP2A
  961.     MOV    C,A    ; ... IN C
  962.     LDAX    D    ; COMPARE
  963.     ANI    7FH    ; MASK MSB
  964.     CMP    C
  965.     RNZ
  966. COMP2A:
  967.     INX    H    ; PT TO NEXT
  968.     INX    D
  969.     DCR    B    ; COUNT DOWN
  970.     JNZ    COMP2
  971.     RET
  972.  
  973. ;
  974. ;  SORT BUFFERS
  975. ;
  976. ORDER:
  977.     DS    2    ; PTR TO ORDER TABLE
  978. DIRBUF:
  979.     DS    2    ; POINTER TO DIRECTORY
  980. DSTART:
  981.     DS    2    ; POINTER TO FIRST DIRECTORY ENTRY
  982. FCOUNT:
  983.     DS    2    ; TOTAL NUMBER OF FILES/NUMBER OF SELECTED FILES
  984. HOLD:
  985.     DS    ESIZE    ; EXCHANGE HOLD BUFFER FOR FCB'S
  986. PTPTR:
  987.     DS    2    ; POINTER POINTER
  988. PTDIR:
  989.     DS    2    ; DIRECTORY POINTER
  990. I:
  991.     DS    2    ; INDEXES FOR SORT
  992. J:
  993.     DS    2
  994. JG:
  995.     DS    2
  996. N:
  997.     DS    2    ; NUMBER OF ELEMENTS TO SORT
  998. GAP:
  999.     DS    2    ; BINARY GAP SIZE
  1000. ;
  1001. ; THIS IS THE WORKING COPY OF THE BIOS JUMP TABLE
  1002. ;
  1003. WBOOT:     DS    3
  1004. CONST:     DS    3
  1005. CONIN:     DS    3
  1006. CONOUT:     DS    3
  1007. LIST:     DS    3
  1008. PUNCH:     DS    3
  1009. READER:     DS    3
  1010. HOME:     DS    3
  1011. SELDSK:     DS    3
  1012. SETTRK:     DS    3
  1013. SETSEC:     DS    3
  1014. SETDMA:     DS      3
  1015. READ:     DS    3
  1016. WRITE:     DS    3
  1017. LISTST:     DS    3
  1018. SECTRAN: DS    3
  1019. ;
  1020. STACK:
  1021.     DS    2        ;LOCATION OF STACK
  1022. ;
  1023. ; DATA AREAS
  1024. ;
  1025. FNCOUNT:
  1026.     DS    1        ;NUMBER OF FILE NAMES FOUND
  1027. CLPFLG:    DS    1        ;0 FOR NO MATCH LOCALLY
  1028. SYSTEM:    DS    1        ;0 IF NO SYSTEM FILES
  1029. ECOUNT:    DS    1        ;COUNT OF ENTRIES PRINTED - 1
  1030. FFLAG:    DS    1        ;FILE FOUND FLAG (0=NO)
  1031. TEMP:    DS    2        ;TEMP STORAGE FOR FCB PRINT
  1032. ;
  1033. ;  DISK PARAMETER DATA
  1034. ;
  1035. DPH:    DS    2        ;ADDRESS OF DPH
  1036. DIRMAX:    DS    2        ;NUMBER OF SECTORS IN DIRECTORY =
  1037. ;                ;   MAXIMUM NUMBER OF DIRECTORY ENTRIES
  1038. ;                ;   DIVIDED BY 4 (ENTRIES PER SECTOR)
  1039. EXTENT:    DS    1        ;EXTENT MASK
  1040. MAXSEC:    DS    2        ;MAXIMUM NUMBER OF SECTORS/TRACK
  1041. SECTOR:    DS    2        ;CURRENT SECTOR NUMBER
  1042. TRACK:    DS    2        ;TRACK NUMBER OF DIRECTORY
  1043.  
  1044. FNTAB:    DS    2        ;FILE NAME TABLE
  1045.  
  1046. SCRATCH:
  1047.     DS    2        ;SCRATCH AREA
  1048.  
  1049.     END
  1050.