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.
This commit is contained in:
David Guillen Fandos 2021-03-08 02:59:11 +01:00
parent 3d558413fd
commit 02e35339ee
1 changed files with 16 additions and 20 deletions

View File

@ -277,19 +277,17 @@ mips_indirect_branch_dual:
lui $2, %hi(\ftable) lui $2, %hi(\ftable)
addu $2, $2, $1 addu $2, $2, $1
lw $2, %lo(\ftable)($2) # new function handler is in $2 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) sw $1, -8($ra) # Overwrite jal instruction w/ new handler
ins $1, $2, 0, 26 # insert offset into jal
addiu $ra, $ra, -8 # rewind return address to function call cache 0x1a, -8($ra) # hit writeback dcache line
sw $1, ($ra) # modify to call new handler cache 0x08, -8($ra) # hit invalidate icache line
jr $2 # Jump to new handler directly
nop
cache 0x1a, ($ra) # hit writeback dcache line
cache 0x08, ($ra) # hit invalidate icache line
jr $ra # return
nop # wary of putting cache here
.endm .endm
@ -311,19 +309,17 @@ mips_indirect_branch_dual:
addu $2, $2, $1 addu $2, $2, $1
lw $2, %lo(\ftable)($2) # new function handler is in $2 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) sw $1, -8($ra) # modify to call new handler
ins $1, $2, 0, 26 # insert offset into jal
addiu $ra, $ra, -8 # rewind return address to function call cache 0x1a, -8($ra) # hit writeback dcache line
sw $1, ($ra) # modify to call new handler cache 0x08, -8($ra) # hit invalidate icache line
jr $2 # Jump to new handler
nop
cache 0x1a, ($ra) # hit writeback dcache line
cache 0x08, ($ra) # hit invalidate icache line
jr $ra # return
nop # wary of putting cache here
.endm .endm