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.
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.
You don't get to pre-define the contents of RAM. That's what makes it RAM instead of ROM.But where in your code do you define all the WRAM data (that would physically reside on the WRAM chip on the cart)?
That's only for MMC1 / mapper 1. Different mappers have different conventions.- To initiate a swap, you do 5 writes to a CPU memory address anywhere in a certain range.
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.
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.
$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.
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.But where in your code do you define all the WRAM data (that would physically reside on the WRAM chip on the cart)?
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.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?
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: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.
Code: Select all
PlayerTiles: .incbin "player-tiles.chr"
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.Actually, there's no copying at all going on.
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...
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.
This answered my next question, which was how is it that some variables are stored at: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.
(variables defined here)
then later on....
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.
Maybe this is why I could have:it silently drops any data that goes beyond an 8kB boundary
.incbin (chr file here)
.incbin (chr file here)
.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...
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.