What should write-only registers return when read? ($200x)

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

User avatar
Petruza
Posts: 311
Joined: Mon Dec 22, 2008 10:45 pm
Location: Argentina

What should write-only registers return when read? ($200x)

Post by Petruza » Sat May 29, 2010 8:03 pm

Registers like $2000, $2001, $2003, $2005, $2006, $4014, are write-only.
What should those registers return when there's an attempt to read them?

I guess for $2000 and $2001, the flags that are written to those registers, could also be returned when read.
For $2003, 2005 and $2006 maybe the last value that was written to them, can be returned.

Or should they return garbage? or zeros?

User avatar
tokumaru
Posts: 11864
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru » Sat May 29, 2010 8:07 pm

Most likely open bus... None of them will return what was written to them last, that's for sure.

User avatar
Dwedit
Posts: 4354
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit » Sat May 29, 2010 8:07 pm

I hear they return the low address byte back. Open bus.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

User avatar
Disch
Posts: 1849
Joined: Wed Nov 10, 2004 6:47 pm

Post by Disch » Sat May 29, 2010 8:31 pm

Dwedit wrote:I hear they return the low address byte back. Open bus.
Open Bus usually results in the high address byte.

User avatar
Dwedit
Posts: 4354
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit » Sat May 29, 2010 8:42 pm

Oops. I knew it was one of those.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

User avatar
Petruza
Posts: 311
Joined: Mon Dec 22, 2008 10:45 pm
Location: Argentina

Post by Petruza » Sat May 29, 2010 9:07 pm

by address you mean the last address that was fetched by a CPU instruction?

User avatar
tokumaru
Posts: 11864
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru » Sat May 29, 2010 9:29 pm

Petruza wrote:by address you mean the last address that was fetched by a CPU instruction?
If the last command was 'LDA $2001' the returned value will be $20. That's because in the ROM that instruction is stored as $AD $01 $20, and the bytes are read by the CPU in that order, which means that the last byte that goes through the data bus is the high address of the address that was read.

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Sun May 30, 2010 6:38 am

I just had some code write $FF to $2002, then read back $2001 at 10 msec invervals:

Code: Select all

msec 0  ... 260 270 ... 340 350 360 370 ... 440 450 460 470 480 490 500 510 520 
read FF ... FF  EF  ... EF  CD  CD  C9  ... C9  C1  81  81  81  81  81  81  00
So the last value written (and probably read) gets held for a while, but slowly decays to zero by around 520 msec (half a second), but at different rates for each bit. I imagine the decay rates vary slightly for each NES unit.

EDIT: Haha, as expected, the decay rate is affected significantly by the PPU temperature. I wrote a second test that accurately times how long it takes for each bit to decay. You could use this in a game to tell whether the NES had been on for a long time, perhaps in a scene like in Metal Gear Solid for PSX where it examines your memory card and says things based on what other games you've played.

Just powered on, taking measurement every 10 seconds or so (114 clocks per unit):

Code: Select all

 7    6    5    4    3    2    1    0
253F 2085 1D30 15DB 27D1 1EB0 214C 2A95 
237E 1E9F 1B80 14B7 25DE 1D5D 1F96 283A 
2293 1DE3 1B13 146D 2515 1CE1 1F55 278D 
222E 1DAA 1A85 143A 2470 1CA3 1EF4 26ED 
2180 1D28 1A2D 13D9 2432 1C4E 1E73 25EB 
2093 1CAA 19D0 13AA 2391 1BF0 1DEA 25E7 
207E 1C51 1980 1376 2343 1B9C 1D8B 255B 
202A 1C11 192B 1331 22CD 1B39 1D62 24EE 
1F5A 1B6F 188F 12B2 220A 1AE6 1CE3 23E3 
... after several minutes ...
16B5 13E6 11A9 0E01 1946 149A 15F5 1A4D 
16A2 13E0 1184 0DE3 1914 14AC 15C5 1A32

User avatar
Bregalad
Posts: 7951
Joined: Fri Nov 12, 2004 2:49 pm
Location: Chexbres, VD, Switzerland

Post by Bregalad » Sun May 30, 2010 8:14 am

Well there is probably a lot of other factors, such as how is the PCB inside the NES, etc... The values would probably differ a lot between various models of Famicoms and NESs.
Useless, lumbering half-wits don't scare us.

3gengames
Formerly 65024U
Posts: 2277
Joined: Sat Mar 27, 2010 12:57 pm

Post by 3gengames » Sun May 30, 2010 10:14 am

Code: Select all

 7    6    5    4    3    2    1    0
253F 2085 1D30 15DB 27D1 1EB0 214C 2A95 
237E 1E9F 1B80 14B7 25DE 1D5D 1F96 283A 
2293 1DE3 1B13 146D 2515 1CE1 1F55 278D 
222E 1DAA 1A85 143A 2470 1CA3 1EF4 26ED 
2180 1D28 1A2D 13D9 2432 1C4E 1E73 25EB 
2093 1CAA 19D0 13AA 2391 1BF0 1DEA 25E7 
207E 1C51 1980 1376 2343 1B9C 1D8B 255B 
202A 1C11 192B 1331 22CD 1B39 1D62 24EE 
1F5A 1B6F 188F 12B2 220A 1AE6 1CE3 23E3 
... after several minutes ...
16B5 13E6 11A9 0E01 1946 149A 15F5 1A4D 
16A2 13E0 1184 0DE3 1914 14AC 15C5 1A32

"Random" Numbers anyone? Unless I am missing anything, can't you read it if you CLR $200X and get a random number and re-write what was last wrote to said location?[/quote]

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Sun May 30, 2010 11:03 am

It's not very random. My current model is simple: anytime after nothing is written to a PPU register or read from $2002, $2004, or $2007, the last value written/read hangs around, but individual bits eventually decay to 0. The time of decay is specific to each bit, depends on how long the NES has been on (most likely temperature), and likely differs from one NES to another. I suppose you could get random values by timing the decay and looking at the low bits of the time.

I think the best source of random bits is having the user press a button. You can monitor the A button in a tight loop almost 200000 times per second (9 clocks per iteration, including incrementing an 8-bit counter), and keep the low 8 bits of the iteration count as random. This 8-bit count overflows almost 800 times per second, so the player won't be able to influence it very easily.

3gengames
Formerly 65024U
Posts: 2277
Joined: Sat Mar 27, 2010 12:57 pm

Post by 3gengames » Sun May 30, 2010 12:21 pm

Hmm okay....

User avatar
cpow
NESICIDE developer
Posts: 1097
Joined: Mon Oct 13, 2008 7:55 pm
Location: Minneapolis, MN
Contact:

Post by cpow » Sun May 30, 2010 12:24 pm

blargg wrote:I just had some code write $FF to $2002, then read back $2001 at 10 msec invervals:

Code: Select all

msec 0  ... 260 270 ... 340 350 360 370 ... 440 450 460 470 480 490 500 510 520 
read FF ... FF  EF  ... EF  CD  CD  C9  ... C9  C1  81  81  81  81  81  81  00
Are there any games that rely on this kind thing?

If so...what fun that will be to emulate!

User avatar
blargg
Posts: 3715
Joined: Mon Sep 27, 2004 8:33 am
Location: Central Texas, USA
Contact:

Post by blargg » Sun May 30, 2010 12:58 pm

I think at least one demo relies on some of this behavior. Here you go, a test ROM for this "decay register" behavior:

ppu_open_bus.zip

The only explanation I can come up with for this is that the PPU has a bidirectional data bus buffer at its interface, resulting in an internal bus that can float and thus hold a separate value from the CPU's main data bus.

I also tried using the decay time as a source of randomness, using a tight loop similar to the A button press described earlier, but it wasn't very random at all from one timing to the next. It apparently is somewhat related to where you are in the video frame, even if PPU rendering is disabled. Oh well. Might still be useful if you don't have a player to press a button.

User avatar
Dwedit
Posts: 4354
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit » Sun May 30, 2010 8:51 pm

What about the joypad "open bus" bits? I'm using some of that CPX \ ROR based joypad reading code. Would the open bus bits stay reliable for a total of 8 joystick reads?
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!

Post Reply