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

📄 boot.s

📁 GBA游戏程序
💻 S
📖 第 1 页 / 共 2 页
字号:
        bl      CopyMem
CIW0Skip:

@ Copy external work ram (ewram section) from LMA to VMA (ROM to RAM)
        ldr     r1,=__ewram_lma
        ldr     r2,=__ewram_start
        ldr     r4,=__ewram_end
        bl      CopyMemChk

@ Copy external work ram overlay 0 (ewram0 section) from LMA to VMA (ROM to RAM)
        ldr     r2,=__load_stop_ewram0
        ldr     r1,=__load_start_ewram0
        sub     r3,r2,r1         @ Is there any data to copy?
        beq     CEW0Skip         @ no

        ldr     r2,=__ewram_overlay_start
        bl      CopyMem
CEW0Skip:

@ Jump to user code

        mov     r0,#0            @ int argc
        mov     r1,#0            @ char *argv[]

        ldr     r3,=start_vector
        mov     lr,r3            @ Set start_vector as return address

.ifdef __CPPSupport
        ldr     r3,=main
.else
        ldr     r3,=AgbMain
.endif
        bx      r3


    .GLOBAL     __FarFunction,__FarProcedure
    .THUMB_FUNC
__FarFunction:
    .THUMB_FUNC
__FarProcedure:
        bx      r0
        nop
        nop          @ This nop is here to allow unmapped memory to be used as
                     @ as a delay of almost 1 sec with a 1 cycle resolution.
                     @ Read this for technical info:
                     @  http://www.devrs.com/gba/files/gbadevfaqs.php#RepeatUses

@ Clear memory to 0x00 if length != 0
@ r0 = Start Address
@ r1 = Length

ClearMem:
        cmp     r1,#0           @ Is length zero?
        beq     ClearMX         @ yes, exit

.ifdef __DMACopyClear
        ldr     r2,reg_base
        lsr     r1,#2           @ r1 = (length/4) & 0xffff

        adr     r3,fill_val
        str     r3,[r2,#0x4]    @ Set source address (fill value)
        str     r0,[r2,#0x8]    @ Set destination address (fill dest address)
        strh    r1,[r2,#0xc]    @ Set DMA length
        ldr     r1,=0x8500      @ dma_clrb
        strh    r1,[r2,#0xe]    @ Start DMA
.else
        mov     r2,#0
ClrLoop:
        stmia   r0!,{r2}
        sub     r1,#4
        bne     ClrLoop
.endif
ClearMX:
        bx      lr

@ Copy memory if length != 0
@ r1 = Source Address
@ r2 = Dest Address
@ r4 = Dest Address + Length

CopyMemChk:
        sub     r3,r4,r2         @ Is there any data to copy?
        beq     CIDExit          @ no

@ Copy memory
@ r1 = Source Address
@ r2 = Dest Address
@ r3 = Length

CopyMem:
.ifdef __DMACopyClear
        ldr     r0,reg_base
        lsr     r3,#2           @ r3 = (length/4) & 0xffff

        str     r1,[r0,#0x4]    @ Set source address
        str     r2,[r0,#0x8]    @ Set destination address
        strh    r3,[r0,#0xc]    @ Set DMA length
        ldr     r3,=0x8400      @ dma_copy
        strh    r3,[r0,#0xe]    @ Start DMA
.else
CIDLoop:
        ldmia   r1!,{r0}
        stmia   r2!,{r0}
        sub     r3,#4
        bne     CIDLoop
.endif
CIDExit:
If_Undefined_Reference__rename_main_or_AgbMain_to_each_other_in_your_C_file:
        bx      lr

        .ALIGN

.ifdef __DMACopyClear
fill_val: .word  0
reg_base: .word  0x040000d0
.endif

        .ALIGN
        .POOL

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@                  Interrupt Processing                  @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

 .ifdef __ISRinIWRAM
    .SECTION    .iwram
 .endif

    .EXTERN     IntrTable
    .EXTERN     InterruptProcess
    .GLOBAL     intr_main
    .ALIGN
    .ARM

@ NOTE: Ifyou copy the following code (start: intr_main -
@ end: intr_main_end) to internal WRAM then do not forget
@ to copy everything between these two labels. The .POOL
@ data must be copied since it is used by intr_main.

@ NOTE2: If __ISRinIWRAM is defined then the copy to
@ IWRAM is done automatically for you.

 .ifdef __InterruptSupport

  .ifdef __FastInterrupts
intr_main:
        ldr     r0,=InterruptProcess
        bx      r0
  .endif

  .ifdef __SingleInterrupts
intr_main:
                                         @ Single interrupts support
        mov     r3, #0x4000000           @ REG_BASE
        ldr     r2, [r3,#0x200]!         @ Read REG_IE
        and     r1, r2, r2, lsr #16      @ r1 = IE & IF
        ldr     r2, =IntrTable

        ands    r0, r1, #1               @ V-Blank Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #2               @ H-Blank Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #4               @ V Counter Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #8               @ Timer 0 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x10            @ Timer 1 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x20            @ Timer 2 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x40            @ Timer 3 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x80            @ Serial Communication Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x100           @ DMA0 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x200           @ DMA1 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x400           @ DMA2 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x800           @ DMA3 Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x1000          @ Key Interrupt
        bne     jump_intr
        add     r2, r2, #4
        ands    r0, r1, #0x2000          @ Cart Interrupt

   .ifdef __HandleCartInterrupt
        strneb  r0, [r3, #0x84 - 0x200]  @ Stop sound if cart removed (REG_SOUNDCNT_X)
loop:   bne     loop                     @ Infinite loop if cart removed
   .endif

jump_intr:
        strh    r0, [r3, #2]             @ IF Clear
        ldr     r0, [r2]                 @ Jump to user IRQ process
        bx      r0
  .endif

  .ifdef __MultipleInterrupts
intr_main:
                                         @ Multiple interrupts support
        mov     r2, #0x4000000           @ REG_BASE
        ldr     r3, [r2,#0x200]!         @ r2 = IE : r3 = IF|IE
        ldrh    r1, [r2, #0x8]           @ r1 = IME
        mrs     r0, spsr
        stmfd   sp!, {r0-r2,lr}          @ {spsr, IME, REG_IE, lr}  // IF|IE

        mov     r0, #1                   @ IME = 1 (To permit multiple interrupts if
                                         @ an interrupt occurs)
        strh    r0, [r2, #0x8]
        and     r1, r3, r3, lsr #16      @ r1 = IE & IF
        ldr     r12, =IntrTable

        ands    r0, r1, #1               @ V-blank interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #2               @ H-blank interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #4               @ V-counter interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #8               @ Timer 0 interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x10            @ Timer 1 interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x20            @ Timer 2 interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x40            @ Timer 3 interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x80            @ Serial Communication Interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x100           @ DMA 0 interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x200           @ DMA 1 interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x400           @ DMA 2 interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x800           @ DMA 3 interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x1000          @ Key interrupt
        bne     jump_intr
        add     r12,r12, #4
        ands    r0, r1, #0x2000          @ Cart interrupt

   .ifdef __HandleCartInterrupt
        strneb  r0, [r2, #0x84 - 0x200]  @ Stop sound if cart removed (REG_SOUNDCNT_X)
loop:   bne     loop                     @ Infinite loop if cart removed
   .endif

jump_intr:
        strh    r0, [r2, #2]             @ Clear IF

@ Enable multiple interrupts & switch to system
@ mode if __SwitchToUserStack is defined.

        mrs     r3, cpsr
   .ifdef __SwitchToUserStack
        bic     r3, r3, #0xdf            @ \__
        orr     r3, r3, #0x1f            @ /  --> Enable IRQ & FIQ. Set CPU mode to System.
   .else
        bic     r3, r3, #0xc0            @ Enable IRQ & FIQ
   .endif
        msr     cpsr, r3

        ldr     r0, [r12]

        stmfd   sp!, {lr}
        adr     lr, IntrRet
        bx      r0
IntrRet:
        ldmfd   sp!, {lr}

@ Disable multiple interrupts & switch to IRQ Mode
@ if __SwitchToUserStack is defined.

        mrs     r3, cpsr
   .ifdef __SwitchToUserStack
        bic     r3, r3, #0xdf            @ \__
        orr     r3, r3, #0x92            @ /  --> Disable IRQ. Enable FIQ. Set CPU mode to IRQ.
   .else
        orr     r3, r3, #0x80            @ Disable IRQ.
   .endif
        msr     cpsr, r3

        ldmfd   sp!, {r0-r2,lr}          @ {spsr, IME, REG_IE, lr}  //IF|IE
@        strh    r3,  [r2]                @ set IE
        strh    r1,  [r2, #0x8]          @ restore REG_IME
        msr     spsr, r0                 @ restore spsr
        bx      lr

  .endif

    .ALIGN
    .POOL               @ Ifyou copy the intr_main routine, above, to internal
                        @ RAM then copy the pool data as well because IntrTable
                        @ address is stored here. Use intr_main_end as last address+1.
intr_main_end:
 .endif

    .ALIGN
    .POOL


    .END


⌨️ 快捷键说明

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