cube/source/sys/gba_crt0.s
2025-08-21 22:26:26 -04:00

142 lines
2.9 KiB
ArmAsm

// SPDX-License-Identifier: CC0-1.0
//
// SPDX-FileContributor: Antonio Niño Díaz, 2022
.section .gba_crt0, "ax"
.global entrypoint
.cpu arm7tdmi
.arm
entrypoint:
b header_end
.fill 156, 1, 0 // Nintendo Logo
.fill 12, 1, 0 // Game Title
.fill 4, 1, 0 // Game Code
.byte 0x30, 0x30 // Maker Code ("00")
.byte 0x96 // Fixed Value (must be 0x96)
.byte 0x00 // Main unit code
.byte 0x00 // Device Type
.fill 7, 1, 0 // Reserved Area
.byte 0x00 // Software version
.byte 0x00 // Complement check (header checksum)
.byte 0x00, 0x00 // Reserved Area
header_end:
b start_vector
// Multiboot Header Entries
.byte 0 // Boot mode
.byte 0 // Slave ID Number
.fill 26, 1, 0 // Not used
.word 0 // JOYBUS entrypoint
.align
start_vector:
// Disable interrupts
mov r0, #0x4000000
mov r1, #0
str r1, [r0, #0x208] // IME
// Setup IRQ mode stack
mov r0, #0x12
msr cpsr, r0
ldr sp, =__STACK_IRQ_END__
// Setup system mode stack
mov r0, #0x1F
msr cpsr, r0
ldr sp, =__STACK_USR_END__
// Switch to Thumb mode
add r0, pc, #1
bx r0
.thumb
// Clear IWRAM
ldr r0, =#0x3000000
ldr r1, =#(32 * 1024)
bl mem_zero
// Copy data section from ROM to RAM
ldr r0, =__DATA_LMA__
ldr r1, =__DATA_START__
ldr r2, =__DATA_SIZE__
bl mem_copy
// Copy IWRAM data from ROM to RAM
ldr r0, =__IWRAM_LMA__
ldr r1, =__IWRAM_START__
ldr r2, =__IWRAM_SIZE__
bl mem_copy
// Clear EWRAM
ldr r0, =#0x2000000
ldr r1, =#(256 * 1024)
bl mem_zero
// Copy EWRAM data from ROM to RAM
ldr r0, =__EWRAM_LMA__
ldr r1, =__EWRAM_START__
ldr r2, =__EWRAM_SIZE__
bl mem_copy
// Global constructors
ldr r2, =__libc_init_array
bl blx_r2_trampoline
// Call main()
mov r0, #0 // int argc
mov r1, #0 // char *argv[]
ldr r2, =main
bl blx_r2_trampoline
// Global destructors
ldr r2, =__libc_fini_array
bl blx_r2_trampoline
// If main() returns, reboot the GBA using SoftReset
swi #0x00
// r0 = Base address
// r1 = Size
mem_zero:
and r1, r1
beq 2f // Return if size is 0
mov r2, #0
1:
stmia r0!, {r2}
sub r1, #4
bne 1b
2:
bx lr
// r0 = Source address
// r1 = Destination address
// r2 = Size
mem_copy:
and r2, r2
beq 2f // Return if size is 0
1:
ldmia r0!, {r3}
stmia r1!, {r3}
sub r2, #4
bne 1b
2:
bx lr
// r2 = Address to jump to
blx_r2_trampoline:
bx r2
.align
.pool
.end