ssss0000: Position fraction bits, Stored in RAM $13DA and $13DC
ssss = subpixels, this ranges from 0-15.
PPPPPPPPPPPPPPPP: Position, in pixels (stored in $94 and $96). Ranges from 0-65535 (or (-32768) to 32767 in the signed context)
Mario's speed data ($7B and $7D) is formatted like this in binary:
ssss = subpixels
PPP = pixels. When the S bit is clear, this is treated as 0000000000000PPP, otherwise 1111111111111PPP. Therefore increasing the size and keeping the value it represents.
S = sign bit
To perform movement:
- First take the speed value's SPPPssss, move it to the high nybble (4 ASLs, SPPPssss becomes ssss0000) and add it with the fraction bits, store that as the new fraction bits. The carry bit after adding will be used later (if the addition exceeds 15, carry is set, otherwise clear).
- Second, we are handling the P bits. The speed value is only 3-bit and the pixel position is 16-bit, so we need to expand the number of bits so that we can correctly adjust to the 16-bit position. We take the speed value, and move the upper nybble to the lower (4 LSRs) so that the PPP bits are at the lowest bit position (it is now 0000SPPP). Check if the S bit is set (CMP #$08), and if not (less than 8), treat it as 0000000000000PPP otherwise (≥ 8) 1111111111111PPP. This handles the data using two's complement when handling signed values.
- Finally, perform movement in pixels. We take the expanded value from the previous step, and add by the pixel position, adding with the carry obtained from the first step (so that if enough fractional movement are made, move an additional pixel).