Phew, that's a long story and I haven't made notes so I forgot some of it.
I was using FCEUX. I was running the hex editor while playing to find patterns. Some memory adresses there were easy enough to spot (e.g. $0030 seems to be 0 when walking/standing, 1 when jumping/falling, 2 when hovering. $0328 and $033C are your X position, so e.g. absolute position 255 would be 255 at $0328 and 0 at $033C, while adding one to that (256) would be 0 at $0328 and 1 at $033C. This coordinate would be pretty easy to spot in the code in many situations.
While moving around, one address in particular seemed suspicious. $0314 only changes when moving left/right while jumping/falling. It is static when on the ground, static when hovering, static when jumping straight up/falling straight down. It was only changing when you were moving left/right in jump mode. It was increased by $C0(192) per frame when moving right and decreased by the same amount when moving left. This resulted in a pattern of four values $00, $40, $80, $C0 (0, 64, 128, 192) rapidly cycling on a per-frame basis.
I had a feeling I was on to something here and I had a theory: what if the carry flag from the +192 decided if you moved forward or not? Like, in 8-bit logic:
0 + 192 = 192 -- carry flag = 0
192 + 192 = 128 -- carry flag = 1
128 + 192 = 64 -- carry flag = 1
64 + 192 = 0 -- carry flag = 1
I had an idea that maybe the game decides if you move a pixel or not is decided by the carry flag from this operation. Move only when carry flag is set would mean 75% speed, which is exactly what you get in the game.
I set a cheat code to lock it to 0, and as expected, 0+192 would never set the carry flag, and I couldn't move right anymore during jump. Locking it to 192 meant subtracting 192 would never set the carry flag, so I couldn't move left anymore during jump. Locking it to 128 meant the carry flag would always be set either way, and indeed I got full 100% horizontal speed. It seemed to work.
Sadly, this messed up a few other things, like moving platforms. They also move at 75% speed, but locking the RAM value forced Firebrand to move at full speed instead of 75%, so he'd fall off the edge. It also messed with the pushback from the Blower boss. I realised that the end result stored at $0314 was a sum of several independent operations, and locking it would really mess with those.
So I started digging into the code via FCEUX's debugging disassembly. I understood a little of it thanks to my previous humble forays into x86 assembly, but was completely lost most of the time. With the help of this friggin amazing interactive 6502 tutorial:
http://skilldrick.github.io/easy6502/ I understood more.
In the end, I don't really remember how, I found that the game's jumping subroutine stores $C0(192) at $038C before that value is added to/subtracted from $0314. Locking this value via cheat code again didn't do any good either, but tbh I don't remember how exactly. However, changing this particular instruction in the ROM (changing the value to be added/subtracted) to value $FF so that it would set the carry flag in 255 of 256 frames did the trick. No issues with platforms or Blower. That's how I got here.
December 11, 2020, 06:51:43 pm - (Auto Merged - Double Posts are not allowed before 7 days.)
Uploaded it to RHDN, here's the link if anyone's interested:
https://www.romhacking.net/hacks/5590/