home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
simtel
/
sigm
/
vols000
/
vol041
/
cdossap.z80
< prev
next >
Wrap
Text File
|
1984-04-29
|
9KB
|
394 lines
; SAP - SORT AND PACK DISK DIRECTORY
;
; Originally coded for CP/M by L.E. Hughes 8080SDC
; Modified 5/30/78 BY B.R. Ratoff
; 1) PICK UP VECTORS FOR ANY SIZE SYSTEM
; 2) HANDLE NULL EXTENTS OF NON-NULL FILES
; PROPERLY
;
; Modified by Trevor MARSHALL 18/10/79
; add SAP B:,etc AND ATTRIBUTE HIDE
;
;
; Rewritten by Trevor MARSHALL, 13 Apr 80
; Elec Eng Dept
; Uni W.A.
; to be compatible with all disks supported by CDOS 2.17
; by including the 'READ SYSTEM DIRECTORY' feature
; of the CDOS
;
; Modified 31 Oct '80 to handle the large files of
; CDOS 2.36 by adding double precision pointer bumping
;
;********** WARNING ********* Do not use with hard disks
; (not tested other than with floppies)
;
BDOS: EQU 5
FCB: EQU 5CH
;
ORG 100H
;
SAP: LD SP,STACK+64
LD C,19H ;WHAT DSK IS CURRENT?
CALL BDOS
LD (DSKSAV),A
LD A,(FCB) ;DSK REQUEST PRESENT?
LD (SYSDIR),A ;Set up 'SYS DIR' FCB
LD (DSK),A ;Save it for write
; Now check CDOS ver 1 or higher is in use
LD C,8DH
CALL BDOS
LD A,B
CP 1
JR GE,NEXT21
LD DE,CDOSERR ;Must be incompatible sys
LD C,9 ;Write error msg and exit
CALL BDOS
JP 0
NEXT21: LD C,0FH ;Open SYS DIR
LD DE,SYSDIR
CALL BDOS
CP A,0FFH ;Error?
JR NZ,NEXT
LD DE,OPENERROR ;Yes
LD C,9 ;Print the message
CALL BDOS
JP 0
NEXT: LD DE,MSG1 ;.....reading
LD C,9
CALL BDOS
;
LD A,0 ;Initialize
LD (SECTORCOUNT),A ;the sector count
LD DE,BUF-80H ;prepare for DMA increment
LP1: LD HL,SECTORCOUNT
INC (HL) ;Incr the sectorcount
LD HL,80H ;Need to increment bffr pointer
ADD HL,DE
EX DE,HL
LD C,1AH ;Set DMA address to buffer
PUSH DE ;Save it
CALL BDOS
LD C,14H ;Read next record
LD DE,SYSDIR ;Point at 'FCB'
CALL BDOS
POP DE ;Fetch buffer DMA addr
CP A,0 ;Any errors?
JR Z,LP1 ;No, get more sectors
CP 1
JR Z,NEXT1 ;End of file OK
LD DE,READERROR ;All else are errors
LD C,9
CALL BDOS
JP 0
NEXT1: LD HL,SECTORCOUNT
DEC (HL) ;As we musn't pass the EOF
; We have now read in the directory. The number of
; records read is in sectorcount.
; Now calculate the directory memory image length.
LD A,(HL)
LD L,A
LD H,0
; How long are the sectors?
; We may have to use a system call to find out
LD DE,80H ;Presently 80H
LD C,89H ;Multiply DE = DE * HL
CALL BDOS
;
LD HL,BUF ;Add the buffer base addr
ADD HL,DE
LD (BUFEND),HL ;Save end addr in BUFEND
;
CALL CLEAN ;CLEAN THE DIRECTORY
;
LD DE,MSG2 ;.....Sorting
LD C,9
CALL BDOS
;
CALL SORT ;SORT THE DIRECTORY
; I have deleted PACK as it is assumed that single disk systems
; will not be used under CDOS. User may modify as required
; CALL PACK ;PACK THE DIRECTORY
;
; Now we must write the directory to the disk
WRITE: LD DE,MSG3 ;.....Writing
LD C,9
CALL BDOS
;
LD A,(DSK)
LD (SYSDIR),A ;Poke byte 1 of FCB
LD C,0FH ;Open SYS DIR
LD DE,SYSDIR
CALL BDOS
CP A,0FFH ;Error?
JR NZ,NEXT2
LD DE,WRITEERROR ;Yes
LD C,9 ;Print the message
CALL BDOS
JP 0
NEXT2: LD A,1 ;Initialize
LD (SECTORSWRITTEN),A
LD HL,SYSDIR
RES 7,(HL) ;Reset the 'read only' atribute
LD DE,BUF-80H ;prepare for DMA increment
LP11: LD HL,SECTORSWRITTEN
INC (HL) ;increment the count of sectors
LD HL,80H ;Need to increment bffr pointer
ADD HL,DE
EX DE,HL
LD C,1AH ;Set DMA address to buffer
PUSH DE ;Save it
CALL BDOS
LD C,15H ;Write next record
LD DE,SYSDIR ;Point at 'FCB'
CALL BDOS
POP DE ;Fetch buffer DMA addr
CP A,0 ;Any errors?
JR NZ,WERR ;Yes
; Now see if we have finished write
LD A,(SECTORCOUNT)
LD HL,SECTORSWRITTEN
CP (HL) ;Have we written enough?
JR NC,LP11 ;No, get more sectors
JR NEXT12
WERR: LD DE,WRITEERROR ;All else are errors
LD C,9
CALL BDOS
JP 0
NEXT12:
; We have now written the directory.
LD A,(DSKSAV) ;Restore logged disk
LD E,A
LD C,0EH
CALL BDOS
JP 0 ;And exit to CDOS
;
;
CLEAN: LD BC,0 ;III = 0
CLEAN1: LD (III),BC
CALL INDEX2 ;HL = BUF + 16 * III
PUSH HL
; HL now contains the addr of the buffer entry
; we want to return if it is beyond BUFEND
XOR A ;Clear carry
LD DE,(BUFEND)
SBC HL,DE ;HL = HL - DE - CY
; DE should be > HL, if not, return
POP HL
RET NC
;
; Continue
LD A,(HL) ;JUMP IF THIS IS A DELETED FILE
CP 0E5H
JP Z,CLEAN2
LD A,L ;HL = HL + 12
ADD 12
LD L,A
JP NC,$+4
INC H
LD A,(HL) ;CHECK EXTENT FIELD
OR A
JP NZ,CLEAN4 ;SKIP IF NOT EXTENT ZERO
EXTENT0: INC HL ;POINT TO RECORD COUNT FIELD
INC HL
INC HL
LD A,(HL) ;CHECK RECORD COUNT FIELD
OR A
JP NZ,CLEAN4 ;JUMP IF NON-ZERO
LD BC,(III) ;Clear all 32 bytes
CALL INDEX2
CLEAN2: LD C,32
CLEAN3: LD (HL),0E5H
INC HL
DEC C
JP NZ,CLEAN3
CLEAN4: LD BC,(III) ; III = III + 1
INC BC
JP CLEAN1
RET
;
COMP: LD BC,(III) ;;HL = BUF + 16 * III
CALL INDEX2
PUSH HL
LD BC,(J) ;HL = BUF + 16 * J
CALL INDEX2
EX DE,HL
POP HL
; Need to allocate highest priority to disk label
LD A,(DE) ;Is 2nd entry a label?
CP 81H ;The label's attribute
JR NZ,NEXT56 ;NZ=> not a label
SCF ;Must be a disk label
RET ;Swap them
NEXT56: LD A,(HL) ;Is 1st entry a label?
CP 81H
JR NZ,NEXT57
SCF
CCF ;Dont swap
RET
NEXT57: INC HL
INC DE ;POINT PAST ATRIBUTES
LD C,12 ;NUMBER OF BYTES TO COMPARE
COMP1: LD A,(DE) ;COMPARE NEXT BYTE
CP (HL)
RET NZ ;RETURN IF NOT EQUAL
INC DE
INC HL
DEC C ;LOOP THRU FIRST 13 BYTES
JP NZ,COMP1
XOR A ;CLEAR FLAGS AND EXIT
RET
SORT: LD BC,0 ;III = 0
LD (III),BC
SORT1: LD BC,(III) ;J = III + 1
INC BC
LD (J),BC
SORT2: CALL COMP ;IF NAME(J)<NAME(III), SWAP
CALL C,SWAP
LD BC,(J) ;J = J + 1
INC BC
LD (J),BC
;
; See if J beyond BUFEND
CALL INDEX2
; HL now contains the addr of the buffer entry
; we want to jump if it is not beyond BUFEND
XOR A ;Clear carry
LD DE,(BUFEND)
DEC DE ;Make end addr not inclusive
SBC HL,DE ;HL = HL - DE - CY
; DE should be > HL
JR C,SORT2
;
LD BC,(III) ;III = III + 1
INC BC
LD (III),BC
;
; See if I beyond BUFEND - 10H
CALL INDEX2
PUSH HL
; HL now contains the addr of the buffer entry
; we want to jump if it is not beyond BUFEND-20H
LD DE,(BUFEND)
DEC DE ;Make end addr not inclusive
LD HL,-20H
ADD HL,DE
EX DE,HL ;Now have end addr - 10H
XOR A ;Clear carry
POP HL
SBC HL,DE ;HL = HL - DE - CY
; DE should be > HL
JR C,SORT1
;
RET
;
;
SWAP: LD BC,(III)
CALL INDEX2
PUSH HL
LD BC,(J)
CALL INDEX2
EX DE,HL
POP HL
LD C,32
SWAP1: LD A,(DE)
LD B,A
LD A,(HL)
LD (DE),A
LD (HL),B
INC DE
INC HL
DEC C
JP NZ,SWAP1
RET
; Bump index in double precision
INDEX2: PUSH BC ;Get BC
POP HL ;into HL
ADD HL,HL ; X 2
ADD HL,HL ; X 4
ADD HL,HL
ADD HL,HL
ADD HL,HL ; X 32
LD DE,BUF
ADD HL,DE
RET
;PACK: LD BC,0 ;III = 0
; LD (III),BC
;PACK1: LD BC,(III)
; CALL INDEX2 ;HL = BUF + 16 * I
; LD A,L ;HL = HL + 9
; ADD 9
; LD L,A
; JP NC,$+4
; INC H
; LD A,(HL) ;JUMP IF FILETYPE NOT 'X$$'
; SUB '0' ; WHERE 0.LE.X.LE.9
; JP C,PACK2
; CP 10
; JP NC,PACK2
; LD (J),A ; ?????
; INC HL
; LD A,(HL)
; CP '$'
; JP NZ,PACK2
; INC HL
; LD A,(HL)
; CP '$'
; JP NZ,PACK2
; INC HL ;SET EXTENT NUMBER TO X
; LD A,(J) ; ????
; LD (HL),A
; DEC HL ;SET FILETYPE TO '$$$'
; LD (HL),'$'
; DEC HL
; LD (HL),'$'
; DEC HL
; LD (HL),'$'
;PACK2: LD BC,(III) ;I = I + 1
; INC BC
; LD (III),BC
;
; See if I beyond BUFEND
; CALL INDEX2
; HL now contains the addr of the buffer entry
; we want to jump if it is not beyond BUFEND
; XOR A ;Clear carry
; LD DE,(BUFEND)
; SBC HL,DE ;HL = HL - DE - CY
; DE should be < HL
; JR C,PACK1
; RET
;
; ERROR MESSAGES
;
CDOSERR: DB 0AH,0DH,'Incompatible with this version of CDOS.$'
OPENERROR: DB 0AH,0DH,'Error in opening directory file.$'
READERROR: DB 0AH,0DH,'Error whilst reading directory.$'
WRITEERROR: DB 0AH,0DH,'Error whilst writing directory.'
DB 0AH,0DH,'The image starts in memory at 500 H'
DB 0AH,0DH,'Save it on a BLANK disk (allow 40 Blocks).$'
MSG1: DB 0AH,0DH,'......Reading$'
MSG2: DB 0AH,0DH,'......Sorting$'
MSG3: DB 0AH,0DH,'......Writing$'
;
; DATA AREA
;
SYSDIR: DB 0,'SYS DIR',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
;
STACK: DEFS 64
SECNO: DEFS 1
SECTORSWRITTEN: DS 1
SECTORCOUNT: DS 1
III: DEFS 2
J: DEFS 2
DSKSAV: DS 1
DSK: DS 1
BUFEND: DS 2
ORG 500H
BUF: DEFS 8192
;
END 100H