📄 fat16driver.bas
字号:
'Print "new sector offset: " ; Lus_sectoroffset
Next Wr_sectloop
End Sub
' **
' * calculates the next cluster/sector to use for a new file
' **
Sub Findnextavailable()
Lus_sectoroffset = 0
'if empty, then set to the min
If Lus_cluster < 2 Then
Print "First cluster entry- setting to 2"
Lus_cluster = 2
Lus_bytes = 0
Lus_sector = Findsector(lus_cluster)
Lus_sectorincluster = 1
Else
'if this is not a new file
If Lus_isnewfile = 0 Then
Print "Calculating cluster/sector/byte to append"
If Fat_filesize > 512 Then
Lus_calc1 = Fat_filesize / 512
Lus_calc2 = Lus_calc1 / Br_sectorspercluster
Lus_sectorincluster = Lus_calc1 Mod Br_sectorspercluster
Lus_sectorincluster = Lus_sectorincluster + 1
Lus_sectoroffset = Fat_filesize Mod 512
Lus_sector = Findsector(fat_cluster)
Lus_sector = Lus_sector + Lus_calc1
Lus_cluster = Lus_cluster + Lus_calc2
Else
Lus_sectoroffset = Fat_filesize Mod 512
Lus_sectorincluster = 1
Lus_sector = Findsector(fat_cluster)
End If
'this is a new file
Else
Print "Calculating next cluster/sector/byte for new file"
Lus_sectoroffset = 0
Lus_sectorincluster = 1
'the previous file was greater than 1 sector
If Lus_bytes > 512 Then
Lus_calc1 = Lus_bytes / 512
Lus_calc1 = Lus_calc1 + 1 'add one for the
mod
'the previous file fit in to a silgle cluster
If Lus_calc1 <= Br_sectorspercluster Then
Print "previous file was greater than 512 but less than a cluster"
Lus_cluster = Lus_cluster + 1
Else
Print "previous file was greater than 512 and more than a cluster"
Lus_calc2 = Lus_calc1 / Br_sectorspercluster
Lus_calc2 = Lus_calc2 + 1
Lus_cluster = Lus_cluster + Lus_calc2
End If
Lus_sector = Findsector(lus_cluster)
Lus_sectorincluster = 1
'previous file was less than one sector so te calc is easy
Else
Print "previous file was less then 1 sector (512 bytes)"
Lus_cluster = Lus_cluster + 1
Lus_sector = Findsector(lus_cluster)
Lus_sectorincluster = 1
End If
End If
Print "Use clust: " ; Lus_cluster ; " sect: " ; Lus_sector ; "
secinclus: " ;
Print Lus_sectorincluster ; " secoffset: " ; Lus_sectoroffset
End If
End Sub
' **
' * checks to see if a file exists, if not, it gets created
' **
Sub Createorappendtofile(byval Fname As String)
'search the root dir for the datafile
G_touchvalue = Searchrootdir(fname)
'check the search results
If G_touchvalue > 0 Then
Print "File: " ; Fname ; " clust: " ;
Print Fat_cluster ; " size: " ; Fat_filesize
Lus_isnewfile = 0
'find the cluster/sector/byte offset for the existing file
Call Findnextavailable()
'file not found so create it
Else
Print "File: " ; Fname ; " not found "
Lus_isnewfile = 1
'calculate the next available cluster
Call Findnextavailable()
'create a root entry for the file
Call Createrootentry(fname)
'update the allocation table
Call Updateallocationtable(0)
End If
End Sub
' **
' * updates the allocation table
' **
Sub Updateallocationtable(byval Isnew As Byte)
'flag to track if this entry spans two sectors
Alloc_isnewsector = 0
'point to the first byte of the array
Allocpointer = Varptr(g_allocbuffer(1))
'calculate the cluster offset
Alloc_clustcalc1 = Lus_cluster * Mbr_fatoffset
Alloc_clustcalc1 = Alloc_clustcalc1 + 1
'how many sectors
Alloc_clustoffset = Alloc_clustcalc1 / 512
Alloc_clustcalc1 = Alloc_clustcalc1 Mod 512
'calculate what sector to read for the alloction table
Alloc_currentsector = Mbr_sectfrom + Alloc_clustoffset
Alloc_currentsector = Alloc_currentsector + 1
Print "Reading allocation table at sector: " ; Alloc_currentsector
'read sector number 1 into the 512 byte array starting at the pointer
address
Readsector Allocpointer , Alloc_currentsector , 1
'update the bytes
Print "setting " ; Mbr_fatoffset ; " bytes at " ; Alloc_clustcalc1
'this is part of an existing cluster chain so set the previous entry to
here
If Isnew = 1 Then
If Alloc_clustcalc1 > 2 Then
'back up two bytes
Alloc_clustcalc1 = Alloc_clustcalc1 - 2
'convert the previous cluster 'word' to two bytes
Call Convertword(lus_cluster)
'set the two byte words
G_allocbuffer(alloc_clustcalc1) = Convw_bytes(1)
Alloc_clustcalc1 = Alloc_clustcalc1 + 1
G_allocbuffer(alloc_clustcalc1) = Convw_bytes(2)
Alloc_clustcalc1 = Alloc_clustcalc1 + 1
Else
'indscates that this entry will span two sectors
Alloc_isnewsector = 1
End If
End If
'set the 'end of chain' marker
G_allocbuffer(alloc_clustcalc1) = &HFF
Alloc_clustcalc1 = Alloc_clustcalc1 + 1
G_allocbuffer(alloc_clustcalc1) = &HFF
'write the xferbuffer to the appropriate setcor on the storage media
Writesector Allocpointer , Alloc_currentsector , 1
'we man need to back up one sector because the chain spans over to a new
one
If Alloc_isnewsector = 1 Then
'read sector into the 512 byte array starting at the pointer address
Readsector Allocpointer , Alloc_temp1 , 1
'convert the previous cluster 'word' to two bytes
Call Convertword(lus_cluster)
'set the two byte words
G_allocbuffer(511) = Convw_bytes(1)
G_allocbuffer(512) = Convw_bytes(2)
'debug info
Print "Writing allocation table at sector: " ; Alloc_currentsector
'write sector from the 512 byte array starting at the pointer address
Writesector Allocpointer , Alloc_temp1 , 1
End If
End Sub
' **
' * finds the sector and entry number on the root that is available
' **
Sub Pointtofreeentry()
'point to the first byte of the array
G_pointer = Varptr(g_xferbuffer(1))
'start by adding the starting sector with the reserved sectors
Br_actualstartsector = Mbr_sectfrom + Br_reservedsectors
'calculate all of the sectors in every copy of the FAT table
Br_sectorsinallfats = Br_sectorsperfat * Br_copiesoffat
'add the total sectors in all copies of the FAT table
Br_actualstartsector = Br_actualstartsector + Br_sectorsinallfats
G_rootloop = 0
While G_rootloop <= Br_sectorsinroot
'read sector number 1 into the 512 byte array starting at the pointer
address
Readsector G_pointer , Br_actualstartsector , 1
'set the fat directory sector for future updates
Fat_dirsector = Br_actualstartsector
'start with record 0
G_volumerecord = 0
'examine each of 16 records on this sector until the volume attribute
is found
While G_volumerecord < 16
'set the fat directory entry number for future updates
Fat_direntry = G_volumerecord
G_attribreturn = Parsefatrecord(g_volumerecord)
'the attribute indicates this entry is a file
If G_attribreturn = 0 Then
Print "Empty dir entry at location " ; Fat_direntry ; " on
sector " ; Fat_dirsector
G_volumerecord = 254
G_rootloop = 254
End If
'increase the volume record counter
G_volumerecord = G_volumerecord + 1
Wend
'increase the sector and loop counters
Br_actualstartsector = Br_actualstartsector + 1
G_rootloop = G_rootloop + 1
Wend
End Sub
' **
' * creates a new directory entry on the root
' **
Sub Createrootentry(byval Touchname As String)
'copy the frame variable to the stack
G_touchholder = Touchname
'set the dot position to zero
G_dotposition = 0
G_dotextcount = 0
'point the buffer to an empty entry
Call Pointtofreeentry()
'iterate the filename characters and copy to the shortname and extension
For G_dotloop = 1 To Len(g_touchholder)
'get the single character from the string position
G_dotchar = Mid(g_touchholder , G_dotloop , 1)
'if its the left side of the dot, then build the shortname
If G_dotposition = 0 Then
'if dot was found, skip and mark it
If G_dotchar = "." Then
'Print "." ;
G_dotposition = G_dotloop
Else
'set the shortname value
Fat_shortname(g_dotloop) = G_dotchar
'Print Dotchar ;
End If
'this must be the right side of the dot
Else
'set the byte position of the extension and assign a value
G_dotextcount = G_dotextcount + 1
Fat_extension(g_dotextcount) = G_dotchar
'Print Dotchar ;
End If
Next Dotloop
'set the various field values to write
Fat_attribute = 32
Fat_createdms = 0
Fat_createdtm = 0
Fat_createddt = 0
Fat_accessdt = 0
Fat_fathighcluster = 0
Fat_updatetime = 0
Fat_updatedate = 0
Fat_cluster = Lus_cluster
Fat_filesize = 0
'set the dir values to the xfer buffer before writing
Call Setdirvalues()
'write the xferbuffer to the appropriate setcor on the storage media
Writesector G_pointer , Fat_dirsector , 1
End Sub
' **
' * sets the dir values to a record on a speficied sector
' **
Sub Setdirvalues()
'byte offset for the directory entry
Set_diroffset = Fat_direntry * 32
'set the xferbuffer bytes for the shortname
For G_cntr = 1 To 8
Set_diroffset = Set_diroffset + 1
If Fat_shortname(g_cntr) > 0 Then
G_xferbuffer(set_diroffset) = Fat_shortname(g_cntr)
Else
G_xferbuffer(set_diroffset) = 32
End If
Next G_cntr
'set the xferbuffer bytes for the extension
For G_cntr = 1 To 3
Set_diroffset = Set_diroffset + 1
If Fat_extension(g_cntr) > 0 Then
G_xferbuffer(set_diroffset) = Fat_extension(g_cntr)
Else
G_xferbuffer(set_diroffset) = 32
End If
Next G_cntr
'set the attribute
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = Fat_attribute
'skip the reserved byte
Set_diroffset = Set_diroffset + 1
'set the rest of the values
'For Cntr = 1 To 13
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H0C
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H20
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H91
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H3C
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H2E
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H3C
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H2E
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H00
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H00
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H28
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H91
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H3C
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = &H2E
'Next Cntr
Call Convertword(fat_cluster)
'set the rest of the values
For G_cntr = 1 To 2
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = Convw_bytes(g_cntr)
'Print Convw_bytes(cntr) ; " " ;
Next G_cntr
'Print " = " ;
Call Convertlong(fat_filesize)
'set the rest of the values
For G_cntr = 1 To 4
Set_diroffset = Set_diroffset + 1
G_xferbuffer(set_diroffset) = Conv_bytes(g_cntr)
'Print Conv_bytes(cntr) ; " " ;
Next G_cntr
End Sub
' **
' * finds the next available cluster
' **
Sub Findlastusedsector()
Print "FindLastUsedSector()"
'point to the first byte of the array
G_pointer = Varptr(g_xferbuffer(1))
Lus_fatsector = Br_actualstartsector
Lus_sector = 0
Print "Finding Last Used Cluster starting at: " ; Lus_fatsector
'MBR fits on a simgle 512 byte sector
Lus_loop = 0
While Lus_loop <= Br_sectorsinroot
'read sector number 1 into the 512 byte array starting at the pointer
address
Readsector G_pointer , Lus_fatsector , 1
'start with record 0
Lus_rec = 0
'exame each of 16 records on this sector until the volume attribute is
found
While Lus_rec < 16
'parse the record
G_attribreturn = Parsefatrecord(lus_rec)
'the attribute indicates this entry is a file
If G_attribreturn > 31 And Fat_shortname(1) <> 229 Then
Print "file: " ; Fat_filename ; " at cluster: " ; Fat_cluster ;
Print " size: " ; Fat_filesize
If Fat_cluster > Lus_cluster Then
Print "Setting last used cluster to: " ; Fat_cluster
Lus_cluster = Fat_cluster
Lus_sector = Findsector(lus_cluster)
Lus_bytes = Fat_filesize
End If
End If
Lus_rec = Lus_rec + 1
Wend
Lus_fatsector = Lus_fatsector + 1
Lus_loop = Lus_loop + 1
Wend
End Sub
' **
' * This function is used to calculate the sector from the cluster
' **
Function Findsector(byval Clusternumber As Word) As Long
'calc the sectors based on the cluster * sectors per cluster
Fnd_sectorcalc = Br_sectorspercluster * Clusternumber
Fnd_spcoffset = Br_sectorspercluster * 2
Fnd_sectorcalc = Fnd_sectorcalc - Fnd_spcoffset
'cluster
Findsector = Data_sector + Fnd_sectorcalc
End Function
' **
' * This function is used to read the Master Boot Record of the storage
device.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -