$4016 bit 0 output is connected to the load pin of the 4021 8-bit shift register. When load is 1, the data output always reflects the current status of data 0 (the A button). When load transitions from 1 to 0, the shift register latches the data at each input and the output reflects bit 0 of the shift register.
byuu wrote:
Ok, so when $4016.d0 is set, the read position is reset to 0 (status of A), and all reads from $4016 at this point return the status of A, at the time of reading $4016, as if having the strobe bit set means the NES is constantly polling the joypad in realtime, and acts basically like a real-time state buffer? So eg multiple reads can return different values at this point?
Yes. The joypad would be constantly feeding the current status of A to the data input on the joypad connector, and when you read the CPU just takes the current value.
Quote:
But then, when you write a 1 to $4016.d0, it then stops polling the joypad any more. So now you read $4016 and it returns the status of each button in sequential order, at the time that you write to $4016, not when you read from it?
Assuming you mean writing 0 to $4016, yes.
Quote:
And it's been verified that the NES controller doesn't just keep polling anyway, eg by doing something like holding down B, reading A, releasing B, waiting 5 seconds, and then reading B and seeing if it is set? So that eg the strobe bit only affects the read position?
It's all based on the behavior of the 4021 shift register. When strobe transitions from 1 to 0, it latches. When you clock it, the the register's contents shift right by one bit. Not much else to it. Here's some test code I just ran on my NES, with a NES and SNES controller (using a SNES-to-NES adaptor I made):
Code:
; I start holding B before running code
lda #0 ; strobe = 0
sta $4016
lda #1 ; strobe = 1
sta $4016
lda #0 ; strobe = 0
sta $4016
lda $4016 ; read status of A
lda #100 ; wait one second
jsr delay_10msec
; I release B button during delay
lda $4016 ; read status of B
and #$01
jsr print_a ; prints 1
Quote:
So you could theoretically just set the strobe bit to 1 and use the A button as a real-time status button without ever writing to $4016 again?
Right. You could make a one-button game that never needed to toggle the strobe line.
There was another thread a while back where I posted some other explanation and test code too:
http://nesdev.com/bbs/viewtopi ... =4606#4606hap wrote:
something even more obscure: what happens if you read button status after turning the NES on, or after reset, without having strobed?
Heh, I like the obscurity of this. I just tried a few times and at power-up and reset and it acts as if you had written 1 then 0 to $4016, i.e. it latches the current button state and is in read mode. Apparently it's the controller itself, because I get the same behavior when I plug it in then immediately try reading data. Same for NES and SNES joypads.