Bits have two possible states, so if you have three bits, you're guaranteed a matching pair of values somewhere among those three bits. If you fetch 3 controller status bytes, you should be able to build a new controller status byte by finding the matching pair for each bit, using the three bytes.
The truth table to apply to each bit is this:
Code: Select all
A B C
0 0 0 | 0
0 0 1 | 0
0 1 0 | 0
0 1 1 | 1
1 0 0 | 0
1 0 1 | 1
1 1 0 | 1
1 1 1 | 1
If you read the controller three times and store each byte in A, B, and C, the 6502 code to do a bitwise "sock pairing" is this:
Code: Select all
lda B
ora C
and A
sta A
lda B
and C
ora A
sta A
Edit: One caveat is, because of the possible latency with the individual bits, there are extremely extremely extremely rare situations where a DMC glitch can happen right as you shift your thumb on the d-pad to another direction, to cause the software to see both up+down or both left+right pressed simultaneously. For instance, one byte of left pressed, one byte of right pressed, and a DMC-glitched byte of right pressed that looks like left+right are pressed; the pairing algorithm will see two 1's for left and two 1's for right, giving the software one frame of left+right. This requires an extremely specific case of everything being timed perfectly, and may be just as rare as a real controller physically having left+right pressed.