I mentioned this in another thread, but didn't want to clutter up that thread with too many details.
If you compile the mupen64plus update that I posted a few days ago then you will find that since I fixed the DSRLV instruction, Super Smash Bros runs for awhile, but crashes when you try to play. This is because of another bug...
I do constant folding to combine the results from LUI, ADDI and similar instructions. When the instructions are decoded, a series of flags are set which identify registers with known constants. During assembly, the normal assembly of these instructions is suppressed, and instead load_consts() calls get_final_value() to determine what the combined constant ends up being. This value is then loaded with movw/movt (or from the constant pool if generating ARMv5 code).
The mistake I made was that I used the same bit to flag when the output of the instruction is a constant (as in LUI) and where the input is a constant (as in LW). Super Smash Bros contains the following code:
Result was that things got mixed up since the isconst flag for r8 was set through this entire sequence including the last instruction. I'm rather amazed that SSB was the only game that triggered this bug.
Once I made separate flags for inputs and outputs then it worked correctly.
The game still doesn't work well due to really high CPU usage. This is especially noticable in the "vs Yoshi Team" battle where there are a lot of characters on the screen. The N64 has to compute 3D vectors on the MIPS CPU, so CPU load tends to scale with polygon count.
This could possibly be improved by reducing the FPU precision somewhat (eg using NEON) but I am loath to do that since it will make it very difficult to find bugs like the example above amongst a whole bunch of differences caused by floating-point values being slightly inaccurate.
If you compile the mupen64plus update that I posted a few days ago then you will find that since I fixed the DSRLV instruction, Super Smash Bros runs for awhile, but crashes when you try to play. This is because of another bug...
I do constant folding to combine the results from LUI, ADDI and similar instructions. When the instructions are decoded, a series of flags are set which identify registers with known constants. During assembly, the normal assembly of these instructions is suppressed, and instead load_consts() calls get_final_value() to determine what the combined constant ends up being. This value is then loaded with movw/movt (or from the constant pool if generating ARMv5 code).
The mistake I made was that I used the same bit to flag when the output of the instruction is a constant (as in LUI) and where the input is a constant (as in LW). Super Smash Bros contains the following code:
Code:
80137478: LUI r8,80140000
8013747c: ADDIU r8,r8,-29648 (ffff8c30)
80137488: LW r10,r8+0 (00000000)
...
801374b8: LW r9,r8+12 (0000000c)
801374bc: LUI r8,80140000
...
801374e0: LW r8,r8-26976 (ffff96a0)
Once I made separate flags for inputs and outputs then it worked correctly.
The game still doesn't work well due to really high CPU usage. This is especially noticable in the "vs Yoshi Team" battle where there are a lot of characters on the screen. The N64 has to compute 3D vectors on the MIPS CPU, so CPU load tends to scale with polygon count.
This could possibly be improved by reducing the FPU precision somewhat (eg using NEON) but I am loath to do that since it will make it very difficult to find bugs like the example above amongst a whole bunch of differences caused by floating-point values being slightly inaccurate.