Memory mirroring?

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
djcouchycouch
Posts: 97
Joined: Sat May 28, 2011 10:30 am

Memory mirroring?

Post by djcouchycouch »

I've always wondered: why do the NES CPU and PPU have areas in their memory map that are mirrors of other areas?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Because not all address lines are decoded. The NES decides which memory chips to activate based on the addresses that are accessed by the CPU or PPU. For example, since PRG-ROM is supposed to be mapped at $8000-$FFFF, only one address line is required to detect that this range is being accessed: A15 will be low when accessing $0000-$7FFF, and high when acessing $8000-$FFFF.

Since it takes more hardware to watch more address lines, some of them are ignored if there are no undesired side effects. The NES only has 2KB of RAM, mapped at $000-$7FF. To guarantee that this RAM would be visible only at that range, the CPU would have to check if a bunch of address lines were low, which would require extra hardware and would bring no advantage. So it's easier/cheaper to ignore those address lines, causing the same memory to be visible no matter what those lines are, effectively making the same memory visible at different addresses.
User avatar
Edgyr45
Posts: 7
Joined: Sun Jun 19, 2011 12:04 pm
Location: Québec, Canada

Post by Edgyr45 »

Because not all address lines are decoded
What is an address line?
0x0700 is an address
0x0000-0x0700 is a range of addresses

I'm really trying to understand this here (you can laugh at me all you want :))

I'll take 0x0700 which is in the 0x0000-0x07FF range that get repeated 3 times in RAM.

If I want to read 0x0700's mirror, I must read at : 0x0700 + 2kb = 0x0F00 which is also in the range of the 1st mirror memory 0x0800–0x0FFF

I tried to see how those two memory are related and I still don't get it...

0x0700 = 00000111 00000000b
0x0F00 = 00001111 00000000b

Perhaps with this post you will identify what is it I don't get...
Thanks
User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow »

Edgyr45 wrote:
Because not all address lines are decoded
What is an address line?

0x0700 = 00000111 00000000b
0x0F00 = 00001111 00000000b

Perhaps with this post you will identify what is it I don't get...
Thanks
An address line is a physical wire that carries a signal. A signal is a voltage level (say 0volts to 5volts). In *most* computers the signal is "quantized" into three regions where a "voltage above some value" means a logic 1 and a "voltage below some other value" means a logic 0 (and a voltage between these values is "bad news" but that's not relevant here). Realistically a computer doesn't *know* it's dealing with 1's and 0's. But...anyway.

If you look at the addresses you've converted from hexadecimal to binary notation above, you should quickly see the only difference between them is that leftmost 1 in the 0x0F00 case that is not there in the 0x0700 case. It is that 0/1 bit of the address that rides on an address line that is not connected to the NES RAM. The rest of the address lines to the right of that 0/1 bit *are* connected to the NES RAM. Thus, for both of those addesses you gave above the NES RAM will put data onto the data bus from its "address 0x0700".
User avatar
Bregalad
Posts: 8056
Joined: Fri Nov 12, 2004 2:49 pm
Location: Divonne-les-bains, France

Post by Bregalad »

Well how you guys are over complicating things.

Simply put, the RAM chip is enabled to respond in the $0000-$1fff range, but is only 2k, so like cpow said two adress lines are simply unconnected to the chip and will not have any effect on it.
The higher adress lines aren't connected to the chip eihter - they are instead connected to some 74 series logic chip that will do the decoding / that is tell the RAM chip to respond when the CPU acess $0000-$1fff, tell the PPU to respond when adressing $2000-$3fff, etc...

Of course it could have been possible to fully decode the adress and disable the RAM chip for range $800-$1fff, but this would waste hardware for no reason.
Useless, lumbering half-wits don't scare us.
User avatar
MottZilla
Posts: 2837
Joined: Wed Dec 06, 2006 8:18 pm

Post by MottZilla »

The address lines are the bits that make up the address you are accessing. In order to access the RAM the system checks that certain bits in the address are low (0) to determine you are accessing the memory region between $0000 and $2000. This means you have less bits to check than specifically checking for less than $0800.

So what happens is if the address is $1FFF which is

Code: Select all

01111111111111
32109876543210 - guide
That 0 which would start being set at address $2000 is letting the logic know to enable the RAM chip. Since the address lines above $7FF don't actually connect to the memory it loops around as the lines that are connected still change.

Not sure how to make it much more clear.

In a smaller example say you had a memory that was only 4 bytes. If the address is 00, 01, 10, or 11 they would all access a different byte of memory. When you try to access 100, that first 1 is ignored cause it connects to nothing. So you're accessing the same as 00.

Logically you can get the RAM address for NES by doing Address & $7FF. This logical and operation will remove any address bits higher than what actually exists on the NES RAM chip. I hope this helped.
IbrahimSba3i
Posts: 1
Joined: Wed Apr 16, 2014 2:35 am

Re: Memory mirroring?

Post by IbrahimSba3i »

So 0x2000 which is 0b 0010 0000 0000 0000 is equivalent to 0x0000 which is 0b0000 0000 0000 0000 in binary because the first 3 bits are ignored anyways???
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Memory mirroring?

Post by tepples »

No, $2000 isn't the same as $0000 because they result in different chips being enabled. CPU A15-A13 go to the 74LS139 address decoder at U3 in this schematic, which computes three chip select signals:
  • 000: Internal RAM
  • 001: PPU ports
  • 100-111: /ROMSEL
EDIT: corrected
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Memory mirroring?

Post by Quietust »

tepples wrote:No, $2000 isn't the same as $0000 because they result in different chips being enabled. CPU A15-A13 go to the 74LS139 address decoder at U3 in this schematic, which computes three chip select signals:
  • 000: Internal RAM
  • 001: PPU ports
  • 100: /ROMSEL
Nitpick: that third one should be 1XX, since 100/101/110/111 are all included (otherwise it'd only be $8000-$9FFF).

The way it actually works is as follows:
1. The 'secondary' decoder in the 74139 is always enabled (/EN connected to GND) and decodes A15 and M2; for 1/1 (valid access to $8000-$FFFF) it enables /ROMSEL (i.e. PRG /CE), and for 0/1 (valid access to $0000-$7FFF) it enables the 'primary' decoder in the 74139.
2. The 'primary' decoder in the 74139 is enabled as above and decodes A14 and A13; for 0/0 ($0000-$1FFF) it enables CPU RAM, and for 0/1 ($2000-$3FFF) it enables the PPU.
In theory, pins 6 and 7 on the 74139 could have also been tapped in order to decode $4000-$5FFF and $6000-$7FFF, but the NES itself doesn't map anything to those address spaces (the APU registers at $4000-$401A are internal to the CPU itself and don't count) and there wasn't room for them on the cartridge connector.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Post Reply