Annoying Crash/Reset Bug

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Annoying Crash/Reset Bug

Post by neilbaldwin »

I've got quite a nasty crash/reset bug in my project. It occurs when it's running right on the edge of using too much CPU time in a frame but is it normal for the NES to reset itself in those kind of circumstances? It happens both on hardware (via PowerPak) and in Nestopia (but oddly I can't make it happen in Nintendulator).

There's a lot of PRG and WRAM bank-switching going on so that's probably where I'm going to start looking but I'm pretty fastidious with making sure the correct banks are switched (excessively some might say).

Problem is, because of the configuration, I can only run it in Nestopia (which doesn't have debugging) or Nintendulator (which does but the crash doesn't happen).


Any tips or ideas?
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

This sure sounds like an annoying bug.

I'd check how you handle interrupts and stack. Maybe this is due to an NMI interrupting right before the frame finishes, and then the next NMI acts the same etc... and this leads the stack to overflow. This is pure speculation though.
Useless, lumbering half-wits don't scare us.
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

Definitely sounds like a possibility.

OK, this might be a dumb question but: how would you prevent that from happening?
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

That was a dumb question. I just moved a big chunk of code out of the NMI and put it in the background loop.

Seems a lot more stable. Schoolboy error :)
User avatar
MottZilla
Posts: 2835
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

Still isn't that just hiding the problem? Your program shouldn't crash because too much cpu time is used in a frame. While you could go on like that just trying to make it impossible for that to happen, what if you miss something? Crashing bugs are definitely not something you want to leave unfixed.
User avatar
Memblers
Site Admin
Posts: 3901
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers »

You can increment a counter in the NMI, and decrement it before returning. If the increment makes it higher than 1, then it's a recursive NMI. I think I had seen code like that in Metroid.
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

MottZilla wrote:Still isn't that just hiding the problem? Your program shouldn't crash because too much cpu time is used in a frame. While you could go on like that just trying to make it impossible for that to happen, what if you miss something? Crashing bugs are definitely not something you want to leave unfixed.
Oh, I totally agree.

Evidence would definitely point to a recursive NMI though - if I added deliberate delay loops into the block of code (that I've now moved to background loop), it would crash with far higher frequency.

Now that I (hopefully) know what conditions are causing the issue I can try to figure out how to cope with them.

So far though, without changing any other code, it survived an extended period of 'stress testing'.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

If you did it the "everything in NMI way", then you'd want to make sure only the first "quick" part of the NMI (video + sound) is done each time, but that the next part (logic) is only done if there isn't any previous NMI going on.
Useless, lumbering half-wits don't scare us.
User avatar
neilbaldwin
Posts: 481
Joined: Tue Apr 28, 2009 4:12 am
Contact:

Post by neilbaldwin »

I have a feeling that what happens is that because I'm saving the current PRG bank and the current WRAM bank at the start of the NMI and then restoring it at the end, if I get a recursive NMI the PRG/WRAM banks could get restored to the wrong values.

For example, say the PRG bank was set to 0 when the NMI occurred and then in the NMI I'm switching the PRG bank to 1 (where, say, my screen code is located), then restoring it back to 0 on exiting the NMI. If the PRG bank hasn't been restored by the time another NMI occurs, the saved PRG bank then becomes 1, so when it does eventually get restored from the saved value (next frame), it gets restored to 1 instead of the 0 that it was originally.

I'm pretty sure that's what was happening. I'd be interested in suggestions of how to get around that although I have moved code around (out of the NMI) now and it's a lot more stable.
User avatar
Bregalad
Posts: 8036
Joined: Fri Nov 12, 2004 2:49 pm
Location: Caen, France

Post by Bregalad »

I'd suggest save the old bank on the stack instead of using a fixed memory adress.
Useless, lumbering half-wits don't scare us.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

If you save data to the stack instead of fixed memory locations (variables), as long as the stack doesn't overflow everything can be restored correctly.
Post Reply