Posting everything I have so far.
After hours of reverse engineering
literally everything that happens
(juggling two emulators, a bunch of scripts, tons of logs, etc. you get the idea), I found out a lot of things that
don't happen.
Process of elimination then got me to a conclusion which was quickly confirmed by a conversation with link_7777 (thanks for that!).
With that I then wrote a bot that would test a bunch of possible situations, but that was only possible thanks to the
emu.totalexecutedcycles() implemented by adelikat (thanks for that!).
Let's start with things we already got by simply trying:
Changing button presses changes if the glitch works or not.
So how does changing the button presses, !which, when processed, are not even read!, change the glitch results?
Now let's start with the further explanations:
The obvious thing that I already found out last time is how the whole process will jump to an address in the wrong bank. It will execute a bunch of bogus code and maybe land in the credits routine mode.
Now the question is, what is the difference between a result of a simple crash and a credits jump?
Logging both, comparing files, critical point at a certain
JSR $3C37, which jumps into the mirrors of the PPU registers.
3C37: 00 BRK
<BRK>
3C39: 00 BRK
<BRK>
3C3B: 00 BRK
<BRK>
3C3D: 00 BRK
<BRK>
3C3F:
I stopped at $3C3F because that's where the code differs. $3C3F is a mirror of $2007 which is the PPUDATA register. The important part here is the fact that
we're not in VBlank (the part of the frame where the scanline laser reverts back to the top left of the screen), and reading PPU registers when not in VBlank will give us strange values
[1], values used by the PPU drawing pixels on the screen.
What does this tell us?
It means two things:
1. Changing the pixels on the screen could change the results of the glitch.
2. Changing the time at which $3C3F is executed could change the results of the glitch.
And how do you change the timing? Exactly! Different button presses lead to different branch paths in the button processing code and thus lead to different timing. This also means that it's possible to exchange different buttons (assuming they both aren't accessed beyond the processig) and still get the credits! (Which is confirmed to work.)
Most importantly though, which timing do we need now? The problem is that even small cycles amounts can and will change the outcome completely, so I wrote a bot that tries every single cycle (to like +300, because we won't be able to change it much more). The only cycles it found was the one we already got, and
this one, which resets you to the start of the room. The one we already got requires so many buttons, and changing buttons before the frame with the mandatory Start barely changes the cycles, so it won't be possible to reduce that two frame input to a single one.
At least not without changing the pixels on the screen, which is what I'm trying currently.
[1] - You might have seen that $3C37 is also a mirror of $2007, but it seems like the first read of that register (including mirrors) in non-VBlank gives you a stable 00.