Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- So when VC hits an instruction in needs to recompile (meaning turn the MIPS instruction into PPC) It'll run through the recompile function 80039fe4
- The crashing instruction is at N64 803903FC Which is a LW t6, 0xFFFE(T4)
- T4 *should* be a pointer to the entrance for this exit which is calculated from t4 = t3 + t5 where t3 *should* be a pointer to all the scene exits, and t5 exit number, For this scene setup there is no exit list defined, so t3 is 0, so t4 = t4 + t5 which is an invalid address and why n64/emu crashes.
- So this is what happens on VC, the instruction LW t6, 0xFFFE(T4) 858efffe which this instruction is encoded as
- LW t i(s)
- 0b10000101100011101111111111111110
- oooooossssstttttiiiiiiiiiiiiiiii
- o = opcode 0b100001 (LW)
- s = 0b01100 0xC Which is T4 Source register
- t = 0b01110 0xE Which is T6 Destination Register
- i = 0b1111111111111110 which is -2 immediate value (signed 16 bit integer)
- r0 contains the instruction
- At 0x809F6C80 on VC is all the emulated registers, VC extracts the s portion of the instruction by doing a
- rlwinm r4, r0, 14, 24, 28
- This instruction is really stupid, but basically it left rotates r0 by 14 bits, then creates a mask to and with bits 24-28....the overall result of this instruction is s * 8
- The emulated registers plus the previous calculation is loaded into a register r5, which *should* be the memory address of the entrance for this exit, but in this case It's simply 0 (Null ptr) + exit
- r5 is then added with the i value and placed in r7 which is extracted from the instruction via
- rlwinm r6, r0, 0, 16, 31
- This just takes the instruction and and's it with 0xFFFF giving 0xfffe (-2)
- So at this point r7 contains the address to load from which is 0x04, 0x06, or some invalid value based on which lz you're trying
- This is a bit irrelevant for this, but this is how the rest of the load works
- r7 is then and'd with 0xFFFF0000 via
- rlwinm r5, r7, 16, 16, 31
- Without getting into too many specifics at this point r5 should contains something like 0x8XXX, but it's 0, VC has a table which is indexed by r5 telling us where in memory to load from. The address to load from is added to the address we're trying to load, then placed in the t register, and things continue as they should
- BUT before the actual load happens VC checks if the address is valid by running
- rlwinm r5, r7, 4, 28, 31
- This takes the most significant 4 bits of the address to load, and compares it with 8. If it is 8 then it goes to what I mentioned before, and loads the address and goes on its happy way. If it is NOT 8, then the whole load instruction is essentially skipped, and the recompiler simply places a branch of the next instruction in place, leaving the emulated t6 register at it's previous value
- So why does the entrance seem to differ with links Y position? Because it IS links Y position at the time the loading zone is triggered. The last time that T6 is loaded it is via a
- mfc1 t6, f6
- f6 is gotten from links y value which is then truncated (floor) So if links y is currently 83.925 (0x42a7d99a), it is rounded down towards 83 (0x53), and that is the value of t6. VC will use that value for the entrance
- TL;DR VC loads odd entrances
- VC will ignore a load instruction if it determines the address to load from is not in the format 0x8XXXXXXX. In this case, it is attempted to read an invalid value, the load is ignored, and the next instruction is to store the next entrance. The value to store is links y value at this point because the load was ignored.
- TL;DR For Crash
- There are no defined exits for the scene setup for the credits. When attempted to exit the scene, it references the scene list at a null pointer
Add Comment
Please, Sign In to add comment