summaryrefslogtreecommitdiff
path: root/libpsx/src/runexe
diff options
context:
space:
mode:
authorXavi Del Campo <xavi.dcr@tutanota.com>2020-01-31 10:32:23 +0100
committerXavi Del Campo <xavi.dcr@tutanota.com>2020-01-31 10:32:23 +0100
commit7c24e9a9b02b04dcaf9507acb94091ea70a2c02d (patch)
treec28d0748652ad4b4222309e46e6cfc82c0906220 /libpsx/src/runexe
parenta2b7b6bb1cc2f4a3258b7b2dbc92399d151f864d (diff)
downloadpsxsdk-7c24e9a9b02b04dcaf9507acb94091ea70a2c02d.tar.gz
Imported pristine psxsdk-20190410 from official repo
Diffstat (limited to 'libpsx/src/runexe')
-rw-r--r--libpsx/src/runexe/runexe.c76
-rw-r--r--libpsx/src/runexe/stage2.s40
2 files changed, 116 insertions, 0 deletions
diff --git a/libpsx/src/runexe/runexe.c b/libpsx/src/runexe/runexe.c
new file mode 100644
index 0000000..5fe22b0
--- /dev/null
+++ b/libpsx/src/runexe/runexe.c
@@ -0,0 +1,76 @@
+/**
+ * PSXSDK
+ *
+ * RunEXE functionality
+ */
+
+#include <psx.h>
+#include <stdio.h>
+#include <string.h>
+#include <runexe.h>
+
+// Include runexe stage2 position independent code
+
+extern void PSX_RunExeStage2();
+extern void PSX_RunExeStage2_END();
+
+static void *runExeBuffer;
+
+int PSX_RunExe(void *exeBuffer)
+{
+ //unsigned char *exe = exeBuffer;
+ unsigned int *exe = exeBuffer;
+// Size of position indipendent code
+ int sz = PSX_RunExeStage2_END -
+ PSX_RunExeStage2;
+
+ if(!(PSX_GetInitFlags() & PSX_INIT_SAVESTATE))
+ {
+ printf("RunExe error: State was not saved!\n");
+ return 0;
+ }
+
+ if(((unsigned int)exeBuffer & 3))
+ {
+ printf("RunExe: Alignment violation.\n");
+ printf("Specified buffer must have an address which is a multiplier of 4.\n");
+ return 0;
+ }
+
+ // Check magic string
+ if(strcmp(exeBuffer, "PS-X EXE") != 0)
+ return 0; // Return failure if magic string couldn't be found
+
+ runExeBuffer = exeBuffer;
+
+ printf("PSXSDK RunExe Debug Information\n");
+ printf("t_addr = %08x\n", exe[6]);
+ printf("t_size = %08x\n", exe[7]);
+ printf("d_addr = %08x\n", exe[8]);
+ printf("d_size = %08x\n", exe[9]);
+ printf("b_addr = %08x\n", exe[10]);
+ printf("b_size = %08x\n", exe[11]);
+ printf("s_addr = %08x\n", exe[12]);
+ printf("s_size = %08x\n", exe[13]);
+
+ printf("OK..! Farewell.\n");
+
+// Deinitialize the PSXSDK library
+ PSX_DeInit();
+
+// Copy the position independent stage2 code in high memory
+ memcpy((void*)0x801fef00, PSX_RunExeStage2, sz);
+
+// Stack is unusable now! Do not do anything else except calling the stage2 code.
+
+// Jump to the stage2 code without using the stack..
+
+ __asm__("la $a0, runExeBuffer");
+ __asm__("nop");
+ __asm__("lw $a0, 0($a0)");
+ __asm__("j 0x801fef00");
+ __asm__("nop");
+
+// This is never reached but keep the compiler happy
+ return 0;
+}
diff --git a/libpsx/src/runexe/stage2.s b/libpsx/src/runexe/stage2.s
new file mode 100644
index 0000000..e60e109
--- /dev/null
+++ b/libpsx/src/runexe/stage2.s
@@ -0,0 +1,40 @@
+.global PSX_RunExeStage2
+.global PSX_RunExeStage2_END
+
+PSX_RunExeStage2:
+# a0 = address of PSX-EXE buffer
+
+# Load initial program counter in t0
+ lw $t0, 0x10($a0)
+# Load text section address in t1
+ lw $t1, 0x18($a0)
+# Load text section size in t2
+ lw $t2, 0x1c($a0)
+
+# Load initial sp register value in sp
+ lw $sp, 0x30($a0)
+
+# t3 = current source address
+ addiu $t3, $a0, 0x800
+
+# t4 = current destination address
+ addu $t4, $t1, $zero
+
+copyExeLoop:
+ beq $t2, $zero, copyExeLoop_End
+ nop
+copyExeLoop_2:
+ lb $t5, 0($t3)
+ nop
+ sb $t5, 0($t4)
+ addiu $t3, $t3, 1
+ addiu $t4, $t4, 1
+ addiu $t2, $t2, -1
+ beq $zero, $zero, copyExeLoop
+
+copyExeLoop_End:
+# Jump to the program we loaded
+ jr $t0
+ nop
+
+PSX_RunExeStage2_END: