My cart runs differently in different emulators

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Pokun
Posts: 1917
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: My cart runs differently in different emulators

Post by Pokun » Sat May 08, 2021 6:21 am

Yeah if you use cc65 for assembly you just need to grab the assembler ca65 and linker ld65. It's a bit iffy to set up though as you need to make a config file, so if you can't figure it out there is always asm6 which I and many others here mainly use. It should have famitracker support as well. It's a less advanced assembler though.

puppydrum64 wrote:
Fri May 07, 2021 2:19 pm
Would this get stored in CHR-ROM or PRG-ROM? Does the assembler decide where it goes or do I?
You decide where it goes by placing it in your source file. You don't need to use org $10000, if you use CHR-ROM you just put it right after the vectors as they end at $FFFF which is the end of the PRG-ROM. If you use CHR-RAM the cartridge will only have one ROM chip (the PRG-ROM), so you can only store it in the PRG-ROM (but anywhere you want) and then copy it to CHR-RAM at runtime (google the difference between ROM and RAM if you don't already know). You copy it the same way as you write to nametables or the palette, but the location is PPU $0000-$1FFF. Note that there are two pattern tables: 0 ($0000-$0FFF) and 1 ($1000-$1FFF), and which is used by sprites and which is used by tiles depends on what you set $2000 to. It's common to use pattern table 0 for sprites and 1 for tiles, so in that case you copy your smiley to the area starting at PPU memory $1000 if you want it to be used by a background tile.

puppydrum64
Posts: 160
Joined: Sat Apr 24, 2021 2:18 pm

Re: My cart runs differently in different emulators

Post by puppydrum64 » Sat May 08, 2021 8:59 am

Pokun wrote:
Sat May 08, 2021 6:21 am
Yeah if you use cc65 for assembly you just need to grab the assembler ca65 and linker ld65. It's a bit iffy to set up though as you need to make a config file, so if you can't figure it out there is always asm6 which I and many others here mainly use. It should have famitracker support as well. It's a less advanced assembler though.

