Jump to content
IGNORED

4 joysticks on the 2600 (v2)


appleo

Recommended Posts

I think it is possible to connect 4 joysticks to the 2600 using paddles. I had hoped you could do it with the keyboard controllers, which still might work, but we need some specs.

 

Basically, instead of plugging the joystick into the joystick pins, we plug it into the paddle pins. Connect the ground to the +5v for the paddle, and connect each direction and fire button in the joystick to a fixed resistor (resistors should be gold tolerance), all leading to the gnd for the paddle. The resistances, added up, should not be > 1 MOhm (the max resistance of a paddle pot). Each resistance would need to have a base 2 number, like:

 

JOYSTICK, RESISTANCE

up, 8k ohm

down, 16k

left, 32k

right, 64k

fire, 128k

(total), <1 MOhm

 

I am using the larger numbers (8,16,32,64,128 as opposed to 1,2,4,etc) because I think the smaller numbers would be harder to detect. So if the player pressed up, right and fire simultaneously, the value read on the paddle would be 8k + 64k + 128k = 200k ohms, which would coincide with a unique paddle position (or time for the cap to discharge or whatever). Translate this time back into the number 200 and the individual bits, and you can detect that up / right and fire bits = on.

 

Is this doable?

Thoughts?

 

 

A thread on the topic:

 

appleo:

2600 keyboard controller - simultaneous keypresses

Is it possible to read >1 key being pressed on the keyboard controller at one time? For instance if the "1" and the "7" keys are pressed simultaneously can this be detected?

 

batari:

You can read the keyboard controllers in bB, but there's no built-in functions for them as there are for joysticks. You will need to use the SWCHA and INPT4 registers directly. I've never actually tried to read them in a program, but I have heard that some keys on the controller can't be read simultaneously. I recall a post about this a while back but I can't find it.

The poster was asking if it was possible to modify a keyboard controller to simulate two joysticks, and the answer was no because some combinations of button presses couldn't be read at the same time.

 

appleo:

Actually, that was my question for the joysticks. A long time ago I had come up with this scheme (http://softintheheadware.com/soft/4_atari_...s_invention.asp) for 4 joysticks on the C=64, and now that I am interested in the 2600, seeing that each keypad has 12 buttons would mean the possibility of 4 joysticks with 2 buttons each. I would like to experiment with some 4 player games - after all there are 4 player paddle games, why not for the joystick? Some specs on the keyboard controllers might help. If they are read using resistances like my c64 scheme uses, then it might be possible. Otherwise, multiple joysticks could still be used on the 2600 using the c64 scheme (resistances attached to the paddle ports in a binary fashion)

 

I found what you were talking about - from "synthcart for the atari 2600":

>Note that the Atari is not designed to read multiple keys off the keypads, so although one or two keys can be read accurately, the Atari may sometimes read keys in the wrong row when you are holding down three or more keys at once.

(full text)

 

I wonder though if this is a hardware or a software limitation. I need to find some specs on these keypad controllers.

Edited by appleo
Link to comment
Share on other sites

I found what you were talking about - from "synthcart for the atari 2600":

>Note that the Atari is not designed to read multiple keys off the keypads, so although one or two keys can be read accurately, the Atari may sometimes read keys in the wrong row when you are holding down three or more keys at once.

(full text)

 

I wonder though if this is a hardware or a software limitation. I need to find some specs on these keypad controllers.[/font]

940482[/snapback]

I'm pretty sure that's a hardware limitation.

 

My suggestion: you have 5 on/off pins in each port (UDLR and fire), why not use them?

 

So:

8K = U

16K = D

32K = L

64K = R

 

L = J0 fire, R = J1 fire.

 

Or something.

 

The fewer values you need to read off the pots the easier it is to read in the program.

Link to comment
Share on other sites

The thing is, you're only reading one value off the pot, a single resistance. Then it's up to the code to interpret the value - ie decipher it into the bits it represents. Or are you saying that the value read from the paddle is not precise enough to be able to translate into bitwise values?

 

What you said is interesting though because theoretically if you can read paddles AND joysticks you could have 6 joysticks.

 

-----

 

I found what you were talking about - from "synthcart for the atari 2600":

>Note that the Atari is not designed to read multiple keys off the keypads, so although one or two keys can be read accurately, the Atari may sometimes read keys in the wrong row when you are holding down three or more keys at once.

(full text)

 

I wonder though if this is a hardware or a software limitation. I need to find some specs on these keypad controllers.[/font]

940482[/snapback]

I'm pretty sure that's a hardware limitation.

 

My suggestion: you have 5 on/off pins in each port (UDLR and fire), why not use them?

 

So:

8K = U

16K = D

32K = L

64K = R

 

L = J0 fire, R = J1 fire.

 

Or something.

 

The fewer values you need to read off the pots the easier it is to read in the program.

940500[/snapback]

Link to comment
Share on other sites

The thing is, you're only reading one value off the pot, a single resistance. Then it's up to the code to interpret the value - ie decipher it into the bits it represents. Or are you saying that the value read from the paddle is not precise enough to be able to translate into bitwise values?

What I mean is that it is very kernel-intensive to read paddles, since you have to do it during the kernel. The fewer values you have to check for, the more that requirement is eased.

 

For example, if you only need to check against one value, < 128K or > 128K for example, then you only need to read the paddles once during your kernel. That's pretty easy to stick in there somewhere.

 

On the other end of the extreme...if (like for Breakout or something) you need to read one of ~100 values, then you essentially need to read the paddle on every line of your kernel. That really restricts what you can display on screen.

 

The fewer possible values, the easier it will be to program for.

 

The six-joystick idea is very interesting, though! :)

Link to comment
Share on other sites

Alright, now I'm getting into lower level operations that are currently over my head, but let me venture an idea. What if we just let the kernel read the one value (0-255), and make it available to the main program code, so we interpret the value outside the kernel? Just leave the kernel to do raw i/o.

 

The thing is, you're only reading one value off the pot, a single resistance. Then it's up to the code to interpret the value - ie decipher it into the bits it represents. Or are you saying that the value read from the paddle is not precise enough to be able to translate into bitwise values?

What I mean is that it is very kernel-intensive to read paddles, since you have to do it during the kernel. The fewer values you have to check for, the more that requirement is eased.

 

For example, if you only need to check against one value, < 128K or > 128K for example, then you only need to read the paddles once during your kernel. That's pretty easy to stick in there somewhere.

 

On the other end of the extreme...if (like for Breakout or something) you need to read one of ~100 values, then you essentially need to read the paddle on every line of your kernel. That really restricts what you can display on screen.

 

The fewer possible values, the easier it will be to program for.

 

The six-joystick idea is very interesting, though! :)

940535[/snapback]

Link to comment
Share on other sites

Alright, now I'm getting into lower level operations that are currently over my head, but let me venture an idea. What if we just let the kernel read the one value (0-255), and make it available to the main program code, so we interpret the value outside the kernel? Just leave the kernel to do raw i/o.

I was talking about the reading. Just doing the reading is limiting. And you aren't going to get a value from 0-255 in any case, more like a value from 0-200 for NTSC.

Link to comment
Share on other sites

The thing is, you're only reading one value off the pot, a single resistance. Then it's up to the code to interpret the value - ie decipher it into the bits it represents. Or are you saying that the value read from the paddle is not precise enough to be able to translate into bitwise values?

 

What you said is interesting though because theoretically if you can read paddles AND joysticks you could have 6 joysticks.

940506[/snapback]

EDIT: OOPS, corrections needed.

 

Well... if we're talking theory, we can easily find the minimum number of bits needed to read X joysticks. We'll assume that combinations such as up and down or left and right at the same time are not allowed. So for each joystick, we have 9 positions of the joystick (including centered) and the button, so there are 18 possible states per joystick. Encoding 18 states requires at least 5 bits of information.

 

Two joysticks, therefore, require 324 states. At the very minimum, this requires 9 bits to encode, but it would be much easier to do in 10 bits. Since there are only 5 bits for reading a single joystick and two more for reading paddles, we are short three bits of information.

 

If we just keep one joystick using the original 5 bits, we could read the other joystick completely within the two paddle inputs. There are three ways I could see in doing this.

 

1. Divide one of the inputs into four states and one into eight. With this low resolution, perhaps it is possible to read the paddle entirely in the overscan or vblank area and not affect the kernel at all.

 

2. We could divide one paddle into four and one into five states, but this would be harder to encode, and would require more complex circuitry and more complex code on the 2600's side as well. But it would be even easier to put it completely within overscan or vblank.

 

3. Make one input solely responsible for the button and the other paddle responsible for the directions of the joystick. It would be easiest to read if we allowed for 16 states. This would be the simplest method code-wise and circuit-wise, most likely, but a little challenging to get into vblank/overscan.

 

To read three joysticks in a single port requires 5832 states, which requires a minimum of 13 bits of information, but it would be notiriously hard to encode, so we'd probably want to do 15. Therefore with two inputs, we'd need to read 10 bits, which would require breaking up each paddle input into 32 distinct states. This is possible but would probably require kernel hacking.

Edited by batari
Link to comment
Share on other sites

I would think the paddle pins would be useful when reading two joysticks, but not in the indicated fashion. I would suggest that for reading two joysticks on one joyport, one use the 'discharge' function on the paddle input to select which joystick should appear on the joystick pins. This would result in 'normal' software seeing the first joystick as it normally would. Special software could view the second joystick, however:

 lda SWCHA; First joystick
 sta firstjoystick
 lda #$81 ; Or $80, depending upon whether we want to be blanked now
 sta VBLANK
; Kill a little time (probably about 20 cycles worth)
 lda SWCHA
 sta secondjoystick
 lda #$01 ; Or $00
 sta VBLANK

Piece of cake. For more than two joysticks, I would suggest having a circuit so that a long period of time (>10ms) without draining the paddle would select the first joystick; draining and releasing the paddle would select each joystick in turn provided that it was drained at least once every 1ms. This would allow any number of joysticks to be read with much less software overhead than trying to read analog signals off the paddles.

  • Like 1
Link to comment
Share on other sites

I would think the paddle pins would be useful when reading two joysticks, but not in the indicated fashion.  I would suggest that for reading two joysticks on one joyport, one use the 'discharge' function on the paddle input to select which joystick should appear on the joystick pins.  This would result in 'normal' software seeing the first joystick as it normally would.  Special software could view the second joystick, however:

 lda SWCHA; First joystick
 sta firstjoystick
 lda #$81; Or $80, depending upon whether we want to be blanked now
 sta VBLANK
; Kill a little time (probably about 20 cycles worth)
 lda SWCHA
 sta secondjoystick
 lda #$01; Or $00
 sta VBLANK

Piece of cake.  For more than two joysticks, I would suggest having a circuit so that a long period of time (>10ms) without draining the paddle would select the first joystick; draining and releasing the paddle would select each joystick in turn provided that it was drained at least once every 1ms.  This would allow any number of joysticks to be read with much less software overhead than trying to read analog signals off the paddles.

940687[/snapback]

That's an interesting solution.

 

Much easier on the 2600's side. Though it would probably require much more than just passive components as some parts of my solution would (i.e. mine could be done with just resistors and caps.) So in that sense, it's a compromise.

Edited by batari
Link to comment
Share on other sites

I would think the paddle pins would be useful when reading two joysticks, but not in the indicated fashion.  I would suggest that for reading two joysticks on one joyport, one use the 'discharge' function on the paddle input to select which joystick should appear on the joystick pins.  This would result in 'normal' software seeing the first joystick as it normally would.  Special software could view the second joystick, however:

 lda SWCHA; First joystick
 sta firstjoystick
 lda #$81; Or $80, depending upon whether we want to be blanked now
 sta VBLANK
; Kill a little time (probably about 20 cycles worth)
 lda SWCHA
 sta secondjoystick
 lda #$01; Or $00
 sta VBLANK

Piece of cake.  For more than two joysticks, I would suggest having a circuit so that a long period of time (>10ms) without draining the paddle would select the first joystick; draining and releasing the paddle would select each joystick in turn provided that it was drained at least once every 1ms.  This would allow any number of joysticks to be read with much less software overhead than trying to read analog signals off the paddles.

940687[/snapback]

That's an interesting solution.

 

Much easier on the 2600's side. Though it would probably require much more than just passive components as some parts of my solution would (i.e. mine could be done with just resistors and caps.) So in that sense, it's a compromise.

940691[/snapback]

 

 

I recommend that you use a MUX chip. Run the 4 direction lines from each stick into the MUX. Use the fire line as an output to select the set of lines you want output from the MUX into the 2600. Then reroute the Fire buttons into the paddle inputs. In software you clear the paddle timers, then set the output low and read the 1st joystick. Set the output high and read the second joystick. wait the min time for a the paddle lines to charge if the fire button is pressed and go from their. It should be quite doable and not too processor or external hardware intensive.

 

Cheers!

Link to comment
Share on other sites

I recommend that you use a MUX chip.  Run the 4 direction lines from each stick into the MUX.  Use the fire line as an output to select the set of lines you want output from the MUX into the 2600.  Then reroute the Fire buttons into the paddle inputs.      In software you clear the paddle timers, then set the output low and read the 1st joystick.  Set the output high and read the second joystick.  wait the min time for a the paddle lines to charge if the fire button is pressed and go from their.  It should be quite doable and not too processor or external hardware intensive.

940706[/snapback]

 

