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
/
SIMTEL
/
CPMUG
/
CPMUG029.ARK
/
SAP.ASM
< prev
next >
Wrap
Assembly Source File
|
1984-04-29
|
4KB
|
264 lines
; SAP - SORT AND PACK CP/M DISK DIRECTORY
;
; 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
;
ORG 100H
;*****
; OBTAIN BIOS VECTORS
;*****
VECTRS: JMP GETVEC
DS 42
WBOOTE EQU VECTRS+3
CSTS EQU VECTRS+6
CI EQU VECTRS+9
CO EQU VECTRS+12
LO EQU VECTRS+15
PO EQU VECTRS+18
RI EQU VECTRS+21
HOME EQU VECTRS+24
SELDSK EQU VECTRS+27
SETTRK EQU VECTRS+30
SETSEC EQU VECTRS+33
SETDMA EQU VECTRS+36
READ EQU VECTRS+39
WRITE EQU VECTRS+42
GETVEC: LXI D,WBOOTE
LHLD 1
MVI B,42
GETVE1: MOV A,M
STAX D
INX H
INX D
DCR B
JNZ GETVE1
;
SAP: LXI H,0
DAD SP
SHLD OLDSP
LXI SP,STACK+64
MVI C,0 ;SELECT DISK A
CALL SELDSK
MVI C,2 ;SET TO TRACK 2
CALL SETTRK
MVI A,1 ;SECNO=1
STA SECNO
LXI H,BUF ;ADDR = FWA OF BUFFER
SHLD ADDR
SAP1: LDA SECNO ;SET TO SECTOR "SECNO"
LXI H,LPMAP-1
ADD L
MOV L,A
JNC $+4
INR H
MOV C,M
CALL SETSEC
LHLD ADDR ;SET DMA ADDRESS TO "ADDR"
MOV B,H
MOV C,L
CALL SETDMA
CALL READ ;READ SECTOR INTO MEMORY
LHLD ADDR ;ADDR = ADDR + 80H
MOV A,L
ADI 80H
MOV L,A
JNC $+4
INR H
SHLD ADDR
LDA SECNO ;SECNO = SECNO + 1
INR A
STA SECNO
CPI 17 ;LOOP UNTIL SECNO>16
JC SAP1
CALL CLEAN ;CLEAN THE DIRECTORY
CALL SORT ;SORT THE DIRECTORY
CALL PACK ;PACK THE DIRECTORY
MVI A,1 ;SECNO = 1
STA SECNO
LXI H,BUF ;ADDR = FWA OF BUFFER
SHLD ADDR
SAP2: LDA SECNO ;SET TO SECTOR "SECNO"
LXI H,LPMAP-1
ADD L
MOV L,A
JNC $+4
INR H
MOV C,M
CALL SETSEC
LHLD ADDR ;SET DMA ADDRESS TO "ADDR"
MOV B,H
MOV C,L
CALL SETDMA
CALL WRITE ;WRITE SECTOR TO DISK
LHLD ADDR ;ADDR = ADDR + 80H
MOV A,L
ADI 80H
MOV L,A
JNC $+4
INR H
SHLD ADDR
LDA SECNO ;SECNO = SECNO + 1
INR A
STA SECNO
CPI 17 ;LOOP UNTIL SECNO > 16
JC SAP2
LHLD OLDSP ;EXIT TO CP/M
SPHL
RET
CLEAN: MVI A,0 ;I = 0
CLEAN1: STA I
CALL INDEX ;HL = BUF + 16 * I
MOV A,M ;JUMP IF THIS IS A DELETED FILE
CPI 0E5H
JZ CLEAN2
MOV A,L ;HL = HL + 12
ADI 12
MOV L,A
JNC $+4
INR H
MOV A,M ;CHECK EXTENT FIELD
ORA A
JNZ CLEAN4 ;SKIP IF NOT EXTENT ZERO
INX H ;POINT TO RECORD COUNT FIELD
INX H
INX H
MOV A,M ;CHECK RECORD COUNT FIELD
ORA A
JNZ CLEAN4 ;JUMP IF NON-ZERO
LDA I ;CLEAR ALL 32 BYTES OF
CALL INDEX ; DIRECTORY ENTRY TO E5
CLEAN2: MVI C,32
CLEAN3: MVI M,0E5H
INX H
DCR C
JNZ CLEAN3
CLEAN4: LDA I ;I = I + 1
INR A
CPI 64 ;LOOP UNTIL I > 63
JC CLEAN1
RET
LPMAP: DB 01,07,13,19,25,05,11,17,23,03,09,15,21
DB 02,08,14,20,26,06,12,18,24,04,10,16,22
COMP: LDA I ;HL = BUF + 16 * I
CALL INDEX
PUSH H
LDA J ;HL = BUF + 16 * J
CALL INDEX
XCHG
POP H
MVI C,13 ;NUMBER OF BYTES TO COMPARE
COMP1: LDAX D ;COMPARE NEXT BYTE
CMP M
RNZ ;RETURN IF NOT EQUAL
INX D
INX H
DCR C ;LOOP THRU FIRST 13 BYTES
JNZ COMP1
XRA A ;CLEAR FLAGS AND EXIT
RET
SORT: MVI A,0 ;I = 0
STA I
SORT1: LDA I ;J = I + 1
INR A
STA J
SORT2: CALL COMP ;IF NAME(J)<NAME(I), SWAP
CC SWAP
LDA J ;J = J + 1
INR A
STA J
CPI 64 ;IF J < 64 GOTO SORT2
JC SORT2
LDA I ;I = I + 1
INR A
STA I
CPI 63 ;IF I < 63 GOTO SORT1
JC SORT1
RET
SWAP: LDA I
CALL INDEX
PUSH H
LDA J
CALL INDEX
XCHG
POP H
MVI C,32
SWAP1: LDAX D
MOV B,A
MOV A,M
STAX D
MOV M,B
INX D
INX H
DCR C
JNZ SWAP1
RET
INDEX: MOV L,A
MVI H,0
DAD H
DAD H
DAD H
DAD H
DAD H
LXI D,BUF
DAD D
RET
PACK: MVI A,0 ;I = 0
PACK1: STA I
CALL INDEX ;HL = BUF + 16 * I
MOV A,L ;HL = HL + 9
ADI 9
MOV L,A
JNC $+4
INR H
MOV A,M ;JUMP IF FILETYPE NOT 'X$$'
SUI '0' ; WHERE 0.LE.X.LE.9
JC PACK2
CPI 10
JNC PACK2
STA J
INX H
MOV A,M
CPI '$'
JNZ PACK2
INX H
MOV A,M
CPI '$'
JNZ PACK2
INX H ;SET EXTENT NUMBER TO X
LDA J
MOV M,A
DCX H ;SET FILETYPE TO '$$$'
MVI M,'$'
DCX H
MVI M,'$'
DCX H
MVI M,'$'
PACK2: LDA I ;I = I + 1
INR A
CPI 64 ;LOOP UNTIL I > 63
JC PACK1
RET
; DATA AREA
OLDSP: DS 2
STACK: DS 64
SECNO: DS 1
ADDR: DS 2
BUF: DS 64*32
I: DS 1
J: DS 1
END