|
|
|
.section .init
|
|
|
|
.global _start
|
|
|
|
.align
|
|
|
|
.arm
|
|
|
|
|
|
|
|
_start:
|
|
|
|
b start_vector
|
|
|
|
|
|
|
|
// ROM header
|
|
|
|
.byte 0x24,0xff,0xae,0x51,0x69,0x9a,0xa2,0x21,0x3d,0x84,0x82,0x0a,0x84,0xe4,0x09,0xad
|
|
|
|
.byte 0x11,0x24,0x8b,0x98,0xc0,0x81,0x7f,0x21,0xa3,0x52,0xbe,0x19,0x93,0x09,0xce,0x20
|
|
|
|
.byte 0x10,0x46,0x4a,0x4a,0xf8,0x27,0x31,0xec,0x58,0xc7,0xe8,0x33,0x82,0xe3,0xce,0xbf
|
|
|
|
.byte 0x85,0xf4,0xdf,0x94,0xce,0x4b,0x09,0xc1,0x94,0x56,0x8a,0xc0,0x13,0x72,0xa7,0xfc
|
|
|
|
.byte 0x9f,0x84,0x4d,0x73,0xa3,0xca,0x9a,0x61,0x58,0x97,0xa3,0x27,0xfc,0x03,0x98,0x76
|
|
|
|
.byte 0x23,0x1d,0xc7,0x61,0x03,0x04,0xae,0x56,0xbf,0x38,0x84,0x00,0x40,0xa7,0x0e,0xfd
|
|
|
|
.byte 0xff,0x52,0xfe,0x03,0x6f,0x95,0x30,0xf1,0x97,0xfb,0xc0,0x85,0x60,0xd6,0x80,0x25
|
|
|
|
.byte 0xa9,0x63,0xbe,0x03,0x01,0x4e,0x38,0xe2,0xf9,0xa2,0x34,0xff,0xbb,0x3e,0x03,0x44
|
|
|
|
.byte 0x78,0x00,0x90,0xcb,0x88,0x11,0x3a,0x94,0x65,0xc0,0x7c,0x63,0x87,0xf0,0x3c,0xaf
|
|
|
|
.byte 0xd6,0x25,0xe4,0x8b,0x38,0x0a,0xac,0x72,0x21,0xd4,0xf8,0x07
|
|
|
|
|
|
|
|
// Game title
|
|
|
|
.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
|
|
|
|
|
|
// Game code
|
|
|
|
.byte 0x00,0x00,0x00,0x00
|
|
|
|
|
|
|
|
// Maker code
|
|
|
|
.byte 0x00,0x00
|
|
|
|
|
|
|
|
// Fixed value
|
|
|
|
.byte 0x96
|
|
|
|
|
|
|
|
// Main unit code
|
|
|
|
.byte 0x00
|
|
|
|
|
|
|
|
// Device type (0x00 retail, 0x80 debug)
|
|
|
|
.byte 0x00
|
|
|
|
|
|
|
|
// Reserved
|
|
|
|
.byte 0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
|
|
|
|
|
|
// Software version
|
|
|
|
.byte 0x00
|
|
|
|
|
|
|
|
// Complement check
|
|
|
|
.byte 0x51
|
|
|
|
|
|
|
|
// Reserved area
|
|
|
|
.space 98
|
|
|
|
|
|
|
|
start_vector:
|
|
|
|
// Configure stacks
|
|
|
|
mov r0, #0x12 // Switch to IRQ Mode
|
|
|
|
msr cpsr, r0
|
|
|
|
ldr sp, =_stack_top_irq // Set IRQ stack
|
|
|
|
mov r0, #0x1f // Switch to System Mode
|
|
|
|
msr cpsr, r0
|
|
|
|
ldr sp, =_stack_top // Set user stack
|
|
|
|
|
|
|
|
// Configure interrupt handler
|
|
|
|
mov r0, #0x4000000 // REG_BASE
|
|
|
|
ldr r1, =handleInterruptARM
|
|
|
|
str r1, [r0, #-4] // actually storing to 0x03007FFC due to mirroring
|
|
|
|
|
|
|
|
// Enable interrupts
|
|
|
|
mov r1, #1
|
|
|
|
str r1, [r0, #0x208] // 0x04000208 Interrupt Master Enable
|
|
|
|
|
|
|
|
// Jump to user code (switching to Thumb mode)
|
|
|
|
ldr r3, =main
|
|
|
|
bx r3
|
|
|
|
|
|
|
|
// Small interrupt handler that immediately jumps to a function defined in the
|
|
|
|
// program (in Thumb) for further processing.
|
|
|
|
handleInterruptARM:
|
|
|
|
ldr r0, =handleInterrupt
|
|
|
|
bx r0
|