tokumaru wrote:One could argue that dealing with this problem is a part of the learning process...
Yep!
tokumaru wrote:
... but there are cases when fixing this is very frustrating because it requires great changes in the game's architecture.
And yep again.
Fixed it! I was reluctant to disable my NMI because I'm doing sprite 0 hit for my status bar. So whenever I disable my NMI interrupt during gameplay, everything goes to hell.
Let me describe real quick what I did. A lot of this will be real basic to a lot of you, but just in case it might help some other people with a similar issue in the future.
I took advantage of a variable already in my NMI handler. This variable (called sleeping) gets set to 0 at the end of the NMI handler just before the registers are restored. In the gameloop, it doesn't proceed past the continuous loop into the rest of the engine unless this "sleeping" is 0 (meaning NMI has fired). This particular process I learned from Metalslime, but of course it's a variant of what a lot of you do in your gameloops.
I basically applied the same thing to the PRG bank switching subroutine. At the end of the sub, it now checks if the variable is 0. If not, it branches to RTS. If it is, then it resets the MMC1 latch by writing $80 to $8000 (just to be safe) and then jumps back to the beginning of the sub to re-write to REG3. Also, I've now added a couple of lines pushing my current PRG bank # to the stack (where the registers get pushed) at the beginning on NMI and pulling at the end. Yeah, I think this describes all of what I did.
Regardless, I set a breakpoint on the new part of bankswitching sub and it's working exactly like I needed it to. Also tested it on the NES and there wasn't any noticeable slowdown. Then again, I should hope not, as it's only dropping one of 60 frames about 3% of the time. (This bug frame overflow was really random, another thing that made it so damn hard to find.)
It's still going to be my policy to keep things within the frame as much as possible, but it's nice to have this safegaurd here in case that doesn't happen.
Thanks for the help folks!