A mux chip would be pretty good for the two-stick case, but the fire button pin is input only. On the other hand, you could use one paddle pin as an output like I suggested and use the other one for the second joystick fire button. To me, though, the key points are:

 

-1- Keep things compatible as much as possible, so as not to force people to switch cables around for legacy software.

 

-2- Keep things digital as much as possible, 'cos reading analog controls on the 2600 is a pain in the patouie.

Link to comment
Share on other sites

I would think the paddle pins would be useful when reading two joysticks, but not in the indicated fashion.  I would suggest that for reading two joysticks on one joyport, one use the 'discharge' function on the paddle input to select which joystick should appear on the joystick pins.  This would result in 'normal' software seeing the first joystick as it normally would.  Special software could view the second joystick, however:

 lda SWCHA; First joystick
 sta firstjoystick
 lda #$81; Or $80, depending upon whether we want to be blanked now
 sta VBLANK
; Kill a little time (probably about 20 cycles worth)
 lda SWCHA
 sta secondjoystick
 lda #$01; Or $00
 sta VBLANK

Piece of cake.  For more than two joysticks, I would suggest having a circuit so that a long period of time (>10ms) without draining the paddle would select the first joystick; draining and releasing the paddle would select each joystick in turn provided that it was drained at least once every 1ms.  This would allow any number of joysticks to be read with much less software overhead than trying to read analog signals off the paddles.

940687[/snapback]

That's an interesting solution.

 

Much easier on the 2600's side. Though it would probably require much more than just passive components as some parts of my solution would (i.e. mine could be done with just resistors and caps.) So in that sense, it's a compromise.

940691[/snapback]

 

 

I recommend that you use a MUX chip. Run the 4 direction lines from each stick into the MUX. Use the fire line as an output to select the set of lines you want output from the MUX into the 2600. Then reroute the Fire buttons into the paddle inputs. In software you clear the paddle timers, then set the output low and read the 1st joystick. Set the output high and read the second joystick. wait the min time for a the paddle lines to charge if the fire button is pressed and go from their. It should be quite doable and not too processor or external hardware intensive.

 

Cheers!

940706[/snapback]

If you're talking about mine, a MUX is much more than is needed. I think that mine could easily be done with just resistors and a cap (like a common resistor-based D/A converter, with a small resistor and several more at 2x the resistance of the former.)

 

If you're talking about Supercat's, it could be done with MUX chips, but I don't think it's ideal, as you'd need several of the chips to make it work Unless I'm missing something, I think that Supercat's would be easier to construct with tri-state buffers.

Link to comment
Share on other sites

That's an interesting solution.

 

Much easier on the 2600's side.  Though it would probably require much more than just passive components as some parts of my solution would (i.e. mine could be done with just resistors and caps.)  So in that sense, it's a compromise.

940691[/snapback]

 

Two more nice things about it:

 

1) it could be made into a product that could be widely distributed

2) no need to modify the original joysticks

 

I've seen the paddle-as-joystick idea before somewhere, but I can't recall where.

Link to comment
Share on other sites

If you're talking about Supercat's, it could be done with MUX chips, but I don't think it's ideal, as you'd need several of the chips to make it work  Unless I'm missing something, I think that Supercat's would be easier to construct with tri-state buffers.

940716[/snapback]

 

Use one quad mux (for the joystick directions) and a couple resistors. One of the resistors provides a stiff pullup on the first paddle input which is then connected to the mux select pin. The other resistor provides a pullup for the other paddle input, which should be pulled down by the second fire button (the first fire button should be wired direct).

 

One chip and two resistors. Don't know how much simpler it could get.

  • Like 1
Link to comment
Share on other sites

  • 8 years later...

Slightly different idea for a four joysticks in one port adapter:

 

- use the paddle registers digitally, so that they only can have 0 ohm or infinate ohm

- use these two lines now for left and right

- switch the now-free left and right pins to output for joystick selection

- these two bit now select one of the four joysticks by activating the GND pin, all other three joysticks have the GND pin disconnected

 

I'm no expert on hardware, so I can't tell if it's really possible to "disconnect" the other three joysticks. Putting them to +5V instead of GND would short circuit the whole system.

Link to comment
Share on other sites

  • 2 weeks later...

Each port could support 7 bits of data. Which would translate into Up/Down/Left/Right, One button and 1 Analogue stick. For a custom controller, on a game expecting it, you could also get an analogue stick, with 5 buttons.

 

Simple solution: the normal up, down, left, and right would become the extra buttons- or how about a secondary direction pad like that on the Nintendo 64?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...