 Rem File: Dndsub10 for Dndbbs Version v5.0a Release r2.0 Tweak t4.0a
 Rem $Include: 'dndbbs.inc'
 Rem $Include: 'fat32.bi'

' get drive freespace (modified 12/09/2022)
SUB FreeSpace (T%, T#)
 On Local Error Goto DriveError
 Dim ASCIIZ As String * 260

 ' declare structures
 Dim FAT32struc AS FAT32Type

 Temp.Path$=Environ$("DNDBBS")
 If Temp.Path$<>Nul Then
    If Right$(Temp.Path$,1)<>"\" Then
       Temp.Path$=Temp.Path$+"\"
    Endif
 Endif
 If Temp.Path$="" Then
    Temp.Path$=CURDIR$
 Endif
 ' get drive letter
 T# = 0#
 D$ = Left$(Temp.Path$,1)
 D$ = Ucase$(D$)
 If D$>="A" And D$<="Z" Then
    V = Asc(D$) - 64
 Else
    V = 3
 Endif

 ' get FAT32 drive space
 ASCIIZ = CHR$(V + 64) + ":\" + CHR$(0)
 InregsX.AX = &H7303
 InregsX.DS = VARSEG(ASCIIZ)
 InregsX.DX = VARPTR(ASCIIZ)
 InregsX.ES = VARSEG(FAT32Struc)
 InregsX.DI = VARPTR(FAT32Struc)
 InregsX.CX = LEN(FAT32Struc)
 CALL InterruptX(&H21, InregsX, OutregsX)
 IF (OutregsX.Flags AND &H1) = &H0 THEN
    If T% = 1 Then ' free
       Gosub Get.Free
    END IF
    If T% = 2 Then ' total
       Gosub Get.Total
    END IF
    If T% = 3 Then ' used
       Gosub Get.Total
       Total#=T#
       Gosub Get.Free
       Free#=T#
       T# = Total# - Free#
    END IF
    IF T# Then
       EXIT SUB
    END IF
 END IF

 ' check disk space.
 InregsX.AX = &H3600
 InregsX.DX = V
 CALL InterruptX(&H21, InregsX, OutregsX)
 ' check drive exists.
 IF OutregsX.AX = &HFFFF THEN
    T# = 0#
 ELSE
    ' Note: FAT16 only reports up to 2 GB.
    If T% = 1 Then ' free
       Gosub Get.Free16
    Endif
    If T% = 2 Then ' total
       Gosub Get.Total16
    Endif
    If T% = 3 Then ' used
       Gosub Get.Total16
       Total#=T#
       Gosub Get.Free16
       Free#=T#
       T# = Total# - Free#
    Endif
 END IF
DriveResume:
 IF T#=0# Then
    T#=256*1024^2
 Endif
 Exit Sub
Get.Free:
 Bytes# = CDBL(ASC(MID$(FAT32Struc.BytesPerSector, 1, 1)))
 Bytes# = Bytes# + CDBL(ASC(MID$(FAT32Struc.BytesPerSector, 2, 1))) * 256#
 Bytes# = Bytes# + CDBL(ASC(MID$(FAT32Struc.BytesPerSector, 3, 1))) * 65536#
 Bytes# = Bytes# + CDBL(ASC(MID$(FAT32Struc.BytesPerSector, 4, 1))) * 16777216#
 Sectors# = CDBL(ASC(MID$(FAT32Struc.FreeSectors, 1, 1)))
 Sectors# = Sectors# + CDBL(ASC(MID$(FAT32Struc.FreeSectors, 2, 1))) * 256#
 Sectors# = Sectors# + CDBL(ASC(MID$(FAT32Struc.FreeSectors, 3, 1))) * 65536#
 Sectors# = Sectors# + CDBL(ASC(MID$(FAT32Struc.FreeSectors, 4, 1))) * 16777216#
 T# = Bytes# * Sectors#
 Return
Get.Total:
 Bytes# = CDBL(ASC(MID$(FAT32Struc.BytesPerSector, 1, 1)))
 Bytes# = Bytes# + CDBL(ASC(MID$(FAT32Struc.BytesPerSector, 2, 1))) * 256#
 Bytes# = Bytes# + CDBL(ASC(MID$(FAT32Struc.BytesPerSector, 3, 1))) * 65536#
 Bytes# = Bytes# + CDBL(ASC(MID$(FAT32Struc.BytesPerSector, 4, 1))) * 16777216#
 Sectors# = CDBL(ASC(MID$(FAT32Struc.TotalSectors, 1, 1)))
 Sectors# = Sectors# + CDBL(ASC(MID$(FAT32Struc.TotalSectors, 2, 1))) * 256#
 Sectors# = Sectors# + CDBL(ASC(MID$(FAT32Struc.TotalSectors, 3, 1))) * 65536#
 Sectors# = Sectors# + CDBL(ASC(MID$(FAT32Struc.TotalSectors, 4, 1))) * 16777216#
 T# = Bytes# * Sectors#
 Return
Get.Free16:
 ' free space on drive in bytes is AX * BX * CX adjusted signed-int
 T1# = OutregsX.AX: IF T1# < 0# THEN T1# = T1# + 65536#
 T2# = OutregsX.BX: IF T2# < 0# THEN T2# = T2# + 65536#
 T3# = OutregsX.CX: IF T3# < 0# THEN T3# = T3# + 65536#
 T# = T1# * T2# * T3#
 Return
Get.Total16:
 ' total space on drive in bytes is AX * CX * DX adjusted signed-int
 T1# = OutregsX.AX: IF T1# < 0# THEN T1# = T1# + 65536#
 T2# = OutregsX.CX: IF T2# < 0# THEN T2# = T2# + 65536#
 T3# = OutregsX.DX: IF T3# < 0# THEN T3# = T3# + 65536#
 T# = T1# * T2# * T3#
 Return
DriveError:
 Resume DriveResume
END SUB
