summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Guillen Fandos2021-03-08 02:59:11 +0100
committerDavid Guillen Fandos2021-03-08 02:59:11 +0100
commit02e35339ee89f92d346d290c24497bbbae59ea79 (patch)
tree27713ac2cf1b7fc65716e402006c4aeb387d0fea
parent3d558413fd42078f112dfee4ccc2e3c36978923f (diff)
downloadpicogpsp-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.
-rw-r--r--psp/mips_stub.S36
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