NES (vs. SNES) controller timing?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
NES (vs. SNES) controller timing?
by on (#143916)
I'm working on a project to retrofit wireless connectivity into NES controllers. When I started the project and was doing research, I learned that both NES and SNES use the "same" protocol for transferring data (differing only in how many bits and what order they come in). So I started on the SNES, because then I have the option of only modding one set of controllers, building two receivers, and then it works with both consoles.

I've done the SNES part and everything works great. But the only/best data I could find online about the real wire protocol for the NES ( http://www.mit.edu/~tarvizo/nes-controller.html ) says "Every 60 Hz, the NES sends a 12us high signal to the Latch pin, telling the controller to latch the state of of all buttons internally. Six microseconds later, the NES sends 8 high pulses on the Pulse pin, 12us per full cycle, 50% duty cycle." This is definitely exactly what I observed with the SNES (except 16 clock pulses). But when I built the NES receiver, it wasn't working reliably.

As far as I can tell, the NES does not quite do this. On the NES, I'm seeing only a ~4 microsecond (not 12) latch pulse.
Attachment:
File comment: Latch timing.
smb-latch.png
smb-latch.png [ 109.09 KiB | Viewed 2964 times ]


The first falling edge of the clock is only ~9 us from the rising edge of latch (not 18), and the clock A) has a ~10 us period with B) only ~0.5us low (not 6).
Attachment:
File comment: Clock timing.
smb-clk.png
smb-clk.png [ 99.29 KiB | Viewed 2964 times ]


Is this normal/expected? It's causing trouble for me.
Re: NES (vs. SNES) controller timing?
by on (#143918)
The SNES reads the first 16 bits of the control word automatically, by hardware, and the result is buffered for the game to use. (The mouse, however, has to read an additional 16 bits in software)

The NES, on the other hand, has to bit-bang this half-duplex SPI-like protocol. There's no necessary or consistent timing, and some controller-reading routines violate the abstraction with the knowledge that they're talking to a shift register.

The only real constraint is that it will take 4cy to write to $4016, where the LATCH signal is held, or not less than ≈2µs. Most often it'll be 6cy (STX $4016; DEX; STX $4016), or ~3.4µs. Similarly, read spacing could be as little as 4cy if it's throwing away certain reads, but it'll probably be at least 8cy (LDA $4016; LSR A; ROL A).

Some read routines might latch the first bit while LATCH is high.


The NES joypad "protocol", from the point of view of the NES itself is
- Writes to the LSbit of register $4016 control the LATCH signal, which reloads the shift register
- Reads from $4016 and/or $4017 generate the negative pulse on CLK
- Games expect that the device attached to this bus is a 4021 or 74'165.
Re: NES (vs. SNES) controller timing?
by on (#143923)
Thanks! That explains the behavior I'm seeing. It's trickier than the regular/slower timing of the SNES but I think I'll get it sorted out.
Re: NES (vs. SNES) controller timing?
by on (#143983)
It's worth mentioning that the SNES controller is simply just two CD4021 (NES controller chip, a CMOS shift register) chips crammed inside of a custom chip.

Since the timing is controlled by the HOST using the shift register control pins, I don't think there's much one need to worry about the protocol if the behavior of the said pins are implemented (or emulated) properly.

I remember last century I tested connecting a SNES controller to the NES and it worked correctly. The only issue I had was the way the buttons were arranged.
Re: NES (vs. SNES) controller timing?
by on (#143988)
l_oliveira wrote:
I remember last century I tested connecting a SNES controller to the NES and it worked correctly.

Still does. One of my NES games even works with a Super NES Mouse through a pin adapter cable.
Re: NES (vs. SNES) controller timing?
by on (#144081)
I'd just have your microcontroller load the last known button state into a parallel-load shift register, and let the NES shift it out whenever it wants (obviously make sure the NES isn't reading it during your parallel load). This way you don't need to worry about timing your outputs, as the NES will clock it out in a virtually non-deterministic way (you have no idea which game a user may be playing or how they are reading the controller ports). Then use your wireless system to poll the NES gamepad at a reasonably fast rate (something faster than T = 1.667mS :roll: ) and send the new state to be loaded into the register, and things should work out fine.