Here's an updated version that should work correctly for Famicom external controllers. I thoroughly tested it at maximum DMC rate and it passes. The three reads now take longer than 432 clocks, but the reads are spaced so that the DMC cannot corrupt more than one. Inserting an 8+16*n (n >= 0) clock delay after the first read causes it to fail, confirming that they are spaced properly. I also added a controller button test.
read_joy2.zip
I also finally got around to doing the analysis of the case where the DMC corrupts the first read, and the controller input changes during the the second two reads. In this case, the corrupted first read will be returned, rather than one of the two correct reads from the controller.
There are 8 opportunities for DMC corruption of the first read, and the window for the controller change during the second two is 162 clocks. That means that the DMC corruption at maximum rate has an 8 in 29780 = 1 in ~3722 chance in a given frame, and the controller change a 162 in 29780 = 1 in ~184 chance in a given frame.
Assuming the controller were changing at a random time each frame, and the DMC were running, that makes the chance of both occurring in a given frame 1 in ~684848. So there would be an average of one of these errors every 3.2 hours at this worst-case setup. If the controller input were changing on average 10 times per frame, that would put one error every 19 hours.
I guess I'll try writing and analyzing a version that reads until two consecutive reads give the same value. The main problem is that this takes a varying amount of time, and would hang if someone fed the controller a very rapid turbo signal.