User File #637864080729078524

Upload All User Files

#637864080729078524 - Gimmick! "Subframe Inputs" in 00:00.25

Gimmick!_15f_100th_Coin.bk2
In 00:00.25 (15 frames), 360 rerecords
Game: Gimmick! ( NES, see all files )
5 comments, 141 downloads
Uploaded 4/24/2022 2:41 PM by OnehundredthCoin (see all 12)
Use the Bizhawk SubNesHawk Core to watch. (Or the youtube link)
This has not been console verified yet, so if anybody wants to give it a go, it would be very appreciated. But you should know this run involves executing uninitialized RAM as code, (using bizhawk's 00 00 00 00 FF FF FF FF pattern) so keep that in mind. I'm hesitant to submit a Subframe Input TAS without console verification.
In this TAS, I complete the Game "Gimmick" by utilizing subframe inputs, not unlike my TAS of Super Mario Bros. 3. More info on the technical details if verified, but I'll explain a general idea of how the "route" works.
At the moment I execute RAM as code, the game has uninitialized RAM from address $F1 through $F4. This is a bit problematic for verification, but it's also the key idea of how this run works. Controller data is stored at $F5 through $F8, in pretty much the same manner as SMB3.
Circling back to the uninitialized RAM, bizhawk's "00 00 00 00 FF FF FF FF" pattern for RAM on console boot leaves address $F2 with "00" and $F4 with "FF". Both of those bytes get executed, and "FF" is a 3 byte instruction. That limits the number of "controller bytes" from 4 to 2. (Those are also the only uninitialized bytes that get executed. Gimmick! Clears the first 240 bytes of the zero page, leaving $F0 - $FF uninitialized, but by the time I execute code, the only uninitialized bytes are $F1 through $F4)
On the first frame with inputs, I 'stall' for 58 inputs, then using both controllers, I write STY $00F4. This replaces the "FF" at address $F4 with "08", as that's what was held in the Y register. This creates a PHP instruction, but what's more useful is that it's only 1 byte long. Now I have the full 4 "controller bytes"
I reset the console, and recall that address $F4 is uninitialized. That means when resetting, Gimmick doesn't clear the 08. I might go back and try to improve this TAS, but the subframe mashing to execute code seems to only work on the first frame with inputs. I need to strategically write JSR $E0F0, or 20 F0 E0 written as bytes. I need to hold down E0 (A + B + Select) on controller 1, while the new inputs are 20 (Select) so I use the first possible frame after resetting to hold down A + B. Then I reset again.
On the third and final loop, I repeat the same subframe mashing as before, and hold down the buttons that write JSR $E0F0, which wins the game when executed.
If I could find a way to offset the code so I can execute 3 controller bytes while also lining up the 20 F0 E0 for loop 2, I could save 5 frames. Likewise, if I can execute RAM after the first frame with inputs, it's likely I could cut out the second reset, saving time.
Samsara
on 4/24/2022 2:43 PM
\o/
DJ_Incendration
on 4/24/2022 6:42 PM
Why are you hesitant to submit it without console verification? It beats the game way faster than any previous submission.
OnehundredthCoin
on 4/24/2022 7:34 PM
Console verification might not be as important as I think it is, but if the TAS fails to win the game on actual hardware then it's not accurate. It would be like publishing misinformation. I'd like to make sure it works on console, just in case there's an inaccuracy in the emulator's part that allows for this run to work, where it would otherwise not work on console. If the run didn't require subframe inputs then I wouldn't be as concerned, but the timing of this exploit is extremely precise.
Alyosha
on 4/24/2022 8:34 PM
Neat. I have verified a few TASes that rely on uninitialized RAM by using a cart that sets RAM to the 00 FF pattern and then power cycling (and hoping it doesn't decay in between changing carts.)
More recent work seems to indicate that RAM is more likely all zeros at power on, but I haven't read out all values to check. There is also the fact that Gimmick is a Famicom game, and I have no knowledge of the power on state of a Famicom. I suppose it could still be run on a US NES anyway though.
Would it still work with all 0's?
OnehundredthCoin
on 4/24/2022 8:43 PM
I don't think it would work with all zeroes, since $F4 would be a two byte long instruction instead of a three byte long instruction. I would need to flip controller 1 and 2's inputs for the first section.