Micro Optimizations - RetroKoH/S1Fixed GitHub Wiki
(Compilation Guide by RetroKoH)
The following is a collection of micro-optimizations made throughout S1Fixed. Credit for each one is attributed based on where and how I learned about said method when applying it to S1Fixed.
In-depth information on potential optimizations can be found at this page. (Credit: flamewing)
Quick Moves
Credit: Filter
Throughout your disassembly, you'll find instructions moving number values to data registers (d0-d7). Here is one example that we will focus on for the purposes of this guide:
Rock_Solid: ; Routine 2
move.w #$1B,d1 ; width [8 (2/0)] 4
move.w #$10,d2 ; height (jumping) [8 (2/0)] 4
move.w #$10,d3 ; height (walking) [8 (2/0)] 4
move.w obX(a0),d4 ; axis position
bsr.w SolidObject ; check for Sonic's collision
In this example, 3 values are loaded to registers d1, d2, and d3, using move.w. When loading to a data register like this, it is twice as fast to use a quick move. Let's look at an improved version:
Rock_Solid: ; Routine 2
! moveq #$1B,d1 ; width [4 (1/0)] 2
! moveq #$10,d2 ; height (jumping) [4 (1/0)] 2
! moveq #$10,d3 ; height (walking) [4 (1/0)] 2
move.w obX(a0),d4 ; axis position
bsr.w SolidObject ; check for Sonic's collision
The result is the exact same, AND it clears out the entire register when loading the value, which can be quite helpful. Do note that the moveq instruction only works on immediate number vales and data registers, hence why we didn't change the 4th instruction. Also, we are limited to a range of $00-$7F when using this instruction.
Quicker AND Instructions
Credit: TheBlad768
It is quite common that you will want to use an AND instruction to isolate specific bits of a value to test for certain conditions. This is most commonly done with the obSubtype and obStatus OST bytes. This often looks something like:
move.b obSubtype(a0),d0
andi.b #$1F,d0
Note that it's possible to see moveq #0,d0 above these instructions in order to clear the register. Now, this works, and there is absolutely nothing wrong with it, but we can optimize this, AND remove the need for a potential third clearing instruction by doing this instead:
moveq #$1F,d0
and.b obSubtype(a0),d0