puppydrum64 wrote:
Fri May 07, 2021 2:19 pm
Would this get stored in CHR-ROM or PRG-ROM? Does the assembler decide where it goes or do I?
You decide where it goes by placing it in your source file. You don't need to use org $10000, if you use CHR-ROM you just put it right after the vectors as they end at $FFFF which is the end of the PRG-ROM. If you use CHR-RAM the cartridge will only have one ROM chip (the PRG-ROM), so you can only store it in the PRG-ROM (but anywhere you want) and then copy it to CHR-RAM at runtime (google the difference between ROM and RAM if you don't already know). You copy it the same way as you write to nametables or the palette, but the location is PPU $0000-$1FFF. Note that there are two pattern tables: 0 ($0000-$0FFF) and 1 ($1000-$1FFF), and which is used by sprites and which is used by tiles depends on what you set $2000 to. It's common to use pattern table 0 for sprites and 1 for tiles, so in that case you copy your smiley to the area starting at PPU memory $1000 if you want it to be used by a background tile.
I understand that ROM is read-only and RAM can be read or written to. For PRG-ROM it makes sense to me, for example in Zelda, Link's current Rupees, health, and items are stored in RAM and the code that handles the overall game structure (such as what happens when Link runs out of hearts, etc) is ROM. For graphics I get confused. It was my understanding that a level isn't stored completely put together in the ROM (e.g. if you opened Super Mario Bros. in a CHR editor you wouldn't see World 1-1 fully assembled in there, but you would see each possible tile stored in the file. It sounds like you're saying that CHR-RAM is when you have a section of code that pieces together the background by looping through a tile map and repeatedly writing to $2007 and CHR-ROM would be if the levels were fully assembled ahead of time and just loaded into the PPU. But I don't think that's what you're trying to say. I don't mean to be wasting your time, I really just don't get it... :cry:
Current Projects: Aquarium Simulator (MMC1), Astro Birds (VRC6)

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

Re: My cart runs differently in different emulators

Post by tepples » Sat May 08, 2021 9:24 am

All games, whether they use CHR ROM or CHR RAM, need to assemble structures larger than 8x8 pixels from data in PRG ROM. The difference lies in how the 8x8-pixel pieces themselves, called "tiles" or "characters", are stored.
  • CHR ROM means that sets of 64, 128, 256, or 512 tiles are stored fully assembled. A game swaps in a whole bank at once.
  • CHR RAM means that the game has to assemble even those from data in PRG ROM. This is sometimes done to fit more data into a memory with a given capacity (data compression), to juxtapose arbitrary things (such as allowing different sets of enemies to appear together in a level, or customize a character's appearance, or assemble Chinese characters into a sentence), or to place things at fine position (such as variable-width fonts).
Open various games in Mesen or FCEUX. Open the pattern table (FCEUX: Debug > PPU Viewer; Mesen: Debug > PPU Viewer > CHR Viewer) to see the 8x8-pixel pieces. Look at how use of the pattern table differs between games using mapper 2 (UNROM, which uses CHR RAM) and games using mapper 4 (MMC3, which overwhelmingly uses CHR ROM). In particular, look at 240p Test Suite, which uses CHR RAM to plot letters and numbers at positions measured in single pixels. Qix, Hatris, and Videomation are examples of using CHR RAM as a canvas on which to draw more or less arbitrary pictures, whereas Super Mario Bros. 3, Dr. Mario, and Kirby's Adventure use CHR ROM to animate the shape of a large number of tiles.

See also "CHR ROM vs. CHR RAM" on the wiki.

User avatar
Quietust
Posts: 1785
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: My cart runs differently in different emulators

Post by Quietust » Sat May 08, 2021 9:31 am

puppydrum64 wrote:
Sat May 08, 2021 8:59 am
It was my understanding that a level isn't stored completely put together in the ROM (e.g. if you opened Super Mario Bros. in a CHR editor you wouldn't see World 1-1 fully assembled in there, but you would see each possible tile stored in the file. It sounds like you're saying that CHR-RAM is when you have a section of code that pieces together the background by looping through a tile map and repeatedly writing to $2007 and CHR-ROM would be if the levels were fully assembled ahead of time and just loaded into the PPU. But I don't think that's what you're trying to say. I don't mean to be wasting your time, I really just don't get it... :cry:
The PPU has 2 separate parts of memory that are connected to the cartridge: at $0000-$1FFF there are pattern tables which define all of the graphical tiles that can appear on the screen (either in the background or as sprites), and at $2000-$2FFF there are nametables that specify which tiles are displayed where. In nearly all cases, the nametables are stored in RAM, but the pattern tables can either be in ROM or in RAM.

If you think of the pattern table like a font, it should make more sense - some games might have one or more hardcoded fonts for displaying different things, and others dynamically load the font so they can change individual characters as appropriate for different scenes.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

Pokun
Posts: 1917
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: My cart runs differently in different emulators

Post by Pokun » Sat May 08, 2021 12:07 pm

Yeah and that is also why it's called CHR. It's really an 8x8 pixel character font that can have 3 colors + transparent (due to it being in a 2 bit/pixel format). Each of the two pattern tables can have 256 characters each which is 4 kB as each character is 16 byte large.
There is no level data or anything in the CHR-ROM/-RAM.

puppydrum64 wrote:
Sat May 08, 2021 8:59 am
I understand that ROM is read-only and RAM can be read or written to.
Yes that's true, but you missed another important difference that is normally implied when you say ROM and RAM. That is that RAM is volatile while ROM isn't. That means that RAM can only keep data as long as the power is on, while ROM keeps it permanently. There are actually non-volatile RAM as well, such as FRAM, MRAM and plain old SRAM with a battery attached to it to keep it powered on, but those are exceptions and not what we usually mean if we just say RAM.

CHR-RAM is a normal SRAM chip normally without a battery, so there is no way that it can keep the content after you turn off power, nor would it have any meaningful data the first time you turn it on when it's fresh from the factory. A ROM on the other hand is hardwired in the factory with the data (or in our hobbyist case we would program an EPROM or similar with our data) so it will have the correct data long before you turn on power. That's the reason why you need to fill the pattern tables if you use CHR-RAM, but you don't need to (and can't) do it with CHR-ROM.

The Famicom's setup with a PRG-ROM and a CHR-ROM is actually quite different from how most other consoles and computers work (including Nintendo's later consoles like the Game Boy and SFC). Usually the pattern table is part of the VRAM inside the console and not on the cartridge. Every game thus would need to fill the pattern table and it's like you always have CHR-RAM. The Famicom's way of doing it is quite powerful as it gives you more options and you can do some things not otherwise possible, but I guess the cartridge might be a bit more expensive. The Neo Geo is also doing something similar to the Famicom by having a character ROM on the cartridge.

puppydrum64
Posts: 160
Joined: Sat Apr 24, 2021 2:18 pm

Re: My cart runs differently in different emulators

Post by puppydrum64 » Sat May 08, 2021 7:43 pm

I think I'm starting to get it. Certain systems like the GBA and the Commodore 64 let you draw individual pixels to the screen. The NES cannot do that; you can only assign predefined tiles and then draw them into place
Current Projects: Aquarium Simulator (MMC1), Astro Birds (VRC6)

unregistered
Posts: 1187
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Re: My cart runs differently in different emulators

Post by unregistered » Sat May 08, 2021 11:47 pm

puppydrum64, if you are not 100% sure of the difference between ROM and RAM by now, try reading booker’s post in my thread:

viewtopic.php?p=83021#p83021

He pulled me into the ROM vs RAM light. :D

—-
And, you can place pixels on the screen by coloring one dot on an 8x8 pixel transparent sprite tile and then placing copies of that tile around the screen. But, remember that more than 8 sprites on the same scanline causes sprites to blink. :)

User avatar
Quietust
Posts: 1785
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: My cart runs differently in different emulators

Post by Quietust » Sun May 09, 2021 5:48 am

unregistered wrote:
Sat May 08, 2021 11:47 pm
But, remember that more than 8 sprites on the same scanline causes sprites to blink. :)
No it doesn't - putting more than 8 sprites on the same scanline causes the extra ones to simply not appear.

When you see sprites flickering, it's because the programmer wrote special code to rearrange the sprites in memory to ensure that they would all be visible to some degree.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.

Pokun
Posts: 1917
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: My cart runs differently in different emulators

Post by Pokun » Sun May 09, 2021 10:48 am

puppydrum64 wrote:
Sat May 08, 2021 7:43 pm
I think I'm starting to get it. Certain systems like the GBA and the Commodore 64 let you draw individual pixels to the screen. The NES cannot do that; you can only assign predefined tiles and then draw them into place
I think you are thinking of bitmapped graphics now, that's not it. Bitmapped graphics is when you can address every single pixel on the screen instead of using a tile grid, and the NES don't have enough memory and speed for that so it uses tiled graphics instead. The GBA and C64 has much more memory so both can afford a mode for bitmapping the screen, but they also both support a tiled mode and sprites, just like the NES. The tiled modes are used more in games because bitmapped graphics is slower to work with.

Tiled graphics means you have a nametable (AKA tilemap) and a pattern table with the character patterns (AKA tileset). The nametable is an array of tile numbers that each represents a tile (AKA background character) on the screen. The first byte in the nametable is the top-left tile on the screen and the last is the bottom-right one. Each nametable entry is a number which assigns what character pattern from the pattern table that is to be displayed in the tile's location. 0 is the first character pattern and 255 is the last one in the pattern table. If you start the emulator Mesen and choose Debug -> PPU Viewer you can see this visually so it should be clear to you what is what. The CHR Viewer shows the pattern table and the Nametable Viewer obviously shows all the nametables (the NES has four adjacent nametables that can be scrolled into, although two of them are usually mirrors of the other two). The nametable is basically the screen but without sprites (sprites is a separate subsystem that has no effect on the nametable).

