diff options
| author | Xavi Del Campo <xavi.dcr@tutanota.com> | 2020-01-31 10:32:23 +0100 |
|---|---|---|
| committer | Xavi Del Campo <xavi.dcr@tutanota.com> | 2020-01-31 10:32:23 +0100 |
| commit | 7c24e9a9b02b04dcaf9507acb94091ea70a2c02d (patch) | |
| tree | c28d0748652ad4b4222309e46e6cfc82c0906220 /libpsx/src/runexe | |
| parent | a2b7b6bb1cc2f4a3258b7b2dbc92399d151f864d (diff) | |
| download | psxsdk-7c24e9a9b02b04dcaf9507acb94091ea70a2c02d.tar.gz | |
Imported pristine psxsdk-20190410 from official repo
Diffstat (limited to 'libpsx/src/runexe')
| -rw-r--r-- | libpsx/src/runexe/runexe.c | 76 | ||||
| -rw-r--r-- | libpsx/src/runexe/stage2.s | 40 |
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: |
