Reading and saving $2000: Why does this change the behavior?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems.

Moderator: Moderators

Post Reply
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Reading and saving $2000: Why does this change the behavior?

Post by DRW »

When I write this:

Code: Select all

	LDA $2000
	STA $2000
this shouldn't do anything useful, right? It reads the value and writes it back.

So, how come that if I do this and then I do some background graphics work, that my new tiles are drawn vertically while they would be drawn horizontally without these two calls?

The acual code:

Code: Select all

	LDA $2000
	STA $2000
	; --> Should actually be useless, but influences the following output.
	
	LDA $2002
	LDA $20
	STA $2006
	LDA $00
	STA $2006
	
	LDX #$00
@loop:
	LDA TilesForUpdate, X
	STA $2007
	INX
	CPX #TILES_FOR_UPDATE_COUNT
	BNE @loop
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Reading and saving $2000: Why does this change the behav

Post by rainwarrior »

I believe $2000 is a write-only register, which means trying to read it will give you some sort of open busweird behaviour? It doesn't give you the contents of the register. (You need to store that in a variable if you want to recover it later.)

Edit: tepples explains in detail below.
Last edited by rainwarrior on Wed Aug 12, 2015 6:54 pm, edited 1 time in total.
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Re: Reading and saving $2000: Why does this change the behav

Post by DRW »

O.k., I'll do. I didn't know that you cannot read from it. But it makes sense since all these $200x values are just for writing.
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Reading and saving $2000: Why does this change the behav

Post by rainwarrior »

$2002 is just for reading.

$2004 and $2007 are read-write, though there are some big caveats about reading from $2007 (there is a buffer delay, it's... weird)

wiki: PPU registers
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Reading and saving $2000: Why does this change the behav

Post by tepples »

Reading any write-only PPU port will give you the last value written to or read from any PPU port. For example, if you just wrote to $2001 or $2007, then reading $2000 will return that last value you wrote. Reading video memory through $2007 also sets the previous value. Reads from $2002 return the status in bits 7-5 and bits 4-0 of the previous value in bits 4-0. (Low-level explanation: The PPU uses an 8-bit internal data bus for communication with the CPU, which functions as a dynamic latch.)

But I'd recommend against relying on that behavior, as a dynamic latch decays at an unspecified rate, and emulators and famiclones are unlikely to implement it perfectly. If you want to do read-modify-write on a PPU port, save a backup copy of the port in a variable in RAM:

Code: Select all

VRAM_DOWN = $04

  lda last_PPUCTRL
  ora #VRAM_DOWN
  sta last_PPUCTRL
  sta $2000
User avatar
rainwarrior
Posts: 8062
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Reading and saving $2000: Why does this change the behav

Post by rainwarrior »

tepples wrote:a dynamic latch decays at an unspecified rate, and emulators and famiclones are unlikely to implement it perfectly
I'm trying to imagine an emulator with a room temperature setting, and simulation of heat dissipation within the NES.
User avatar
DRW
Posts: 2070
Joined: Sat Sep 07, 2013 2:59 pm

Re: Reading and saving $2000: Why does this change the behav

Post by DRW »

tepples wrote:But I'd recommend against relying on that behavior
Exactly. After reading all your posts, I won't try to read any of these values at all. If I still need the value, I'll save it into an own variable.
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg
bootmii
Posts: 12
Joined: Sat Jul 25, 2015 11:53 am

Re: Reading and saving $2000: Why does this change the behav

Post by bootmii »

rainwarrior wrote:
tepples wrote:a dynamic latch decays at an unspecified rate, and emulators and famiclones are unlikely to implement it perfectly
I'm trying to imagine an emulator with a room temperature setting, and simulation of heat dissipation within the NES.
Can you also simulate ZIF stress if region is not set to Japan? :mrgreen:
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Reading and saving $2000: Why does this change the behav

Post by tepples »

bootmii wrote:Can you also simulate ZIF stress if region is not set to Japan? :mrgreen:
Not if we're also simulating a Blinking Light Win.
User avatar
Quietust
Posts: 1786
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: Reading and saving $2000: Why does this change the behav

Post by Quietust »

tepples wrote:But I'd recommend against relying on that behavior, as a dynamic latch decays at an unspecified rate, and emulators and famiclones are unlikely to implement it perfectly.
Interestingly, it's not a true dynamic latch - the value just sits on the bus lines (via capacitance). Furthermore, writing to VRAM via $2007 actually "stores" the to-be-written value directly on the bus, relying on it not decaying within the dozen or so cycles it takes for the VRAM write to finish. If you were somehow able to write to another PPU register before the VRAM write finished, you'd overwrite the value to be written.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
Post Reply