mirror of
https://github.com/pret/pokeruby.git
synced 2026-08-08 10:34:12 -05:00
551 lines
12 KiB
ArmAsm
551 lines
12 KiB
ArmAsm
@ This library can be used to download and execute a multi-boot image from
|
|
@ a GameCube using the JOY Bus protocol over the link cable.
|
|
|
|
.include "asm/macros.inc"
|
|
.include "constants/constants.inc"
|
|
|
|
.equiv GCMB_STRUCT_BASE_DEST_PTR, 0x20
|
|
.equiv GCMB_STRUCT_CUR_DEST_PTR, 0x24
|
|
.equiv GCMB_STRUCT_SERIAL_INTR_HANDLER, 0x28
|
|
|
|
.equiv ROM_HEADER_NINTENDO_LOGO_OFFSET, 0x4
|
|
|
|
.syntax unified
|
|
|
|
.text
|
|
|
|
thumb_func_start GameCubeMultiBoot_Hash
|
|
GameCubeMultiBoot_Hash: @ 81DCB38
|
|
push {r4,lr}
|
|
ldr r4, pool_HashVal
|
|
eors r3, r1
|
|
movs r2, 0x20
|
|
|
|
GameCubeMultiBoot_Hash_Loop:
|
|
lsrs r3, 1
|
|
bcc GameCubeMultiBoot_Hash_SkipEor
|
|
|
|
eors r3, r4
|
|
|
|
GameCubeMultiBoot_Hash_SkipEor:
|
|
subs r2, 0x1
|
|
bne GameCubeMultiBoot_Hash_Loop
|
|
|
|
pop {r4,pc}
|
|
thumb_func_end GameCubeMultiBoot_Hash
|
|
|
|
thumb_func_start GameCubeMultiBoot_Main
|
|
@ void GameCubeMultiBoot_Main(struct GameCubeMultiBoot *mb)@
|
|
GameCubeMultiBoot_Main: @ 81DCB4C
|
|
ldr r1, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
|
|
cmp r1, 0
|
|
beq _081DCB72
|
|
ldrb r1, [r0, 0x1]
|
|
adds r1, 0x1
|
|
strb r1, [r0, 0x1]
|
|
ldrb r1, [r0, 0x2]
|
|
cmp r1, 0x2
|
|
beq _081DCBBC
|
|
ldr r3, pool_InterruptRegs
|
|
ldrh r2, [r3, OFFSET_REG_IME - 0x200]
|
|
movs r1, 0
|
|
strh r1, [r3, OFFSET_REG_IME - 0x200]
|
|
ldrb r1, [r0]
|
|
cmp r1, 0xA
|
|
bgt _081DCB70
|
|
adds r1, 0x1
|
|
strb r1, [r0]
|
|
_081DCB70:
|
|
strh r2, [r3, OFFSET_REG_IME - 0x200]
|
|
_081DCB72:
|
|
bcs GameCubeMultiBoot_Init
|
|
ldrb r1, [r0, 0x2]
|
|
cmp r1, 0
|
|
bne _081DCBBE
|
|
ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
|
ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
|
subs r1, r2
|
|
beq _081DCC3E
|
|
cmp r1, 0xA0
|
|
bcc _081DCC3E
|
|
push {r4-r6}
|
|
movs r1, 0x98
|
|
adds r2, ROM_HEADER_NINTENDO_LOGO_OFFSET
|
|
ldr r4, pool_NintendoLogo
|
|
_081DCB8E:
|
|
ldm r2!, {r5}
|
|
ldm r4!, {r6}
|
|
cmp r5, r6
|
|
bne _081DCBA4
|
|
subs r1, 0x4
|
|
bne _081DCB8E
|
|
ldm r2!, {r5}
|
|
ldm r4!, {r6}
|
|
eors r5, r6
|
|
lsrs r5, 8
|
|
str r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
|
_081DCBA4:
|
|
pop {r4-r6}
|
|
bne GameCubeMultiBoot_Init
|
|
movs r1, 0x1
|
|
strb r1, [r0, 0x2]
|
|
ldr r1, [r0, 0x4]
|
|
ldr r2, [r0, 0x8]
|
|
eors r1, r2
|
|
str r1, [r0, 0x18]
|
|
ldr r2, pool_Kawa
|
|
muls r1, r2
|
|
adds r1, 0x1
|
|
str r1, [r0, 0x14]
|
|
_081DCBBC:
|
|
bx lr
|
|
_081DCBBE:
|
|
ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
|
mov r12, r1
|
|
ldr r3, [r0, 0x18]
|
|
push {r4-r7}
|
|
ldr r4, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
|
ldr r5, pool_Kawa
|
|
ldr r6, [r0, 0x14]
|
|
ldr r7, pool_HashVal
|
|
_081DCBCE:
|
|
cmp r4, r12
|
|
bcs _081DCBEE
|
|
ldr r1, [r4]
|
|
eors r1, r6
|
|
adds r1, r3
|
|
stm r4!, {r1}
|
|
eors r3, r1
|
|
movs r2, 0x20
|
|
_081DCBDE:
|
|
lsrs r3, 1
|
|
bcc _081DCBE4
|
|
eors r3, r7
|
|
_081DCBE4:
|
|
subs r2, 0x1
|
|
bne _081DCBDE
|
|
muls r6, r5
|
|
adds r6, 0x1
|
|
b _081DCBCE
|
|
_081DCBEE:
|
|
str r4, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
|
str r6, [r0, 0x14]
|
|
pop {r4-r7}
|
|
str r3, [r0, 0x18]
|
|
ldrh r1, [r0, 0x12]
|
|
cmp r1, 0
|
|
bne _081DCC3E
|
|
ldr r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
|
ldr r2, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
|
cmp r1, r2
|
|
bne _081DCC3E
|
|
ldr r1, [r0, 0xC]
|
|
cmp r1, 0
|
|
beq _081DCC28
|
|
ldrh r1, [r0, 0x10]
|
|
cmp r1, 0
|
|
beq _081DCBBC
|
|
mov r12, lr
|
|
movs r1, 0xBB
|
|
ldr r3, [r0, 0xC]
|
|
bl GameCubeMultiBoot_Hash
|
|
ldrh r1, [r0, 0x10]
|
|
mov lr, r12
|
|
subs r1, r3
|
|
bne GameCubeMultiBoot_Init
|
|
movs r1, 0x2
|
|
strb r1, [r0, 0x2]
|
|
bx lr
|
|
_081DCC28:
|
|
mov r12, lr
|
|
ldrb r1, [r0, 0x3]
|
|
lsls r1, 24
|
|
subs r1, 0x1
|
|
str r1, [r0, 0xC]
|
|
bl GameCubeMultiBoot_Hash
|
|
lsls r3, 8
|
|
adds r3, 0xFF
|
|
str r3, [r0, 0x1C]
|
|
bx r12
|
|
_081DCC3E:
|
|
bx lr
|
|
thumb_func_end GameCubeMultiBoot_Main
|
|
|
|
.align 2, 0
|
|
|
|
pool_HashVal: .4byte 0xa1c1
|
|
|
|
pool_Kawa: .ascii "Kawa" @ name of BIOS developer
|
|
|
|
pool_NintendoLogo: .4byte RomHeaderNintendoLogo
|
|
|
|
thumb_func_start GameCubeMultiBoot_ExecuteProgram
|
|
@ void GameCubeMultiBoot_ExecuteProgram(struct GameCubeMultiBoot *mb)@
|
|
GameCubeMultiBoot_ExecuteProgram: @ 81DCC4C
|
|
ldrb r1, [r0, 0x2]
|
|
cmp r1, 0x2
|
|
bne GameCubeMultiBoot_ExecuteProgram_Fail
|
|
ldr r3, pool_InterruptRegs
|
|
movs r1, 0
|
|
strh r1, [r3, OFFSET_REG_IME - 0x200]
|
|
ldr r1, pool_MultiBootLoadAddr
|
|
adds r1, 0xC0
|
|
bx r1
|
|
GameCubeMultiBoot_ExecuteProgram_Fail:
|
|
bx lr
|
|
thumb_func_end GameCubeMultiBoot_ExecuteProgram
|
|
|
|
thumb_func_start GameCubeMultiBoot_Init
|
|
@ void GameCubeMultiBoot_Init(struct GameCubeMultiBoot *mb)@
|
|
GameCubeMultiBoot_Init: @ 81DCC60
|
|
ldr r3, pool_InterruptRegs
|
|
|
|
@ Save IME register.
|
|
ldrh r2, [r3, OFFSET_REG_IME - 0x200]
|
|
|
|
@ Disable interrupts.
|
|
movs r1, 0
|
|
strh r1, [r3, OFFSET_REG_IME - 0x200]
|
|
|
|
@ Set the handler to the "Stop" routine.
|
|
@ Unless the first command that is received is a device reset command, the
|
|
@ "Stop" routine will be executed and no further commands will be processed.
|
|
adr r3, GcMbIntrHandler_Stop
|
|
str r3, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
|
|
|
|
ldrb r3, [r0, 0x3]
|
|
push {r3}
|
|
ldrb r3, [r0, 0x1]
|
|
push {r0,r3}
|
|
|
|
adds r3, r0, 0
|
|
adds r3, GCMB_STRUCT_BASE_DEST_PTR
|
|
|
|
@ clear all but the last 3 fields of the struct
|
|
GameCubeMultiBoot_Init_ClearStructLoop:
|
|
stm r0!, {r1}
|
|
cmp r0, r3
|
|
blo GameCubeMultiBoot_Init_ClearStructLoop
|
|
|
|
pop {r0,r3}
|
|
lsrs r3, 1
|
|
strb r3, [r0, 0x3]
|
|
pop {r3}
|
|
strb r3, [r0, 0x1]
|
|
|
|
ldr r3, pool_SerialRegs
|
|
|
|
@ Turn off JOY Bus mode.
|
|
lsls r0, r3, 10
|
|
strh r0, [r3, OFFSET_REG_RCNT - 0x120]
|
|
|
|
@ Turn on JOY Bus mode.
|
|
movs r0, 0xC0
|
|
lsls r0, 8
|
|
strh r0, [r3, OFFSET_REG_RCNT - 0x120]
|
|
|
|
@ Init JOY Bus registers.
|
|
movs r0, 0x47
|
|
strh r0, [r3, OFFSET_REG_JOYCNT - 0x120]
|
|
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
|
|
|
ldr r3, pool_InterruptRegs
|
|
|
|
@ Acknowledge serial interrupt.
|
|
movs r0, INTR_FLAG_SERIAL
|
|
strh r0, [r3, OFFSET_REG_IF - 0x200]
|
|
|
|
@ Enable serial interrupt.
|
|
ldrh r1, [r3, OFFSET_REG_IE - 0x200]
|
|
orrs r1, r0
|
|
strh r1, [r3, OFFSET_REG_IE - 0x200]
|
|
|
|
@ Restore IME register.
|
|
strh r2, [r3, OFFSET_REG_IME - 0x200]
|
|
|
|
bx lr
|
|
thumb_func_end GameCubeMultiBoot_Init
|
|
|
|
non_word_aligned_thumb_func_start GameCubeMultiBoot_HandleSerialInterrupt
|
|
@ void GameCubeMultiBoot_HandleSerialInterrupt(struct GameCubeMultiBoot *mb)@
|
|
GameCubeMultiBoot_HandleSerialInterrupt: @ 81DCCAA
|
|
ldr r3, pool_SerialRegs
|
|
|
|
@ Acknowledge reset/receive/send flags.
|
|
ldrh r1, [r3, OFFSET_REG_JOYCNT - 0x120]
|
|
strh r1, [r3, OFFSET_REG_JOYCNT - 0x120]
|
|
|
|
movs r2, 0
|
|
strb r2, [r0]
|
|
|
|
ldr r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
|
|
cmp r2, 0
|
|
beq GameCubeMultiBoot_HandleSerialInterruptDone
|
|
|
|
lsrs r1, 1 @ was a device reset command received?
|
|
bcs GameCubeMultiBoot_BeginHandshake @ branch if so
|
|
|
|
mov pc, r2
|
|
|
|
.align 2, 0
|
|
|
|
@ Zero the status and the interrupt handler pointer.
|
|
@ Commands from the GameCube will not be processed after this is executed
|
|
@ unless GameCubeMultiBoot_Init() is called again.
|
|
GcMbIntrHandler_Stop:
|
|
movs r2, 0
|
|
strh r2, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
|
|
|
GameCubeMultiBoot_SetInterruptHandler:
|
|
str r2, [r0, GCMB_STRUCT_SERIAL_INTR_HANDLER]
|
|
|
|
GameCubeMultiBoot_ReadVCount:
|
|
ldr r3, pool_RegDispstat
|
|
ldrh r1, [r3, OFFSET_REG_VCOUNT - OFFSET_REG_DISPSTAT]
|
|
strb r1, [r0, 0x3]
|
|
|
|
GameCubeMultiBoot_HandleSerialInterruptDone:
|
|
bx lr
|
|
|
|
GameCubeMultiBoot_BeginHandshake:
|
|
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
|
ldr r1, pool_RubyUSAGameCode
|
|
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
|
|
movs r1, 0x10
|
|
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
|
ldrb r1, [r0, 0x3]
|
|
strb r1, [r0, 0x9]
|
|
ldrb r1, [r0, 0x2]
|
|
cmp r1, 0
|
|
bne GcMbIntrHandler_Stop
|
|
ldr r1, pool_MultiBootLoadAddr
|
|
str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
|
str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
|
adr r2, GcMbIntrHandler_CheckGameCodeSent
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
GcMbIntrHandler_CheckGameCodeSent: @ 81DCCEC
|
|
lsls r1, 31
|
|
bcc GcMbIntrHandler_Stop @ stop if send failed
|
|
bmi GameCubeMultiBoot_CheckHandshakeResponse @ branch if receive is complete
|
|
|
|
@ If the response hasn't been fully received yet,
|
|
@ check again upon the next interrupt.
|
|
adr r2, GcMbIntrHandler_CheckHandshakeResponse
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
GcMbIntrHandler_CheckHandshakeResponse: @ 81DCCF8
|
|
lsrs r1, 1 @ is receive complete?
|
|
bcc GcMbIntrHandler_Stop @ stop if not
|
|
|
|
GameCubeMultiBoot_CheckHandshakeResponse:
|
|
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
|
ldr r2, pool_RubyUSAGameCode
|
|
cmp r1, r2
|
|
bne GcMbIntrHandler_Stop @ stop if the GameCube didn't reply with the same game code
|
|
ldrb r1, [r0, 0x3]
|
|
strb r1, [r0, 0xB]
|
|
adr r2, GcMbIntrHandler_81DCD0C
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
GcMbIntrHandler_81DCD0C: @ 81DCD0C
|
|
lsrs r1, 1 @ is receive complete?
|
|
bcc GcMbIntrHandler_Stop @ branch if not
|
|
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
|
lsrs r2, r1, 24
|
|
cmp r2, 0xDD
|
|
bne GcMbIntrHandler_Stop
|
|
str r1, [r0, 0x4]
|
|
ldrb r1, [r0, 0x1]
|
|
strb r1, [r0, 0xA]
|
|
movs r2, 0
|
|
movs r3, 0
|
|
ldr r1, [r0, 0x8]
|
|
lsrs r1, 8
|
|
_081DCD26:
|
|
lsrs r1, 1
|
|
adcs r2, r3
|
|
cmp r1, 0
|
|
bne _081DCD26
|
|
cmp r2, 0xE
|
|
bgt _081DCD38
|
|
cmp r2, 0x7
|
|
bge _081DCD3A
|
|
movs r1, 0xFF
|
|
_081DCD38:
|
|
strb r1, [r0, 0xA]
|
|
_081DCD3A:
|
|
ldr r1, [r0, 0x8]
|
|
adds r1, 0xEE
|
|
ldr r3, pool_SerialRegs
|
|
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
|
|
movs r1, 0x30
|
|
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
|
adr r2, GcMbIntrHandler_81DCD4C
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
GcMbIntrHandler_81DCD4C: @ 81DCD4C
|
|
lsls r1, 31
|
|
bcc GcMbIntrHandler_Stop @ stop if send failed
|
|
bmi _081DCD5C @ branch if receive is complete
|
|
adr r2, GcMbIntrHandler_81DCD58
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
GcMbIntrHandler_81DCD58: @ 81DCD58
|
|
lsrs r1, 1 @ is receive complete?
|
|
bcc GcMbIntrHandler_Stop @ branch if not
|
|
_081DCD5C:
|
|
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
|
ldr r2, _081DCDFC
|
|
cmp r1, r2
|
|
bhs GcMbIntrHandler_Stop
|
|
adds r1, 0x1
|
|
adds r1, r1
|
|
strh r1, [r0, 0x12]
|
|
ldrb r1, [r0, 0x2]
|
|
cmp r1, 0
|
|
_081DCD6E:
|
|
bne GcMbIntrHandler_Stop
|
|
ldr r1, pool_MultiBootLoadAddr
|
|
str r1, [r0, GCMB_STRUCT_BASE_DEST_PTR]
|
|
str r1, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
|
adr r2, GcMbIntrHandler_81DCD7C
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
GcMbIntrHandler_81DCD7C: @ 81DCD7C
|
|
lsrs r1, 1 @ is receive complete?
|
|
bcc GcMbIntrHandler_Stop @ branch if not
|
|
ldr r2, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
|
movs r1, 0x4
|
|
ands r1, r2
|
|
adds r1, 0x8
|
|
lsls r1, 2
|
|
strh r1, [r3, OFFSET_REG_JOYSTAT - 0x120]
|
|
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
|
stm r2!, {r1}
|
|
str r2, [r0, GCMB_STRUCT_CUR_DEST_PTR]
|
|
ldrh r1, [r0, 0x12]
|
|
subs r1, 0x1
|
|
strh r1, [r0, 0x12]
|
|
bne GameCubeMultiBoot_ReadVCount
|
|
|
|
_081DCD9A:
|
|
ldrb r1, [r0, 0x1]
|
|
lsls r1, 8
|
|
adds r1, 0xCC
|
|
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
|
|
adr r2, _081DCDA8
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
_081DCDA8:
|
|
lsls r1, 31
|
|
|
|
_081DCDAA:
|
|
bcc GcMbIntrHandler_Stop
|
|
ldr r1, [r0, 0x1C]
|
|
cmp r1, 0
|
|
beq _081DCD9A
|
|
str r1, [r3, OFFSET_REG_JOY_TRANS - 0x120]
|
|
adr r2, GcMbIntrHandler_81DCDB8
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
GcMbIntrHandler_81DCDB8: @ 81DCDB8
|
|
lsls r1, 31
|
|
bcc _081DCDAA @ branch if send failed
|
|
bmi _081DCDC8 @ branch if receive is complete
|
|
adr r2, GcMbIntrHandler_81DCDC4
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
GcMbIntrHandler_81DCDC4: @ 81DCDC4
|
|
lsrs r1, 1 @ is receive complete?
|
|
bcc _081DCDAA @ branch if not
|
|
|
|
_081DCDC8:
|
|
ldr r1, [r3, OFFSET_REG_JOY_RECV - 0x120]
|
|
lsrs r2, r1, 24
|
|
cmp r2, 0xBB
|
|
bne _081DCD6E
|
|
strh r1, [r0, 0x10]
|
|
adr r2, GcMbIntrHandler_81DCDD8
|
|
b GameCubeMultiBoot_SetInterruptHandler
|
|
|
|
.align 2, 0
|
|
|
|
GcMbIntrHandler_81DCDD8: @ 81DCDD8
|
|
b GcMbIntrHandler_Stop
|
|
|
|
thumb_func_end GameCubeMultiBoot_HandleSerialInterrupt
|
|
|
|
non_word_aligned_thumb_func_start GameCubeMultiBoot_Quit
|
|
@ void GameCubeMultiBoot_Quit()@
|
|
GameCubeMultiBoot_Quit: @ 81DCDDA
|
|
ldr r3, pool_InterruptRegs
|
|
|
|
@ Save IME register.
|
|
ldrh r2, [r3, OFFSET_REG_IME - 0x200]
|
|
|
|
@ Disable interrupts.
|
|
movs r1, 0
|
|
strh r1, [r3, OFFSET_REG_IME - 0x200]
|
|
|
|
ldr r3, pool_SerialRegs
|
|
|
|
@ Acknowledge all JOYCNT flags.
|
|
movs r0, 0x7
|
|
strh r0, [r3, OFFSET_REG_JOYCNT - 0x120]
|
|
|
|
@ Turn off JOY Bus mode.
|
|
lsls r0, r3, 10
|
|
strh r0, [r3, OFFSET_REG_RCNT - 0x120] @ store 0x8000
|
|
|
|
ldr r3, pool_InterruptRegs
|
|
|
|
@ Acknowledge serial interrupt.
|
|
movs r0, INTR_FLAG_SERIAL
|
|
strh r0, [r3, OFFSET_REG_IF - 0x200]
|
|
|
|
@ Disable serial interrupt.
|
|
ldrh r1, [r3, OFFSET_REG_IE - 0x200]
|
|
bics r1, r0
|
|
strh r1, [r3, OFFSET_REG_IE - 0x200]
|
|
|
|
@ Restore IME register.
|
|
strh r2, [r3, OFFSET_REG_IME - 0x200]
|
|
|
|
bx lr
|
|
thumb_func_end GameCubeMultiBoot_Quit
|
|
|
|
.align 2, 0
|
|
|
|
_081DCDFC: .4byte 0x00004000
|
|
|
|
pool_InterruptRegs: .4byte REG_BASE + 0x200
|
|
|
|
pool_SerialRegs: .4byte REG_BASE + 0x120
|
|
|
|
pool_RegDispstat: .4byte REG_DISPSTAT
|
|
|
|
pool_RubyUSAGameCode: .ascii "AXVE"
|
|
|
|
pool_MultiBootLoadAddr: .4byte EWRAM_START
|
|
|
|
.align 2, 0 @ Don't pad with nop.
|