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

📄 bbu_fat.s

📁 关于PXA310的最小系统的程序,初级学习阶段会有所帮助,汇编语言编写的
💻 S
📖 第 1 页 / 共 5 页
字号:
;       In that case BBU assumes this sector only contains partition information
;       and will attempt to read in the boot record for the first partition
;       on this volume.
;
;       The quick and easy way to get to the boot record for the first partition
;       is to simply get the starting Logical Block Address (LBA) for the first
;       partition which is the 4 bytes starting at offset 0x1C6 and read in that
;       sector from the volume.
;       
7       add     r0,     r0,     #0x100  ; Add an offset into the sector
        ldrh    r1,     [r0, #0xC6]     ; Get bottom 2 bytes of starting LBA
        ldrh    r2,     [r0, #0xC8]     ; Get top 2 bytes of starting LBA
        mov     r2,     r2,     LSL #16 ; Move to the top 16 bits
        orr     r0,     r1,     r2      ; Generate the boot sector number  in r0
        cmp     r0,     #0              ; Is this sector zero?
        moveq   r0,     #0xFF           ; Yes - load error code into r0
        beq     %F9                     ; ...and take the exit path
        ldr     r2,     =BBU_VOL_SLBA   ; Starting Logical Block Address
        str     r0,     [r2]            ; Save this value
        b       %B2                     ; Otherwise read this sector & try again
;
;       Exit path - do final calculation for cluster zero sector number
;
9       ldr     r2,     =BBU_VOL_SLBA   ; Starting Logical Block Address
        ldr     r3,     [r2]            ; Get this value
        add     r1,     r1,     r3      ; r1 now equals sector # of cluster zero
        ldr     r2,     =BBU_CLUSZ_SEC  ; Address of Cluster Zero Sector #
        str     r1,     [r2]            ; Save this sector data
        mov     r0,     r5              ; Return total byte count in r0
        ldmfd   sp!,    {r1-r5, pc}     ; Restore registers, return to caller

        ENDFUNC
;
;*******************************************************************************
;
;       *********************
;       *                   * 
;       * BBU_FAT_NEXT_CLUS * 
;       *                   *
;       *********************
;
;       Given a cluster number, this subroutine returns the next cluster to be
;       read for the current file.      
;
; PARAMETER PASSING:
;
;       INPUT:
;
;         r0 - The current cluster number
;
;       OUTPUT:
;
;         r0 = The next cluster to read from.
;
;
BBU_FAT_NEXT_CLUS       FUNCTION

        stmfd   sp!,    {r1-r6, lr}     ; Save registers and link on the stack
;
;       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     %F63                    ; 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     %F64                    ; 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.
;
63      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

64      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     %F65                    ; 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       %F69                    ; and take the exit path
;
;       Code continues here if the file structure is FAT16 or FAT32
;
65      mov     r1,     r3,     LSR #1  ; Generate byte offset into FAT
        cmp     r5,     #16             ; Is this a FAT16 structure?
        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
;
69      ldmfd   sp!,    {r1-r6, pc}     ; Restore registers, return to caller
        ENDFUNC
;
;*******************************************************************************
;
;       ****************
;       *              * 
;       * BBU_LOAD_FAT *        Load a section of the FAT into memory
;       *              *
;       ****************       
;       
;
; PARAMETER PASSING:
;
;       INPUT:
;
;         r0 - Byte OFFSET into FAT table to be used as the starting point for
;              the load. A value of 0x0 starts the load at the first sector of
;              the FAT. As currently written 4 sectors (2kB) are of the FAT are
;              loaded into memory. NOTE: the code always reads in 2kB which
;              means that is is possible to read past the end of the FAT if a
;              high offset value is entered.
;
;       OUTPUT:
;
;         r0 = 0xFF If the read failed, otherwise non-useful data is returned
;
; NOTE ABOUT BBU'S FAT TABLE BUFFER:
;
;       FAT tables should start on a 3 sector boundry and be a multiple of 3
;       sectors in length. The reason for this is to make it easier to deal
;       with FAT12 file structures which pack 2-1/3 cluster entries per 32-bit
;       doubleword or 341.33 per 512 BYTE sector; hence reading in 3 sectors
;       results in 1024 complete FAT12 clusters and avoids having to deal with
;       buffer boundry issues. If the volume is using FAT16 or FAT32 the code
;       does not have to be concerned about the buffer starting with a sector
;       that is evenly divisable by 3.
;
;
BBU_LOAD_FAT       FUNCTION

        stmfd   sp!,    {r1-r5, lr}     ; Save registers and link on the stack
;
;       Figure out where the FAT starts by examining the data the has been saved
;       from decoding the volume's boot block.
;
        mov     r3,     r0              ; Save a copy of r0
        ldr     r1,     =BBU_RES_SEC    ; Address of reserved sector count
        ldrh    r2,     [r1]            ; FAT starts at sector offset in r2
        ldr     r1,     =BBU_VOL_SLBA   ; Address of Starting Logical Blk Addrs
        ldr     r5,     [r1]            ; Fetch this value
        add     r2,     r2,     r5      ; Sector where FAT starts is in r2
        mov     r1,     r0,     LSR #9  ; r1 = requested sector offset
        ldr     r5,     =BBU_FAT_TYPE   ; Where the FAT type is saved
        ldrb    r4,     [r5]            ; Get the FAT type
        cmp     r4,     #12             ; is it FAT12?
        bne     %F9                     ; No (thank goodness!) - skip some code
;
;       The sector offset value in r1 should be evenly divisible by 3 in order
;       to make it easier to deal with FAT12 tables. If the value is not
;       divisible by 3, decrement the value until it is. This number shouldn't
;       be very large so it's faster to use repetitive subtraction than to use
;       BBU's divide routine.
;
        cmp     r1,     #0              ; Is r1 =0?
        beq     %F9                     ; Yes - skip over the following
6       mov     r5,     r1              ; Copy starting sector to r5
7       subs    r5,     r5,     #3      ; Subtract 3
        beq     %F9                     ; If result was 0, r1 is divisable by 3
        bgt     %B7                     ; If the result was .GT. 0 sub 3 again
        subs    r1,     r1,     #1      ; Negative result, decrement r1
        beq     %F9                     ; If result was 0, r1 is divisable by 3
        b       %B6                     ; ...otherwise see if this divides by 3
;
;       FAT16, FAT32 and FAT12 (sector offset divisable by 3) continues here
;
9       mov     r4,     r1,     LSL #9  ; Offset (in bytes) where FAT starts
        ldr     r5,     =BBU_FAT_OFFSET ; We will want to save a copy of this
        str     r4,     [r5]            ; Save the data here for future use.
        add     r4,     r1,     r2      ; Calculate starting sector number
        ldr     r5,     =BBU_FAT_1      ; Address where data goes
        mov     r3,     #BBU_FAT_BUFSZ  ; Number of sectors to read

10      mov     r0,     r4              ; Copy sector # to r0
        mov     r1,     r5              ; Address to be written to
        bl      BBU_MMC_Read            ; Read from MMC
        cmp     r0,     #0xFF           ; Did the read fail?
        beq     %F12                    ; Oooops! It did, Inform the user
        subs    r3,     r3,     #1      ; Read another sector?
        beq     %F14                    ; No - take the exit path
        add     r4,     r4,     #1      ; Request the next sector
        add     r5,     r5,     #0x200  ; Update the address
        b       %B10                    ; Read another sector
;
;       Read failure
;
12      ldr     r0,     =BBU_GEN_DRF    ; Read failed message
        bl      BBU_putstr              ; Output the message
        mov     r0,     #0xFF           ; Set error return value

14      ldmfd   sp!,    {r1-r5, pc}     ; Restore registers, return to caller
        ENDFUNC
;
;*******************************************************************************
;
;       ****************
;       *              * 
;       * BBU_LOAD_DIR *        Load directory segment into memory
;       *              *
;       ****************       
;       
;
; PARAMETER PASSING:
;
;       INPUT:
;
;         r0 - Starting offset into sector table generated by the BBU_SET_DIR
;              subroutine. Zero means loads the start of the directory. Each
;              succeding sector is an index of 4 bytes into the table.
;              Typically sucessive calls to this routine would be offsets of
;              four times the value of BBU_DIR_BUFSZ to work through the
;              directory entries.
;
;       OUTPUT:
;
;         r0 = 0xFF If theree was a read failure.
;         r0 = 0x00 If the end of the directory sector table was reached.
;         otherwise r0 = offset to the next entry into the sector table.
;
;
BBU_LOAD_DIR       FUNCTION

        stmfd   sp!,    {r1-r5, lr}     ; Save registers and link on the stack

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -