19

[Please see answers to this related question as well]

I've started reading the "official" NES Documentation and in page ten, it says that "memory locations $0000-$07FF are mirrored three times at $0800-$1FFF". My question is, what is the purpose of this mirroring? Wouldn't it make more sense to use that space for other purposes or just to increase the number of available resources in a very limited hardware?

I've searched over the Internet and maybe it could be for compatibility between devices from the same family or improving redundancy in case of data loss, in which case, shouldn't it be enough with just one mirroring instead of three?

Thanks for any answer you can provide.

2
  • I'm not sure this is a duplicate. It's asking about RAM and not PPU. Commented Sep 15, 2021 at 14:26
  • 1
    @OmarL Well, it is, but then again, it's the very same issue of partial decoding in the very same machine, It may be useful to keep both and add a pointer to each other at the top of the question. Kinda "[Please see the realted question: <link>]".
    – Raffzahn
    Commented Sep 15, 2021 at 14:38

3 Answers 3

42

It is not intentionally mirrored, it is just a side effect of making the address decoding hardware for RAM as simple and cheap as possible with a single common 74LS139 chip used for the task, when an 8k area of addresses are reserved for RAM, but only 2k of RAM is present in the 8k area.

If you look at the address map, 0x0000 to 0x1FFF is reserved for the RAM area, that is 8 kilobytes, which means that from the 16-bit memory address, the uppermost 3 bits of the memory address must be zeroes to select RAM area. These three address bits are decoded by the 74LS139 and when all three bits are 0, the RAM chip select is enabled.

This means that the lowermost 13 bits are used within that RAM area to select which RAM address to access. But as there is only a 2 kilobyte RAM present, it only uses lowermost 11 bits of the memory address, and thus the 2 memory address bits from address bus are ignored.

Thus, as long as the CPU wants to access any address in the 8k RAM area, it makes no difference what the two unused address bits are set to, the memory addresses just wrap down to the 2 kilobyte RAM chip.

And that is the reason the CPU sees the single 2k RAM memory chip four times in the 8k window reserved for RAM access.

It would take in fact more complex or just different or additional logic circuitry to try to prevent that from happening, and it would take also additional logic circuitry to be able to expand the memory size to use multiple 2k chips. Who knows, maybe they originally planned for reserving a 8k area for RAM, but instead of single 8K RAM chip, or single 4K RAM chip, they settled for single 2K RAM chip, as the design allows to use a single RAM chip of any size.

1
  • When I used to design DSP and microprocessor hardware back in the 1980s I would frequently have address lines that were ignored when decoding the addresses for memory or peripheral I/O addresses meaning that a particular location or register could appear at multiple addresses in the memory map. It simply was not worth the cost of the logic to fully decode the address as long as all of the required addressable components could be individually read and written.
    – uɐɪ
    Commented Sep 16, 2021 at 7:24
14

My question is, what is the purpose of this mirroring?

There is no purpose. It's simply the way the address range is decoded. The decoder looks only at the top 3 bits to decide which internal device (RAM, I/O) is to be accessed. If the two topmost bits are zero then the third (A13) selects between RAM and I/O:

   A15/A14/A13  Addressrange     Device
    0   0   0   0000-1FFF    ->  RAM
    0   0   1   2000-3FFF    ->  I/O

This is a very simple and hardware serving way to decode - keep in mind a console has to be as simple as possible to be cheap. Money is earned with cartridges, not the console device.

The remaining 13 Bit within that 8 KiB Region are used to address RAM - but a 2 KiB RAM only needs 11 address bits, two are ignored, making the 2 KiB of RAM show up 4 times.

The very same is to be found with the I/O area. Here only 3 bits are needed to address the 8 registers, the other 10 are ignored, resulting in these registers showing up 1024 times.

Wouldn't it make more sense to use that space for other purposes or just to increase the number of available resources in a very limited hardware?

Sure, but what for? The basic console does not have more hardware to address. Decoding more than the minimum means adding hardware, making the console more expensive, increasing upfront cost, potentially repelling customers. So unless there is a need important enough to spend that money, noone will do so.

The same issue can be found in many other early/low priced micro computer. The Commodore PET for example used A15 to distinguish between RAM and other devices, so only 32 KiB RAM could be used. But hey, 32 KiB is an unimaginable lot, isn't it?

5
  • Interestingly, the 2A03 chip containing the CPU along with some audio and I/O logic contains hard-wired circuitry for the purpose of fetching 256 bytes quickly from RAM and feeding them to address $2004, which I find something of a curious design choice. I don't know to what extent the designers of the 2A03 and PPU coordinated their efforts, but the hard-coded transfer address of $2004 seems oddly application-specific. It would seem like it would have been more "natural" to have a common PPU data register for OAM, picture memory, and palette all at $4000.
    – supercat
    Commented Sep 15, 2021 at 16:54
  • @supercat You mean beside that this would be a complete different question? Providing DMA 'to' 2004 is essentially half of the transfer engine, as behind $2004 lies the Sprite-RAM, which can be written (or read) on a single byte base after setting the destination in $2003. Quite nice and fast, as the destination pointer is incremented automatically - essentially the storing part of a DMA controller. It still leaves some 14+ CPU cycles per byte transferred. The DMA initiated by $4014 simply adds the second half of DMA, the loading part, making it fully self contained.
    – Raffzahn
    Commented Sep 15, 2021 at 17:11
  • Having $2004 as a hard-wired DMA destination address means the DMA function will only really be useful if the $2000-$3FFF address block contains a PPU, and of course the APU registers preclude the use of $4000-$5FFF as a 8K contiguous block for other purposes. Having the PPU be accessed using portions of the $4000-$5FFF block not used by the APU would have left the $2000-$3FFF region available as extra address space that would be available to cartridges.
    – supercat
    Commented Sep 15, 2021 at 23:22
  • @supercat you're aware that the PPU is build in with each and every NES and always on that address? No need for anotehr what if scenario.
    – Raffzahn
    Commented Sep 16, 2021 at 0:07
  • It always happens to be at that address, but it could just as easily have been at $4xxx leaving the $2000-$3FFF available as another contiguous 8K chunk of address space for cartridge expansion. Further, while DMA-blasting to the OAM is useful, DMA blasting to video memory would also have been very useful but the design of the APU and PPU don't allow that because the APU only outputs to $2004, which is only usable for loading OAM data.
    – supercat
    Commented Sep 16, 2021 at 3:37
4

Educated guess here...

$07ff is 0000 0111 1111 1111 in binary. So all addresses in that 2k are represented in the 11 least significant bits (bit 0 through bit 10). Mirror #8 runs from $1800 thru $1fff. $1fff is 0001 1111 1111 1111. So you can see that bits 11 and 12 don't matter (ie: 000x x111 1111 1111) - they're ignored.

Ignoring a bit on a CPU is accomplished by not connecting it's corresponding address line (pin) to anything. Since the designers didn't have any more memory to talk to, that is just what they did.

As a developer, I would have only used the base address, just in the extremely remote case that Nintendo came out with a 4k or (gasp!) 8k version.

So in short, it wasn't intentional, just an effect of not having enough RAM/ROM to fill the entire 64k that the 6502 could address.

Not the answer you're looking for? Browse other questions tagged .