; TITLE TIDY - Alphabetizes diskette directory ; ; Tidy assumes C: and D: are DSDD 8" disks. Dangerous to SSSD ; Edit ATEDIRS ATELEN and ATEST below to change this. ; ; Call Walter Burt, 109 N. Few, Madison WI 53703, 257-0373 with gripes ; PROGSEG SEGMENT ASSUME CS:PROGSEG, SS:PROGSEG, DS:PROGSEG, ES:PROGSEG .XCREF .XLIST INCLUDE DEFMS.ASM .CREF .LIST ORG 100H ; ; Note; labels of variables are at the end. ; TIDY: EVAL: XOR DX,DX MOV SI, PHD_DIOA MOV DL,[SI] MOV SI,0081H FIND: CMP DX,0 ; See if there is any parameter JE DEFAULT ; Otherwise, go get default drive MOV AL,[SI] CMP AL,SPACE ; If it's a space JE SKIPR CMP AL,COMMA ; or a comma, JNE LOOK SKIPR: DEC DX ; then look at the next character INC SI JMP SHORT FIND LOOK: CMP DX,2 JB DRIVE ; If more than one char. MOV BL,[SI+1] ; then CMP BL,COLON ; it must be a colon JE DRIVE ; to reference a drive. CMP BL,SPACE ; or a space JE DRIVE CMP BL,COMMA ; or a comma JE DRIVE ERROR: MOV DX, OFFSET ERRMSG ; otherwise signal an error MOV AH, DOSF_OUTSTR INT DOSI_FUNC INT DOSI_TERM ; and quit. DRIVE: CMP AL,61H ; Test for lower case JL DJST ; SUB AL,20H ; If so, fix it. DJST: SUB AL,41H ; Turn ASCII to drive # JL ERROR ; Filter non drives out JMP SHORT KIND DEFAULT: ; Read default disk MOV AH,DOSF_GETDISK INT DOSI_FUNC KIND: ; See what kind of disk it is CMP AL,3 ; If > D: then it's not supported JA ERROR MOV DRVN,AL ;Save drive number CMP AL,1 ; If > B: then its 8" JA ATE MOV DX,1 ; Parameters for start of FAT MOV BX,DIR MOV CX,1 INT DOSI_ADREAD ; Get start of FAT JC DISKER POP BX ; Dummy POP MOV SI,DIR ; Get first byte (DISK ID) MOV AL,[SI] ; CMP AL,0FEH ; If DSDD JA READIN ; it's OK JB TTPI ; If single-sided MOV BX,SDIRS ; Fix disk params MOV DIRSECS,BX JMP SHORT READIN TTPI: CMP AL,0FDH JB DISKER ; If 96 TPI MOV BX,DTPI MOV DIRSECS,BX JMP SHORT READIN ATE: ; Fix for 8" drive MOV BX,ATEDIRS MOV DIRSECS,BX MOV BX,ATELEN MOV SECLEN,BX MOV BX,ATEST MOV STARTSEC,BX READIN: MOV BX,DIR ; Parameters to read disk directory MOV CX,DIRSECS ; See ZDOS vol II: H.1 and I.4 MOV DX,STARTSEC ; and LABEL definitions below. MOV AL,DRVN INT DOSI_ADREAD POP AX ; Dummy POP since INT 25 PUSHed the flags JNC SCAN ; Check for disk errors DISKER: MOV DX,OFFSET DSKERM ; A disk error was detected. MOV AH,DOSF_OUTSTR ; so report it, INT DOSI_FUNC INT DOSI_TERM ; and quit SCAN: MOV BX, DIRSECS ;Calculate the top of DIR MOV AX,SECLEN ; This will allow other disk formats. MUL BX ; by changing these parameters. MOV BX,DIR ADD AX,BX MOV TOP,AX ADD BX,64 ; skip over system files MOV DI,BX LEA SI,COMMAND ; see if COMMAND.COM is there MOV CX,11 CLD REPE CMPSB JNE DEFBOT ; and if it is then ADD BX,32 ; skip over it, too. DEFBOT: MOV BOT,BX ; This is the bottom of the files to sort. CALL DEPRESS ; Find the highest active file, make it TOP. UP1: CMP BX,TOP ; Step up from BOT file to TOP file JNB SORT ; and then go on to sort them. MOV AL,[BX] ; If the current files isn't marked as CMP AL,0E5H ; deleted then, step on to the JNE NEXT1 ; next file up, otherwise MOV DI,TOP ; put it at the top of the sorting area MOV SI,BX CALL SWAP ; by exchanging with TOP and CALL DEPRESS ; move TOP down to the next highest active file. NEXT1: ADD BX,32 ; Then move up to the next file JMP SHORT UP1 SORT: MOV BX,TOP SUB BX,BOT SHR BX,1 AND BX,0FFE0H OUTLP: MOV DX,BOT ; Begin outer loop MDLP: MOV SI,DX ; Middle loop INRLP: MOV AX,SI LEA DI, [BX][SI] ;compare filenames MOV CX,11 REPE CMPSB MOV SI,AX JB NXTMDLP ; If in wrong order LEA DI,[BX][SI] CALL SWAP ; Exchange them. SUB SI,BX CMP SI,BOT JA INRLP ; Next Inrlp NXTMDLP: ADD DX,32 MOV AX,TOP SUB AX,BX CMP DX,AX JBE MDLP ;Next Mdlp SHR BX,1 AND BX,0FFE0H JNZ OUTLP ; Next Outlp WRTOUT: MOV AL,DRVN ; Retrieve disk parameters MOV BX,DIR MOV CX,DIRSECS MOV DX,STARTSEC INT DOSI_ADWRITE ; Write new directory to disk. POP AX ; Dummy POP JNC QUIT JMP DISKER QUIT: MOV BX,DIR2 ; Read directory back in MOV AL,DRVN MOV CX,DIRSECS MOV DX,STARTSEC INT DOSI_ADREAD POP AX ; Another dummy POP JE CHECK JMP DISKER CHECK: MOV SI,DIR MOV DI,DIR2 MOV CX,DRSIZ CLD REPE CMPSB ; See if DIR was written correctly JE OK INC OOPS ; If not, try again MOV DX, OFFSET BAD MOV AH, DOSF_OUTSTR ; and report failure INT DOSI_FUNC MOV CL,OOPS CMP CL,2 JB WRTOUT INT DOSI_TERM OK: MOV DX, OFFSET GOOD ; If directory OK MOV AH, DOSF_OUTSTR ; Report success INT DOSI_FUNC INT DOSI_TERM ; and return to ZDOS ; ; ; ; SUBROUTINES: ; ; SWAP PROC NEAR ; ; SWAP exchanges the files pointed to by SI and DI ; no registers are thereby wiped ; PUSH BX PUSH AX MOV AX,DI MOV BX,SI LEA DI,BUF ; Move SI string into buffer MOV CX,32 REP MOVSB MOV SI,AX ; Move DI string to SI MOV DI,BX MOV CX,32 REP MOVSB MOV DI,AX ;Move Buffer to DI LEA SI,BUF MOV CX,32 REP MOVSB MOV SI,BX ; Retrieve values MOV DI,AX POP AX POP BX RET SWAP ENDP ; ; DEPRESS PROC NEAR ; ; DEPRESS MOVES DOWN TO THE HIGHEST ACTIVE FILE, SETS TOP AND ; SI TO THAT. DESTROYS PREVIOUS SI AND AL ; MOV SI,TOP ; Get the old highest active file DOWN1: SUB SI,32 MOV AL,[SI] ; And if that file was either CMP AL,0 ; never written to JE DOWN1 CMP AL,0E5H ; Or previously deleted then JE DOWN1 ; Go down another file. MOV TOP,SI CMP SI,BOT ; If its also the lowest then JA BACK ; There's no need to sort anything. INT DOSI_TERM ; So quit. BACK: RET ; Else return to TIDY DEPRESS ENDP ; ; ; DEFINE LABELS: ; ERRMSG DB ' Unknown parameter$' DSKERM DB ' Disk error!$' GOOD DB ' Tidy verified$' BAD DB 7,' Tidy NOT verified$' SPACE DB ' ' COMMA DB ',' COLON DB ':' COMMAND DB 'COMMAND COM' OOPS DB 0 ; Times Tidy wasn't verified DRVN DB ? ; Number of disk drive DIRSECS DW 7 ; Sectors of disk reserved for directory by ZDOS STARTSEC DW 3 ; First sector of the directory SECLEN DW 512 ; Number of bytes in one sector. DRSIZ DW ? ; Size of directory read DIR DW 03000H ; space to fill with directory ; (Will accommodate up to DSDD 8" floppies) SDIRS DW 4 ; DIRSECS for single sided DTPI DW 9 ; for 96 TPI ATEDIRS DW 6 ; for 8" DSDD -> 26 for SSSD ATELEN DW 1024 ; SECLEN for 8" DSDD -> 80 for SSSD ATEST DW 5 ; STARTSEC " 10 for SSSD TOP DW ? ; Pointer to top of area to be sorted BOT DW ? ; bottom of same area. BUF DB 32 DUP (?) ; transfer area for switching files. DIR2 DW 06000H ; Space for verified copy of DIR ; PROGSEG ENDS END TIDY