Blast from the Past :: JoyPort Networking ! Nov 21, 2018 15:19:37 GMT
Post by jmpff3d on Nov 21, 2018 15:19:37 GMT
JoyPort Networking !
From: firstname.lastname@example.org (Michael Miller)
Subject: Joystick Port Interfacing
Date: 21 Jul 1996 16:17:21 GMT
This is what I wrote up over the last few days. I'm sorry if you don't
like the not-exactly-serious style, but that's just how I've been lately.
Michael Jay Miller's Wonderful Joystick Port Networking System
...or at least a bunch of musings while watching an LED turn on and off
at my command while the LED is sitting in a Radio Shack box connected to
my joystick port...
**WARNING: I don't have all the original stuff for this anymore; too many
moves have caused it to disappear on me. I also don't have the box
anymore, so I can't test this right offhand. Plus I don't remember how
much current you can slap through a CIA chip. Hopefully it will be
helpful, but if your Commodore fries messing around with this, I will not
be responsible. I didn't fry my Commie doing this, so you probably won't
have any trouble.
This text is copyright (C)1996 Michael Jay Miller. You may freely
distribute, print, etc. this text, so long as this message remains intact.
If you make something useful out of this information, and you're releasing
it for free, please credit me; if you're releasing useful stuff from this
and "$$$$$$ MAKING MONEY FAST $$$$$$ Moola Buckazoids....", then send me
some of the money!
...sorry, my mind gets away from me at times.
The basic theory behind using the joystick ports lies in the 6526 CIA 1/A
chip that controls the keyboard, joystick ports, and is used for tape and
serial timing. For my simple tests, only 4 memory locations in that
chip's registers are actually used: $DC00-$DC03 (56320-56323).
If you have the book "Programming the Commodore 64" by Raeto Colin West,
open to page 125 for a nice diagram of how the CIA looks in memory. If
not, open to pages 328 & 329 of your Commodore 64 Programmer's Reference
Guide. Here's a quick summary:
$DC00 is Joystick Port 2 ("CIA Port A")
$DC01 is Joystick Port 1 ("CIA Port B")
Bit 4=Fire, Bit 3=E/Right, Bit 2=W/Left, Bit 1=S/Down, Bit 0=N/Up
$DC02 is "Port A Data Direction Register"
$DC03 is "Port B Data Direction Register"
To read bits coming in (for a joystick, for example), you set the bits you
want to read to 0 in the appropriate Data Direction Register, and then
read the appropriate bits in the Port.
The practical upshot of all this: if you disable the interrupts (because
the keyboard runs off this as well), reset the Data Direction Registers to
how you want to read or write, and then put the right bits into the two
ports, whatever is connected to the other side can read or write to this.
This may be easier to see with an example:
"The Box, Mark 1"
Parts: 1 joystick extension cable (or end from a broken joystick), 1
project box, 1 or more LEDs, 1 or more switches, one of those
speaker-wire clip 8-packs (the things you can clip wires into), and
connection methods (clip leads, solder, etc.) + a monitor and assembler.
In the Commodore 64 Programmer's Reference Guide, page 395, they show the
pinout for the two joystick ports. Something like this:
------------------------- 1=Bit 0 7=5 volt
! o o o o o ! 2=Bit 1 8=GND
! 1 2 3 4 5 ! 3=Bit 2
! o o o o ! 4=Bit 3 5=POT Y
! 6 7 8 9 ! 6=Bit 5 9=POT X
What you want to do is wire up pins 1-4 to 4 ends of the speaker wire
things, pin 7 to one of the speaker wire things, pin 8 to one of them, and
maybe wire a couple switches in as well. Hook up an LED between pins 7
and 8: plug it in a joystick port, and turn on the computer. Hopefully
it lights. If not, turn the LED around, check connections, etc. Once
you know which way the LED works, remember which pin goes to 7 and which
goes to 8; these remain the same throughout the experiments.
Once you know which way to plug in your LED, hook it between pins 0 and 8.
Turn the computer off, plug it into Joystick Port 2, and turn it back on.
It should light up, since port 2 is set to all outputs, and the system is
constantly looking for input there. Then try hooking it up to pins 7 and
0, and plugging it into port 1. It should light up as well. Either of
these may cause characters to run across the screen, just like if you were
holding up on the joystick in the appropriate port.
Now try hooking up a few LEDs to pins 1-4 and 8. For sake of example,
I'll work with pins 1 and 2. Hook your box to port 1, and turn on the
computer. The LEDs should be off. Now load up your favorite monitor (or
assembler, I guess) and type in this:
A C000 ; or A 1300 (C128)
sei ; disable keyboard
lda #0 ; initialize
sta $DC01 ; joyport 1
sta $DC03 ; and its DDR : 4321 pins
lda #07 ; that's 0000 1111=bits 0-3, pins 1-4 outputs
sta $DC03 ; that's DDR B, setting pins 1-4 to output
lda #01 ; pin 1 on
sta $DC01 ; and get it going
here jmp here ; here is the address your monitor gave for this line.
G C000 ; or G 1300 (C128)
Hopefully the LED turned on and the computer seems to lock up. Press
RESTORE a few times to get back to the monitor (at least, my monitor does
that.) By editing the line
lda #01 ; pin 1 on
to anything from 0 to 15, you can control the lights via their appropriate
bits. Have fun.
By changing the LEDs to being hooked between pins 7 and 1-4, with a switch
wired in, and a nice BASIC program, you can read the status (just like a
joystick). Page 344 of the Programmer's Reference Guide has a program you
can adapt: just get rid of all the stuff about North and South and just
PRINT the value in 56320 (port 2) or 56321 (port 1). Push the switch, the
value should change. Yay!
Now, hook an LED between pins 1 and 2. Put the voltage side (pin 7) on
pin 1. Get back into your monitor, and try this:
A C000 ; or A 1300 (C128)
lda #00 ; init
lda #01 ; output for pin 1, input for pin 2
sta $DC01 ; activate
nop ; pause
lda $DC01 ; read
sta $FE ; temp
lda $00 ; reset
sta $DC03 ; normally all reads
cli ; back to normal
lda $FE ; reload acc
brk ; exit to monitor
G C000 ; G 1300 (C128)
Hopefully, the accumulator now holds $03. The pause may take longer, or
may not be needed (my notes don't indicate). By setting the appropriate
bits, you can now read and write through the port. If you have two boxes,
you can read and write between joystick ports (much safer). "But," you
ask, "I can't do much in the way of input..." Well, that's why you need:
"The Box, Mark 2"
Parts: "The Box, Mark 1", Other end of joystick extension cable or similar
9-pin Male port, 1351 mouse or compatible, good ML skills.
Remember we didn't use pin 6/bit 5, the fire button? This is why: if you
wire in an extra joystick port with pins 5-9 attached, you can hook a 1351
up to it and read that from the SID chip, with the fire button running
from pin 6 (bit 5) on the CIA. You don't want to hook up pins 1-4 because
the other fire buttons run off there.
Also, you want to make sure you set the CIA appropriately: $DC00 bits 7
and 6 control which paddle you're reading:
10xx xxxx = Paddles in Joyport 1
01xx xxxx = Paddles in Joyport 2
I'm sorry I don't have much in the way of specific examples for this,
because this is where I stopped doing things and just wrote down ideas.
If I can find that box again, I should be able to do a full-blown writeup
for C=Hacking or something.
A MikeNet Cable
To set up an actual cable to hook between two Commies and still allow one
of them to use a mouse (for, say, selecting files from an on-screen
directory list and menu?), you want to hook lines 1-4 direct connect, and
pins 5-9 to pins 5-9 of a male 9-pin port or cable to hook to your
The direct-connect file transfer protocol I had in mind would use pins 1
and 2 to send 2 bits at a time, pin 3 for a RDY line from the sending
machine, and pin 4 for an ACK line from the receiving machine. Basically,
the RDY line would change level when the sending computer had the
appropriate bits on pins 1 and 2, and the ACK line would change every time
the receiving computer got it. Or something like that. Or do like Craig
Bruce and junk all that kind of ACKing for speed. Whatever.
I had two basic ideas for network setups, a Ring style (not too great) and
a Server style (cool, but requires lots of hardware).
Each computer would be hooked from their joyport 2 to the next computer's
joyport 1. One machine is designated "Master". This machine would send
"I'm number 1, you're a Slave, take the next number and pass it along"
until the Master received something like "I'm number 8, you're a Slave,
take the next number and pass it along". Of course, the Master knows it's
not a Slave. Then it sends out something like "There's 8 computers in the
ring. We're open for business."
Then, each computer can pass messages to each computer by number, and if
you get a message that isn't your number, you pass it along. The master
computer double-checks that the ring is working, and resets it if
How can the computer keep working? Well, Craig Bruce has that 3-key
rollover routine that also checks to see if the joystick ports are being
used: if so, just trigger a routine to handle the message, pass it along
if necessary, then clear the ports and continue. That's why I designated
an RDY line: if that's up, the previous computer has a message to send.
As long as the messages aren't sent very often, the system shouldn't slow
down too much, and you may even be able to do other things in the
meantime. Or you could go to where I got the idea from, the Atari ST
program MIDIMaze, and write a fun game like that. Of course, you have to
use the mouse to control it, but something could be arranged.
With a server, my design has a box hooked between the server and the other
systems in the network. This box has its own processor (it might be a 64
only running this program) that has lines running to each system. Data
pins 1 and 2 are hooked up to all systems and the box. Each system gets
its own RDY and ACK line (from somewhere!) The server and the box have a
standard 1/2/RDY/ACK that the box echos to the appropriate system. Each
system has a number; the server is 0.
Basically, when a system has a request for the server, it raises its ACK
line; when the box and server are ready to process, the box raises the RDY
line for that system, and then they transfer messages. If the system is
sending a message to another system (like talk or ping in unix) the box
handles sending that along. Otherwise, the box calls up the server, and
sends messages to there to be handled.
The messages would be queued, to avoid deadlocks--whenever a system is
sending a message, the box would check to see if that system had any
messages it needs to receive, and send them.
That's basically all I have right now...feel free to comment on this, send
me messages, design better systems, etc.