Controller reading: Difference between revisions
Rainwarrior (talk | contribs) (→DPCM Conflict: moved from Standard controller) |
Rainwarrior (talk | contribs) m (→DPCM Conflict: capitalization) |
||
Line 47: | Line 47: | ||
The CLK line for controller port is ''R/W nand (ADDRESS == $4016/$4017)'' (i.e., CLK is low only when reading $4016/$4017, since R/W high means read). When this transitions from high to low, the buffer inside the NES latches the output of the controller data lines, and when it transitions from low to high, the shift register in the controller shifts one bit.<ref>[//forums.nesdev.org/viewtopic.php?t=4116 Forum post:] DPCM generates extra $4016 read pulse</ref> | The CLK line for controller port is ''R/W nand (ADDRESS == $4016/$4017)'' (i.e., CLK is low only when reading $4016/$4017, since R/W high means read). When this transitions from high to low, the buffer inside the NES latches the output of the controller data lines, and when it transitions from low to high, the shift register in the controller shifts one bit.<ref>[//forums.nesdev.org/viewtopic.php?t=4116 Forum post:] DPCM generates extra $4016 read pulse</ref> | ||
=== DPCM | === DPCM conflict === | ||
Using DPCM sample playback while trying to read the controller can cause problems because of a [[Errata#APU DMC|bug in its hardware implementation]]. | Using DPCM sample playback while trying to read the controller can cause problems because of a [[Errata#APU DMC|bug in its hardware implementation]]. |
Revision as of 00:03, 21 April 2019
NES and Famicom controllers are operated through a register interface that is connected to the controller port and expansion port, as well as hardwired controllers on the Famicom.
For most input devices a standard procedure is used for reading input:
- Write 1 to $4016 to signal the controller to poll its input
- Write 0 to $4016 to finish the poll
- Read polled data one bit at a time from $4016 or $4017
$4016 Write
7 bit 0 ---- ---- xxxx xEES ||| ||+- Controller port latch bit ++-- Expansion port latch bits
The low 3 bits written to this register will be latched and held. Its output will be continuously available on the OUT line of the controller port, and the expansion port.
Other bits are ignored.
On the standard controller this is connected to the PARALLEL/SERIAL CONTROL of a 4021 8-bit shift register. Writing 1 to $4016 causes the register to fill its parallel inputs from the buttons currently held. Writing 0 to $4016 returns it to serial mode, waiting to be read out one bit at a time. Most other input devices operate in a similar way.
$4016 / $4017 Read
7 bit 0 ---- ---- xxxD DDDD |||+-++++- Input data lines D4 D3 D2 D1 D0 +++------- Open bus
Reading from this register causes a clock pulse to be sent to the controller port CLK line on one controller, and one bit will be read from the connected input lines. $4016 reads only from controller port 1, and $4017 reads only from controller port 2. The read value is inverted: a high signal from the data line will read as 0, and a low signal will read as 1.
For most devices it is necessary to read several times from these registers to collect multiple output bits from the device.
The specific use of each data line depends on the input device connected. For the standard controller and zapper which commonly came with the NES/Famicom:
D0 - NES standard controller, Famicom hardwired controller D1 - Famicom expansion port controller D2 - Famicom microphone (controller 2 only) D3 - Zapper light sense D4 - Zapper trigger
The NES controller port makes only D0, D3 and D4 available for peripherals. The Famicom hardwired controllers connect to D0, and $4016.D2 (microphone) only. Some of the other lines can be connected through the expansion port on the Famicom. The NES expansion port was never used commercially, but connects all 5 data lines to both ports.
Clock timing
The CLK line for controller port is R/W nand (ADDRESS == $4016/$4017) (i.e., CLK is low only when reading $4016/$4017, since R/W high means read). When this transitions from high to low, the buffer inside the NES latches the output of the controller data lines, and when it transitions from low to high, the shift register in the controller shifts one bit.[1]
DPCM conflict
Using DPCM sample playback while trying to read the controller can cause problems because of a bug in its hardware implementation.
If the DMC DMA is running, and happens to start a read in the same cycle that the CPU is trying to read from $4016 or $4017, the values read will become invalid. Since the address bus will change for one cycle, the shift register will see an extra rising clock edge (a "double clock"), and the shift register will drop a bit out. The program will see this as a bit deletion from the serial data. Not correcting for this results in spurious presses. On the standard controller this is most often seen as a right-press as a trailing 1 bit takes the place of the 8th bit of the report (right).
This glitch is fixed in the 2A07 CPU used in the PAL NES.
This detail is poorly represented in emulators[2]. Because it is not normally a compatibility issue, many emulators do not simulate this glitch at all.
Multiple Read Solution
The standard solution used in most games using DMC will read the controller multiple times and compare the results to avoid this problem. This is not suitable for controllers that can't be reread, such as the SNES Mouse.
Synchronized OAM Solution
Because OAM DMA synchronizes the CPU and APU such that reads on an "even" CPU cycle never overlap a glitch, a program on an NTSC NES can miss all the glitches by triggering an OAM DMA as the last thing in vblank just before reading the controller, so long as all the reads are spaced an even number of cycles apart.[3]
Because this is a relatively new discovery, many current emulated implementations of the DMC glitch may be inadequate for testing this technique[4]. Hardware testing is recommended.
Unconnected data lines and open bus
The behaviour of unconnected lines is more complicated. For the most part, unconnected lines are either pulled to 0, or exhibit open bus behaviour.
NES-001 $4016/$4017:
- D0 0 if not connected
- D1 always 0
- D2 always 0
- D3 0 if not connected
- D4 0 if not connected
NES-101 $4016/$4017
- D0 0 if not connected
- D1 always 0
- D2 open bus[5]
- D3 always 0
- D4 always 0
Famicom $4016
- D0 always connected to controller 1
- D1 0 if not connected
- D2 microphone on controller 2
- D3 open bus
- D4 open bus
Famicom $4017
- D0 always connected to controller 2
- D1 0 if not connected
- D2 0 if not connected
- D3 0 if not connected
- D4 0 if not connected
All other lines are open bus.
See Also
References
- ↑ Forum post: DPCM generates extra $4016 read pulse
- ↑ http://forums.nesdev.org/viewtopic.php?p=231604#p231604
- ↑ Forum post: Rahsennor's OAM-synchronized controller read
- ↑ Forum post: as of May 2016, Nintendulator and Nestopia do not accurately emulate OAM-synchronized controller reading.
- ↑ Forum post: Riding the open bus (NES-101 D2 behaviour)