📄 bbu_fat.s
字号:
; INPUT:
;
; NONE - Looks for file name in BBU's input buffer (BBU_CMD_ASCII)
;
; OUTPUT:
;
; NONE - Places formatted file/directory name in BBU_FD_NAME
;
; Put the file name into the proper 8.3 format. If the user enters a "."
; or ".." as the first characters this needs to be allowed so the user
; can change directories.
;
BBU_NAME_83 FUNCTION
stmfd sp!, {r1-r4, lr} ; Save registers and link on the stack
ldr r1, =BBU_CMD_ASCII ; BBU Input buffer address
ldr r2, =BBU_FD_NAME ; Where the formatted data goes
mov r4, #8 ; Set the byte counter
82 ldrb r3, [r1], #1 ; Fetch a byte
cmp r3, #'.' ; Is this byte a "."?
beq %F83 ; Yes - skip over the following
cmp r3, #0 ; Is this the end of the input string?
beq %F87 ; Yes - go here to finish the formatting
b %F84 ; Otherwise - copy a byte
;
; "." found in input file name. Pad the name (if necessary)
;
83 cmp r4, #8 ; Was this "." the first character?
beq %F87 ; Yes - Assume this is a dir change
mov r3, #' ' ; Load a <space> into r1
strb r3, [r2], #1 ; Save character to the buffer
subs r4, r4, #1 ; Decrement the byte counter
bne %B83 ; Move in spaces until 8 bytes are used
b %F85 ; Get the extension data
;
; mov input byte to buffer
;
84 strb r3, [r2], #1 ; store byte into output buffer
subs r4, r4, #1 ; Decrement the byte count
bne %B82 ; Get the next byte if count not zero
ldrb r3, [r1], #1 ; Get the next byte
cmp r3, #0 ; End of the input string?
beq %F87 ; YES - go here
;
; Take care of the file extension
;
85 mov r4, #3 ; File extension byte count
86 ldrb r3, [r1], #1 ; Get a byte
cmp r3, #0 ; Is this a null byte?
moveq r3, #' ' ; Yes - replace with a <space>
beq %F88 ; ...and branch here
strb r3, [r2], #1 ; No - Store this byte in output string
subs r4, r4, #1 ; Decrment byte count
bne %B86 ; Loop until the file extension is done
strb r4, [r2] ; NULL the last byte of this buffer
b %F89 ; ...and take this exit path
;
; Code branches here if a "." was detected as the first byte in the name
; or when the end of the input string is detected before a "." is found
; in the input string.
;
87 add r4, r4, #3 ; Bump remaining byte counter by 3
strb r3, [r2], #1 ; store "." byte into output buffer
sub r4, r4, #1 ; Decrement the byte count
ldrb r3, [r1], #1 ; Fetch the next byte
cmp r3, #'.' ; Is this byte also a "."?
movne r3, #' ' ; No - change to a space
strb r3, [r2], #1 ; store byte into output buffer
sub r4, r4, #1 ; Decrement the byte count
mov r3, #' ' ; Make r3 a space (it MAY already be)
88 strb r3, [r2], #1 ; store byte into output buffer
subs r4, r4, #1 ; Decrement the byte count
bne %B88 ; Loop until name is filled
mov r3, #0 ; NULL the last byte
strb r3, [r2], #1 ; store NULL byte into output buffer
89 ldmfd sp!, {r1-r4, pc} ; Restore registers, return to caller
ENDFUNC
;
;*******************************************************************************
;
; *********************
; * *
; * BBU_FAT_NFRE_CLUS * ***** CODE UNDER DEVELOPMENT *****
; * * ***** NOT READY FOR USE *****
; *********************
;
; Given a starting cluster number, this subroutine returns the next
; available free cluster number. In addition, this subroutine can be
; instructed to update the FAT table (the buffer version only for now) by
; updating the the input cluster number with the pointer to the next
; free cluster (which is returned by this subroutine)
;
; PARAMETER PASSING:
;
; INPUT:
;
; r0 - Cluster number to start the search from. If this is the start
; of a search for free clusters, it is suggested the search start
; at cluster #2. If serching for the next aviable free cluster
; in a linked list, the user should provide the last free
; cluster number that this routine found. If it 31 is set on the
; input cluster number, this cluster number is updated with the
; next free cluster number. If bits 31 and 30 are set, the input
; cluster number is marked with the End Of File <EOF> marker.
;
; NOTE: As of 9-Aug-07 the bit 31:30 update code is NOT in place
;
; OUTPUT:
;
; r0 = The next free cluster number
;
;
BBU_FAT_NFRE_CLUS FUNCTION
stmfd sp!, {r1-r7, lr} ; Save registers and link on the stack
mov r7, r0 ; Save copy of the start cluster
bic r0, r0, #0xF0000000 ; Make sure bits 31:28 are clear
;
; First calculate the offset into the FAT where the next cluster data
; is saved. NOTE: this offset is calculated in NIBBLES.
;
ldr r1, =BBU_FAT_TYPE ; Address where FAT type is saved
ldrb r5, [r1] ; Get the FAT type
mov r1, #0 ; Set default nibble multiplier to zero
cmp r5, #32 ; FAT32?
moveq r1, #8 ; Yes - multiply by 8
cmp r5, #16 ; FAT16?
moveq r1, #4 ; Yes - multiply by 4
cmp r5, #12 ; FAT12?
moveq r1, #3 ; Yes - multiply by 3
mul r3, r0, r1 ; Calculate the NIBBLE offset into FAT
;
; Check to see if this offset is within the range of FAT data already in
; memory. If not, a new area of the FAT will have to be read in.
;
ldr r0, =BBU_FAT_OFFSET ; Buffer offset base is saved here
ldr r4, [r0] ; Get FAT offset base for current buffer
mov r0, r3, LSR #1 ; Load desired byte offset into r0
cmp r0, r4 ; Compare desired offset to base offset
bmi %F93 ; Desired offset .LT. base - update FAT
mov r2, #BBU_FAT_BUFSZ ; # of sectors used for FAT BUFFER
mov r2, r2, LSL #9 ; Multiply by 512 (sector size)
add r2, r2, r4 ; r2 = End of FAT table (by offset)
cmp r0, r2 ; Is the desired offset in memory?
bmi %F94 ; Yes - skip over the following
;
; The desired FAT entry is not in BBU's internal buffer. Read a new
; segment of the FAT into BBU's buffer.
;
93 bl BBU_LOAD_FAT ; Load the desired FAT segment
ldr r6, =BBU_FAT_OFFSET ; New FAT offset is saved here
ldr r4, [r6] ; Get a copy of it
94 ldr r2, =BBU_FAT_1 ; Start of the FAT in BBU's buffer
mov r4, r4, LSL #1 ; Generate the nibble offset into FAT
sub r3, r3, r4 ; Subtract out any offset into this FAT
cmp r5, #12 ; Is this a FAT12 structure?
bne %F95 ; No - assume FAT16 or FAT32
;
; Code continues here if the file structure is FAT12
;
mov r1, r3, LSR #1 ; Generate byte offset into FAT
ldrb r4, [r2, r1] ; Load this byte into r4
add r1, r1, #1 ; point to the next byte
ldrb r5, [r2, r1] ; Load the next byte into r5
ands r3, r3, #1 ; Check for a nibble offset
movne r4, r4, LSR #4 ; If nibble offset valid, LSR low byte
movne r5, r5, LSL #4 ; ...and LSL high byte 4 bits left
moveq r5, r5, LSL #8 ; If nibble byte not set, LSL 8 bits
andeq r5, r5, #0xF00 ; ...and only save bits 11:8
orr r0, r4, r5 ; Generate next cluster offset to use
b %F99 ; and take the exit path
;
; Code continues here if the file structure is FAT16 or FAT32
; Start with the user supplied cluster number and search forward
; until the next free cluster is found.
;
95 mov r1, r3, LSR #1 ; Generate byte offset into FAT
ldr r4, =(BBU_FAT_DIR - BBU_FAT_1) ; Size of FAT table
cmp r5, #16 ; Is this a FAT16 structure?
96 ldreqh r0, [r2, r1] ; Load the 16 bit cluster number into r0
ldrne r0, [r2, r1] ; Load the 32 bit cluster number into r0
bic r0, r0, #0xF0000000 ; Insure upper 4 bits are clear
cmp r0, #0 ; Is this an empty cluster?
beq %F98 ; YES - Take this way out
add r7, r7, #1 ; No - increment the cluster number
cmp r5, #16 ; Is this table FAT16 or FAT32?
addeq r1, r1, #2 ; FAT16 - add an offset of 2
addne r1, r1, #4 ; FAT32 - add an offset of 4
cmp r4, r1 ; Is r1 past the end of the buffer?
blt %B96 ; YES - Test the next cluster number
;
; Code needs to be added here to read in the next portion of the FAT table
;
98 bic r0, r7, #0xF0000000 ; Return this cluster number
;
99 ldmfd sp!, {r1-r7, pc} ; Restore registers, return to caller
ENDFUNC
;
; ******************
; ** **
; ** LITERAL POOL ** LOCAL DATA STORAGE
; ** **
; ******************
;
LTORG
;
; Buffer areas: One for FAT and one for directory information
; Six sectors worth of space is allocated for each buffer
;
BBU_FAT_1 SPACE (6 * 0x200) ; Reserve 3kB area for FAT table
BBU_FAT_DIR SPACE (8 * 0x200) ; Reserve 4kB area for directory data
BBU_FAT_DIR_END DCD 0 ; Enforces a marked end to the directory
;
; FAT related messages
;
BBU_MONTH DCB "JanFebMarAprMayJunJulAugSepOctNovDec"
BBU_FAT_SUBD DCB " <DIR>",0xD,0xA,0
BBU_DIR_TOT DCB 0xA," Total of ",0
BBU_DIR_BYT DCB " bytes in ",0
BBU_DIR_FIL DCB " files.",0xD,0xA,0xA,0
BBU_GEN_DRF DCB "bbu-->ERROR! - Failed to read from device!",0xD,0xA
DCB 0xA,0
;
;================ MISC DATA SAVED BELOW ========================================
;
; The following area keeps data about the currently active volume for
; reference by the subroutines in this file.
;
BBU_FAT_TYPE DCB 0 ; Contains 12, 16 or 32 (0 if not initialized)
BBU_SEC_CLUS DCB 0 ; Sectors per cluster
ALIGN 2
BBU_BYTE_SEC DCW 0 ; Bytes per sector
BBU_RES_SEC DCW 0 ; Reserved Sector Count
BBU_ROOT_DIRE DCW 0 ; Max root directory entry count
BBU_ROOT_SIZE DCW 0 ; Root directory size in sectors
ALIGN 4
BBU_FD_NAME DCD 0,0,0 ; Space for formatted file/directory name
BBU_SEC_FAT DCD 0 ; Sectors per FAT
BBU_TOT_SEC DCD 0 ; Total sector count
BBU_ROOT_SECT DCD 0 ; Root directory sector number
BBU_CLUSZ_SEC DCD 0 ; Effective sector number for cluster #0
BBU_FAT_OFFSET DCD 0 ; Starting offset into FAT of BBU_FAT_1
BBU_DIR_START DCD 0 ; Sarting sector # for the current directory
BBU_DIR_CURRE DCD 0 ; Current sector # for the current directory
BBU_VOL_SLBA DCD 0 ; Starting Logical Block Address
BBU_DIR_SECT SPACE (65 * 4) ; Current directory sectors list - 64 sectors!
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -