TITLE 'SAP - SORT AND PACK DIRECTORY' ; ; L.E. HUGHES 8080SDC ; ; FIX 1/23/81 W. EARNEST FOR CP/M 2.2 & 1.4 ; FIX FOR ANY SIZE SYSTEM TO 256 DIRECT ENTRIES ; FIX FOR ANY DRIVE UP TO 4 ; ; OFFSET FROM WARM BOOT VECTOR ; SELDSK EQU 24 SETTRK EQU 27 SETSEC EQU 30 SETDMA EQU 33 READ EQU 36 WRITE EQU 39 XLT EQU 45 BDOS EQU 5 ORG 100H SAP: LXI SP,STACK+32 MVI C,12 ;CHECK VERSION CALL BDOS MOV A,H ORA L STA VERFLG MVI C,25 ;GET CURR DSK CALL BDOS MOV C,A ;SELECT IT ASSUMED LDA 5CH ;FCB ORA A ;TEST IF DEFINED JZ SEDRV ;NO, USE DEFAULT DCR A ;ADJUST FOR BIOS MOV C,A SEDRV: MVI E,SELDSK CALL XCPM LDA VERFLG ORA A JZ SELSKP ;NOT 2.X MOV A,H ORA L JZ 0 ;ABORT IF ILLEGAL MOV E,M INX H MOV D,M ;XLATE MAP ADDRESS XCHG SHLD ADMAP LXI H,9 ;DPB OFFSET DAD D MOV A,M INX H MOV H,M ;DPB ADDR MOV L,A MOV E,M INX H MOV D,M ;SECTORS PER TRK XCHG SHLD SPERT LXI H,6 DAD D MOV E,M INX H MOV D,M ;DIRECT ENTRIES XCHG SHLD DIRENT LXI H,5 DAD D MOV E,M INX H MOV D,M XCHG SHLD TKOFFS ;OFFSET TO FIRST DIR TRK ; SELSKP: LHLD TKOFFS SHLD CURTRK CALL DOTRK XRA A ;SECNO=0 LOGICAL STA SECNO STA LSEC LXI H,BUF ;ADDR = FWA OF BUFFER SHLD ADDR ; SAP1: CALL XLATS ;SET TO SECTOR "SECNO" LHLD ADDR ;SET DMA ADDRESS TO "ADDR" MOV B,H MOV C,L MVI E,SETDMA CALL XCPM MVI E,READ CALL XCPM ;READ SECTOR INTO MEMORY LHLD ADDR ;ADDR = ADDR + 80H LXI D,128 DAD D SHLD ADDR LDA SECNO ;SECNO = SECNO + 1 INR A STA SECNO LXI H,SPERT CMP M JC SAMTK1 LHLD CURTRK INX H SHLD CURTRK XRA A STA SECNO CALL DOTRK SAMTK1: LXI H,LSEC INR M MOV A,M ADD A ADD A ;TIMES 4ENT/TRK DCR A LXI H,DIRENT CMP M JNZ SAP1 ; CALL CLEAN ;CLEAN THE DIRECTORY CALL SORT ;SORT THE DIRECTORY CALL PACK ;PACK THE DIRECTORY XRA A ;SECNO = 0 LOGICAL STA SECNO STA LSEC LHLD TKOFFS SHLD CURTRK CALL DOTRK LXI H,BUF ;ADDR = FWA OF BUFFER SHLD ADDR ; SAP2: CALL XLATS LHLD ADDR ;SET DMA ADDRESS TO "ADDR" MOV B,H MOV C,L MVI E,SETDMA CALL XCPM MVI E,WRITE CALL XCPM ;WRITE SECTOR TO DISK LHLD ADDR ;ADDR = ADDR + 80H LXI D,128 DAD D SHLD ADDR LDA SECNO ;SECNO = SECNO + 1 INR A STA SECNO LXI H,SPERT CMP M JC SAMTK2 LHLD CURTRK INX H SHLD CURTRK XRA A STA SECNO CALL DOTRK SAMTK2: LXI H,LSEC INR M MOV A,M ADD A ADD A DCR A LXI H,DIRENT CMP M JNZ SAP2 JMP 0 ;EXIT TO CP/M WARM BOOT ; DOTRK: MOV B,H MOV C,L MVI E,SETTRK JMP XCPM ; CLEAN: MVI A,0 ;I = 0 CLEAN1: STA I CALL INDEX ;HL = BUF + 32 * I MOV A,M ;JUMP IF THIS IS A DELETED FILE CPI 0E5H JZ CLEAN2 LXI D,9 ;OFFSET TO R/O FLG DAD D MOV A,M ANI 80H JNZ CLEAN4 LXI D,6 ;HL = HL + 6 DAD D MOV A,M ;CHECK RECORD COUNT FIELD ORA A JNZ CLEAN4 ;JUMP IF NON-ZERO CLEAN2: LDA I ;CLEAR ALL 32 BYTES OF CALL INDEX ; DIRECTORY ENTRY TO E5 MVI C,32 CLEAN3: MVI M,0E5H INX H DCR C JNZ CLEAN3 CLEAN4: LDA I ;I = I + 1 LXI H,DIRENT CMP M RZ INR A JMP CLEAN1 ; XLATS: LDA VERFLG ORA A LDA SECNO JNZ XLT2 LXI H,LPMAP ADD L MOV L,A JNC NOCRY INR H NOCRY: MOV C,M XLT3: MVI E,SETSEC JMP XCPM ; XLT2: MOV C,A MVI B,0 LHLD 1 LXI D,XLT DAD D LXI D,XRSLT PUSH D ;FAKE CALL XCHG LHLD ADMAP XCHG PCHL ; XRSLT: MOV C,L JMP XLT3 ; ADMAP: DW LPMAP ; 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 + 32 * I CALL INDEX PUSH H LDA J ;HL = BUF + 32 * J CALL INDEX XCHG POP H MVI C,13 ;NUMBER OF BYTES TO COMPARE COMP1: MOV A,M ;GET NEXT BYTE ANI 7FH ;REMOVE ATTRIBUTE MOV B,A LDAX D ;COMPARE NEXT BYTE ANI 7FH ;REMOVE ATTRIBUTES CMP B 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)