diff options
author | David Guillen Fandos | 2021-03-08 02:59:11 +0100 |
---|---|---|
committer | David Guillen Fandos | 2021-03-08 02:59:11 +0100 |
commit | 02e35339ee89f92d346d290c24497bbbae59ea79 (patch) | |
tree | 27713ac2cf1b7fc65716e402006c4aeb387d0fea /psp | |
parent | 3d558413fd42078f112dfee4ccc2e3c36978923f (diff) | |
download | picogpsp-02e35339ee89f92d346d290c24497bbbae59ea79.tar.gz picogpsp-02e35339ee89f92d346d290c24497bbbae59ea79.tar.bz2 picogpsp-02e35339ee89f92d346d290c24497bbbae59ea79.zip |
Fix a ghost bug with some games
Affects at least SM Adv 4 on PSP, which doesn't load at all.
I think the MIPS pipeline does not like invalidating the Icache and
using it immediately after (seems to read an old value sometimes?).
Rewired it to not do that and instead jump to the handler directly.
Diffstat (limited to 'psp')
-rw-r--r-- | psp/mips_stub.S | 36 |
1 files changed, 16 insertions, 20 deletions
diff --git a/psp/mips_stub.S b/psp/mips_stub.S index 031e4b5..420f602 100644 --- a/psp/mips_stub.S +++ b/psp/mips_stub.S @@ -277,19 +277,17 @@ mips_indirect_branch_dual: lui $2, %hi(\ftable) addu $2, $2, $1 lw $2, %lo(\ftable)($2) # new function handler is in $2 - srl $2, $2, 2 # remove lower two bits + sll $1, $2, 4 # shift left by 4 (6 LSB are zero) + ori $1, $1, 3 # Insert the opcode in the LSB + ror $1, $1, 6 # Rotate to the opcode is now in the MSB - lui $1, %hi(3 << 26) # $1 = 3 (JAL opcode) - ins $1, $2, 0, 26 # insert offset into jal + sw $1, -8($ra) # Overwrite jal instruction w/ new handler - addiu $ra, $ra, -8 # rewind return address to function call - sw $1, ($ra) # modify to call new handler - - cache 0x1a, ($ra) # hit writeback dcache line - cache 0x08, ($ra) # hit invalidate icache line + cache 0x1a, -8($ra) # hit writeback dcache line + cache 0x08, -8($ra) # hit invalidate icache line + jr $2 # Jump to new handler directly + nop - jr $ra # return - nop # wary of putting cache here .endm @@ -311,19 +309,17 @@ mips_indirect_branch_dual: addu $2, $2, $1 lw $2, %lo(\ftable)($2) # new function handler is in $2 - srl $2, $2, 2 # remove lower two bits + sll $1, $2, 4 # Build the new JAL instruction + ori $1, $1, 3 # same as above. + ror $1, $1, 6 - lui $1, %hi(3 << 26) # $1 = 3 (JAL opcode) - ins $1, $2, 0, 26 # insert offset into jal + sw $1, -8($ra) # modify to call new handler - addiu $ra, $ra, -8 # rewind return address to function call - sw $1, ($ra) # modify to call new handler - - cache 0x1a, ($ra) # hit writeback dcache line - cache 0x08, ($ra) # hit invalidate icache line + cache 0x1a, -8($ra) # hit writeback dcache line + cache 0x08, -8($ra) # hit invalidate icache line + jr $2 # Jump to new handler + nop - jr $ra # return - nop # wary of putting cache here .endm |