4 ms·
> (The only annoying part to using the NES to learn graphics programming is the time you waste wrapping your brain around the "mappers" concept, because it has
by khedoros1 9y ago
> (The only annoying part to using the NES to learn graphics programming is the time you waste wrapping your brain around the "mappers" concept, because it has no applicability to any other system.)
A number of other gaming systems used similar mapping systems. And it's not so far conceptually from EMS on real-mode x86.
- derefr 9y agoNES Mappers aren't quite the same thing as regular memory bank-switching, or even the same as MMU programmability. They were a whole lot weirder. Mappers, in the context of NES programming, are regions of on-cart ROM or WRAM that were wired up through various custom ASICs (the eponymous "mapper" chips) to do things like, for example, have contiguous looping reads to the same 64-byte address sequence (so, one 8x8 tile's worth of nametable data) produce as output a sequence of animated frames, by having the ASIC switch which physical page is backing that region of the address space once per VBLANK, entirely transparently to the CPU and asynchronously to running code (i.e. not driven by a maskable interrupt.) In other words, each cartridge essentially cobbled together its own MMU by throwing together random chips which could respond in completely arbitrary ways to specific masked read-lines from the address bus; and many of these chips did very domain-specific things to very small regions of memory, rather than being general-purpose (there have been more than 100 different mapper chips put into NES cartridges, some used by only one released game.) As far as I know, no other system has ever done anything quite so weird as that at a hardware level.
- jacquesm 9y agoIt definitely upped the gamesmanship required for cloners of cartridges, and it made the system somewhat future proof.
- khedoros1 9y agoOne 8x8 tile takes 16 bytes of nametable data, not 64. There are a couple hundred mappers and variants, but the 4 most common ones (thinking of cnrom, unrom, mmc1, mmc3) cover 90-something percent of all cartridges out there, and don't have the address increment that you're describing. Most of them just cover bank switching, or (like MMC3) add some IRQ stuff under certain conditions. There are cartridges with extra copy protection, extra audio channels, etc. As you said, the ASICs do basically arbitrary things, but it's not like you have to learn one of the really esoteric mappers. The most common mapper behaviors are comparable to bank-switching on other systems. I'd say that the SNES gives NES a run for its money, in terms of weirdness. The ASICs in many of the cartridges there included whole processor cores.
- derefr 9y ago> it's not like you have to learn one of the really esoteric mappers True. I guess I have console-manufacturer-coloured glasses on†; I was more thinking about what you'd have to know to be able to reimplement the NES mapper architecture yourself, such as in an emulator. Though, also, if you want to do NES demoscene stuff, you're gonna want to understand the more esoteric mappers. And that's usually what amateur graphics programmers inevitably want to do when learning their first platform—use every feature to get a cool demo—which in the NES can result in a heavy focus on abusing mappers, which ends up not really giving you useful portable insight for anything else. (Except, maybe, for pixel shaders!) † ala Raymond Chen's "kernel-colores glasses" — https://blogs.msdn.microsoft.com/oldnewthing/20110512-00/?p=10683 https://blogs.msdn.microsoft.com/oldnewthing/20110512-00/?p=...
- khedoros1 9y agoThe way I implemented it was with a "memory" class that provides the memory map intrinsic to the system itself. When I load the ROM, I identify the mapper specified in the iNES header. There's a mapper class that basically provides the NROM variants, and classes derived from that (one per mapper family) to implement the ASICs. I have toy-emulator-colored glasses ;-) I've got a few mappers written, but never tried to tackle MMC3 or MMC5, just because the CPU code isn't well-situated to handle most interrupts properly right now. It's been a while since I've thought about that part of the code, but I think that the mappers might be aware of the current PPU cycle (or could be easily wired to be) to support some kind of frame-dependent addressing.