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
/
SYSLIB
/
SLIB1.LBR
/
SDIR05.Z80
< prev
next >
Wrap
Text File
|
2000-06-30
|
7KB
|
280 lines
;
; SYSLIB Module Name: SDIR05
; Author: Richard Conn
; Part of SYSLIB3 SDIR Series
; SYSLIB Version Number: 3.6
; Module Version Number: 1.5
public dirload,dirsload
MACLIB SDIRHDR.LIB
EXT SDMOVE
;*
;* 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)
;* ON OUTPUT, BC IS NUM OF FILES
;* A=0 AND ZERO FLAG SET IF TPA OVERFLOW
;* DE, HL UNAFFECTED
;*
DIRLOAD:
PUSH HL ; SAVE REGISTERS
PUSH DE
LD A,0FFH ; SELECT FILES OF SMALLER EX
LD (DFLAG),A ; SET FLAG
DLCOMMON:
LD A,'?' ; SELECT FILES FROM ALL USER AREAS
LD (TFCB),A ; SET DR FIELD TO ZERO TO DO THIS
LD (DIRBUF),HL ; SAVE PTR TO DIRECTORY BUFFER
LD (DSTART),HL ; SET START OF BUFFER AREA
;*
;* THIS SECTION OF CODE INITIALIZES THE COUNTERS USED
;*
LD HL,0 ; HL=0
LD (FCOUNT),HL ; TOTAL FILES ON DISK = 0
;*
;* NOW WE BEGIN SCANNING FOR FILES TO PLACE INTO THE MEMORY BUFFER
;*
LD C,17 ; SEARCH FOR FILE
JP DIRLP1
DIRLP:
CALL PENTRY ; PLACE ENTRY IN DIR
JP 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?
JP NZ,DIRLP
;*
;* NOW WE ARE DONE WITH THE LOAD -- SET UP RETURN VALUES
;*
DIRDN:
XOR A ; LOAD OK
DEC A ; SET FLAGS (NZ)
DIRDNX:
LD HL,(FCOUNT) ; GET TOTAL NUMBER OF FILES
LD B,H ; ... IN BC
LD C,L
;*
;* RESTORE REGISTERS AND RETURN
;*
POP DE
POP HL
RET
;*
;* MEMORY OVERFLOW ERROR
;*
DIROVFL:
XOR A ; LOAD ERROR
JP 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?
JP Z,PEDONE ; SKIP IT IF DELETED
;*
;* 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
JP 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
;*
EX DE,HL ; SAVE PTR IN DE
LD HL,(DIRBUF) ; PT TO NEXT ENTRY LOCATION
EX DE,HL ; HL PTS TO FCB, DE PTS TO NEXT ENTRY LOCATION
LD B,ESIZE ; NUMBER OF BYTES/ENTRY
CALL SDMOVE ; COPY FCB INTO MEMORY BUFFER
EX DE,HL ; HL PTS TO NEXT ENTRY
LD (DIRBUF),HL ; SET PTR
EX DE,HL ; PTR TO NEXT ENTRY IN DE
LD HL,(BDOS+1) ; BASE ADDRESS OF BDOS IN HL
LD A,H ; GET BASE PAGE OF BDOS
SUB 9 ; COMPUTE 1 PAGE IN FRONT OF BASE PAGE OF CCP
CP D ; IS PTR TO NEXT ENTRY BEYOND THIS?
JP NZ,PEDONE ; OK IF NOT AT BUFFER OVERFLOW LEVEL
;* DONE WITH PENTRY WITH MEMORY OVERFLOW ERROR
PEOVFL:
XOR A ; ERROR
POP HL ; RESTORE REGS
POP DE
POP BC
RET
;* DONE WITH PENTRY AND NO ERROR
PEDONE:
XOR A ; NO ERROR
DEC A ; SET FLAGS (NZ)
POP HL ; RESTORE REGS
POP DE
POP BC
RET
;*
;* BUILD DIRECTORY TABLE AT DIRBUF
;* THIS DIRECTORY LOAD ROUTINE IS MUST LESS EFFICIENT THAN DIRLOAD,
;* BUT IT DOES LOAD ENOUGH INFORMATION TO COMPUTE THE FILE
;* SIZES USING THE FSIZE ROUTINE
;* ON INPUT, HL PTS TO DIRECTORY BUFFER (16 x N MAX)
;* ON OUTPUT, BC IS NUM OF FILES
;* A=0 AND ZERO FLAG SET IF TPA OVERFLOW
;* DE, HL UNAFFECTED
;*
DIRSLOAD:
PUSH HL ; SAVE REGISTERS
PUSH DE
XOR A ; SELECT LARGER EX
LD (DFLAG),A ; SET FLAG
JP DLCOMMON
;*
;* 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 HL,(FCOUNT) ; CHECK COUNT
LD A,H ; NO ENTRIES?
OR L
JP Z,NODUP ; NO DUPLICATE ENTRY RETURN
LD B,H ; BC=NUMBER OF ENTRIES
LD C,L
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 COMP
POP DE ; RESTORE PTRS
POP HL
JP 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 TARGET
LD A,(DE) ; GET EXTENT FIELD FROM DIRECTORY ENTRY
CP (HL) ; COMPARE WITH THAT IN TARGET
POP DE ; GET PTRS
POP HL
JP NC,DUPSMALL
; NEW TARGET IS LARGER THAN STORED ENTRY
LD A,(DFLAG) ; CHECK FLAG FOR LARGE OR SMALL EX
OR A ; 0=SELECT LARGER
JP NZ,DUPFND
DUPSEL:
EX DE,HL ; MAKE HL PT TO NEW TARGET, DE PT TO DEST
LD B,ESIZE ; NUMBER OF BYTES TO MOVE
CALL SDMOVE ; MOVE IT
JP DUPFND
; NEW TARGET IS SMALLER THAN STORED ENTRY
DUPSMALL:
LD A,(DFLAG) ; CHECK FLAG FOR LARGE OR SMALL EX
OR A ; 0FFH=SELECT SMALLER
JP 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, SO ADD ESIZE TO IT
ADD HL,BC
POP BC ; GET COUNT
DEC BC ; COUNT DOWN
LD A,B ; CHECK FOR DONE
OR C
JP NZ,DUPELOOP
; NO DUPLICATE FOUND, PERIOD
NODUP:
XOR A ; INDICATE DUP NOT FOUND
DEC A ; SET FLAGS (NZ)
POP HL ; RESTORE PTR TO ENTRY TO SCAN FOR
RET
;*
;* COMP COMPARES DE W/HL FOR B BYTES; RET W/CARRY IF DE<HL
;* MSB IS DISREGARDED
;*
COMP:
LD A,(HL) ; GET (HL)
AND 7FH ; MASK MSB
LD C,A ; ... IN C
LD A,(DE) ; COMPARE
AND 7FH ; MASK MSB
CP C
RET NZ
INC HL ; PT TO NEXT
INC DE
DEC B ; COUNT DOWN
JP NZ,COMP
RET
;*
;* BUFFERS
;*
TFCB:
DB 0,'???????????',0,0,0,0 ; TEMPORARY FCB (FN,FT WILD)
DB 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
DB 0,0,0
DFLAG: ; 0=SELECT FILES OF LARGER EX, ELSE OF SMALLER EX
DS 1
DSTART:
DS 2 ; POINTER TO FIRST DIRECTORY ENTRY
FCOUNT:
DS 2 ; TOTAL NUMBER OF FILES/NUMBER OF SELECTED FILES
END