I hadn't really thought about name tables yet, just pattern tables. The idea was inspired by some GBA code I wrote that faked a bitmap mode by filling the screen with a sequential tile pattern and using a custom tile for each one. (Yes, I'm aware the GBA has a real bitmap mode). So the name tables never needed changing. (Yes, it's horribly inefficient.)
Of course, on the NES, with only 512 tiles total (using both banks), this wouldn't quite work. So it would be necessary to update the name tables too. Assuming that you only use 256 tiles for the background, 8k would be enough. One 4k page for the front buffer and one 4k page for the back buffer. This requires that the sprites share the same bank as the background.
If you wanted the sprites to have their own bank, then you'd need 12k. I'm assuming you could use whatever RAM you currently have onboard for CHR-RxM already. However, switching banks for the sprite table reads would require a level of PPU monitoring similar to the MMC5. If you wanted the sprites double buffered too, you'd need 16k, all of it dual ported. (Or at least psudo dual: PPU read, CPU read/write.)
Unfortunately, the 7k you've got easy access to isn't quite enough for even the basic setup. My suggestion would be to use 6k of it as two 3k pages. That leaves 1k for other stuff (a third name table, extended attributes, etc.) That would give 192 double buffer tiles. The other 64 could be used for something fixed, like alphanumerics. Not too shabby if you ask me.
Of course the real limitation (which I ought to know, but don't) is how fast the NES can update these tiles. How many bytes can the NES move in one frame. Assuming you're just grabbing the tiles from PRG-ROM and they're not dynamically composed (like one needs to do variable width fonts, vector graphics, or bitmap emulation), then all you need to do is move the bits. There's not much point in supporting double buffers larger than the CPU can fill in a frame anyway. (Unless you wanted to cut the frame rate to 30 FPS.)
As for how the rest of the mapper would be setup, I hadn't gotten that far. When I first had the idea, which was basically "Hey, dual ported CHR-RAM could be used for double buffering", I was assuming the dual ported RAM would a separate chip. Then I started thinking about how many IO lines the mapper would need:
Code: Select all
PRG-CART-A 16
PRG-CART-D 8
PRG-ROM-A 15+
PRG-ROM-D 8
CHR-CART-A 14
CHR-CART-D 8
CHR-RAM-P1-A 15+
CHR-RAM-P1-D 8
CHR-RAM-P2-A 15+
CHR-RAM-P2-D 8
Which is a bare minimum of 115 pins for just addressing and data. Not to mention the chip enables and stuff. Plus even more for PRG-RAM. Which isn't required, but nice to have. (At least as an option.) So that's as far as my design went.
Another idea I had for working around the 7k limit was to only use 4k and implement a DMA engine to copy it to the real CHR-RAM during V-blank. It's probably not a viable idea though.
And now for something completely different...
With 7k of built in RAM, you could implement the various things the MMC5 uses ExRam for, all at the same time. The first thing that comes to mind is true four screen mirroring (which is a misnomer, 'cause they're not mirrored at that point), rather than the three the '5 has. And extended attributes on all of them at the same time. That alone would be pretty impressive.