Why use repeated STZ instructions with the same operand on the 65c816 for the SNES (Super Nintendo)?

2018-07-21 19:09:04

Please consider the code at:

https://en.wikibooks.org/wiki/Super_NES_Programming/Initialization_Tutorial/Snes_Init

Here is an excerpt:

stz $2113 ; Plane 3 scroll x (first 8 bits)

stz $2113 ; Plane 3 scroll x (last 3 bits) #$0 - #$07ff

From the comments, this seems intuitive enough. However, when I look at the instruction set reference provided here:

http://www.6502.org/tutorials/65c816opcodes.html#6.5

"STZ store zero into the memory location specified by the operand." and "Note that no registers are affected by STZ."

From this it seems that STZ with some constant operand should yield the exact same result every time it is executed, so what is the point in executing it with the same operand immediately after the previous instruction?

What is the variable here? Time? 0x2113 is a hardware register, and according to:

https://en.wikibooks.org/wiki/Super_NES_Programming/SNES_Hardware_Registers

it is the "BG 4 Horizontal Scroll Offset". This doesn't seem t

  • This is a “write-twice” register, a 16-bit register mapped into a single byte, which takes two 8-bit stores to populate. There are a number of these on the SNES, with varying write orders (high or low byte first). The Super Famicom Development Wiki describes the behaviour of this particular family of registers thus:

    Note that these are "write twice" registers, first the low byte is written then the high. Current theory is that writes to the register work like this:

    BGnHOFS = (Current<<8) | (Prev1&~7) | (Prev2&7);

    Prev1 = Current;

    Prev2 = Current;

    or

    BGnVOFS = (Current<<8) | Prev1;

    Prev1 = Current;

    2018-07-21 19:53:58
  • As RichF already mentioned, it's a 16-bit register, which means there are two 8-bit values needed. Usually such a register would be mapped into two addresses. The NES is a bit special here, as it only uses one memory address which results in the need of two consecutive writes with the same address (*1).

    The tutorial shows an example by setting the background colour where two bytes are written into $2122, low byte first.

    What is the variable here? Time?

    Exactly, instead of spreading the halves across a spacial (address) dimension, they are separated temporal (sequence) on the same location. First low byte then high byte. The initialization example shows nicely (*2) that these writes can be mixed in-between other instructions, as long as the sequence of low first, high next is kept.

    Anyway, does 0x2113 perhaps map to different actual memory/hardware registers depending on time?

    Within the graphics hardware, yes. Depending on the sequence to either 'half' of the full 11-bit

    2018-07-21 20:54:17