Tiled graphics greatly reduces the amount of memory required as you only address each tile not each pixel, and it takes less time to update the screen too as you have less bytes to work with. A 256x240 pixel screen has 61 440 pixels total, so if each one was addressed by a byte (as a bitmapped system might use) that would be 61 440 byte! Since the NES uses 8x8 pixel tiles each nametable only needs to hold 960 byte (as each tile is 1 byte). The drawback with tiled graphics is that you only have so many different kinds of character patterns in the pattern table to use (the NES has 256 patterns), so a lot of tiles will have to use the same tile pattern.
Modern consoles basically only use bitmapped graphics, because memory is cheaper now and the hardware is fast enough to update every single pixel on the screen every frame. The NES is too slow to even update every tile on the screen in a single frame.

Back to the difference between CHR-ROM and CHR-RAM, the later means we can redefine tile patterns in the pattern table while the game is running, while the former doesn't since the pattern table is inside a ROM chip (which is, as you said, read-only).

If you think it's too complicated I suggest to start with using CHR-ROM as it's a bit simpler. Change the header and add your CHR data after the PRG-ROM in that case.

puppydrum64
Posts: 160
Joined: Sat Apr 24, 2021 2:18 pm

Re: My cart runs differently in different emulators

Post by puppydrum64 » Sun May 09, 2021 11:05 am

Pokun wrote:
Sun May 09, 2021 10:48 am
puppydrum64 wrote:
Sat May 08, 2021 7:43 pm
I think I'm starting to get it. Certain systems like the GBA and the Commodore 64 let you draw individual pixels to the screen. The NES cannot do that; you can only assign predefined tiles and then draw them into place
I think you are thinking of bitmapped graphics now, that's not it. Bitmapped graphics is when you can address every single pixel on the screen instead of using a tile grid, and the NES don't have enough memory and speed for that so it uses tiled graphics instead. The GBA and C64 has much more memory so both can afford a mode for bitmapping the screen, but they also both support a tiled mode and sprites, just like the NES. The tiled modes are used more in games because bitmapped graphics is slower to work with.

Tiled graphics means you have a nametable (AKA tilemap) and a pattern table with the character patterns (AKA tileset). The nametable is an array of tile numbers that each represents a tile (AKA background character) on the screen. The first byte in the nametable is the top-left tile on the screen and the last is the bottom-right one. Each nametable entry is a number which assigns what character pattern from the pattern table that is to be displayed in the tile's location. 0 is the first character pattern and 255 is the last one in the pattern table. If you start the emulator Mesen and choose Debug -> PPU Viewer you can see this visually so it should be clear to you what is what. The CHR Viewer shows the pattern table and the Nametable Viewer obviously shows all the nametables (the NES has four adjacent nametables that can be scrolled into, although two of them are usually mirrors of the other two). The nametable is basically the screen but without sprites (sprites is a separate subsystem that has no effect on the nametable).

Tiled graphics greatly reduces the amount of memory required as you only address each tile not each pixel, and it takes less time to update the screen too as you have less bytes to work with. A 256x240 pixel screen has 61 440 pixels total, so if each one was addressed by a byte (as a bitmapped system might use) that would be 61 440 byte! Since the NES uses 8x8 pixel tiles each nametable only needs to hold 960 byte (as each tile is 1 byte). The drawback with tiled graphics is that you only have so many different kinds of character patterns in the pattern table to use (the NES has 256 patterns), so a lot of tiles will have to use the same tile pattern.
Modern consoles basically only use bitmapped graphics, because memory is cheaper now and the hardware is fast enough to update every single pixel on the screen every frame. The NES is too slow to even update every tile on the screen in a single frame.

Back to the difference between CHR-ROM and CHR-RAM, the later means we can redefine tile patterns in the pattern table while the game is running, while the former doesn't since the pattern table is inside a ROM chip (which is, as you said, read-only).

If you think it's too complicated I suggest to start with using CHR-ROM as it's a bit simpler. Change the header and add your CHR data after the PRG-ROM in that case.
By "redefine tile patterns" I'm assuming you don't mean that you can't change what's in the nametable once it's drawn. Otherwise when Mario punches a brick from below it wouldn't break and disappear. So when you say "you can't redefine tile patterns stored in CHR-ROM," for example if I wanted to make a rom hack of Mario 1 except all the pipes on World 1-1 are replaced with the coral from World 2-2 I can't do that without altering the CHR-ROM to add them to the ground theme's tile map.
Current Projects: Aquarium Simulator (MMC1), Astro Birds (VRC6)

Pokun
Posts: 1917
Joined: Tue May 28, 2013 5:49 am
Location: Hokkaido, Japan

Re: My cart runs differently in different emulators

Post by Pokun » Sun May 09, 2021 11:46 am

You are right, the nametable can always be redefined of course, otherwise we would hardly be able to update the screen at all. The nametable resides in VRAM which is an SRAM chip inside the NES, so it's always writable no matter the game.

If you made a ROM-hack of SMB1 you would probably just change the CHR-ROM. The benefit of CHR-RAM is that you can redefine patterns while the game is running by using code. If you change a single character pattern, all tiles on the screen that is assigned to the said pattern will change accordingly. You could for example animate all water tiles this way, or do advanced transformations like rotation in software. The game can alter itself so to speak.

One benefit of CHR-ROM is if you have several banks of CHR-ROM that you can switch with your mapper, you can switch the whole pattern table or a small part of it (different mappers has different granularity of bank-switching) instantly. This makes it possible to do tile animation while wasting very little time since a bank switch is usually just a write to a mapper register, while redefining a character pattern with CHR-RAM could mean writing 16 bytes for a single pattern. That is one reason the NES' solution of having CHR-ROM on the cartridge (instead of having the pattern table in VRAM inside the console like many systems do) so powerful.

User avatar
tokumaru
Posts: 12107
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: My cart runs differently in different emulators

Post by tokumaru » Sun May 09, 2021 4:14 pm

Pokun wrote:
Sun May 09, 2021 11:46 am
The nametable resides in VRAM which is an SRAM chip inside the NES, so it's always writable no matter the game.
Cartridges can be wired to disable the internal VRAM and provide their own memory in place of it, though. Very few games did it, but there is at least one game that used ROM for name tables.

puppydrum64
Posts: 160
Joined: Sat Apr 24, 2021 2:18 pm

Re: My cart runs differently in different emulators

Post by puppydrum64 » Sun May 09, 2021 6:46 pm

It seems that my test ROM isn't the only one with these issues. I downloaded a VRC7 test ROM from the VRC7 Nesdev wiki page. From looking at the .asm file and the Word document associated with it, the program is supposed to let you edit the contents of each audio register using the buttons. I'm getting different results on different emulators but none of them work.

FCEUX: Blue and white text appears displaying the audio registers. Does not respond to player input.

Nestopia: Blue, white, and green text appears. A faint noise is output that sounds like crickets chirping. Does not respond to player input.

Mesen: Solid green screen, no audio (just like my test ROMs)
Current Projects: Aquarium Simulator (MMC1), Astro Birds (VRC6)

lidnariq
Posts: 10666
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: My cart runs differently in different emulators

Post by lidnariq » Sun May 09, 2021 7:06 pm

Unfortunately, I would conclude that zzo38's contribution there isn't known to work and no-one else has ever tested it.

puppydrum64
Posts: 160
Joined: Sat Apr 24, 2021 2:18 pm

Re: My cart runs differently in different emulators

Post by puppydrum64 » Sun May 09, 2021 11:20 pm

lidnariq wrote:
Fri May 07, 2021 6:54 pm
CC65 is a whole suite of C compiler, assembler, and linker. No need to use C unless you want to.
I'll give it a try. I'm interested in using it for Famitracker's NSF driver. But there's just one problem right now: I don't have the music.asm or music.bin files. I don't see an option in Famitracker for exporting as a bin or asm
Current Projects: Aquarium Simulator (MMC1), Astro Birds (VRC6)

Post Reply