Super Mario Bros. starts in invalid world

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

The Lord
Posts: 9
Joined: Fri Dec 04, 2009 1:12 pm
Location: Berlin, Germany
Contact:

Super Mario Bros. starts in invalid world

Post by The Lord »

Hallo all,

years ago I made first experience in NES emulation. I managed to write an emulator which was capable of emulating simple no-mapper games correctly. Only problem was that SMB always started in the first water world.

Now, for about a week, I'm having my second go on it.
I built a new emulator from scratch, now working my way around all the mistakes I made on my first attempt.
It works really well, and I even got the PPU scrolling working just like it is described in Brad Taylor's PPU document.
All no-mapper games seem to work great.
Except SMB. It still has the same issue, though this time you don't start in first water world, but in a castle. And you are able to swim in there ;D

After starting emulation, the status bar shows "WORLD" 1-1 correctly for 1 frame (or a bit more), but then it immediately switches to someting like P-1. P being any weird symbol.
Still, the game intro is correctly playing in 1-1.

Any ideas what could cause this problem?

Thanks!
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Starting in the wrong world is one common symptom of an incorrect ROM dump. Have you checked your ROM with GoodNES?
The Lord
Posts: 9
Joined: Fri Dec 04, 2009 1:12 pm
Location: Berlin, Germany
Contact:

Post by The Lord »

That's incredible!
Indeed, when I use another rom of SMB, the problem doesn't occur.
Thanks for that hint!

But I still think there must be an issue with my emulator, because
the SMB rom that starts in the wrong world, works very fine with NESticle95. So NESticle95 must do something right, that my emulator doesn't.

Another symptom is, that - in my emulator - the background of world 1-1 is black instead of a light blue.
tepples
Posts: 22705
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

The Lord wrote:But I still think there must be an issue with my emulator, because
the SMB rom that starts in the wrong world, works very fine with NESticle95. So NESticle95 must do something right, that my emulator doesn't.
Nesticle is inaccurate. It was good for its time, but it was obsolete as soon as LoopyNES was released. Knowledge of how the NES actually works has advanced since then. It takes four lines of assembly language for a program to determine whether it is running on an NES or on Nesticle. The boot sequence of LJ65 incorporates code like the following:

Code: Select all

vwait2:
  bit $2002
  bpl vwait2
  bit $2002
  bmi is_running_on_nesticle
If you want to benchmark your emulator against another emulator running the same ROM, benchmark it against Nintendulator and Nestopia. If you want to be sure, benchmark it against an NES with a PowerPak.
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

It has entirely to do with whether you are initializing RAM to 00 or FF. If you initialize to 00, the bad dump of SMB1 works, and if you initialize to FF, it starts at 0-1.
Of course, you can always use the Continue feature (A+Start) and start at 1-1 regardless.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
The Lord
Posts: 9
Joined: Fri Dec 04, 2009 1:12 pm
Location: Berlin, Germany
Contact:

Post by The Lord »

Dwedit wrote:It has entirely to do with whether you are initializing RAM to 00 or FF. If you initialize to 00, the bad dump of SMB1 works, and if you initialize to FF, it starts at 0-1.
Of course, you can always use the Continue feature (A+Start) and start at 1-1 regardless.
Nice. You are completely right. Initializing the RAM to 0 did the trick.
Didn't know the NES clears its RAM.

tepples wrote:Nesticle is inaccurate.
Yes I though so. My point was, that Nesticle managed to execute SMB right. So that made me conclude that my emulator must have a bug that Nesticle doesn't have. And it had, as Dwedit made me realize.
User avatar
Dwedit
Posts: 4922
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

However, the NES's ram is approximately initialized to FFs in reality, so people trying to speedrun Final Fantasy (which relies on uninitialized memory for the RNG) will fail if memory is cleared to zeroes.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

The Lord wrote:Didn't know the NES clears its RAM.
It doesn't. If a game relies on any RAM it didn't initialize, it's badly programed (except if it's for generating random numbers, like Dwedit mentioned FF does).
So that made me conclude that my emulator must have a bug that Nesticle doesn't have.
Why can't Nesticle be the one with the bug? As tepples said, Nesticle is very old and many new things have been discovered about the NES since the last version of it. You should completely disregard what Nesticle does if you are aiming for accuracy, because you are trying to emulate a NES, not Nesticle. The emulators tepples mentioned (Nintendulator and Nestopia) are the most accurate nowadays.
And it had, as Dwedit made me realize.
Initializing the RAM to something other than 0 isn't a bug. The contents of RAM on start up shouldn't matter, because no well programmed game will rely on uninitialized RAM.

Don't make your emulator less accurate just to support a crappy hack or a bad dump. The ROM has a bug, not your emulator.
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers »

tepples wrote: If you want to be sure, benchmark it against an NES with a PowerPak.
Actually if you load it from the PowerPak, the RAM will probably be in an entirely pre-determined state by the time your program starts. I wonder if that messes up the Excitebike music variations or something like that.
The Lord
Posts: 9
Joined: Fri Dec 04, 2009 1:12 pm
Location: Berlin, Germany
Contact:

Post by The Lord »

tokumaru, I know what you mean.
The second SMB rom I tested doesn't depend on initial RAM content at all. It simply always works. And thats all to the good.

Thanks all, I guess that problem is solved for good.
User avatar
essial
Posts: 72
Joined: Thu Dec 03, 2009 8:20 am

Post by essial »

I've been eyeing these posts.. Would it be right to initialize ram to FF, or should it be initialized to random values throughout?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

essial wrote:I've been eyeing these posts.. Would it be right to initialize ram to FF, or should it be initialized to random values throughout?
People who have tested on hardware say that the RAM contains mostly $FFs, but this behaviour isn't constant enough for you to count on it. This is one of those things that change with the phase of the moon and you simply can't replicate exactly. So I guess you can do whatever you want with the RAM, it shouldn't matter.
User avatar
Memblers
Site Admin
Posts: 4044
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Post by Memblers »

I don't think it would be anywhere near white-noise style random on the real system (I haven't checked though, but you can see it when you don't clear the nametable memory). FCEU I noticed seems start out with some pattern of eight 00s then eight FFs. kinda helps for checking if people cleared RAM or not in their programs
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

In my NES programs I do the exact opposite of clearing RAM: I fill it with "random" values myself. I do this to make sure I haven't used any variable without initializing it properly. Of course I have to change the seed a few times to in order to detect if something is wrong with a new piece of logic. It doesn't catch everything, but it helps. I don't plan on leaving the code that randomizes RAM on the release versions though, this is just for debugging.

I always found clearing RAM an evil thing, because although it might save you some specific initializations it will make it easier for you to forget to initialize something. Say you have a routine that happens to work when it reads a zero from RAM. You forgot to clear that variable, but the routine will work because you cleared the whole memory before. So you tested the routine and have considered it works, and you decide to use it in other parts of the program. But if this particular byte happens to be changed by this very routine or by some other code, the other times this routine is called it might not work. That's a very hard bug to find, as you don't even have that routine in mind because you tested it before and it worked fine. This is why I consider clearing RAM evil. I initialize before I use it, always.
User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow »

Memblers wrote:I don't think it would be anywhere near white-noise style random on the real system (I haven't checked though, but you can see it when you don't clear the nametable memory). FCEU I noticed seems start out with some pattern of eight 00s then eight FFs. kinda helps for checking if people cleared RAM or not in their programs
I used to just leave the RAM contents alone but then I noticed that uninitialized it was typically CDCDCDCD values which just looked aesthetically wrong to me. So I now set it to zeros.
Post Reply