; TITLE "SDIR05 - Syslib 4.0" NAME ('DIRLOA') ;================================================================= ; The Libraries, Version 4, (C) 1989 by Alpha Systems Corp. ;----------------------------------------------------------------- ; Author : Harold F. Bower ; Derived from SDIR05.Z80 Ver 1.5 by Richard Conn ; Date : 17 Sep 89 ; Version : 1.6 ; Module : SDIR05 ; Abstract: This module contains the routines DIRLOAD and ; DIRSLOAD which build a table of file names in memory. ; Each entry is 16 bytes long, with DIRSLOAD entries ; containing enough information to permit file sizes to ; be determined. DIRSLOAD is less efficient in terms of ; file size and execution speed. ; Revision: ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ; Module Entry Points PUBLIC DIRLOAD, DIRSLOAD ; From SYSLIB Get.. EXT SELFLG, DIRBUF, @FNCMP, HFILB, GETMTOP ; Definitions BDOS EQU 5 ; CP/M, ZRDOS, P2DOS Entry Point BUFF EQU 0080H ; Default CP/M Sector Buffer ESIZE EQU 16 ; Element size in bytes .Z80 CSEG ;=============================================================== ; NAME - DIRLOAD (No Sizing Info) ; Entry: HL - Points to Directory Buffer (16 X N max) ; Exit : BC - Contains the Number of Files loaded ; A = 0 and Zero Flag Set (Z) if TPA overflow ; Zero Flag Reset (NZ) if No errors ; Uses : AF,BC ; Special Requirements: None ;=============================================================== DIRLOAD: DEFB 0F6H ; Select files of smaller EX by setting ; .flag to Non-0 with "OR 0AFH" ;..fall thru ;=============================================================== ; NAME - DIRSLOAD (WITH Sizing Info) ; Entry: HL - Points to Directory Buffer (16 X N max) ; Exit : BC - Contains the Number of Files loaded ; A = 0 and Zero Flag Set (Z) if TPA overflow ; Zero Flag Reset (NZ) if No errors ; Uses : AF,BC ; Special Requirements: None ;=============================================================== DIRSLOAD: XOR A ; Select Larger EX LD (DFLAG),A ; Set Flag PUSH HL ; Save Registers PUSH DE LD (DIRBUF),HL ; Save ptr to Directory Buffer LD (DSTART),HL ; Set start of buffer area LD HL,TFCB ; Prepare the FCB for all Users, LD A,'?' LD B,12 ; ..Names and Types CALL HFILB XOR A ; Zero all other entries LD B,24 CALL HFILB ; This section of code initializes the counters used LD HL,0 ; HL = 0 LD (FCOUNT),HL ; Total Files on Disk = 0 ; Insure default DMA address set to 80H LD DE,BUFF LD C,26 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 Wild Name CALL BDOS CP 255 ; Done? JR NZ,DIRLP ; Now we are done with the Load -- Set up Return Values OR 0FFH ; Set Flags for Load OK (NZ) DIRDNX: LD BC,(FCOUNT) ; Get total number of files in BC POP DE ; Restore Registers and return POP HL 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: PUSH BC ; Save Regs PUSH DE PUSH HL 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 LD A,(HL) ; Get User Number CP 0E5H ; Deleted? JR Z,PEDONE ; ..Skip it if deleted CP 21H ; Is it a CP/M Plus Time Stamp or illegal? JR NC,PEDONE ; ..quit here if so ; HL = Adr of FCB in Buff ; Scan Directory entries as loaded so far for another entry by the same ; name; If found, set that entry to be the entry with the larger EX ; and return with the zero flag set, indicating no new file; If not ; found, return with Zero Flag Reset (NZ) CALL DUPENTRY ; Check for Duplicate and select EX JR Z,PEDONE ; Skip if Duplicate ; Increment total number of Files PUSH HL ; Save ptr to FCB LD HL,(FCOUNT) ; Total Files = Total Files + 1 INC HL LD (FCOUNT),HL POP HL ; Get ptr to FCB ; Copy FCB pted to by HL into Directory Buffer LD DE,(DIRBUF) ; DE pta to Next Entry Locn, HL pts to FCB LD BC,ESIZE ; Number of Bytes/Entry LDIR ; Copy FCB into Memory Buffer LD (DIRBUF),DE ; Set ptr to Next Entry CALL GETMTOP ; Get top available addr in HL LD A,H ; Get base page of Bdos DEC A ; ..and move one more page down CP D ; Is ptr to next entry beyond this? JR NZ,PEDONE ; Ok if not at Buffer Overflow Level ; Done with PENTRY with Memory Overflow Error XOR A ; Error DEFB 21H ; Code for "LD HL,xxx". Trash HL and fall thru ; Done with PENTRY and No Error PEDONE: OR 0FFH ; Set Flags for No Error (NZ) POP HL ; Restore regs POP DE POP BC RET ;..... ; Scan Directory Entries as loaded so far for another entry by the same ; name; If found, set that entry to be the entry with the larger EX ; and return with the Zero Flag set, indicating no new file; If not ; found, return with Zero Flag Reset (NZ) ; On Input, HL pts to entry to scan for, FCOUNT = Number of entries so far, ; and (DSTART) = Starting Address of Directory Loaded ; On Output, A = 0 and Zero Flag Set if duplicate entry found; A = 0FFH and NZ ; if no Dup Entry found ; Only HL Not affected DUPENTRY: PUSH HL ; Save ptr to entry to scan for EX DE,HL ; Ptr in DE LD BC,(FCOUNT) ; Check Count LD A,B ; No Entries? OR C JR Z,NODUP ; No Duplicate Entry Return LD HL,(DSTART) ; HL pts to First Entry DUPELOOP: PUSH BC ; Save count PUSH HL ; Save ptrs PUSH DE LD B,12 ; Compare User Number, FN, and FT CALL @FNCMP POP DE ; Restore ptrs POP HL JR NZ,NODUPL ; Continue looking for another entry ; Duplicate entries have been identified at this point PUSH HL ; Save ptrs again PUSH DE LD BC,12 ; Pt to EX Field ADD HL,BC EX DE,HL ADD HL,BC ; DE pts to Directory Entry, HL pts to targer LD A,(DE) ; Get Extent Field from Directory Entry CP (HL) ; Compare with that in targer POP DE ; Get ptrs POP HL JR NC,DUPSMALL ; New target is larger than stored entry LD A,(DFLAG) ; Check flag for large or small EX OR A ; 0 = Select Larger JR NZ,DUPFND DUPSEL: EX DE,HL ; Make HL pt to new targer, DE pt to Dest LD BC,ESIZE ; Number of bytes to move LDIR ; Move it JR DUPFND ; New target is smaller than stored entry DUPSMALL: LD A,(DFLAG) ; Check flag for large or small EX OR A ; 0FFH = Select Smaller JR NZ,DUPSEL ; Return indicator that Duplicate WAS found DUPFND: POP BC ; Clear count from stack XOR A ; Indicate dup found POP HL ; Restore ptr to entry to scan for RET ; No duplicate found; Advance to next entry NODUPL: LD BC,ESIZE ; HL pts to current entry in Buffer ADD HL,BC ; ..Add ESIZE to it POP BC ; Get COUNT DEC BC ; Count down LD A,B ; Check for done OR C JR NZ,DUPELOOP ; No Duplicate found, Period NODUP: OR 0FFH ; Set flags to Indicate Dup not found (NZ) POP HL ; Restore ptr to entry to scan for RET ; Data Buffers DSEG ; Put in Data Segment TFCB: DEFS 36 ; Temporary FCB (FN,FT Wild) DFLAG: DEFS 1 ; 0 = Select Files w/Larger EX, Else w/Smaller EX DSTART: DEFS 2 ; Pointer to First Directory Entry FCOUNT: DEFS 2 ; Total Number of Files/Number of Selected Files END