TITLE "SDIRQ - Syslib 4.3" NAME ('DIRQ') ;================================================================= ; The Libraries, Version 4, (C) 1989 by Alpha Systems Corp. ;----------------------------------------------------------------- ; Author : Harold F. Bower ; Derived from SDIRQ.Z80 Ver 1.5 by Richard Conn ; Date : 17 Sep 89 ; Version : 1.6 ; Module : SDIRQ ; Abstract: This module contains the routine which is a General- ; purpose directory select routine without sizing informa- ; tion. It scans the designated (or default) disk and ; loads all file names matching that contained in an FCB ; which is passed to the routine, to a memory buffer. The ; buffer is sorted in accordance with user-defined flags ; passed to the routine. This routine does NOT provide ; enough information to determine file size, and is intended ; for applications needing only a sorted table of file names. ; Additional capabilities are provided by SDIRQS and SDIR. ; Selection options offered are: ; Bit 7 - If "1", Select Non-System files ; Bit 6 - If "1", Select System Files ; Bit 5 - If "1", Sort by Type then Name ; If "0", Sort by Name then Type ; Bits 4-0 are unused ; Revision: ; 1.7 - 22 Nov 90 - Modified to use general sort routine. HFB ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Module Entry Points PUBLIC DIRQ ;;, ICOMPARE ; From SYSLIB Get.. ;; EXT DBUFFER, DISORT, EXT @FNCMP, dparams, dirmax, ssbinit, sort ;; EXT SELFLG, ORDER, DIRBUF, EXT GETMTOP ; Definitions CPM EQU 0 BDOS EQU 5 ; CP/M, ZRDOS, P2DOS Entry Point SETDMA EQU 26 ; CP/M Command to set DMA transfer addr BUFF EQU 0080H ; Default DMA Buffer ESIZE EQU 16 ; Size of each Entry .Z80 CSEG ;=============================================================== ; NAME - DIRQ ; Entry: HL - Points to Memory Buffer ; DE - Points to FCB for selection ; A - Contains selection flags ; Exit : A = 0 and Zero flag Set (Z) if TPA Overflow ; A <> 0, Zero Flag Clear (NZ) if Ok ; HL - Points to first file in Buffer ; BC - Contains number of files in Buffer ; Uses : AF,BC,HL ; Side Effects: DMA address set to 80H. ;=============================================================== DIRQ: PUSH DE ; Save ptr to FCB LD (SELFLG),A ; Save select flag for selection and Alpha LD (TFCB),HL ; Set ptr to temp FCB LD BC,36 ; Offset to after FCB ADD HL,BC ; ..useable memory not starts at (HL) ;; PUSH DE ; Save ptr to FCB ;; CALL DBUFFER ; Get ptrs call dparams ;; Set parameters for logged disk ex de,hl ;; Save in DE while we set up SSB ld hl,(dirmax) ;; Get Max Number of DIR entries ld (fcount),hl ;; ..save in SSB ld hl,esize ;; Get Size of records ld (elsiz),hl ;; ..save in SSB ld hl,0 ;; Let SSBINIT set buffer addr ld (dstart),hl ;; ld hl,00FFH ;; Use ptrs and reorder after sort ld (ptrflg),hl ;; ..place in POINT (L) and NOREC (H) in SSB ld hl,cmpentry ;; Address of User Compare routine ld (compit),hl ;; ..place addr in SSB ex de,hl ;; Put Memory base back in HL ld de,SSB ;; .point to SSB call ssbinit ;; ..and Initialize the Sort routine ld (dirbuf),hl ;; Save returned Record Buffer Address POP DE ; Get ptr to FCB ;; PUSH HL ; Save ptr to buffer CALL DIRLOAD ; Load directory w/o sizing info (Fast Load) ;; POP HL ; Get ptr to Buffer ;; POP DE ; Get ptr to FCB ;; RET Z ; Abort if TPA overflow ld de,ssb ;; Set parm for Sort routine push af ;; call nz,sort ;; ..and do it ld hl,(dstart) ;; Load exit parms ld bc,(fcount) ;; ;; PUSH AF ; Save flag to indicate No TPA overflow ;; CALL DISORT ; Alphabetize in External Module POP AF ; Get AF (TPA Overflow Flag) RET ; Build Directory Table at DIRBUF ; This is the optimal Directory Load Routine; It only loads unique file names ; from disk, but the information is not sufficient to compute the file sizes ; ; On Input : HL pts to Directory Buffer (16 x N Max) ; DE pts to FCB (Only 12 bytes needed) ; On Output: BC is Number of Files ; A = 0 and Zero Flag set if TPA Overflow DIRLOAD: INC DE ; Pt to file name LD HL,(TFCB) ; Pt to TFCB LD (HL),0 ; Select Current Disk INC HL ; Pt to File Name in TFCB LD B,11 ; 11 Chars DLLOOP: LD A,(DE) ; Copy LD (HL),A INC HL ; Pt to next INC DE DJNZ DLLOOP ; Count down LD B,24 ; 24 chars (Incl Zero EX) XOR A ; Zero rest of TFCB DLLOOP1: LD (HL),A ; Store Zero INC HL ; Pt to next DJNZ DLLOOP1 ; Count down ; This section of code initializes the Counters used LD HL,0 ; HL = 0 LD (FCOUNT),HL ; Total Files on Disk = 0 ; Begin by setting default DMA address to 80H LD DE,BUFF ; Set DMA address to default LD C,SETDMA CALL BDOS ; Now we begin scanning for files to place into the memory buffer LD C,17 ; Search for file JR DIRLP1 DIRLP: CALL PENTRY ; Place entry in Dir JR Z,DIROVFL ; Memory Overflow Error LD C,18 ; Search for Next match DIRLP1: LD DE,(TFCB) ; Pt to FCB CALL BDOS CP 255 ; Done? JR NZ,DIRLP ; Now we are done with the Load -- Set up Return Values DIRDN: OR 0FFH ; Set Flags NZ for Load Ok DIRDNX: LD BC,(FCOUNT) ; Get total number of files in BC RET ; Memory Overflow Error DIROVFL: XOR A ; Load Error JR DIRDNX ; PENTRY -- Place entry in Directory Buffer if not an erased entry ; On Input: A = 0-3 for Adr index in Buff of Entry FCB ; FCOUNT = Number of files in Dir so far ; On Output: FCOUNT = Number of files in dir so far ; A = 0 and Zero Flag Set if Memory Overflow Error PENTRY: RRCA ; Multiply by 32 for Offset computation RRCA RRCA AND 60H ; A = Byte Offset LD DE,BUFF ; Pt to Buffer Entry LD L,A ; Let HL = Offset LD H,0 ADD HL,DE ; HL = Ptr to FCB ; HL = Adr of FCB in BUFF CALL ATTEST ; Test Attributes JR Z,PEDONE ; Skip if attribute not desired ; Copy FCB pted to by HL into Directory Buffer LD DE,(DIRBUF) ; Pt to Next Entry location LD BC,ESIZE ; Number of Bytes/Entry LDIR ; Copy FCB into Memory Buffer LD (DIRBUF),DE ; Set ptr to Next Entry CALL GETMTOP ; Return highest avail addr in HL LD A,H ; Get CCP page in A DEC A ; ..and back one page in front of it CP D ; Is ptr to next entry beyond this? RET Z ; Increment total number of files LD HL,(FCOUNT) ; Total Files = Total Files + 1 INC HL LD (FCOUNT),HL ; Done with PENTRY and No Error PEDONE: OR 0FFH ; Set NZ for No Error RET ; Check Attributes of File Entry pted to by HL against SELFLG ; If System File and System Attribute Set, Return NZ ; If Normal File and Normal Attribute Set, Return NZ ATTEST: PUSH HL ; Save ptr LD BC,10 ; Pt to System Attribute ADD HL,BC BIT 7,(HL) ; Check for System Attribute POP HL ; Restore ptr LD A,(SELFLG) ; Get Selection Flag JR Z,ATDIR AND 01000000B ; Check System Attribute RET ATDIR: AND 10000000B ; Check Normal Attribute RET ; ICOMPARE compares the entry pointed to by the pointer pointed to by HL ; with that pointed to by DE (1st level indirect addressing); on entry, ; HL and DE contain the numbers of the elements to compare (1, 2, ...); ; on exit, Carry Set means ((DE)) < ((HL)), Zero Set means ((HL)) = ((DE)), ; and Non-Zero and No-Carry means ((DE)) > ((HL)) ;;ICOMPARE: ;; LD BC,(ORDER) ; Get address of Order - 2 in BC ;; DEC HL ; Adjust Index to 0...N-1 from 1...N ;; ADD HL,HL ; Double the element number to point to the ptr ;; ADD HL,BC ; Add to this the base address of the ptr table ;; EX DE,HL ; Result in DE ;; DEC HL ; Adjust Index to 0...N-1 from 1...N ;; ADD HL,HL ; Do the same with the Original DE ;; ADD HL,BC ;; EX DE,HL ; HL now points to the pointer whose index was in HL to begin with ; DE now points to the pointer whose index was in DE to begin with ; For example, if DE=5 and HL=4, DE now points to the 5th ptr and HL ; to the 4th pointer ;; LD C,(HL) ; BC is made to point to the object indexed ;; INC HL ; ...by the original HL ;; LD B,(HL) ;; EX DE,HL ;; LD E,(HL) ; DE is made to point to the object indexed ;; INC HL ; ...by the original DE ;; LD D,(HL) ;; LD H,B ; Set HL = Object pted to indirectly by BC ;; LD L,C ; Compare Dir entry pted to by HL with that pted to by DE; ; No net effect on HL, DE; Ret w/Carry Set means DE < HL ; Ret w/Zero Set means DE = HL CMPENTRY: push bc ;; Save counter LD A,(SELFLG) ; Group by File Type? AND 00100000B JR Z,CMPFNFT ; Compare by File Type and File Name (in that order) PUSH HL PUSH DE LD BC,9 ; Pt to FT (8 bytes + 1 byte for user number) ADD HL,BC EX DE,HL ADD HL,BC EX DE,HL ; DE, HL now pt to their FT'S LD B,3 ; 3 bytes CALL @FNCMP ; Compare FT'S POP DE POP HL ;; RET NZ ; Continue if complete match jr nz,cmpex ;; ..exit if mismatch LD B,8 ; 8 bytes JR CMPFT1 ; Compare by File Name and File Type (in that order) CMPFNFT: LD B,11 ; 11 bytes for FN and FT CMPFT1: PUSH HL PUSH DE INC HL ; Pt to FN INC DE CALL @FNCMP ; Do comparison POP DE POP HL cmpex: pop bc ;; Restore file counter RET ; Data Storage/Buffers DSEG ; Put in Data Segment selflg: defs 1 ;; dirbuf: defs 2 ;; TFCB: DS 2 ; Address of temporary FCB ssb: DSTART: DS 2 ; Pointer to first Directory Entry FCOUNT: DS 2 ; Total Number of Files/Number of Sel Files elsiz: defs 2 ;; Size of each element compit: defs 2 ;; Addr of compare routine ordbuf: defs 2 ;; Addr of Order buffer ptrflg: defs 1 ;; FF=Use ptrs, 0=No ptrs defs 1 ;; (reserved) END