📄 boot.s
字号:
@********************************************************************
@* crt0.S v1.26 by Jeff Frohwein *
@********************************************************************
@ v1.0 - Original release
@ v1.1 - Added proper .data section support
@ v1.2 - Added support for c++, overlays, interrupts, and
@ far calls (__FarFunction & __FarProcedure).
@ - Some ideas from Jason Wilkins & Mike Heckenbach.
@ v1.21- Killed the dumb test bug left in the code.
@ v1.22- Killed dumb bug "numero dos" in multiple interrupts routine. Thanks Mike H. :)
@ v1.23- Now correctly handles zero length .bss section.
@ v1.24- Loop back to start_vector now works if main {} exits.
@ v1.25- __FarProcedure now works. It was missing a .thumb_func directive.
@ v1.26- Added missing Serial Interrupt processing to __MultipleInterrupts section.
@ Added __FastInterrupt option for minimal interrupt processing.
@ Optimized __MultipleInterrupts section to save 4 bytes of stack space.
@ Added __ISRinIWRAM option that puts interrupt processing in IWRAM by default.
@ Options passed to main() or AgbMain() are now set to 0. (Thanks to DarkFader)
@
@ This file is released into the public domain for commercial
@ or non-commercial usage with no restrictions placed upon it.
.TEXT
@ Comment out the next line ONLY if you plan to never support
@ multiboot mode and want to save a few bytes by removing
@ multiboot support code. Otherwise, leave it alone. It wont
@ disturb code designed to run only on flash carts.
@
@ The normal way to enable generating code that works with
@ both multiboot and flash carts is to add the following to
@ your C code in your main project file AS A GLOBAL VARIABLE:
@
@ #define MULTIBOOT int __gba_multiboot;
@ Then use it like this : MULTIBOOT
@
@ IT MUST BE A GLOBAL VARIABLE OR IT WILL NOT WORK!
@ If this variable is not defined somewhere in your project
@ then code will be generated to run out of ROM instead of
@ EXRAM. The value of this variable is not important.
.equ __MultiBootInclude, 1
@ If you are compiling for multiboot dedicated (will not
@ run in a cart) code then uncomment the following. Normally
@ you should leave this commented out so that a multiboot
@ image will run in a cart as well (by copying from ROM to RAM).
@
@ This sets the maker code to "MB " which is a key that
@ some emulators look for to know to load the rom image
@ at 0x2000000 instead of the standard 0x8000000.
@ .equ __MultibootDedicated, 1
@ There are two methods for clearing memory and
@ copying appropriate setup data. The fast & bulky
@ method is GBA DMA copy/clear but some emulators
@ do not accurately do DMA. If you have an inaccurate
@ emulator or want to conserve ROM space then comment
@ out the following line. There is not much advantage
@ gained by doing DMA copy/clear.
@ .equ __DMACopyClear, 1
@ Uncomment the following line to support C++ development.
@ You also need to name your main C function the following:
@ int main (void) ...instead of... int AgbMain (void)
@ Doing so will cause ~5500 bytes of c++ support code to be
@ linked in with your project so do not enable c++ support
@ unless you plan to use it.
@ .equ __CPPSupport, 1
@ Comment out the following line to disable interrupt support
@ in your code and to save some space in this file.
@ .equ __InterruptSupport, 1
@ Comment out the following line to put interrupt support in
@ ROM instead of IWRAM. Interrupt support in ROM will slow
@ down interrupt execution and has no advantage other than
@ saving a little bit of IWRAM.
.equ __ISRinIWRAM, 1
@ NOTE: Only ONE of the following 3 interrupt options may be
@ uncommented. Also, __InterruptSupport above must be uncommented
@ for any of the following to have an effect.
@
@ __FastInterrupts
@ Uncomment this line for minimal interrupt processing.
@
@ __SingleInterrupts
@ Uncomment this line if you wish to use a table of function
@ pointers to process specific interrupts.
@
@ __MultipleInterrupts
@ Uncomment this line to allow multiple-interrupts-at-once
@ support. If you have several interrupts where one can
@ occur while another is being serviced then you need to
@ enable this option.
.equ __FastInterrupts, 1
@ .equ __SingleInterrupts, 1
@ .equ __MultipleInterrupts, 1
@ Uncomment the following line to disable sound and enter an
@ infinite loop if cart is removed during game play. You
@ must have the cart interrupt enabled for this to work and
@ __ISRinIWRAM, above, must be enabled (not commented out.)
@ .equ __HandleCartInterrupt, 1
@ The following prevents IRQ stack overflow by switching to
@ System mode (User stack) when handling multiple interrupts.
@ To force use of IRQ stack only, comment out the following line.
.equ __SwitchToUserStack, 1
@ !!!! NOTE: THE COPY ROUTINES IN THIS FILE WORK ON 4 BYTE
@ BOUNDARIES. YOUR LINKER SCRIPT MUST ALIGN SECTION STARTS
@ AND SECTION ENDS FOR SECTIONS THAT GET COPIED TO RAM WITH
@ ALIGN(4) !!!!
.GLOBAL _start
_start:
.ALIGN
.CODE 32
@ Start Vector
b rom_header_end
@ Nintendo Logo Character Data (8000004h)
.fill 156,1,0
@ Game Title (80000A0h)
.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
.byte 0x00,0x00,0x00,0x00
.ifdef __MultibootDedicated
@ Game Code (80000ACh)
.ascii "MB "
.else
@ Game Code (80000ACh)
.byte 0x00,0x00,0x00,0x00
.endif
@ Maker Code (80000B0h)
.byte 0x30,0x31
@ Fixed Value (80000B2h)
.byte 0x96
@ Main Unit Code (80000B3h)
.byte 0x00
@ Device Type (80000B4h)
.byte 0x00
@ Unused Data (7Byte) (80000B5h)
.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00
@ Software Version No (80000BCh)
.byte 0x00
@ Complement Check (80000BDh)
.byte 0xf0
@ Checksum (80000BEh)
.byte 0x00,0x00
.ALIGN
.ARM @ ..or you can use CODE 32 here
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.
.GLOBAL __boot_method, __slave_number
__boot_method:
.byte 0 @ boot method (0=ROM boot, 3=Multiplay boot)
__slave_number:
.byte 0 @ slave # (1=slave#1, 2=slave#2, 3=slave#3)
.ifdef __MultiBootInclude
.byte 0 @ reserved
.byte 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
.word 0 @ reserved
.endif
@ @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@
@ Reset @
@@@@@@@@@@@@@@@@@@@@@@
.GLOBAL start_vector
.ALIGN
.ARM @ ..or you can use CODE 32 here
start_vector:
mov r0, #0x12 @ Switch to IRQ Mode
msr cpsr, r0
ldr sp,=__sp_irq @ Set SP_irq
mov r0, #0x1f @ Switch to System Mode
msr cpsr, r0
ldr sp,=__sp_usr @ Set SP_usr
@ Enter Thumb mode
adr r0,1f + 1 @ add r0,pc,#1 also works here
@ for those that want to conserve labels.
bx r0
.THUMB @ ..or you can use .CODE 16 here
1:
.ifdef __InterruptSupport
ldr r1, =__intr_vector_buf @ Set Interrupt Address
ldr r0, =intr_main
str r0, [r1]
.endif
.ifdef __MultiBootInclude
@ *** Multiboot Copy Routine ***
@ Check the Program Counter to see if code is running
@ at 0x2000000 or 0x8000000. If it is running at 0x8000000
@ then copy 256K bytes of it to 0x2000000 and then branch
@ to 0x2000000.
@ The reason for all this is to allow a program to be used
@ "as is" with an flash cart/emulator or with an MBV2-style
@ multiboot cable.
@ NOTE: You can also detect if this ROM is running from
@ 0x2000000 by checking the multiboot header above.
ldr r0,=__text_start
lsl r0,#5 @ Was code compiled at 0x08000000 or higher?
bcs DoEWRAMClear @ yes, you can not run it in external WRAM
@ Make sure we're in ExWRAM
mov r0,pc
lsl r0,#5 @ Are we running from ROM (0x8000000 or higher) ?
bcc SkipEWRAMClear @ No, so no need to do a copy.
@ We were started in ROM, silly emulators. :P
@ So we need to copy to ExWRAM.
mov r3,#0x40
lsl r3,#12 @ r3 = 0x40000
lsl r2,r3,#7 @ r2 = 0x2000000
mov r6,r2 @ r6 = 0x2000000
lsl r1,r2,#2 @ r1 = 0x8000000
bl CopyMem
@ Jump to the code to execute
bx r6
.endif
DoEWRAMClear:
@ Clear External WRAM to 0x00
mov r1,#0x40
lsl r1,#12 @ r1 = 0x40000
lsl r0,r1,#7 @ r0 = 0x2000000
bl ClearMem
SkipEWRAMClear:
@ ldr r0,=AgbMain
@ bx r0
@ Clear Internal WRAM to 0x00
mov r0,#3
lsl r0,#24 @ r0 = 0x3000000
ldr r1,=__sp_usr_offset - 16
bl ClearMem
.ifdef __MultiBootInclude
@ Clear BSS section to 0x00
@ (Sometimes BSS may be in External WRAM)
ldr r0,=__bss_start
ldr r1,=__bss_end
sub r1,r0
bl ClearMem
.endif
@ Copy initialized data (data section) from LMA to VMA (ROM to RAM)
ldr r1,=__data_lma
ldr r2,=__data_start
ldr r4,=__data_end
bl CopyMemChk
@ Copy internal work ram (iwram section) from LMA to VMA (ROM to RAM)
ldr r1,=__iwram_lma
ldr r2,=__iwram_start
ldr r4,=__iwram_end
bl CopyMemChk
@ Copy internal work ram overlay 0 (iwram0 section) from LMA to VMA (ROM to RAM)
ldr r2,=__load_stop_iwram0
ldr r1,=__load_start_iwram0
sub r3,r2,r1 @ Is there any data to copy?
beq CIW0Skip @ no
ldr r2,=__iwram_overlay_start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -