Re: Commodore joystick ports

From: Jim Brain (
Date: 2007-04-11 07:44:10

Daniel O'Shea wrote:
> I'm a little hazy as to how the IRQ works, I'd still want to have the 
> standard DE9 pinout as the interface to the C64:
That's fine.  If you look at the schematic at (the PSXJoy), you see all of those lines 
already hooked up to an ATMEGA8.  Sub out the 8 for the 8L, and you're 
good to try the code out.

> ...does the IRQ first read from the Pot lines, and then write to them?
The IRQ is a falling edge trigger.  It watches the POTX (maybe it's Y, I 

SID clamps POT line low, IRQ triggers in AVR
AVR puts output line in output mode, set to 0. 
It starts a counter.
A previously computed value is stuffed into each POT counter compare 
register.  The value is 512uS- desired reading.
As the counter reaches the stored values, the internal counter matches 
interrupts trigger.
On trigger, the code sets the appropriate POT line to Hi.
Then, the process repeats.

Why the 512- value? 

Well, when SID clamps, you know there is 256 low uS coming up, and then 
we need to do the PWM stuff.
SID POT registers are backwards.  Namely, 255=0v, while 0=5v.
So, the lower the number desired, the larger the PWM duty cycle.
Adding that all up, it's 256 + 256-value = 512-value.

Now, a normal PWM would go high at 256uS and then low after that.
That won't work, because except for 100% duty cycle, we drop to 0 before 
time 512, missing the trigger.  So, I inverted the PWM phase, having the 
start be variable, but the end always occurs at time 512.  It also 
simplified the code, since you now could care less where time 256 is, 
saving some cycles.

If you look at the code, you'll find reality is a bit messier than my 
description.  Namely:

PSX analog sticks are inverted relative to Atari paddles, so I use 256 + 
The timer is actually more complicated.  I use a free running 65536 
counter, and just add the desired delay to the current counter value and 
store as the compare.  Since I use the counter for the oscillator 
tuning, I needed the counter to be free running, so I could better see 
out-of-bounds values.
The timer counts AVR clocks, not c64 clocks, so everything needs to be *8.
I actually use 246 as my constant, due to the math delay, and the time 
if takes to service the counter match IRQ.  246 is an experimentally 
derived value.


Jim Brain, Brain Innovations                                      (X) 
Dabbling in WWW, Embedded Systems, Old CBM computers, and Good Times! 

       Message was sent through the cbm-hackers mailing list

Archive generated by hypermail pre-2.1.8.