Mapper with combined CHR-ROM and CHR-RAM?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Mapper with combined CHR-ROM and CHR-RAM?
by on (#131490)
After seeing some RAM mostly piggy-backed onto the PRG IC, I thought maybe the same could happen with CHR-ROM and some addressing circuitry to control which one's /CE and /OE lines are active (and /WE, for the RAM). Maybe something interesting could be done with this? Maybe the capability to have /WE on the RAM enabled while the /CE of the ROM is enabled too to allow for quick copying of the ROM into the RAM (which could then be modified)?
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131493)
Could be done. Only problem is, the more shared address lines between the two, the less general (and less clear how it'd be useful).

Most obvious use to me would be for flood fills.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131495)
What would be the advantage over bankable CHR-RAM? It's kinda trivial to fill up RAM pages on startup if you need the fast banking. The only advantage I can think of is not having to reserve PRG space for it, but I feel like having two CHR chips instead of one would be more expensive than doubling your PRG size.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131500)
If you want High Speed updates of part of the pattern table and more flexibility in the other, you need to use a technique first seen in Napoleon Senki and brought stateside in Pin-Bot. See MMC3 with CHR ROM and CHR RAM.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131530)
If you want my opinion (too bad, you're getting it anyway), bankable RAM is the best way to go. However, I think the n106 (or whatever it's called now) has both chr-rom and chr-ram, with the ram just being the last two pages.

The best part about having a large amount of on-cart PPU memory is the fact that you could use the same RAM chip both for nametables and pattern table data. A 16kb RAM chip can hold the entirety of the pattern table, plus 8 extra nametables, in addition to the NES's internal two. With that kind of memory, you could have a large stage and scroll around without needing to paint the seam as you go.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131534)
"n106" is Namco 129 and 163, or iNES #19. The last two pages are the VRAM on the NES motherboard, so you get only 64 tiles of CHR RAM and have to use single screen mirroring.

Try this: Use a mapper with 2K or smaller banking, such as MMC3, and rewire the CHR RAM socket to take a 62256 SRAM (whose size is 32768 bytes). You can do this in emulators supporting the NES 2.0 header by setting the CHR RAM size to 32768 bytes (byte 11 = $09). That gives you 32 1K banks of pattern tables, so you can combine CHR ROM-style bank animation combined with the tile modification traditionally associated with CHR RAM.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131545)
I think the fast copy to CHR-RAM is actually a neat idea, but yeah I agree the cost to benefit ratio isn't too great. A different approach along the same line, what if you ditch the CHR-ROM and give the RAM a switched data bus to the mapper? The mapper could be pulling that data from anywhere, the NES only cares if the next byte will be there after PPU-A0 changes, right? I'd rather have the data originating from an on-cart coprocessor (but whatever it is, it's though the mapper). But it's kind of a solution looking for a problem. I can think of faster ways than this to load CHR-RAM with extra hardware, but this is a new one to me, and seems worth considering.

I still wonder sometimes about the fanciful idea Bananmos mentioned long ago, what if one could force a bus conflict to cause sprite-DMA to write to $2007 instead of $2004? I doubt that specific type of bus conflict could be caused, but if it was possible, that would have really been something, heheh.

edit: Actually if you want to pre-calculate data to write during vblank, a large WRAM filled with LDA #imm / STA $2007 sequences is about as good as it gets. That's just 6 cycles per byte, versus 4 cycles of this fast copy method (but without lots of setup from the NES CPU). Kinda wish I had thought of that about 5 years ago when I was dorking with a Propeller MCU to PPU bus interface. I think this would have been slow enough to work.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131546)
Memblers wrote:
I still wonder sometimes about the fanciful idea Bananmos mentioned long ago, what if one could force a bus conflict to cause sprite-DMA to write to $2007 instead of $2004?
We tested this out (at least in visual2c02): the PPU can't keep up with a write to $2007 every other CPU cycle. IIRC, some writes just get dropped. Could, however, intentionally stall the CPU a bit during writes to the PPU to allow it. Don't know by how much, though.

And while we're at it, fixing the CPU's M2 going high before the data bus is asserted might fix some of the OAM wonkiness.

Quote:
a large WRAM filled with LDA #imm / STA $2007 sequences is about as good as it gets.
A PLA with an automatic loop unroller might be a nicer "pseudo DMA". Other than not running out of the 5 × # of bytes to transfer of address space needed, it could easily handle ROM-to-RAM and ROM-to-PPU copies.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131555)
On an FPGA based mapper one could quite easily place a nametable (or couple) in block RAM, watch for OAM DMA writes as they happen and copy the values to the block RAM. Could even use a "smart" buffer format like often seen in software based PPU update routines (with destination address, address increment mode, etc in the buffer). This could allow up to 1 KB to be transferred in a single vblank.

But of course FPGAs are not cheap and the amount of available block RAM is limited. I guess it might be doable with external RAM by routing all of the PPU related signals through the FPGA, but that would be somewhat more complicated.

EDIT: I realized it wouldn't make much sense to use OAM DMA for a quick transfer to block RAM based nametable, because the nametable could just as easily be mapped directly into CPU address space...
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131558)
thefox wrote:
I guess it might be doable with external RAM by routing all of the PPU related signals through the FPGA, but that would be somewhat more complicated.

It'd probably be exactly as complicated as the MMC5. It has 1K of essentially block RAM for a third nametable or extended attributes of a 1-screen-mirrored nametable.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131575)
I really wish the 6502 had a real way to relinquish the bus like some other processors did. The ability to add an actual coprocessor to the cart would've been incredibly helpful. This is, of course, assuming Nintendo would be smart and actually put the bus control pins on the cart edge. :P

I was thinking of various ways to copy large amounts of data to the vram, but every time, simply using chr-rom would be cheaper.

I'm interested in the usefulness of the 16kb vram idea I had. I even came up with a banking scheme for it (12 1k banks from 0000-2FFF; In 2000-2FFF, pages 0 and 1 are the nes's internal nametables, so of the 16kb cart vram, only 14kb is actually shared between pattern tables and nametables), found 74-series parts to implement it and everything. 16kb is even big enough to provide the 960 unique tiles necessary to fill the screen, so I was playing around with the idea of a togglable mode where fetches to $03FF automatically advance bank 0 to the next page. That'd mean you'd fill the nametable (or a region of it) with tiles 00-3F over and over, enable this mode, and you'd get a bitmap with all points addressable. Since only one bank would be controlled in this manner, the rest of the pattern table would be free to hold other graphics, like UI elements, a font, sprites, etc (subject to what fits in the remainder of the vram).

Even if you used none of that, you'd still have 10 nametables to work with, or 16kb of chr-ram for a combination of bankswitch animations and chr-ram animations.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131577)
Drag wrote:
so I was playing around with the idea of a togglable mode where fetches to $03FF automatically advance bank 0 to the next page.

The Oeka Kids mapper implements that with the simplest possible hardware. It latches A9 and A8 when A13-A12 becomes $2xxx.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131578)
Right, but I wanted it to be more like MMC2, so instead of the mode being based on filling the screen, you could have a smaller window on the screen instead, and you wouldn't burn so many tiles. :P
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131579)
MMC2-style behavior takes a lot of I/O pins; that's my worry.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131589)
On my 8T-ROM board I used a 74HC30 (8-input NAND gate) to combine some of the address lines, freeing up 5 inputs on the CPLD. There's also 74HC133, 13-input NAND gate, but it doesn't seem to have much availability. If that helps.
Re: Mapper with combined CHR-ROM and CHR-RAM?
by on (#131602)
A NOR for the bits that need to be 0, an AND for the bits that need to be 1.

PA10-PA13 are covered because I need to check for bank 0 anyway, since bank 0's page number needs to come from a counter instead of the register array if the special bank mode is activated. So in reality, the hairy part is performing a 10-way AND for the rest of the address bits, and then I'd need to combine this output with the bank 0 check, and an inverted clock signal or something, so the counter changes after the PPU's finished fetching the last byte of the hot tile. I think the logic would be worthwhile in the long run, because this would be a pretty good use for the expanded vram.

By the way, the idea would be 12 writable registers for the 12 PPU banks, plus one register to set the counter (which you'd need to do every vblank if you were using it). Writing to the counter activates the special bank 0 mode and sets the starting page, while writing to the "normal" bank 0 register deactivates it. Then 3 registers for PRG banking (3 switchable banks, 1 fixed) since you'd probably need it if you were ever going to fill out a 16kb vram, yielding an even 16 registers for bank management.