?? boot.s
字號(hào):
IMPORT |Image$$RO$$Base| ; Address of the start of the RO output section.
IMPORT |Image$$RO$$Limit| ; Address of the first byte beyond the end of the RO output section.
IMPORT |Image$$RW$$Base| ; Address of the start of the RW output section.
IMPORT |Image$$RW$$Limit| ; Address of the byte beyond the end of the ZI output section. (The choice of the end of the ZI region rather than the end of the RW region is to maintain compatibility with legacy code.)
IMPORT |Image$$ZI$$Base| ; Address of the start of the ZI output section.
IMPORT |Image$$ZI$$Limit| ; Address of the byte beyond the end of the ZI output section.
IMPORT main ; THE MAIN ENTRY OF MON PROGRAM
EWRAM_START EQU 0x02000000 ;CPU External Working RAM
EWRAM_END EQU 0x02040000-1 ;(256 Kbytes)
EWRAM_LEN EQU EWRAM_END - EWRAM_START+1
IWRAM_START EQU 0x03000000 ;CPU Internal Working RAM
IWRAM_END EQU 0x03008000-1 ;(32 Kbytes)
IWRAM_LEN EQU IWRAM_END - IWRAM_START + 1
EWROM_START EQU 0x08000000
ARM_USR_SP EQU 0x03007F00 ; GBA USR stack adress
ARM_IRQ_SP EQU 0x03007FA0 ; GBA IRQ stack adress
ARM_SVC_SP EQU 0x03007FE0 ; GBA SVC stack adress
INTR_VECTOR_ADDR EQU 0x3008000 - 4;
ARM_USE_MODE EQU 0X10 ; Cpu_Mode_USR EQU 0x10
ARM_FIQ_MODE EQU 0X11
ARM_IRQ_MODE EQU 0X12 ; Cpu_Mode_IRQ EQU 0x12
ARM_SVC_MODE EQU 0X13 ; Cpu_Mode_SVC EQU 0x13
ARM_ABORT_MODE EQU 0X17
ARM_UNDEF_MODE EQU 0X1B
ARM_MODEMASK EQU 0X1F
ARM_NOINT EQU 0XC0
AREA INIT, CODE, READONLY
ENTRY
_start ; Start Vector
b rom_header_end
Nintendo_Logo
SPACE 156 ; Nintendo Logo Character Data (8000004h)
; Game Title (80000A0h)
DCB 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
DCB 0x00,0x00,0x00,0x00
;MultiBoot Game Code (80000ACh)
;ELSE is all zero
DCB "MB "
; Maker Code (80000B0h)
DCB 0x30,0x31
; Fixed Value (80000B2h)
DCB 0x96
; Main Unit Code (80000B3h)
DCB 0x00
; Device Type (80000B4h)
DCB 0x00
; Unused Data (7Byte) (80000B5h)
DCB 0x00,0x00,0x00,0x00,0x00,0x00,0x00
; Software Version No (80000BCh)
DCB 0x00
; Complement Check (80000BDh)
DCB 0xf0
; Checksum (80000BEh)
DCB 0x00,0x00
rom_header_end
b start_vector ; This branch must be here for proper
; positioning of the following header.
; DO NOT REMOVE IT.
;=====================================================================+
;
; The following reserved bytes are used if the code is compiled for
; multiboot mode. It does not hurt anything to leave this header in
; even if the code is not compiled for multiboot. The GBA BIOS will
; auto-patch the first two bytes with 0x03 and 0x01, respectively,
; before running any code if it is executed as multiboot.
;
; The following two bytes are included even for non-multiboot supporting
; builds to guarantee that any generic library code that depends on them
; will still be functional.
EXPORT BOOT_METHOD , SLAVE_NUMBER
BOOT_METHOD
DCB 0 ; boot method (0=ROM boot, 3=Multiplay boot)
SLAVE_NUMBER
DCB 0 ; slave # (1=slave#1, 2=slave#2, 3=slave#3)
DCB 0 ; reserved
DCB 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
DCD 0 ; reserved
;
;========================================================================+
;==================
; Reset ;
;==================
EXPORT start_vector
ALIGN
start_vector
mov r0, #ARM_IRQ_MODE:OR:0x80:OR:0x40 ; Disable interrupts
msr CPSR_c, r0 ; Enable IRQ mode
ldr r13, =ARM_IRQ_SP ; Setup IRQ stack pointer
mov r0, #ARM_SVC_MODE:OR:0x80:OR:0x40 ; Disable interrupts
msr CPSR_c, r0 ; Enable SVC mode
ldr r13, =ARM_SVC_SP ; Setup SVC stack pointer
; Make sure we are in ExWRAM
mov r0,pc ; NOW , we are runing in which space ?
cmp r0,#EWROM_START ; is it less then 0x08000000
bls SkipEWRAMClear ; if less , we are runing in a EWRAM
; if higher, we are runing in a pak ,so no need to do a copy.
; OK, my code is compiler for EWRAM but I run it in a GAMEPAK
; So we need to copy to ExWRAM.
ldr r3,=EWRAM_LEN
ldr r2,=EWRAM_START
mov r6,r2
ldr r1,=EWROM_START
bl CopyMem ; call CopyMem
; Jump to the ERAM to execute
bx r6
SkipEWRAMClear
ldr r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
ldr r1, =|Image$$RW$$Base| ; and RAM copy
ldr r3, =|Image$$ZI$$Base| ; Zero init base => top of initialized data
cmp r0, r1 ; Check that they are different
beq %F1
0 cmp r1, r3 ; Copy init data
ldrcc r2, [r0], #4
strcc r2, [r1], #4
bcc %B0
1 ldr r1, =|Image$$ZI$$Limit| ; Top of zero init segment
mov r2, #0
2 cmp r3, r1 ; Zero init
strcc r2, [r3], #4
bcc %B2
IMPORT OSISR
ldr r1, =INTR_VECTOR_ADDR ; Set Interrupt Address
ldr r0, =OSISR
str r0, [r1]
mov r0, #ARM_SVC_MODE:OR:0x40 ; Only IRQ enabled
msr CPSR_c, r0
mov r0, #ARM_USE_MODE:OR:0x40
msr CPSR_c, r0 ; Switch to USR mode
ldr sp, =ARM_USR_SP ; Setup USR stack pointer
bl main ; Now branch to start of C code
b .
b start_vector
;--------ClearMem----------------------+
; Clear memory to 0x00 if length != 0 |
; r0 = Start Address |
; r1 = Length |
;--------------------------------------+
ClearMem
mov r2,#3 ; These commands are used in cases where
add r1,r1,r2 ; the length is not a multiple of 4,
bic r1,r1,r2 ; even though it should be.
mov r2,#0
cmp r1,r2
beq ClearMX ; Length is zero so exit
ClrLoop
stmia r0!,{r2}
sub r1,r1,#4
cmp r1,#0
bne ClrLoop
ClearMX
bx lr ; ret
;---------end of ClearMem------------
;---------- Copy memory --------------+
; r1 = Source Address |
; r2 = Dest Address |
; r3 = Length |
;-------------------------------------+
CopyMem
mov r0,#3 ; These commands are used in cases where
add r3,r3,r0 ; the length is not a multiple of 4,
bic r3,r3,r0 ; even though it should be.
beq CIDExit ; Length is zero so exit
CIDLoop
ldmia r1!,{r0}
stmia r2!,{r0}
sub r3,r3,#4
cmp r3,#0
bne CIDLoop
CIDExit
bx lr ; ret
;--------- end of CopyMem ------------------
ALIGN
CODE32
;===================================================
; Interrupt Processing
;===================================================
IMPORT IntrTable
EXPORT irq_entry
ALIGN
CODE32
irq_entry ; 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
jump_intr
strh r0, [r3, #2] ; IF Clear
ldr r0, [r2] ; Jump to user IRQ process
bx r0
END
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -