10

I'm attempting to emulate the NES PPU and I'm implementing its registers. In particular, reading from the PPU status register has the following effects:

Reading the status register will clear D7 mentioned above and also the address latch used by PPUSCROLL and PPUADDR. It does not clear the sprite 0 hit or overflow bit.

Source

The PPUSCROLL and PPUADDR registers are both write only. When writing to PPUSCROLL for example, the first write specifies and X-scroll position, and the second write specifies the Y-scroll position.

Is the latch the thing that determines the write state (x or y)? I just want to make sure I'm understanding this correctly.

4 Answers 4

12

Disclaimer: I don't own a NES, aI haven't programmed a NES, nor have I written a NES emulator. The following is just my understanding of the description.

A latch is a set of D-Flip-Flops that is used to temporarily store a value. So an address latch stores an address temporarily. Both PPUSCROLL and PPUADDR need to provide a 16-bit address (or x-y-value), so both would have two 8-bit latches which are filled in turn with 8-bit values when writing to them.

To select one of the 8-bit latches, one would need an address latch toggle. It looks like this toggle (another kind of flip-flop) is re-used to control both the PPUSCROLL and the PPUADDR latch pair. It's reset on reading either of them, and it's also reset by reading PPUSTATUS. The description you reference seems to use the term address latch to both to refer to the proper latches, and the latch toggle (which should be fixed IMHO).

So, yes, it's the thing that determines the write state (high byte or low byte for PPUADDR, x or y for PPUSTATUS).

A question that's not answered is what happens on the third write: Will the value appear again on the first latch (the toggle toggles again), or on the second latch (toggle stays at it is)? If you do have a real NES, it would be interesting to find out.

1
4

Latches are used to hold data temporarily. They're an essential building block of chips and they they were used to simplify interfacing between the CPU and other hardware as CPUs had data registers that couldn't hold a full address (for example 8 bit data registers vs 16 bit addresses for the 6502)

In software terminology (in computer / game console interfaces), it refers to a very common setup I'll try to explain.

Let's suppose you need to write a 16 bit address to a video register with the 6502:

lda #address&255
sta VIDEOREGISTER
lda #address/256
sta VIDEOREGISTER + 1

how would the hardware know when the address is complete? it needs a trigger to make a copy of the value; for example when VIDEOREGISTER + 1 is written.

To simplify the logic, it uses a latch:

lda #address&255
sta VIDEOREGISTER
lda #address/256
sta VIDEOREGISTER

The first write stores the first value, the second write get the second part and triggers the operation.

It is smaller to implement in hardware that way since it is essentially two set (8 bits each) of flip-flops chained with one another (like a shift register). Each write triggers the copy of flip-flop1 to flip-flop2 and the value written goes to flip-flop1. One the second write, you have both values needed "latched".

In this scenario, when you read the status register, it resets the cycle; so if one write was already done, it's gone, and the latch is ready to receive an address through 2 writes.

This is useful since you don't know the status of the hardware after a reset, where maybe the cpu did one write before and then all writes to that register would subsequently not work as expected.

3

Is the latch the thing that determines the write state (x or y)?

While the terminology is not 100% accurate, the above is a pretty good summary.

There are several things going on at the same time which make this complicated. First you are trying to write more than 8 bits of data (X/Y coarse & fine) over an 8-bit bus. So this needs splitting up in two writes of 8 each. The PPU engineers COULD have made this easy and implemented separate I/O registers for those two bytes, but instead they reuse the same target address and keep track of state (referred to as W toggle in the documentation). Every time you write to $2005 the current W state is used to find the destination and then the W bit is flipped.

There is no way to read the current value of W. How do you make sure your first byte goes to the correct destination then? You explicitly set it to 0. This is done via another hack: when you perform a read of $2002, as a side effect it also happens to set W=0.

The next complication is that the engineers decided to use this approach with the generic address pointer as well. So if you write to $2006 it will flip the same W bit that's used by the scroll register $2005. As before, use a $2002 read to reset W. The final issue is that writing to $2006 partially overwrites the fine-Y scroll position, which is why scrolling needs to be set AFTER any $2006 writes were done.

Overall it's just jumping through hoops of a chip design that emphasized transisor savings over usability.

0

If what is being emulated is SNES functionality: The SNES used the 65816, an extended 6502 that could do 24-bit addressing - but still came in a 40 pin case which obviously allows no space for 24 actual address lines, so a partially multiplexed address bus was used - the same 8 lines sometimes acted as the data bus, sometimes as the address bus. In order to have the 24 address lines available for actually addressing anything, one needed to store the contents of the 8 combined lines in a latch at the right time in the machine cycle, so they were available (at the output of the latch) while these lines were used as the data bus.

This kind of multiplexed interface is commonly found on 40-pin microprocessors in various forms, eg on the 8086/8088 and 8031 - note the ADx pins and the ALE (address latch enable. And yes, makes you think the designers were drunk at times...) pin on these.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .