I'm new to this forum

I've done exactly the same mod about a year ago. Back then I've also utilized a PSX analog stick.
Yesterday I've finished another one but this time I used the analog stick and the octagonal restrictor plate of a 3rd party Gamecube controller.
I've decided to publish my experiences with this mod as well as the source code for the MCU I've written on this forum.
The victim:

I didn't have a guilty conscience about cannibalizing a bigben controller

The finished N64 controller:

You can actually see the MCU in the left handle. I'm very pleased with the look and (of course) the feeling of the new stick. It's really perfect.
The hardest part by far was to perfectly fit the stick and the octagonal plate. Really! If you look at the original N64 stick from the side you'll notice that the stick is mounted in a really weird way, the lower end of the gray frame sticks out far.
So take your time mounting the stick & plate and use lots of hot glue. If it's not perfectly fit you can always use a hot air blower to heat the hot glue again (but don't melt the plastic of the controller) and then correct the angle of the stick.
As mentioned before on some threads of this forum, the original N64 analog stick consists of two wheels and a rotary encoder. If you want to know what this means and how it works you should have a look at the wikipedia entry:
http://en.wikipedia.org/wiki/Rotary_encoderInside the N64 controller there is a connector that provides us with everything we need:

I didn't use a PIC like kylejw but instead an Atmel AVR MCU. Unfortunately the only one I had available with analog-to-digital converters was an ATMega8. Having 28 pins it's a little bit over the top but there's plenty of room in the controller housing so it's not really a problem.
I drew this little picture of how to wire the ATMega8:

As you can see there are only 2 inputs from the pots of the new PSX-/GC-style analog stick as well 4 outputs (XA, XB, YA, YB) that go straight into the connector on the N64 controller PCB.
For writing MCU code I'm using Bascom AVR IDE, you can get it for free at
http://www.mcselec.com/ (demo version limited to 4k of code which is MORE THAN ENOUGH for projects like this)
If your PC has a parallel printer port you can get a suitable programmer very cheap or even build one youself.
My code probably has much room for improvement and tweaking but it works great. Also, I've translated my comments into english, I hope they're understandable yet

$regfile = "m8def.dat"
'8MHz = highest internal frequency of the ATMega8
$crystal = 8000000
'configuring the ADC, its resolution is 10bit per channel
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc
'pins for the output of the X-axis
Config Portb.1 = Output
Config Portb.2 = Output
'pins for the output of the y-axis
Config Portb.3 = Output
Config Portb.4 = Output
'variables in which the 10bit value of the ADC will be stored
Dim X As Integer , Y As Integer
'init X axis. the value is divided by 2 because otherwise it's too big
X = Getadc(1)
Shift X , Right , 2 , Signed
'init Y-axis
Y = Getadc(2)
Shift Y , Right , 2 , Signed
'variables to store the old X and Y values for comparison in the next round
Dim Oldx As Integer , Oldy As Integer
Oldx = X
Oldy = Y
'rotating the xwheel and ywheel bytes 1 step to the left or the right is the
'same as turning the optical wheels in the N64 stick 1 step clockwise or
'counter-clockwise.
'by fixating on two bits of these bytes (let's say xwheel.0 and xwheel.1) and
'then rotating the byte 1 step to the left or the right, you'll get the new
'gray code on the these two bits (e.g. xwheel.0=A , xwheel.1=B)
Dim Xwheel As Byte , Ywheel As Byte
Xwheel = &B11001100
Ywheel = &B11001100
Dim I As Byte
'in these two variables we're storing the number of steps we have to process for each axis
Dim Xsteps As Integer , Ysteps As Integer
'main loop:
'-------------
Do
'get and store X-value; resolution/2
X = Getadc(1)
Shift X , Right , 2 , Signed
'get and store X-value; resolution/2
Y = Getadc(2)
Shift Y , Right , 2 , Signed
'calculate the number of steps we have to process
Xsteps = X
Xsteps = Xsteps - Oldx
Ysteps = Y
Ysteps = Ysteps - Oldy
'stay in while-loop until all steps of the X- and Y-axis are processed
While Xsteps <> 0 Or Ysteps <> 0
'steps of the x-axis
If Xsteps > 0 Then
Rotate Xwheel , Left , 1
Xsteps = Xsteps - 1
Elseif Xsteps < 0 Then
Rotate Xwheel , Right , 1
Xsteps = Xsteps + 1
End If
'steps of the y-axis
If Ysteps > 0 Then
Rotate Ywheel , Right , 1
Ysteps = Ysteps - 1
Elseif Ysteps < 0 Then
Rotate Ywheel , Left , 1
Ysteps = Ysteps + 1
End If
'write the new gray codes for both axis in I
I.1 = Xwheel.1
I.2 = Xwheel.2
I.3 = Ywheel.1
I.4 = Ywheel.2
'...and then write I to port B
Portb = I
'we have to wait a little bit for processing the next steps because otherwise
'it would be too fast and the IC in the N64 controller would skip some steps
Waitus 10
Wend
'store the values of both axis for comparison in the next round
Oldx = X
Oldy = Y
Loop
EndAfter having compiled the code and flashed the ATMega8 don't forget to set the speed of the ATMega8 correctly in the fusebits settings, 8MHz internal RC.
I recommend using a socket for the MCU or even including a 10pin ISP connector
inside the controller housing itself so you can re-flash the ATMega8 if something went wrong.
There are several ways how to connect VCC and GND to the pots of the new analog stick AND the stick can be mounted in 4 different angles (0°, 90°, 180°, 270°).
That means you could end up with switched X- and Y-axis and/or reversed X-axis and/or Y-axis. There are 2 ways to solve problems like that:
1.) Redo wiring, e.g. switch the VCC and GND connections on the pots.
2.) Simply switch some words in the code->
if X- and Y-axis are switched:Go to line 22, 26, 56 & 60. Switch the ADC channel in brackets, e.g. getadc(1) -> getadc(2) ; getadc(2) -> getadc(1)
if the X-axis or Y-axis is reversed:Go to line 75 & 78 for the X-axis and line 84 & 87 for the Y-axis. Simply switch "right" for "left" and you're set
So go try it yourself and post your finished controllers
