From f69f5aec921fb6855b3f76c67419fb34fdde6fcc Mon Sep 17 00:00:00 2001 From: Krister Nordvall Date: Tue, 16 Feb 2021 23:25:17 +0100 Subject: [PATCH] Optimizations to FREESPT.ASM. UNTESTED --- FREESPT.ASM | 719 ++++++++++++++++++++++++---------------------------- 1 file changed, 330 insertions(+), 389 deletions(-) diff --git a/FREESPT.ASM b/FREESPT.ASM index be227cd..0957a48 100644 --- a/FREESPT.ASM +++ b/FREESPT.ASM @@ -20,13 +20,16 @@ .code LOCALS @@ + CR EQU 13 + LF EQU 10 + ; We can overwrite the FCBs and parameters in the PSP, starting at 5Ch ; Giving us 164 bytes for this table. Or 18 entries/partitions at max ; If you've got 19 large FAT16 partitions in your XT, god help you. -numdrives EQU 5Ch ; BYTE - # of drives we're monitoring -drvtbl EQU 5Dh ; 9 BYTE per - information needed for each drive + numdrives EQU 5Ch ; BYTE - # of drives we're monitoring + drvtbl EQU 5Dh ; 9 BYTE per - information needed for each drive ; Runs till offset 100h -ENTSIZE EQU 9 + ENTSIZE EQU 9 ; Entry struct: ; BYTE - DRIVE # @@ -37,155 +40,138 @@ ENTSIZE EQU 9 ORG 100h start: - jmp init -myid: DB "FS" -oldint21h: DD 0 -callerax: DW 0 -callerss: DW 0 -callersp: DW 0 -usedclust: - DW 0 ; # of non-free clusters -absdisk: - DB 10 dup(?) ; AbsDiskIORec struct -bootseg: - DB 512 dup(?) -; Stack - DW 32 dup(?) + jmp init +myid: db "FS" +oldint21h: dd 0 +callerax: dw 0 +callerss: dw 0 +callersp: dw 0 +usedclust: dw 0 ; # of non-free clusters +absdisk: db 10 dup(?) ; AbsDiskIORec struct +bootsect: db 512 dup(?) + dw 32 dup(?) ; Stack stacktop: - +even ; Keep the interrupt handler WORD aligned inthandler: - pushf ; Preserve flags - cmp ah, 36h ; Calculate disk free space - je @@handle - cmp ah, 1Ch ; Get allocation data for specified drive - je @@handle - ; 1Bh requires us to get the 'current' drive, as do 36 and 1C w/DL=0 - cmp ah, 1Bh - je @@handle - + pushf ; Preserve flags + cmp ah, 36h ; Calculate disk free space + je @@handle + cmp ah, 1Ch ; Get allocation data for specified drive + je @@handle + cmp ah, 1Bh ; 1Bh requires us to get the 'current' drive, as do 36 and 1C w/DL=0 + je @@handle ; Some other int 21h function, we don't care popf - jmp DWORD PTR cs:[oldint21h] + jmp DWORD PTR cs:[oldint21h] @@handle: - mov WORD PTR cs:[callerax], ax - mov WORD PTR cs:[callersp], sp - mov ax, ss - mov WORD PTR cs:[callerss], ax - mov ax, cs - mov ss, ax - mov sp, OFFSET stacktop - push ds - mov ds, ax ; ds = ss = cs + mov cs:[callerax], ax + mov cs:[callersp], sp + mov cs:[callerss], ss + mov ax, cs + mov ss, ax + mov sp, OFFSET stacktop + push ds + mov ds, ax ; ds = ss = cs ; We now have a stack and ds setup - push dx ; Save dx first + push dx ; Save dx first - cmp BYTE PTR cs:[callerax+1], 1Bh - je @@getdefault - and dl, dl ; Check if drive # is default - jne @@scan + cmp BYTE PTR ds:[callerax+1], 1Bh + je @@getdefault + test dl, dl ; Check if drive # is default + jnz @@scan @@getdefault: - mov ah, 19h - int 21h ; 21h/19h = Get default disk drive - inc al - mov dl, al ; Move into dl to be consistent with others + mov ah, 19h + int 21h ; 21h/19h = Get default disk drive + inc ax + mov dl, al ; Move into dl to be consistent with others @@scan: ; Scan through our drive table to see if we care for this drive ; and if it's unknown - push si - push cx - xor ch, ch - mov cl, ds:[numdrives] - mov si, drvtbl + push si + push cx + xor ch, ch + mov cl, ds:[numdrives] + mov si, drvtbl @@scanloop: - mov al, ds:[si] - inc al - cmp al, dl ; Does the drive match this call? - je @@found - add si, 9 ; Next entry - loop @@scanloop + mov al, ds:[si] + inc ax + cmp al, dl ; Does the drive match this call? + je @@found + add si, 9 ; Next entry + loop @@scanloop ; Not a drive we care about - pop cx - pop si - jmp exit1 + pop cx + pop si + jmp SHORT exit1 @@found: ; The drive requested is one we're monitoring ; Check if free clusters == FFFFh - push ds - push bx + push ds + push bx ; Check if current value is unknown 0FFFFh - mov bx, WORD PTR cs:[si + 7] - mov ds, bx - mov bx, WORD PTR cs:[si + 5] - cmp WORD PTR [bx], 0FFFFh - je recalc ; If so then we need to recalculate + lds bx, ds:[si+5] + cmp WORD PTR [bx], 0FFFFh + pop bx + pop ds + je recalc ; If so then we need to recalculate ; Otherwise just pass through to the int 21h handler - pop bx - pop ds - pop cx - pop si - jmp exit1 + pop cx + pop si + jmp SHORT exit1 recalc: - pop bx - pop ds ; cx, si still on stack from scan loop - - push bx ; Preserve other registers - push di - push bp - push es + push bx ; Preserve other registers + push di + push bp + push es ; We can now run our recalc code ; We are the int 21h handler so don't run `int 21h` ; Instead do: `call doint21` if needed - call docalc + call docalc exit2: ; Return to caller's stack frame - pop es - pop bp - pop di - pop bx - pop cx - pop si + pop es + pop bp + pop di + pop bx + pop cx + pop si exit1: - pop dx - pop ds - mov ax, WORD PTR cs:[callerss] - mov ss, ax - mov sp, WORD PTR cs:[callersp] - mov ax, WORD PTR cs:[callerax] + pop dx + mov ax, ds:[callerax] + pop ds + mov ss, cs:[callerss] + mov sp, cs:[callersp] popf - jmp DWORD PTR cs:[oldint21h] + jmp DWORD PTR cs:[oldint21h] -doint21: - pushf - jmp DWORD PTR cs:[oldint21h] ; tail call +;doint21: +; pushf +; jmp DWORD PTR cs:[oldint21h] ; tail call ; Calculate free space docalc: ; DS:SI still points to entry in drvtbl - mov WORD PTR [usedclust], 0 - mov cx, WORD PTR [si + 1] ; sectperfat - mov bx, WORD PTR [si + 3] ; fatsector - push si ; Preserve entry + mov WORD PTR [usedclust], -2 ; First two entries are used to store the FAT signature + mov cx, [si+1] ; sectperfat + mov bx, [si+3] ; fatsector + push si ; Preserve entry @@fatloop: - push cx ; Preserve count - push bx ; Preserve start sector - mov al, BYTE PTR [si + 0] ; Drive # - push ax - mov ax, 1 ; # of sectors - push ax - push bx ; start sector - call getUsedClust - add sp, 6 - add WORD PTR [usedclust], ax ; # used so far - pop bx ; Restore start sector - add bx, 1 ; # of sectors handled so far - pop cx - loop @@fatloop - - sub WORD PTR [usedclust], 2 ; First two entries are used - ; to store the FAT signature - ; Don't count them. + push cx ; Preserve count + push bx ; Preserve start sector + mov al, [si] ; Drive # + push ax + mov ax, 1 ; # of sectors + push ax + push bx ; start sector + call getUsedClust + add sp, 6 + add [usedclust], ax ; # used so far + pop bx ; Restore start sector + inc bx ; # of sectors handled so far + pop cx + loop @@fatloop ; We've got the number of used clusters ; Get total clusters @@ -193,85 +179,68 @@ docalc: ; calculator for some reason ; Re-Read in boot sector for partition ; Setup abs disk struct - lea bx, absdisk - mov WORD PTR [bx+0], 0 ; Logical sector (low) - mov WORD PTR [bx+2], 0 ; Logical sector (high) - mov WORD PTR [bx+4], 1 ; # of sectors to read - mov WORD PTR [bx+6], OFFSET bootseg - mov ax, ds - mov WORD PTR [bx+8], ax ; Address (FAR) to read to - mov al, BYTE PTR [si+0] ; Drive # - mov cx, 0FFFFh ; Large disk, use AbsDiskIORec Struct - mov dx, 0 ; Beginning sector - int 25h ; Absolute disk read - pop dx ; Remove leftover word from stack from int25h - - jnc @@ahead3 + mov bx, OFFSET absdisk + mov [bx], cx ; Logical sector (low) + mov [bx+2], cx ; Logical sector (high) + mov WORD PTR [bx+4], 1 ; # of sectors to read + mov WORD PTR [bx+6], OFFSET bootsect + mov [bx+8], ds ; Address (FAR) to read to + mov al, [si] ; Drive # + dec cx ; Large disk, use AbsDiskIORec Struct + xor dx, dx ; Beginning sector + int 25h ; Absolute disk read + pop dx ; Remove leftover word from stack from int25h + jnc @@ahead3 ; Read failed, abort/return - pop si + pop si ret @@ahead3: - lea si, bootseg - push si - call getTotalClusters - add sp,2 - sub ax, WORD PTR [usedclust] ; AX = available clusters - - pop si - push ax - mov ax, WORD PTR [si+7] ; dpbclust+2 - mov es,ax - mov bx, WORD PTR [si+5] ; dpbclust - pop ax - mov WORD PTR es:[bx], ax ; Update free clusters + call getTotalClusters + sub ax, [usedclust] ; AX = available clusters + + pop si + les bx, [si+5] + mov es:[bx], ax ; Update free clusters ret getTotalClusters PROC - ARG bootsect:WORD - push bp - mov bp, sp - push si - mov si, [bootsect] + mov si, OFFSET bootsect ; Total clusters = ; total sectors - hidden sectors - num fats * sectors per fat ; ------------------------------------------------------------- ; sectors per cluster ; This will involve 32-bit maths ;--------------------------------- - xor dx,dx - mov ax, WORD PTR [si+13h] ; Number of sectors (small) - and ax,ax - jne @@small ; If not 0 then word sized # of sectors - ; (Why are you using this tool for that...) - mov ax, WORD PTR [si+20h] ; Number of sectors (large-low word) - mov dx, WORD PTR [si+22h] ; (high word) + xor ax, ax + cwd + or ax, [si+13h] ; Number of sectors (small) + jnz @@small ; If not 0 then word sized # of sectors + ; (Why are you using this tool for that...) + mov ax, [si+20h] ; Number of sectors (large-low word) + mov dx, [si+22h] ; (high word) @@small: ; DX:AX contains 32-bit total number of sectors - mov bx, WORD PTR [si+1Ch] ; # of hidden sectors - sub ax, bx ; Subtract from total - sbb dx, 0 - mov cl, BYTE PTR [si+10h] ; # of FATs - xor ch, ch - mov bx, WORD PTR [si+16h] ; Sectors per FAT + xor cx, cx + sub ax, [si+1Ch] ; Subtract # of hidden sectors from total + sbb dx, cx + mov cl, [si+10h] ; # of FATs @@fats: - sub ax, bx ; sectors per FAT - sbb dx, 0 - loop @@fats + sub ax, [si+16h] ; Sectors per FAT + sbb dx, 0 + loop @@fats ; DX:AX is now the number of available sectors ; Convert to clusters - mov bl, BYTE PTR [si+0Dh] ; Sectors per cluster - ; Guaranteed to be power of 2 + mov cl, [si+0Dh] ; Sectors per cluster + ; Guaranteed to be power of 2 @@sectclust: - shr bl, 1 - jc @@found ; Found our power of 2 stop dividing - shr dx, 1 - rcr ax, 1 ; Divide DX:AX by 2 - jmp @@sectclust + shr cl, 1 + jc @@found ; Found our power of 2 stop dividing + shr dx, 1 + rcr ax, 1 ; Divide DX:AX by 2 + jmp SHORT @@sectclust @@found: ; DX:AX now contains available clusters. Since FAT16 must be less ; than 65525 clusters our result is in AX - pop si - pop bp ret getTotalClusters ENDP @@ -284,126 +253,105 @@ getTotalClusters ENDP getUsedClust PROC ARG startsect:WORD, sectcount:BYTE, drive:BYTE - push bp - mov bp, sp - push di - push si - - lea bx, absdisk - mov ax, [startsect] - mov WORD PTR [bx+0], ax ; Start sector (low word) - xor ax, ax - mov WORD PTR [bx+2], ax ; (high word) - mov al, [sectcount] - mov WORD PTR [bx+4], ax ; # of sectors to read - - mov ax, ds - mov WORD PTR [bx+6], OFFSET bootseg - mov WORD PTR [bx+8], ax - - mov al, [drive] ; Drive # - mov cx, 0FFFFh ; Use AbsDiskIORec - mov dx, 0 ; Beginning sector - int 25h - pop dx ; Fix stack - jc @@fail + push bp + mov bp, sp + push di + push si + + mov bx, OFFSET absdisk + mov ax, [startsect] + mov [bx], ax ; Start sector (low word) + xor ax, ax + cwd ; Beginning sector + mov [bx+2], ax ; (high word) + mov al, [sectcount] + mov [bx+4], ax ; # of sectors to read + + mov WORD PTR [bx+6], OFFSET bootsect + mov [bx+8], ds + + mov al, [drive] ; Drive # + mov cx, 0FFFFh ; Use AbsDiskIORec + int 25h + pop dx ; Fix stack + sbb ax, ax ; 0 indicates free sector, -1 = Fail + jc @@fail ; Turn # sectors into number of entries to check - xor cl, cl - mov ch, [sectcount] ; sectcount * 256 (words per sector) - mov ax, ds - mov es, ax - lea di, bootseg - xor bx, bx ; # of non-free sectors - xor ax, ax ; 0 indicates free sector + mov cx, ds + mov es, cx + mov cl, al + mov ch, [sectcount] ; sectcount * 256 (words per sector) + mov di, OFFSET bootsect + mov bx, ax ; # of non-free sectors @@scan: - repe scasw ; Scan till we hit a non-free sector + repe scasw ; Scan till we hit a non-free sector ; We've hit a non-free sector, or are out of sectors to check - jcxz @@done ; Done checking all entries - inc bx ; Sector must not be free, count and - jmp @@scan ; contiue + jcxz @@done ; Done checking all entries + inc bx ; Sector must not be free, count and + jmp SHORT @@scan ; continue @@done: - je @@nofix ; If NE then we didn't count the last used - inc bx ; entry. Fix off by 1 error + je @@nofix ; If NE then we didn't count the last used + inc bx ; entry. Fix off by 1 error @@nofix: - mov ax, bx ; # of non-free sectors - pop si - pop di - pop bp - ret + xchg bx, ax ; # of non-free sectors to AX @@fail: - mov ax, 0FFFFh ; Failed - pop si - pop di - pop bp + pop si + pop di + pop bp ret getUsedClust ENDP - - - ; --------------------------------------------------- ; Split between TSR memory, and initialization memory ; --------------------------------------------------- - - init: - lea sp, stacktop - call parsecmd ; Parse command line + mov sp, OFFSET stacktop + call parsecmd ; Parse command line ; We've got a list of drives in tempdrives to setup, al is the # - mov BYTE PTR ds:[numdrives], al + mov ds:[numdrives], al ; Initialize table for each drive - mov si, OFFSET tempdrives - mov di, drvtbl ; Pointer to start of table - xor cl, cl ; Index # - xor ax, ax + mov si, OFFSET tempdrives + mov di, drvtbl ; Pointer to start of table + xor cl, cl ; Index # + xor ax, ax @@initloop: - push cx ; Preserve cx - push di ; Table entry pointer - lodsb ; Get drive # - push ax - call initdrive ; initdrive(drive #, index) - add sp, 4 - pop cx - add di, ENTSIZE ; Next entry - inc cl - cmp cl, BYTE PTR ds:[numdrives] - jne @@initloop + push cx ; Preserve CX + push di ; Table entry pointer + lodsb ; Get drive # + push ax + call initdrive ; initdrive(drive #, index) + add sp, 4 + pop cx + add di, ENTSIZE ; Next entry + inc cl + cmp cl, ds:[numdrives] + jne @@initloop ; Free our environment to save space - mov ax, WORD PTR ds:[2Ch] ; Environment block - mov es, ax - mov ah, 49h - int 21h ; Free environment block + mov es, ds:[2Ch] ; Environment block + mov ah, 49h + int 21h ; Free environment block ; Install our TSR - mov ax, 3521h ; Get int 21h vector - int 21h ; from int 21h itself :) + mov ax, 3521h ; Get int 21h vector + int 21h ; from int 21h itself :) ; ES:BX contains the vector - mov WORD PTR [oldint21h], bx - mov WORD PTR [oldint21h+2], es + mov [oldint21h], bx + mov [oldint21h+2], es ; Now install our new vector (DS:DX) - mov dx, OFFSET inthandler - mov ax, 2521h ; Install over int 21h - int 21h + mov dx, OFFSET inthandler + mov ah, 25h ; Install over int 21h + int 21h ; Now we terminate and stay resident - mov dx, OFFSET init ; How much do we need to keep - add dx, 15 ; Make sure we round upward in space - shr dx, 1 - shr dx, 1 - shr dx, 1 - shr dx, 1 ; # of paragraphs - mov ax, 3100h ; TSR - int 21h ; Hopefully we haven't broken int 21h here... - -readfail: - mov ah, 09h - lea dx, readfailstr - int 21h - int 20h + mov cl, 4 + mov dx, OFFSET init+15 ; How much do we need to keep + shr dx, cl ; # of paragraphs + mov ax, 3100h ; TSR + int 21h ; Hopefully we haven't broken int 21h here... ;------------------------------------------------------ ; BYTE parsecmd() @@ -411,185 +359,178 @@ readfail: ; Aborts and shows usage if error encountered ; Returns number of drives specified parsecmd PROC - push si - push di + push si + push di - push ds - pop es + push ds + pop es - mov di, 81h ; First character of cmd line ds:di + mov di, 81h ; First character of cmd line ds:di ; Skip any initial spaces - mov al, 20h ; Space - mov cx, 127 ; Max characters - repe scasb - dec di ; scasb will increment over the first non-match + mov al, 20h ; Space + mov cx, 127 ; Max characters + repe scasb + dec di ; scasb will increment over the first non-match - mov si, di + mov si, di lodsb - cmp al, 0Dh ; Were we run with no arguments? - je @@usage - dec si ; Point back at same argument for first entry - + cmp al, CR ; Were we run with no arguments? + je @@usage + dec si ; Point back at same argument for first entry - mov cl, 0 ; Count of drives read + xor cl, cl ; Count of drives read ; Loop over characters adding to array @@argloop: lodsb - cmp al, 0Dh ; End of arguments - je @@doneargs - cmp cl, MAXDRIVES - je @@usage ; Too many drives - and al, 0DFh ; Convert to uppercase - cmp al, 'A' - jb @@usage ; Non-letter character - cmp al, 'Z' - ja @@usage ; Non-letter character - sub al, 'A' ; Convert to drive number + cmp al, CR ; End of arguments + je @@doneargs + cmp cl, MAXDRIVES + je @@usage ; Too many drives + and al, 0DFh ; Convert to uppercase + cmp al, 'Z' + ja @@usage ; Non-letter character + sub al, 'A' ; Convert to drive number + jb @@usage ; Non-letter character ; Scan temp drives to find spot, or repetition - xchg di, si ; save cmd offset in di - mov si, OFFSET tempdrives - mov bl, al + xchg di, si ; save cmd offset in di + mov si, OFFSET tempdrives + mov bl, al @@insert: lodsb - cmp al, bl - je @@usage ; Repetition found, error - cmp al, 0FFh - jne @@insert ; Go until we find a spot - dec si - xchg di, si ; cmd offset in si, tempdrives offset in di - mov al, bl - stosb ; Store into drive list - inc cl ; Count of drives read so far - jmp @@argloop + cmp al, bl + je @@usage ; Repetition found, error + cmp al, 0FFh + jne @@insert ; Go until we find a spot + dec si + xchg di, si ; cmd offset in si, tempdrives offset in di + mov al, bl + stosb ; Store into drive list + inc cx ; Count of drives read so far + jmp SHORT @@argloop @@doneargs: ; We've handled all drives specified. tempdrives contains the list ; of drive #'s to setup - and cl, cl - je @@usage ; One last check to make sure we got a drive - mov al, cl - xor ah, ah ; AL (ax) contains number of drives listed - pop di - pop si + jcxz @@usage ; One last check to make sure we got a drive + xchg cx, ax ; AX contains number of drives listed + pop di + pop si ret @@usage: - mov ah, 09h ; Invalid parameter - lea dx, usagestr - int 21h - int 20h + mov ah, 09h ; Invalid parameter + mov dx, OFFSET usagestr + int 21h + int 20h parsecmd ENDP - ;---------------------------------------- ; void initdrive(BYTE drive, WORD tblptr) ; Initialize given drive and populate drive table entry initdrive PROC ARG drive:BYTE, tblptr:WORD - push bp - mov bp, sp - push di - push si + push bp + mov bp, sp + push di + push si - push ds - pop es + push ds + pop es ; Store drive number first - mov di, [tblptr] - mov al, [drive] + mov di, [tblptr] + mov al, [drive] stosb ; Read in boot sector for partition ; Setup abs disk struct - lea bx, absdisk - mov WORD PTR [bx+0], 0 ; Logical sector (low) - mov WORD PTR [bx+2], 0 ; Logical sector (high) - mov WORD PTR [bx+4], 1 ; # of sectors to read - mov WORD PTR [bx+6], OFFSET bootseg - mov ax, ds - mov WORD PTR [bx+8], ax ; Address (FAR) to read to - - mov al, [drive] ; Drive # - mov cx, 0FFFFh ; Large disk, use AbsDiskIORec Struct - mov dx, 0 ; Beginning sector - int 25h ; Absolute disk read - pop dx ; Remove leftover word from stack from int25h - jnc @@ahead2 - jmp readfail + xor dx, dx ; Beginning sector + mov bx, OFFSET absdisk + mov [bx], dx ; Logical sector (low) + mov [bx+2], dx ; Logical sector (high) + mov WORD PTR [bx+4], 1 ; # of sectors to read + mov WORD PTR [bx+6], OFFSET bootsect + mov [bx+8], ds ; Address (FAR) to read to + + mov al, [drive] ; Drive # + mov cx, 0FFFFh ; Large disk, use AbsDiskIORec Struct + int 25h ; Absolute disk read + pop dx ; Remove leftover word from stack from int25h + jnc @@ahead2 + mov ah, 09h + mov dx, OFFSET readfailstr + int 21h + int 20h + @@ahead2: ; We've now got the partition boot sector ; Figure out which sector the FAT is at - lea si, bootseg - cmp WORD PTR [si+0Bh], 512 ; Make sure this is 512 bytes/sector - jne @@unknowndisk + cmp WORD PTR [OFFSET bootsect+0Bh], 512 ; Make sure this is 512 bytes/sector + jne @@unknowndisk ; Check that the filesystem is FAT16 by looking at the cluster count - push si - call getTotalClusters - add sp,2 - and dx,dx - jne @@unknowndisk ; Total Clusters >= 65536 = FAT32 - cmp ax, 65524 - ja @@unknowndisk ; >= 65525 = FAT32 - cmp ax, 4085 - jb @@unknowndisk ; < 4085 = FAT12 + call getTotalClusters + test dx, dx + jnz @@unknowndisk ; Total Clusters >= 65536 = FAT32 + cmp ax, 65524 + ja @@unknowndisk ; >= 65525 = FAT32 + cmp ax, 4085 + jb @@unknowndisk ; < 4085 = FAT12 ; Assume we're looking at a FAT16 filesystem now - mov ax, WORD PTR [si+16h] ; # of sectors per FAT - cmp ax, 100h ; More than 65536 clusters, not FAT16 - ja @@unknowndisk - + mov ax, [si+16h] ; # of sectors per FAT + cmp ax, 100h ; More than 65536 clusters, not FAT16 + ja @@unknowndisk - stosw ; Sectors per fat - mov ax, WORD PTR [si+0Eh] ; start of FAT - stosw ; Fat start sector + stosw ; Sectors per fat + mov ax, [si+0Eh] ; start of FAT + stosw ; Fat start sector - push ds + push ds ; Now we change the dos data structure - mov ah, 32h ; Get Drive Parameter Block - mov dl, [drive] ; Get drive ID - inc dl ; Drive # is offset by 1 compared with 25h - int 21h + mov ah, 32h ; Get Drive Parameter Block + mov dl, [drive] ; Get drive ID + inc dl ; Drive # is offset by 1 compared with 25h + int 21h ; DS:BX now points straight to the appropriate data structure ; For DOS 4-6 offset 1F contains a word with the # of free clusters ; on drive, with FFFFh if unknown - add bx, 1Fh ; Offset to # of free clusters + add bx, 1Fh ; Offset to # of free clusters ; Save pointer to free cluster value - mov ax, bx + xchg bx, ax stosw - mov ax, ds + mov ax, ds stosw - pop ds + pop ds ; Drive has been initialized - pop si - pop di - pop bp + pop si + pop di + pop bp ret @@unknowndisk: - mov ah, 09h ; Filesystem doesn't match expectations - lea dx, diskerr ; abort - int 21h - int 20h + mov ah, 09h ; Filesystem doesn't match expectations + mov dx, OFFSET diskerr ; abort + int 21h + int 20h initdrive ENDP ; Temporary list of drives since we'll overwrite our arguments -MAXDRIVES EQU 18 ; Maximum drives supported + MAXDRIVES EQU 18 ; Maximum drives supported tempdrives: - DB MAXDRIVES+1 DUP (0FFh) + db MAXDRIVES+1 DUP (0FFh) usagestr: - DB "usage: FREESPT ",10,13 - DB " TSR to monitor when disk free space available is unknown and",10,13 - DB " calculates free space on FAT16 filesystem fast.",10,13 - DB " DRIVELIST consists of a sequence of drive letters to monitor",10,13 - DB " DRIVELIST can contain a maximum of 18 drives", 10,13 - DB " eg. ", 10,13 - DB " FREESPT CDEF", 10,13,10,13 - DB " Version 0.2",10,13,"$" + db "usage: FREESPT ",CR,LF + db " TSR to monitor when disk free space available is unknown and",CR,LF + db " calculates free space on FAT16 filesystem fast.",CR,LF + db " DRIVELIST consists of a sequence of drive letters to monitor",CR,LF + db " DRIVELIST can contain a maximum of 18 drives",CR,LF + db " eg. ",CR,LF + db " FREESPT CDEF",CR,LF,LF + db " Version 0.5",CR,LF,"$" diskerr: - DB "Unknown disk type.",10,13,"$" + db "Unknown disk type.",CR,LF,"$" readfailstr: - DB "Error reading from disk.",10,13,"$" + db "Error reading from disk.",CR,LF,"$" end start - \ No newline at end of file