PPU Nametables

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

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

Post by tepples »

Initialized by the program? Nametables should be initialized with whatever the blank tile is in the CHR bank. This might be zeroes, or it might be space characters ($20) in a game that uses ASCII for tiles $20-$3F, or it might be $24 in a game that uses the same character encoding as Donkey Kong, Super Mario Bros., and a lot of other early NES games.

Initialized by the emulator? That depends on what make and model of RAM chip you're emulating. But make sure you write something there so that an NES game can't covertly read private data from other applications running on the same PC as the game.
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

Tepples, what would be the point of that? It's not like the NES game can then send that information out to the world. That is kind of funny though.

Usually people just zeroed out memory even though that is not accurate. I think FCEUX has a pattern of FFs and 00s. Other emulators initialize everything to like 55 or 53. As tepples said, the real hardware depending on the RAM chip.
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper »

I remember of a few homebrews seem glitched with $FF. OK, perhaps programming errors.
User avatar
Dwedit
Posts: 4924
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

While we're talking about memory initialization: here's some trivia:

Metroid won't boot if CHR-RAM is initialized to certain values. Don't know exactly what values trigger boot failure, but for a while, FCEUX wouldn't boot Metroid if you launched it from the command line. FCEUX did not initlaize CHR-RAM at all, leaving it as whatever was in the PC's memory at the time. After FCEUX started initializing CHR-RAM, Metroid worked again.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

Which shows bad programming on Nintendo's part. You should never use uninitialized memory.
User avatar
Gilbert
Posts: 564
Joined: Sun Dec 12, 2010 10:27 pm
Location: Hong Kong
Contact:

Post by Gilbert »

I think this was possibly because the game was originally programmed for the FDS, in which RAM was supposed to have been initialised before the game booting. The programmers did overlook this important aspect when they converted the game to cart format though.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

MottZilla wrote:It's not like the NES game can then send that information out to the world
Except through steganography. In theory, it can leak data by changing the seed to generate e.g. grass tiles in CHR RAM, which would appear in a screenshot from that emulator. Or perhaps I'm just being as PARANOiD as the OpenBSD people here; any practical application would need inside information comparable to that used to make Stuxnet.
Which shows bad programming on Nintendo's part. You should never use uninitialized memory.
Unless you're looking for signatures that game copier units are known to leave behind, such as the trampoline in RAM that they use to start executing the game.
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

Perhaps, that is possible. They would have to assume that RAM chips would have a specific power on state and that never could you reset the system with the wrong values in place. Really I just think it's bad code. Though that is a good point Gilbert, perhaps because it was a FDS game conversion maybe it assumes the FDS BIOS had run before it.
3gengames
Formerly 65024U
Posts: 2284
Joined: Sat Mar 27, 2010 12:57 pm

Post by 3gengames »

tepples wrote:
MottZilla wrote:
Which shows bad programming on Nintendo's part. You should never use uninitialized memory.
Unless you're looking for signatures that game copier units are known to leave behind
Well if it's equal to those values than it is initialized.
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

No you don't understand. RAM is in an undetermined state on powerup or reset. You cannot assume RAM is all zeroes or all FF or any other pattern. You can check RAM to see if there is integrity markers for some sort of on Reset behavior. X-Men on Sega Genesis does this. But generally you should never use memory that has not been initialized. It could contain anything on power up/reset. Assuming a state is how you end up with software that only works on emulators that initialize this specific state. The same can be said of registers like PPU registers. Their state cannot be assumed on reset.
User avatar
Zepper
Formerly Fx3
Posts: 3262
Joined: Fri Nov 12, 2004 4:59 pm
Location: Brazil
Contact:

Post by Zepper »

In short words, fill up your nametables with $00 and you should be fine. Be clear that the NES hardware might behave differently though.
Bisqwit
Posts: 249
Joined: Fri Oct 14, 2011 1:09 am

Post by Bisqwit »

If you must not read the RAM upon powerup/reset, how are you supposed to detect that the reset button was pressed? Some games do that.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

It's obviously OK to do it if you're looking for signatures (which have been initialized before). What you can't do is use memory locations that have not been initialized.
Bisqwit
Posts: 249
Joined: Fri Oct 14, 2011 1:09 am

Post by Bisqwit »

Depending on particular values in the RAM for functionality is bad, I agree, but how about using the RAM contents to seed the random generator?

Is reading the RAM after poweron a bad idea on electronic basis, or is it just a bad idea because of programming practices basis? In the former case, trying to detect the reset is also a bad idea.
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

It's very simple. On powerup RAM could contain any value at any location. In reality it depends on the chip. I believe they generally have a certain pattern to them. This will only be the case when you power on, not when you reset as RAM contents will contain whatever was there when you reset still.

So to detect a "reset" you just need to reserve some RAM for a signature that you will set at some point in your program. The signature should be defined and not something that would possibly be the value on ram powerup. So you'd want to avoid 00 or FF, and probably F0 or 0F. The more bytes you use the more reliable it is, the easiest thing to do is just a 3 byte string. I mean you could just write the word CAT or DOG to ram and check for it on reset to detect a powerup versus just a reset. There is basically no chance ram will contain those values on powerup, only on reset after your program writes it.

Bad programming is using variables/memory without knowing they have been initialized. This is true in all programming. Unless you have reason to believe the contents are initialized or have a reason to read them. There are reasons you might but when programming a game, you generally should be sure to initialize everything. It's just basic programming.
Post Reply