What do the unimplemented bits read back on 2001, 4016, and 4017?
What's the opposite of a bus conflict?
The upper bits of $4016 and $4017 read back a value held on the data bus by capacitance. In most cases, the operand fetch leaves $40 (the upper byte of $4016 and $4017) on the bus before $4016/$4017 changes the lower bits, but some indexed addressing modes can leave other things (especially $3F with a page crossing) on the bus.
And of course with $2002, there are 31 additional mirrors with different high bytes ($2102, $2202 ... $3E02, $3F02).
About the read value, does it matter for games (including homebrew concepts) or is merely an hardware quirk?
It only matters if you want your CPU trace logs to match another emulator's.
Dwedit wrote:
It only matters if you want your CPU trace logs to match another emulator's.
Are you saying that these open-bus bits cannot affect any NES programs? If so, I disagree.
Actually, this has entirely to do with comparing FCEUXD's trace logs with PocketNES's tracelogs, and I'm using winmerge to compare them. If registers don't match, I get a mismatch.
This is my understanding of register behavior on the Famicom/NES:
For the Famicom, reading $4016 returns controller #1 serial data on bit 0, expansion port data (such as controller #3) on bit 1, and microphone data (from controller #2) on bit 2. Bits 3-7 are all open bus and remain unchanged from earlier read/write transaction(s). Reading $4017 returns controller #2 data on bit 0, expansion port data on bits 1-4 (controller #4 on bit 1), and open bus on bits 5-7.
For the NES, reading $4016 or $4017 returns controller/expansion port data on bit 0, expansion port data (normally zero) on bits 1-4, and open bus on bits 5-7.
Reading $4015 returns open bus on bit 5 (the only unimplemented bit). Reading any unimplemented address from $4000-FFFF returns open bus on all 8 bits.
The PPU registers work differently. There is "open bus," but not on the CPU end - rather, it happens on the PPU side of things. Every time you write to $2000-3FFF, the value written is first placed in a latch register, which is then copied to the intended destination (such as VRAM) after the write cycle is completed. Reading from $2000-3FFF returns the same latch register, in which the PPU places the requested data (such as from the VRAM read buffer if you read from $2007). If you write a value to, say, $2001, then read from an unimplemented register (such as $2005), you will get back the same value you just wrote, since it is coming from this latch register.
Reading from $2002 will cause the PPU to put its three status flags in bits 5-7 of the latch register. Bits 0-4 are not changed, so you will get back whatever value was last read from or written to the PPU registers in those bits. If, for instance, you wrote $FF to $2005, then later read from $2002, you will get $1F in the lower bits. If you read $2002 then, say, read $2001, the value you get from $2001 will match what you just got from $2002.
If the VRAM address is pointing to palette space ($3F00-3FFF), only six bits are updated when reading $2007. The upper two bits remain unchanged from the last PPU transaction.