It's not like there's really any other way to implement this, unless I were to stick it in memory elsewhere. The assembly would still be the same other than the offset.
.global _start
_start:
// Interesting registers and locations to keep in mind, set before this code is ran:
- // - sp + 0x3A8 - 0x70: FIRM path in exefs.
- // - r7 (which is sp + 0x3A8 - 0x198): Reserved space for file handle
- // - *(sp + 0x3A8 - 0x198) + 0x28: fread function.
+ // - r1: FIRM path in exefs.
+ // - r7: Reserved space for file handle
+ // - *(*r7 + 0x28): fread function.
+
+ mov r8, r1
pxi_wait_recv:
ldr r2, =0x44846
ldr r6, [r6, #0x28]
blx r6
+ // Copy the low TID (in UTF-16) of the wanted firm to the 5th byte of the payload
+ ldr r0, =load_addr
+ add r0, #4
+ add r1, r8, #0x1A
+ mov r2, #0x10
+ bl memcpy16
+
// Set kernel state
mov r0, #0
mov r1, #0
die:
b die
+ memcpy16:
+ add r2, r0, r2
+ copy_loop:
+ ldrh r3, [r1], #2
+ strh r3, [r0], #2
+ cmp r0, r2
+ blo copy_loop
+ bx lr
+
+title: .word 0
bytes_read: .word 0
fopen: .ascii "OPEN"
koffset_base: .word kernel_code-jump_to_kernel-12
extern int changed_consoles;
+extern uint16_t titleid_passthru[8];
+
+int get_firmtype() {
+ if (titleid_passthru[5] >= u'0' && titleid_passthru[5] <= u'2')
+ return titleid_passthru[5] - u'0';
+
+ return 0;
+}
+
int
main(int argc, char** argv)
{
- if (ctr_hid_get_buttons() & CTR_HID_LT)
+ if (get_firmtype() != 0)
ctr_system_poweroff();
int have_bg = 0;
.global _start
.section .text.start, "x"
_start:
+ b init
+
+.global titleid_passthru
+titleid_passthru: .fill 8, 2, 0
+argc: .int 0
+argv: .int 0
+
+init:
ldr r2, =argc
str r0, [r2]
ldr r2, =argv
str r1, [r2]
- b init
-
-argc: .int 0x00000000
-argv: .int 0x00000000
-
-init:
// Disable IRQ
mrs r0, cpsr
orr r0, r0, #0x80