Hopefully this will be relatively short - relative to me I mean.
Using Mode-7 for 24-Bit Multiplication:If, for example, we need to multiply 60,186 ($EB1A) by 67 ($43) the result should be 4,032,462 ($3D87CE)
To do this with the Mode-7 Registers that would require code similar to this:
LDA #$1A
STA $211B
LDA #$EB
STA $211B
LDA #$43
STA $211CThe Multiplication starts when $211C is written and the result is:
$2134 = CE
$2135 = 87
$2136 = 3DThat's useful, but not the purpose for which those registers were designed. They were set up specifically to handle the fractionals that show up in rotation and scaling. So a more appropriate example would be this:
18.29 x 67 = 1225.43 ~ 1,225
The trick needed for this calculation is to upscale the 16-bit multiplicand by 256:
18.29 x 256 = 4682.24 ~ 4,682
Then use that number to do the multiplication as shown above. The result is:
4682 x 67 = 313,694
But because we scaled up before we need to scale down to get the real answer:
313694 / 256 = 1225.37 ~ 1225
So in the end it's 1225.37 vs 1225.43, but since we will just ignore the fractional in the end anyway it doesn't matter. The important thing is that by multiplying by 256 we keep the fractional around for computation and then by dividing by 256 we ignore it for later use. The best part is that the final division doesn't need to be performed: just ignore the value in $2134 and read $2135-$2136 as a 16-Bit value and then that's that!
I do not mind saying that given the hardware this seems a pretty clever method to make games like F-Zero possible; I'd never even have thought that such calculations were taking place. Fortunately there should not be too many conflicts in using these registers for our own purposes since FF4 is not a Mode-7 intensive game.