Looking for a layman's explanation of WRAM

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

Post Reply
User avatar
NeverCameBack
Posts: 31
Joined: Mon Feb 24, 2020 12:22 am

Looking for a layman's explanation of WRAM

Post by NeverCameBack » Sat May 09, 2020 11:37 am

Nerdy Nights' explanation is too short for me.
In trying to use WRAM to gain 128 kb of available CHR (graphics), instead of the normal 8 kb (NROM) or 32 kb available with the simpler bank switching method, CNROM.


- From $6000 to $8000 we have our 8 kb of WRAM. This whole section of memory is what is swapped out right?
But where in your code do you define all the WRAM data (that would physically reside on the WRAM chip on the cart)?
The CPU is going to take your entire compiled asm file (.nes file) and copy it to it's memory, placing the sections in areas according to the directives that you defined - right?
I'm having a hard time picturing where in your .asm file you should be putting this 128 kb of CHR data... Since WRAM is not part of the game ROM but a separate chip on an NES Cart.

I think I understand this part:
- To initiate a swap, you do 5 writes to a CPU memory address anywhere in a certain range. This initiates the swap.
But how do you specify "Hey I want to take take Kilo Bytes 50 to 57 out of the total 128 kB of CHR data in WRAM, and copy this data into $6000 to $8000 of the CPU?
From what I understand from the tutorial, you:
In 8 kb CHR mode - Do 5 writes to the $A000-BFFF range. Such as #%00000001, 5 times in a row. This will shift register out to #%00001111, not #%00011111, because in 8kb mode, the bottom bit is ignored. So 15 points to the 16th 8kb byte section, starting at 112 kb through 128 kb, will be copied over to WRAM.


Anyone have experience using this?
Nerdy Nights offers an example code at the end, but it's for PRG swapping only, and even with this I find it hard to decipher what is going on. Especially the fact there is a .txt file being included, and somehow the ascii text is converted into the correct CHR tiles for that letter. I was expecting a look-up table, but see none.

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

Re: Looking for a layman's explanation of WRAM

Post by lidnariq » Sat May 09, 2020 11:55 am

NES carts have two different entire kinds of memory: for the PPU, and for the CPU.

Effectively no-one's ever released a cart that lets you conflate the two, because it would be comparatively expensive, and the hardware needed to do so would provide enough more features that it'd be hard to justify only unifying the two.
But where in your code do you define all the WRAM data (that would physically reside on the WRAM chip on the cart)?
You don't get to pre-define the contents of RAM. That's what makes it RAM instead of ROM.
- To initiate a swap, you do 5 writes to a CPU memory address anywhere in a certain range.
That's only for MMC1 / mapper 1. Different mappers have different conventions.

Only MMC1 and MMC5 (and homebrew using FME7) let you have more than 8KB of RAM for the CPU.

All mappers that support CHR banking will support more than 8KB of RAM for the PPU, but only modern emulators with a NES2.0 header will let you specify this.

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

Re: Looking for a layman's explanation of WRAM

Post by tokumaru » Sat May 09, 2020 12:08 pm

NeverCameBack wrote:
Sat May 09, 2020 11:37 am
Nerdy Nights' explanation is too short for me.
In trying to use WRAM to gain 128 kb of available CHR (graphics), instead of the normal 8 kb (NROM) or 32 kb available with the simpler bank switching method, CNROM.
I don't know where you got the idea that WRAM has anything to do with CHR, but this is NOT what WRAM is for. WRAM is extra work RAM, to complement the 2KB of built-in RAM at $0000-$07FFF. It's used for things like variables, arrays, level maps, game state, and buffers.

If what you want is to use more tiles in your game, you either need a mapper that supports more CHR-ROM (e.g. the MMC3, which supports up to 256KB of CHR-ROM), or you can use CHR-RAM instead.

Unlike CHR-ROM, where the graphics are permanently "burned" into the chip, a CHR-RAM chip can be rewritten as many times as necessary, meaning you can copy new tiles from PRG-ROM to CHR-RAM in order to make new graphics available to the PPU. The main drawback of using CHR-RAM is filling the chip with new tiles takes time (the CPU has to do it byte by byte only during vblank or when referring is off), while CHR-ROM switching is instantaneous.

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

Re: Looking for a layman's explanation of WRAM

Post by tokumaru » Sat May 09, 2020 12:34 pm

It looks like there's a lot of misunderstanding on your part regarding how ROM, RAM, mapping and memory in general works, so I'll try to answer some of your questions even though WRAM has absolutely nothing to do with getting more tiles, as some of this is still relevant to the use of CHR-RAM.
NeverCameBack wrote:
Sat May 09, 2020 11:37 am
From $6000 to $8000 we have our 8 kb of WRAM. This whole section of memory is what is swapped out right?
$6000-$7FFF is the range of memory where most mappers that support WRAM will map it. Not many mappers support more than 8KB of WRAM, but when they do, you can use their registers to select which 8KB chunk of a larger RAM chip will be visible in that range.
But where in your code do you define all the WRAM data (that would physically reside on the WRAM chip on the cart)?
RAM always starts "empty". You can't make data appear automatically in RAM, be it CHR-RAM, WRAM or any other kind. To put data there you have to write code to transfer data from PRG-ROM to WRAM/CHR-RAM.
The CPU is going to take your entire compiled asm file (.nes file) and copy it to it's memory, placing the sections in areas according to the directives that you defined - right?
Actually, there's no copying at all going on. The PRG-ROM containing your assembled program is directly connected to the CPU. The mapper you use will define how that connection is made, and whether it can be changed on the fly (e.g. via bankswitching), but the NES doesn't have any internal memory where the contents of the cartridge are automatically copied to.
I'm having a hard time picturing where in your .asm file you should be putting this 128 kb of CHR data... Since WRAM is not part of the game ROM but a separate chip on an NES Cart.
Things to be copied to RAM are stored as simple data tables anywhere in PRG-ROM. You pick a place in PRG-ROM where there's enough space for your data, create a label there so you can access it, then include the data itself. For example:

Code: Select all

PlayerTiles:
  .incbin "player-tiles.chr"
Like I said before, this isn't automatically copied anywhere, YOU have to write the code to copy this to CHR-RAM. It's the exact same principle of copying a name table or a palette to VRAM, which I assume you're already doing.

User avatar
NeverCameBack
Posts: 31
Joined: Mon Feb 24, 2020 12:22 am

Re: Looking for a layman's explanation of WRAM

Post by NeverCameBack » Sat May 09, 2020 1:38 pm

Actually, there's no copying at all going on.
This cleared up a lot for me. In nerdy nights, it says the CPU has "access to up to 64 kb of memory", which I interpreted as having it's own 64 kb of memory that it copies info from the cart to. I guess if this was the case, you could take the game out and the game would still run, which we all know is ridiculous.

I was confusing WRAM for what I thought should be an extra memory chip on the NES cart, that would allow it to hold up to 128 kb of CHR data, plus more for extra PRG ROM and the 8 kb WRAM - if this were to be an MMC1 utilizing cart. In the old days, I'm guessing the programmer would actually have to load that eprom (or whatever chip it is) up with the CHR data by itself, and same for the PRG ROM chip. This confuses me since our rom is just one .nes file (containing virtual versions of all the chips). So I'm still not clear on how our virtual game cartridge (the .nes file) is separated out with data residing on the PRG ROM, CHR ROM/RAM, and what I may falsely believe to be an additional chip with more memory for holding the extra MMC1 data.


I read your reply to my bank question, and from what I understand, I may not need to use the .org on all my ".incbin "mario.chr"" statements. But maybe with my NASAM assembler, I would still need the bank labels to pick between which one will be sent to the PPU...

.bank 2
.org $0000
.incbin "mario0.chr"

.bank 3
.org $0000
.incbin "mario1.chr"

.bank 4
.org $0000
.incbin "mario2.chr"

Would something like this make any sense? They are all pointing to the same location from the CPU to pick from...

User avatar
Memblers
Site Admin
Posts: 3831
Joined: Mon Sep 20, 2004 6:04 am
Location: Indianapolis
Contact:

Re: Looking for a layman's explanation of WRAM

Post by Memblers » Sat May 09, 2020 4:12 pm

NeverCameBack wrote:
Sat May 09, 2020 1:38 pm
Would something like this make any sense? They are all pointing to the same location from the CPU to pick from...
I'm assuming this for CHR-ROM, and not CHR-RAM (the answer would be totally different).

It seems unnecessary, but NESASM has some quirks around the way it handles banking (it silently drops any data that goes beyond an 8kB boundary), so it makes sense in that context and might even be neccessary.

In an .NES ROM when CHR-ROM is used, it's basically 2 separate ROM files combined into one .NES file. So the .ORG $0000 is a PPU address, rather than a CPU one. But the address isn't really used, because there's no need for labels in PPU address space. I think it might be more to guide NESASM in the right direction, so it doesn't just abandon the incbin'd data.

User avatar
NeverCameBack
Posts: 31
Joined: Mon Feb 24, 2020 12:22 am

Re: Looking for a layman's explanation of WRAM

Post by NeverCameBack » Sat May 09, 2020 5:28 pm

In an .NES ROM when CHR-ROM is used, it's basically 2 separate ROM files combined into one .NES file. So the .ORG $0000 is a PPU address, rather than a CPU one.
This answered my next question, which was how is it that some variables are stored at:

.rsset $0000
(variables defined here)

then later on....

.org $0000
incbin (.chr file here)

It would seem that .rrsett $0000 is referencing the RAM bus of the CPU, while .org $0000 is telling the assembler that this next data goes right to the PPU.
it silently drops any data that goes beyond an 8kB boundary
Maybe this is why I could have:

.bank 3
.org $0000
.incbin (chr file here)

.bank 4
.org $0000
.incbin (chr file here)

.bank 5
.org $0000
.incbin (chr file here)

..... All the way to bank 100 for example.
Only the first bank with .org $0000 is sent to the PPU. The rest is ignored unless it is swapped in...

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

Re: Looking for a layman's explanation of WRAM

Post by tepples » Sat May 09, 2020 7:29 pm

UNROM, SGROM, SNROM, and TGROM cartridges have 8 KiB of CHR RAM. The program copies or decompresses data from PRG ROM to CHR RAM.

Many mappers can bankswitch CHR RAM. This combines some of the advantages of CHR ROM with some of the advantages of CHR RAM. However, due to costs in the original commercial era, Nintendo didn't manufacture a lot of cartridges with more than 8 KiB of CHR RAM. Videomation, on the CPROM board with 16 KiB CHR RAM, comes to mind.

In the modern era, a few cartridges have more memory:
  • Later Action 53 volumes contain 32 KiB of CHR RAM in order to support games originally designed for the CNROM mapper.
  • The board of Haunted: Halloween '86 is basically TGROM with a bigger (32 KiB) CHR RAM. This lets it use both detailed hero sprite animations and intricate, grid-hiding backgrounds.
A few boards have both WRAM and CHR RAM. The most common is the SNROM board used for Metroid, Kid Icarus, The Legend of Zelda, and Final Fantasy. However, a program that copies data from WRAM to CHR RAM must do so byte-by-byte during vertical or forced blanking.

Post Reply