Page 1 of 1
NES Controller to VIA Question
Posted: Thu Jun 19, 2025 10:23 pm
by cbmeeks
I'm connecting two NES controllers to one VIA (65C22).
For those that don't know, the NES controllers essentially have a simple shift register in them. You set the latch pin, then clock it 8 times and you will get the 8-bit value of the buttons.
Since I want to drive two of them, I was thinking that I could use PA0 for CLOCK on both controllers (clock them at the same time). And PA1 for the latch on both controllers (latch them at the same time).
But each controller has a D0 (data) output pin. As I am clocking them, I need to capture two bits at the same time but split them out into two separate bytes. I hope that makes sense.
It would seem using the shift register of the VIA would be a good fit but I would need two of them.
So in theory, I should just need four pins.
Any suggestions?
Thanks!
Re: NES Controller to VIA Question
Posted: Fri Jun 20, 2025 10:00 am
by drogon
I'm connecting two NES controllers to one VIA (65C22).
For those that don't know, the NES controllers essentially have a simple shift register in them. You set the latch pin, then clock it 8 times and you will get the 8-bit value of the buttons.
Since I want to drive two of them, I was thinking that I could use PA0 for CLOCK on both controllers (clock them at the same time). And PA1 for the latch on both controllers (latch them at the same time).
But each controller has a D0 (data) output pin. As I am clocking them, I need to capture two bits at the same time but split them out into two separate bytes. I hope that makes sense.
It would seem using the shift register of the VIA would be a good fit but I would need two of them.
So in theory, I should just need four pins.
Any suggestions?
Thanks!
Shift it in software.
I did this many years back on the Raspberry Pi with my wiringPi library. At the time I used 3 pins per controller but worked out how to do it with 2 pins plus one per controller. It was all done in software, clock then sampling the input pin once every 50µS. I found that any faster wasn't reliable, although I was running it all at 3.3v which was just inside the tolerance of the CMOS 4021N used in the controller. At 50µS per pulse, that's 400µS to read N joysticks. Not too shabby and worth experimenting with the timing if you need to.
My code is all in C, but may be of use for a single joystick case. Easy to change to multiple global variables or an array, one for each joystick, so a single VIA port could handle up to 6 joysticks. Here is the 'core' of it all:
Code: Select all
unsigned int readNesJoystick (int joystick)
{
unsigned int value = 0 ;
int i ;
struct nesPinsStruct *pins = &nesPins [joystick] ;
// Toggle Latch - which presents the first bit
digitalWrite (pins->lPin, HIGH) ; delayMicroseconds (PULSE_TIME) ;
digitalWrite (pins->lPin, LOW) ; delayMicroseconds (PULSE_TIME) ;
// Read first bit
value = digitalRead (pins->dPin) ;
// Now get the next 7 bits with the clock
for (i = 0 ; i < 7 ; ++i)
{
digitalWrite (pins->cPin, HIGH) ; delayMicroseconds (PULSE_TIME) ;
digitalWrite (pins->cPin, LOW) ; delayMicroseconds (PULSE_TIME) ;
value = (value << 1) | digitalRead (pins->dPin) ;
}
return value ^ 0xFF ;
}
-Gordon
Re: NES Controller to VIA Question
Posted: Fri Jun 20, 2025 12:15 pm
by cbmeeks
Very helpful, thanks!
Re: NES Controller to VIA Question
Posted: Fri Jun 20, 2025 5:11 pm
by Yuri
I found that any faster wasn't reliable...
Pretty much the entire circuit of the NES controller is a 4021 wired directly to the buttons. That IC is a 40 series version of the 74xx166, and tops out at about 12MHz according to the TI datasheet, vs. the 74LS version at 45Mhz.
I would either just do one at a time using the shift register CB1/CB2 pins and a couple of PAx pins, or you could put in two serial input registers like the 74xx164 or 74xx299. Personally I'm a fan of the 74xx299, which allows you to control the output of the parallel I/O pins directly.