📄 fat16driver.bas
字号:
' * The resulting values are stored in the global variables starting with
Mbr_
' **
Sub Readmbr()
'output some debug info
Call Debug( "ReadMBR()")
'set the offset values
G_offset = 447
'point to the first byte of the array
G_pointer = Varptr(g_xferbuffer(1))
'MBR is always sector #0
G_sectnum = 0
'debug
Print "Reading MBR at Sector: " ; G_sectnum
'Call Debug(g_debugtext)
'read sector number 1 into the 512 byte array starting at the pointer
address
Readsector G_pointer , G_sectnum , 1
'see if the value is greater than 0, otherwise, that partition not defined
If G_xferbuffer(g_offset) > 0 Then
'update the offset value
G_offset = G_offset + 4
'read the filesystem type from the transfer buffer
Mbr_fstype = G_xferbuffer(g_offset)
Print "File System Type: " ; Hex(mbr_fstype)
G_offset = G_offset + 3
'read the starting sector for the partition
Mbr_sectfrom = Getlongfrombuffer(g_xferbuffer(1) , G_offset)
Print "Start Sector: " ; Mbr_sectfrom
If Mbr_fstype = &H0B Then
Mbr_fatoffset = 4
Mbr_sectorsinroot = 0
Print "Filesystem: FAT32"
End If
If Mbr_fstype = &H06 Then
Mbr_fatoffset = 2
Mbr_sectorsinroot = 14
Print "Filesystem: FAT16"
End If
If Mbr_fstype < &H06 Then
Mbr_fatoffset = 1.5
Mbr_sectorsinroot = 32
Print "Filesystem: FAT12"
End If
End If
End Sub
' **
' * This function is used to read boot record for a given partition
' **
Sub Readbootrecord()
Print "ReadBootRecord()"
'point to the first byte of the array
G_pointer = Varptr(g_xferbuffer(1))
Print "Reading from Sector " ; Mbr_sectfrom
'find the starting sector from the partition table lookup
G_sectnum = Mbr_sectfrom
'read sector number 1 into the 512 byte array starting at the pointer
address
Readsector G_pointer , G_sectnum , 1
'set the offset and get the bytes per sector field
G_offset = 11
Br_bytespersector = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'set the offset and get the sectors per cluster field
G_offset = G_offset + 2
Br_sectorspercluster = G_xferbuffer(g_offset + 1)
'set the offset and get the reserved sectors
G_offset = G_offset + 1
Br_reservedsectors = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'set the offset and get the copies of fat
G_offset = G_offset + 2
Br_copiesoffat = G_xferbuffer(g_offset + 1)
'set the offset and get the max number of root entries
G_offset = G_offset + 1
Br_maxrootentries = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'set the offset and get the sectors per fat
If Mbr_fstype < &H0B Then
'reads the sectors per fat for FAT12/16
G_offset = G_offset + 5
Br_sectorsperfat = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
Else
'reads the sectors per fat for FAT32
G_offset = G_offset + 19
Br_sectorsperfat = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'set the offset and get the root directory starting cluster
G_offset = G_offset + 1
Br_rootcluster = Getlongfrombuffer(g_xferbuffer(1) , G_offset)
End If
'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
'calc the data sector offset based on the max entries * 32 (32 bytes each)
Data_sectoffset = Br_maxrootentries * 32
'devide the offset by bytes per sector to determine the sector number
Data_sectorcluster = Data_sectoffset / Br_bytespersector
Data_sector = Br_actualstartsector + Data_sectorcluster
'For Cntr = 1 To 120
' Print Xferbuffer(cntr) ; " ";
'Next Cntr
'Print " "
Print "Bytes per sector: " ; Br_bytespersector
Print "Sectors per cluster: " ; Br_sectorspercluster
Print "Sectors per fat: " ; Br_sectorsperfat
Print "Reserved sectors: " ; Br_reservedsectors
Print "Copies of fat: " ; Br_copiesoffat
Print "Max root entries: " ; Br_maxrootentries
End Sub
' **
' * This function is used to return a long datatype from the buffer
' *
' * Code originated by Josef Franz
' **
Function Getlongfrombuffer(pbsramarray As Byte , Byval Pbpos As Word) As
Long
' Extract a Long-Value from a Byte-Array
' pbSRAMArray: Byte-array, from which the Long-value should be extracted
' pbPos: Position, at which the Long-Value starts (0-based)
Loadadr Pbsramarray , Z
Loadadr Pbpos , X
ld r24, x+
ld r25, x+
add zl, r24
adc zh, r25
Loadadr Getlongfrombuffer , X
ldi r24, 4
!Call _Mem_Copy
End Function
' **
' * This function is used to return a word datatype from the buffer
' *
' * Code originated by Josef Franz
' **
Function Getwordfrombuffer(pbsramarray As Byte , Byval Pbpos As Word) As
Word
' Extract a Word-value from a Byte-Array
' pbSRAMArray: Byte-array, from which the Word-value should be extracted
' pbPos: Position, at which the Word-Value starts (0-based)
Loadadr Pbsramarray , Z
Loadadr Pbpos , X
ld r24, x+
ld r25, x+
add zl, r24
adc zh, r25
Loadadr Getwordfrombuffer , X
ldi r24, 2
!Call _Mem_Copy
End Function
' **
' * Used to convert a long value to 4 bytes
' **
Sub Convertlong(byval Longvalue As Long)
'set the long value outside the frame
Conv_long = Longvalue
Conv_string = Hex(conv_long)
'parse the HEX string value as 2 char strings
Conv_strbytes(1) = Mid(conv_string , 1 , 2)
Conv_strbytes(2) = Mid(conv_string , 3 , 2)
Conv_strbytes(3) = Mid(conv_string , 5 , 2)
Conv_strbytes(4) = Mid(conv_string , 7 , 2)
'convert the bit order to little endian
Conv_bytes(4) = Hexval(conv_strbytes(1))
Conv_bytes(3) = Hexval(conv_strbytes(2))
Conv_bytes(2) = Hexval(conv_strbytes(3))
Conv_bytes(1) = Hexval(conv_strbytes(4))
End Sub
' **
' * Used to convert a long value to 4 bytes
' **
Sub Convertword(byval Wordvalue As Word)
'set the long value outside the frame
Convw_word = Wordvalue
Convw_string = Hex(convw_word)
'parse the HEX string value as 2 char strings
Convw_strbytes(1) = Mid(convw_string , 1 , 2)
Convw_strbytes(2) = Mid(convw_string , 3 , 2)
'convert the bit order to little endian
Convw_bytes(2) = Hexval(convw_strbytes(1))
Convw_bytes(1) = Hexval(convw_strbytes(2))
End Sub
' **
' * This sub sets the debug output device
' *
' * Set to 1 for RS232
' * Set to 2 for LCD
' **
Sub Setdebug(byval Debugvalue As Byte)
'set the global debug value
G_debug = Debugvalue
End Sub
' **
' * This sub prints a message to the RS232 or LCD if the debug is set
' **
Sub Debug(byval Debugtext As String)
'if debug is set to 1, select the RS232 output device
If G_debug = 1 Then
Print Debugtext
End If
'if debug is set to 2, select the LCD output device
If G_debug = 2 Then
Lcd Debugtext
End If
End Sub
' **
' * This function is used to parse a 512 byte sector for the 32 byte fat
record
' **
Function Parsefatrecord(byval Recordnum As Word) As Byte
'start at byte 0 offset
G_offset = Recordnum * 32
G_parse_temp = G_offset + 12
'set the offset and read the attribute byte
G_attribute = G_xferbuffer(g_parse_temp)
'Print "REC: " ; Recordnum ; " OFFSET: " ; Offset ; " ATTRIB: " ;
Attribute
'For Cntr = 1 To 32
' Parse_temp = Offset + Cntr
' Print Hex(xferbuffer(parse_temp)) ; " " ;
'Next Cntr
'Print ""
'For Cntr = 1 To 32
' Parse_temp = Offset + Cntr
' Print Xferbuffer(parse_temp) ; " " ;
'Next Cntr
'Print ""
'check the attribute byte to determine if this a a LFN ercord.
'The attribute indicates that this is a LFN record if it's OFh
If G_attribute = &H0F Then
'LFN code goes here
Else
Fat_attribute = G_attribute
'Print "VALUES: " ;
'get the 8 byte short file name
For G_cntr = 1 To 8
G_offset = G_offset + 1
Fat_shortname(g_cntr) = G_xferbuffer(g_offset)
Next G_cntr
'get the 3 byte file extension
For G_cntr = 1 To 3
G_offset = G_offset + 1
Fat_extension(g_cntr) = G_xferbuffer(g_offset)
Next G_cntr
'get the files created milliseconds (ms)
G_offset = G_offset + 1 'base 1 array
requires +1
Fat_createdms = G_xferbuffer(g_offset + 1)
'get the create time as a word
G_offset = G_offset + 2
Fat_createdtm = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'get the created date as a word
G_offset = G_offset + 2
Fat_createddt = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'get the last access date as a word
G_offset = G_offset + 2
Fat_accessdt = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'get the high 16 bits of the fat cluster as a word
G_offset = G_offset + 2
Fat_fathighcluster = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'get the last update time as a word
G_offset = G_offset + 2
Fat_updatetime = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'get the last update date as a word
G_offset = G_offset + 2
Fat_updatedate = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'get the 16 bit fat cluster as a word
G_offset = G_offset + 2
Fat_cluster = Getwordfrombuffer(g_xferbuffer(1) , G_offset)
'get the file size as a dword (long)
G_offset = G_offset + 2
'Print "long offset = " ; Offset
Fat_filesize = Getlongfrombuffer(g_xferbuffer(1) , G_offset)
If Fat_attribute > 31 And Fat_shortname(1) <> 229 Then
For G_temp_cntr = 1 To 4
G_temp_val = G_temp_cntr + G_offset
'Print Xferbuffer(temp_val) ; " " ;
Next G_temp_cntr
'Print " = " ; Fat_filesize ; " Bytes at offset " ; Offset ; " cntr="
; Temp_cntr
End If
'point the offset to the end of the 32 byte record
G_offset = G_offset + 4
'set the volume name of attribute indicates this is a file
If Fat_attribute > 31 And Fat_shortname(1) <> 229 Then
Fat_filename = ""
For G_cntr = 1 To 8 '
If Fat_shortname(g_cntr) < 129 And Fat_shortname(g_cntr) > 33 Then
'Print "'" ; Chr(fat_shortname(cntr)) ; "' " ;
Hex(fat_shortname(cntr)) ; " " ;
Fat_filename = Fat_filename + Chr(fat_shortname(g_cntr))
End If
Next G_cntr
Fat_filename = Fat_filename + "."
For G_cntr = 1 To 3
If Fat_extension(g_cntr) < 129 And Fat_extension(g_cntr) > 33 Then
Fat_filename = Fat_filename + Chr(fat_extension(g_cntr))
End If
Next Cntr
'Print "file: " ; Fat_filename
End If
End If
Parsefatrecord = G_attribute
End Function
' **
' * This function is used to list the files on the root dir
' **
Sub Listrootdir()
'empty return value
Local Returnvalue As Byte
'call 'search' with a bogus filename
' NOTE: wild cards '*' are meaningless, this is a totally bogus filename
Returnvalue = Searchrootdir( "*.*")
End Sub
' **
' * Lists a file contents as ascii text
' **
Sub Listfile(byval Fname As String)
'search results
Local Result As Byte
'search for file
Result = Searchrootdir(fname)
'if file was found, dump it as ascii text
If Result > 0 Then
'dump the contents
Call Dumpfile(fat_cluster , Fat_filesize)
End If
End Sub
' **
' * This function is used to search the root dir for a file
' **
Function Searchrootdir(byval Searchname As String) As Byte
'set the value out of the frame
G_touchholder = Searchname
'point to the first byte of the array
G_pointer = Varptr(g_xferbuffer(1))
Print "FAT start sector:" ; Br_actualstartsector ; " for dir entries"
'Print "data start sector:" ; Datasector
Print "Searching for " ; G_touchholder
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
'exame 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 > 31 And Fat_shortname(1) <> 229 Then
Print "File: " ; Fat_filename
'found the filename so return
If Fat_filename = G_touchholder Then
'set the return value and exit
Searchrootdir = G_attribreturn
G_rootloop = 99
G_volumerecord = 99
Else
'file not found
Searchrootdir = 0
End If
End If
G_volumerecord = G_volumerecord + 1
Wend
Br_actualstartsector = Br_actualstartsector + 1
G_rootloop = G_rootloop + 1
Wend
End Function
' **
' * copy Memory from (Z) nach (X)
' * counts of bytes in r24
' *
' * Code originated by Josef Franz
' **
_mem_copy:
ld r25, z+
st x+, r25
dec r24
brne _Mem_Copy
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -