NES Controller to VIA Question

Let's talk about anything related to the 6502 microprocessor.
Post Reply
User avatar
cbmeeks
Posts: 1254
Joined: 17 Aug 2005
Location: Soddy-Daisy, TN USA
Contact:

NES Controller to VIA Question

Post 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.

Code: Select all

CLK
LATCH
D0
D1
Any suggestions?

Thanks!
Cat; the other white meat.
User avatar
drogon
Posts: 1671
Joined: 14 Feb 2018
Location: Scotland
Contact:

Re: NES Controller to VIA Question

Post by drogon »

cbmeeks wrote:
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.

Code: Select all

CLK
LATCH
D0
D1
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
--
Gordon Henderson.
See my Ruby 6502 and 65816 SBC projects here: https://projects.drogon.net/ruby/
User avatar
cbmeeks
Posts: 1254
Joined: 17 Aug 2005
Location: Soddy-Daisy, TN USA
Contact:

Re: NES Controller to VIA Question

Post by cbmeeks »

Very helpful, thanks!
Cat; the other white meat.
User avatar
Yuri
Posts: 371
Joined: 28 Feb 2023
Location: Texas

Re: NES Controller to VIA Question

Post by Yuri »

drogon wrote:
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.
Post Reply