⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fat16driver.bas

📁 MSP430最基本的应用开发实例
💻 BAS
📖 第 1 页 / 共 3 页
字号:


    '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 + -