📄 bbu_fat.s
字号:
mov r6, r0 ; Save offset to next directory sector
;
; Begin the search for the desired file name
;
51 ldr r2, =BBU_FAT_DIR ; Point to start of directory buffer
ldr r0, =BBU_FD_NAME ; Where the file name is stored
52 mov r1, r0 ; Reset input file name pointer
mov r5, r2 ; Copy start address of file name to r4
;
; Check to see if the end of the directory buffer area was reached. If it
; was, read in the next segment of the directory before continuing.
;
ldr r3, =BBU_FAT_DIR_END; This is the end of the buffer
cmp r5, r3 ; Are we atthe end of the buffer?
bne %F53 ; No - check the next file name entry
;
; Read in the next segment of the directory
;
mov r0, r6 ; get offset to next directory sector
b %B50 ; Update buffer and continue search
;
; Compare first bytes of file name to be seached for and the next file
; name in the directory. If the directory file name is a NULL byte it
; indicates the end of the directoy entries. Only a TOTAL match of the
; input file name to the directory file name will return a non-zero
; value from this subroutine.
;
53 ldrb r3, [r5], #1 ; Fetch byte from volume file name
cmp r3, #0 ; End of directory listing?
moveq r0, #1 ; Yes - return file not found value
beq %F59 ; ...and take the exit path
ldrb r4, [r1], #1 ; Get 1st byte of input file name
cmp r3, r4 ; Do the first two byte match?
addne r2, r2, #0x20 ; No - point to next file entry
bne %B52 ; ...and compare the next file entry
;
; The first bytes of the two file name match. The following code will
; check for a match on the rest of the file name.
;
54 ldrb r4, [r1], #1 ; Get next byte from input file name
cmp r4, #0 ; End of the input file name reached?
beq %F56 ; Yes - we have a file name match!
ldrb r3, [r5], #1 ; Get next byte of the volume file name
cmp r3, r4 ; Do these bytes match?
beq %B54 ; Yes - compare the next set of bytes
add r2, r2, #0x20 ; No - point to next file in directory
b %B52 ; ...and start testing the next entry
;
; There was a file name match - get the starting cluster number for
; this file entry and return it to the caller.
;
56 ldrh r0, [r2, #0x1A] ; Get bits 15:0 of the cluster number
ldrh r1, [r2, #0x14] ; Get bits 31:16 of the cluster number
mov r1, r1, LSL #16 ; Shift 16 bits to the left
orr r0, r0, r1 ; OR the two values together
;
; See if the user requested this file entry to be deleted
;
; ldr r6, #'DELE' ; Load ASCII "DELE" into r6
59 ldmfd sp!, {r1-r6, pc} ; Restore registers, return to caller
ENDFUNC
;
;*******************************************************************************
;
; *****************
; * *
; * BBU_READ_FILE * Read a file from the volume and write it to
; * * the user specified memory location.
; *****************
;
; CODE UNDER DEVELOPMENT
;
; PARAMETER PASSING:
;
; INPUT:
;
; r0 - Cluster number where the file starts.
; r1 - Memory location where file is to be loaded to.
;
; OUTPUT:
;
; r0 = 0xFF if there was an error
;
;
BBU_READ_FILE FUNCTION
stmfd sp!, {r1-r7, lr} ; Save registers and link on the stack
ldr r3, =BBU_SEC_CLUS ; Address where sectors/cluster is kept
ldrb r4, [r3] ; Get sectors per cluster count
ldr r2, =BBU_CLUSZ_SEC ; Address where clus #0 sector is kept
ldr r3, [r2] ; Get cluster #0 sector number
70 mov r5, r0 ; Copy the cluster # here
mov r7, r0 ; Also save a copy here for reference
mov r6, r4 ; Copy the sector/cluster count to r6
mul r5, r5, r4 ; r5 = sector count from cluster #0
;
; Read a cluster's worth of data
;
72 add r0, r3, r5 ; Generate desired sector # in r0
add r2, r1, #0x200 ; Save updated destination addrs in r2
bl BBU_MMC_Read ; Read from the MMC
add r5, r5, #1 ; Increment the sector number
mov r1, r2 ; Move destination address into r1
subs r6, r6, #1 ; Decrement the sectors/cluster count
bne %B72 ; Read another sector from the cluster
;
; End of cluster reached - get the next cluster number for this file.
;
mov r0, r7 ; Move saved cluster number to r0
bl BBU_FAT_NEXT_CLUS ; Get the next cluster number
ldr r6, =BBU_FAT_TYPE ; Address where FAT type is kept
ldrb r7, [r6] ; Get fat type
cmp r7, #12 ; Is this FAT12
bne %F74 ; No - skip the following
;
; FAT12 structure
;
ldr r6, =0xFEF ; Assume end of file if greater than r6
cmp r0, r6 ; End of file?
blt %B70 ; No - read another cluster
b %F79 ; Yes - take the exit path
;
; FAT16 structure
;
74 cmp r7, #16 ; Is this FAT16?
bne %F75 ; No - Go here (FAT32)
ldr r6, =0xFFEF ; Assume end of file if greater than r6
cmp r0, r6 ; End of file?
blt %B70 ; No - read another cluster
b %F79 ; Yes - take the exit path
;
; FAT32 structure
;
75 ldr r6, =0xFFFFFEF ; Assume end of file if greater than r6
cmp r0, r6 ; End of file?
blt %B70 ; No - read another cluster
79 ldmfd sp!, {r1-r7, pc} ; Restore registers, return to caller
ENDFUNC
;
;*******************************************************************************
;
; ***************
; * *
; * BBU_SET_DIR * Set a new default directory for BBU
; * *
; ***************
;
;
; PARAMETER PASSING:
;
; INPUT:
;
; r0 - Starting cluster number of the directory
; If r0 = 0, the root directory is selected (FAT12/FAT16)
;
; OUTPUT:
;
; r0 = input value returned (preserved)
;
; PURPOSE:
;
; This subroutine takes a cluster number for a directory and generates a
; table of sectors that make up the the current directory. This is done
; because subdirectories may span multiple clusters. Rather than deal
; with cluster lookups later, the clusters numbers are converted to
; sector numbers and saved in a table for later reference. From this point
; on, loading directory information into BBUs directory buffer only
; requires that the offest into the sector table generated by this
; subroutine be known. This makes life easier for doing directory listings
; and searches.
;
BBU_SET_DIR FUNCTION
stmfd sp!, {r0-r6, lr} ; Save registers and link on the stack
;
; See if the caller is looking for the root directory
;
cmp r0, #0 ; Was the root directory selected?
bne %F81 ; No - skip to this location
;
; Root dircetory selected - get the sector number saved when the volume
; was mounted.
;
ldr r2, =BBU_ROOT_SECT ; Root directory sector saved here
ldr r0, [r2] ; Get the root directory sector number
ldr r4, =BBU_DIR_SECT ; Get start of directory sector table
ldr r3, =BBU_ROOT_SIZE ; Size of root directory in sectors
ldrh r1, [r3] ; Load the size into r1
cmp r1, #0 ; Is this value zero (FAT32 format)
moveq r1, #BBU_DIR_BUFSZ ; TEMP PATCH FOR FAT32 FORMAT!!
;
; Fill the directory sector table with the sector values for
; the root directory.
;
80 str r0, [r4], #4 ; store this value
add r0, r0, #1 ; Increment the sector value
subs r1, r1, #1 ; Decrement the remaining count
bne %B80 ; Loop until the table is complete
str r1, [r4] ; Zero the last table entry
b %F89 ; Exit path
;
; NON-ROOT DIRECTORY CODE - Subdirectories may span multiple clusters!
;
81 ldr r4, =BBU_DIR_SECT ; Get start of directory sector table
ldr r5, =BBU_SEC_CLUS ; Sectors per cluster count saved here
ldrb r6, [r5] ; r6 = sectors per cluster count
82 mov r2, r0 ; Copy cluster number to r2
ldr r3, =BBU_CLUSZ_SEC ; Cluster zero sector # saved here
ldr r1, [r3] ; Get the sector # for cluster zero
mul r2, r2, r6 ; r2 = sector offset to directory
add r5, r1, r2 ; r5 = starting sector of dir
mov r3, r6 ; Copy sectors per custer count to r3
83 str r5, [r4], #4 ; Save sector entry in table
add r5, r5, #1 ; Increment sector pointer
subs r3, r3, #1 ; Decrement sector/cluster count
bne %B83 ; Loop until this cluster is done
;
; Current cluster number is in r0 so we can get the next cluster number
;
bl BBU_FAT_NEXT_CLUS ; Get next directory cluster number
ldr r1, =BBU_FAT_TYPE ; This is where the FAT type is saved
ldrb r2, [r1] ; Get the FAT type
cmp r2, #12 ; FAT12 structure?
bne %F84 ; No - skip to FAT16/FAT32 test
ldr r3, =0xFEF ; Last possible cluster number
cmp r0, r3 ; Last directory cluster?
bge %F89 ; Yes - take the exit path
b %B82 ; Process the next cluster
84 cmp r2, #16 ; FAT16 file structure?
ldreq r3, =0xFFEF ; Last possible cluster for FAT16
ldrne r3, =0xFFFFFEF ; Last possible cluster for FAT32
cmp r0, r3 ; Last directory cluster?
bmi %B82 ; No - process this cluster
;
89 mov r0, #0 ; Zero out a work register
str r0, [r4] ; Zero the last entry in the table
ldmfd sp!, {r0-r6, pc} ; Restore registers, return to caller
ENDFUNC
;
;*******************************************************************************
;
; ***************
; * *
; * BBU_NAME_83 * FORMAT FILE/DIRECTORY NAME IN PROPER 8.3 FORMAT
; * *
; ***************
;
;
; PARAMETER PASSING:
;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -