Initial work on homebrew return to loader

This commit is contained in:
Gericom
2026-01-04 15:39:47 +01:00
parent f1e5f0cddc
commit 5c8e98a03f
13 changed files with 387 additions and 5 deletions

View File

@@ -0,0 +1,237 @@
.syntax unified
.section "patch_bootstub", "ax"
.cpu arm946e-s
.arm
.global patch_bootstub_arm9reboot
.type patch_bootstub_arm9reboot, %function
patch_bootstub_arm9reboot:
// disable irqs
ldr r0,= 0x04000208
strb r0, [r0]
// sync with arm7
// make arm7 jump to arm7_after_arm9_sync
ldr r0,= 0x02FFFE34
adr r1, arm7_after_arm9_sync
str r1, [r0]
ldr r0,= 0x04000180
ldr r1,= 0x0C04000C // LIBNDS_RESET_CODE
str r1, [r0, #8]
// wait for 1 from arm7
1:
ldrb r1, [r0]
cmp r1, #1
bne 1b
// send 1 to arm7
ldr r1,= 0x100
strh r1, [r0]
// wait for 0 from arm7
1:
ldrb r1, [r0]
cmp r1, #0
bne 1b
// send 0 to arm7
strh r1, [r0]
.type arm9_after_arm7_sync, %function
arm9_after_arm7_sync:
// disable irqs
ldr r0,= 0x04000208
strb r0, [r0]
// map vram ABCD to lcdc
mov r0, #0x04000000
ldr r1,= 0x80808080
str r1, [r0, #0x240]
ldr r0,= 0x04000204
ldrh r1, [r0]
bic r1, r1, #0x880 // map slot 1 and 2 to arm9
strh r1, [r0]
ldr r9, patch_bootstub_arm9reboot_readSdSectors_address
ldr sp,= 0x02000000 + (16 * 1024) // the platform code needs a valid stack pointer
// load pico loader arm9
adr r5, patch_bootstub_arm9reboot_loader_info
ldmia r5!, {r4,r6,r7} // clusterShift, database, clusterMap[0]
mov r7, #0x06800000
mov r11, pc
b loadData
// load pico loader arm7
adr r5, patch_bootstub_arm9reboot_loader_info + 52
ldr r7,= 0x06840000
mov r11, pc
b loadData
ldr r7,= 0x06840000
adr r5, patch_bootstub_arm9reboot_loader_info
ldrh r0, [r5, #2] // loader_info_t::picoLoaderBootDrive
strh r0, [r7, #8] // pload_header7_t::bootDrive
ldr r0, patch_bootstub_arm9reboot_dldi_address
str r0, [r7, #4]
// set loadParams->romPath
ldr r0, patch_bootstub_arm9reboot_launcher_path
mov r1, #256
add r3, r7, #0xC
1:
ldr r2, [r0], #4
str r2, [r3], #4
subs r1, r1, #4
bne 1b
// map vram CD to arm7
ldr r0,= 0x04000240
ldr r1,= 0x8A82
strh r1, [r0, #2]
// start arm7 by sending 3
ldr r0,= 0x04000180
mov r1, #0x300
strh r1, [r0]
// invalidate icache
mov r0, #0
mcr p15, 0, r0, c7, c5, 0
mov pc, #0x06800000
loadData_loop:
sub r3, r3, #2
add r0, r6, r3, lsl r4 // start sector
mov r1, r7 // dst
mov r2, r2, lsl r4 // sector count
add r7, r7, r2, lsl #9
blx r9 // read sectors
loadData:
ldmia r5!, {r2, r3} // ncl, startSector
cmp r2, #0
bne loadData_loop
bx r11
.balign 4
.pool
.global patch_bootstub_arm9reboot_readSdSectors_address
patch_bootstub_arm9reboot_readSdSectors_address:
.word 0
.global patch_bootstub_arm9reboot_dldi_address
patch_bootstub_arm9reboot_dldi_address:
.word 0
.global patch_bootstub_arm9reboot_launcher_path
patch_bootstub_arm9reboot_launcher_path:
.word 0
.global patch_bootstub_arm9reboot_loader_info
patch_bootstub_arm9reboot_loader_info:
.space 0x70 // sizeof(loader_info_t)
.balign 4
.cpu arm7tdmi
.global patch_bootstub_arm7reboot
.type patch_bootstub_arm7reboot, %function
patch_bootstub_arm7reboot:
// disable irqs
mov r0, #0x04000000
strb r0, [r0, #0x208]
bl copy_arm7_code
// sync with arm9
// make arm9 jump to arm9_after_arm7_sync
ldr r0,= 0x02FFFE24
adr r1, arm9_after_arm7_sync
str r1, [r0]
ldr r0,= 0x04000180
ldr r1,= 0x0C04000C // LIBNDS_RESET_CODE
str r1, [r0, #8]
mov pc, #0x03800000 // arm7 private ram
.type arm7_after_arm9_sync, %function
arm7_after_arm9_sync:
// disable irqs
mov r0, #0x04000000
strb r0, [r0, #0x208]
bl copy_arm7_code
mov r0, #0x03800000
add r0, r0, #(arm7_iwram_region_after_arm9_sync - arm7_iwram_region)
bx r0
copy_arm7_code:
adr r0, arm7_iwram_region
adr r1, arm7_iwram_region_end
mov r2, #0x03800000 // arm7 private ram
1:
cmp r0, r1
ldrne r3, [r0], #4
strne r3, [r2], #4
bne 1b
2:
bx lr
.balign 4
.pool
// Code loaded to arm7 private wram to avoid main memory contention
arm7_iwram_region:
// wait for 1 from arm9
1:
ldrb r1, [r0]
cmp r1, #1
bne 1b
// send 1 to arm9
ldr r1,= 0x100
strh r1, [r0]
// wait for 0 from arm9
1:
ldrb r1, [r0]
cmp r1, #0
bne 1b
// send 0 to arm9
strh r1, [r0]
arm7_iwram_region_after_arm9_sync:
ldr r0,= 0x04000180
// wait for 3 from arm9
1:
ldrb r1, [r0]
cmp r1, #3
bne 1b
// boot pico loader arm7
mov r0, #0x06000000
ldr r0, [r0]
bx r0
.balign 4
.pool
.balign 4
arm7_iwram_region_end:
.balign 4
.end