📄 bbu_fat.s
字号:
mov r2, r0 ; Copy offset value to r2
mov r3, #BBU_DIR_BUFSZ ; Maximum number of sectors to read
ldr r4, =BBU_DIR_SECT ; Directory sector table address
ldr r5, =BBU_FAT_DIR ; Address of directory buffer area
;
; Loop to read mutiple sectors into memory
; NOTE: Other routines branch to this code!
;
22 ldr r0, [r4, r2] ; Load sector number into r0
cmp r0, #0 ; End of the table?
moveq r0, #0xFF ; Yes - indicate error
beq %F24 ; Yes - take this exit path
mov r1, r5 ; Address to be written to
bl BBU_MMC_Read ; Read from MMC
cmp r0, #0xFF ; Did the read fail?
beq %F23 ; Oooops! It did, Inform the user
add r2, r2, #4 ; Update pointer into table
add r5, r5, #0x200 ; Update destination address
subs r3, r3, #1 ; Decrement maximum sector count to read
bne %B22 ; Loop if room for more in the buffer
str r0, [r5] ; Save this value in the buffer
mov r0, r2 ; Return new offset to the caller
b %F24 ; take the exit path
;
; Read failure
;
23 ldr r0, =BBU_GEN_DRF ; Read failed message
bl BBU_putstr ; Output the message
mov r0, #0xFF ; Set error return value
24 ldmfd sp!, {r1-r5, pc} ; Restore registers, return to caller
ENDFUNC
;
;*******************************************************************************
;
; ****************
; * *
; * BBU_DISP_DIR * Display Directory
; * *
; ****************
;
; For now this code displays a directory listing of the data loaded into
; BBU_FAT_DIR in the order in which the data appears in the directory.
;
; NOTE: This code does not support long files names since adding this
; feature would require royalties to be paid to Microsoft.
;
; PARAMETER PASSING:
;
; INPUT:
;
; r0 - currently not used
;
; OUTPUT:
;
; r0 = currently not used
;
;
BBU_DISP_DIR FUNCTION
stmfd sp!, {r1-r6, lr} ; Save registers and link on the stack
mov r0, #0 ; Point to the start of the directory
bl BBU_LOAD_DIR ; Load the first buffer's worth
cmp r0, #0xFF ; Error?
beq %F49 ; Yes - just exit
mov r6, r0 ; Save retured offset in r6 for later
bl BBU_crlf ; New line
mov r4, #0 ; R4 is used to count # of files
mov r5, #0 ; R5 is used for total byte count
ldr r2, =BBU_FAT_DIR ; Pointer to directory information
;
; Evaluate the next entry in the directory - first find out, on a loop
; back to this point, if r2 went past the end of the directory buffer
; and if so, read in another buffer's worth of the directory.
;
30 ldr r3, =BBU_FAT_DIR_END ; End of the buffer in BBU
cmp r2, r3 ; Is r2 equal to this value?
bne %F32 ; No - Check this dir entry
;
; End of directory in buffer reached. Read in another chunk of the
; directory.
;
mov r0, r6 ; Load next sector table offset into r0
cmp r0, #0 ; Is this value =0?
beq %F39 ; Yes - diplay directory totals
bl BBU_LOAD_DIR ; Load the next buffer's worth of dir
mov r6, r0 ; Save updated pointer
cmp r0, #0xFF ; Error?
beq %F49 ; Yes - take this exit path
ldr r2, =BBU_FAT_DIR ; Reset pointer to directory information
;
; Code continues here if r2 doesn't point past the end of the directory.
;
32 ldrb r3, [r2, #0xB] ; Get the file attributes byte
cmp r3, #0xF ; Is this part of a long file name?
addeq r2, r2, #0x20 ; Yes - point to the next file entry
beq %B30 ; Get the next entry
ldrb r3, [r2] ; Get 1st byte of file name
cmp r3, #0xE5 ; Is this a deleted file entry?
addeq r2, r2, #0x20 ; Yes - point to the next file entry
beq %B30 ; Get the next entry
;
; An entry that is not part of a long file name was found.
;
ldrb r0, [r2] ; Fetch the first byte of the file name
cmp r0, #0 ; Is this the end of the directory?
beq %F39 ; YES - Display totals
;
; Display file name in 8.3 format
;
mov r3, #8 ; Set up a byte counter
34 ldrb r0, [r2], #1 ; Fetch a byte
bl BBU_putchr ; Send to the UART
subs r3, r3, #1 ; Decrement byte count
bne %B34 ; Loop until done
mov r0, #'.' ; Load a "." into r0
bl BBU_putchr ; Send to the UART
mov r3, #3 ; Set up a byte counter
35 ldrb r0, [r2], #1 ; Fetch a byte
bl BBU_putchr ; Send to the UART
subs r3, r3, #1 ; Decrement byte count
bne %B35 ; Loop until done
sub r2, r2, #0xB ; Reset r2 to start of file entry
ldrb r1, [r2, #0xB] ; Read the file attributes byte again
ands r1, r1, #0x10 ; Is this a subdirectory?
beq %F37 ; No - assume it's a file entry
;
; Subdirectory entry found - make this indication in the output listing
;
ldr r0, =BBU_FAT_SUBD ; User message
bl BBU_putstr ; Output this string
add r2, r2, #0x20 ; Point to next file entry in directory
b %B30 ; examine the next entry in the buffer
;
; Display file size
;
37 ldr r0, [r2, #0x1C] ; Fetch file size
add r5, r5, r0 ; Add this to the directory total
add r4, r4, #1 ; Bump the file count while we're at it
mov r1, #0x30 ; Format for the output
bl BBU_UDecToAscii ; Output this value
mov r0, #' ' ; <space>
bl BBU_putchr ; Output the space
mov r0, #' ' ; <space>
bl BBU_putchr ; Output the space
;
; Display file date
;
ldrh r3, [r2, #0x10] ; Fetch the date parameters
and r0, r3, #0x1F ; Get day of month
mov r1, #2 ; Force 2 digit output
bl BBU_UDecToAscii ; Output this value
mov r0, #'-' ; Output "-"
bl BBU_putchr ; send to UART
and r1, r3, #0x1E0 ; Extract month data
mov r1, r1, LSR #5 ; Right justify
sub r1, r1, #1 ; Subtract 1 (so JAN = 0)
mov r0, #3 ; Set up multiplier
mul r1, r1, r0 ; R1 = offset to month
ldr r0, =BBU_MONTH ; Month data located here
add r1, r1, r0 ; R1 points to month data
ldrb r0, [r1], #1 ; Get month byte
bl BBU_putchr ; Output the character
ldrb r0, [r1], #1 ; Get month byte
bl BBU_putchr ; Output the character
ldrb r0, [r1] ; Get month byte
bl BBU_putchr ; Output the character
mov r0, #'-' ; Output "-"
bl BBU_putchr ; send to UART
ldr r0, =1980 ; Load year base into r0
mov r3, r3, LSR #9 ; Right justify year offset in r3
add r0, r0, r3 ; Year is now in r0
mov r1, #0 ; Regular format
bl BBU_UDecToAscii ; Output the year
mov r0, #' ' ; <space>
bl BBU_putchr ; Output the space
mov r0, #' ' ; <space>
bl BBU_putchr ; Output the space
;
; Display file time
;
ldrh r3, [r2, #0xE] ; Get the file creation time
mov r0, r3, LSR #11 ; Copy hours into r0
mov r1, #2 ; Force 2 decimal places
bl BBU_UDecToAscii ; Output the hour
mov r0, #':' ; ":"
bl BBU_putchr ; Output the ":"
mov r0, r3, LSR #5 ; Copy min to r0
and r0, r0, #0x3F ; Mask out the hours data
bl BBU_UDecToAscii ; Output the min
mov r0, #':' ; ":"
bl BBU_putchr ; Output the ":"
and r0, r3, #0x1F ; Get seconds/2
mov r0, r0, LSL #1 ; Convert to seconds
bl BBU_UDecToAscii ; Output the seconds
bl BBU_crlf ; New line
add r2, r2, #0x20 ; Point to next file entry
b %B30 ; Search for another file name
;
; Display directory totals
;
39 ldr r0, =BBU_DIR_TOT ; Totals prefix message
bl BBU_putstr ; Output this message
mov r0, r5 ; Copy byte total to r0
mov r1, #0x20 ; Format for the output
bl BBU_UDecToAscii ; Output this value
ldr r0, =BBU_DIR_BYT ; bytes message
bl BBU_putstr ; Output this message
mov r0, r4 ; Move file count into r0
mov r1, #0 ; Basic output format
bl BBU_UDecToAscii ; Output this value
ldr r0, =BBU_DIR_FIL ; files message
bl BBU_putstr ; Output this message
49 ldmfd sp!, {r1-r6, pc} ; Restore registers, return to caller
ENDFUNC
;
;*******************************************************************************
;
; *****************
; * *
; * BBU_FIND_FILE * Find a file in the current directory
; * * Also used to delete a file entry from the
; ***************** directory.
;
; CODE UNDER DEVELOPMENT
;
; PARAMETER PASSING:
;
; INPUT:
;
; r0 = anything other than 0x454C4544 (ASCII "DELE") will just look for
; the fille name and set up the output value as indicated below.
; if r0 = 0x454C4544 the file entry is deleted (if found).
; The file name is picked up name from BBU_FD_NAME as saved by
; the BBU_NAME_83 routine.
;
; OUTPUT:
;
; r0 = 1 if no match found. (0 is used to indicate the root directory)
; r0 = the first cluster number of the file if the file was found.
;
;
BBU_FIND_FILE FUNCTION
stmfd sp!, {r1-r6, lr} ; Save registers and link on the stack
mov lr, r0 ; Copy user parameter to the link reg
mov r0, #0 ; Point to the starting sector of dir
50 bl BBU_LOAD_DIR ; Load the start of the directory
cmp r0, #0xFF ; Error?
beq %F59 ; Yes - just exit
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -