Here is some more sample code is Applesoft BASIC. Do not enter the text after the forward slashes (//). This code reads two joypads and displaysthe bits at the top of the screen. You will notice that the bits are set all until you press a key. You will also notice that the inputs inside the controller are pulled high with resistors, and when you press a button it shorts the inputs to ground. This is important to know when you write assembly language routines. You will also notice that when no controller is connected that the inputs appear low. When a controller is connected it is impossible to cause all the buttons to appear low. This is due to the fact that you can only get up to two of the inputs that correspond to the directional control to go low at a time. This will help those implementing a driver in a program to tell if a controller is hooked up.
10 HOME // Clear screen and place cursor at top.
20 Z=PEEK(49240) // Set the clock to low.
40 Z=PEEK(49242) // Set the latch to low.
60 HTAB 1: VTAB 1: PRINT A$ // Place the cursor at the top of the screen. Print the bit string for joypad 0.
70 PRINT B$ // Print the bit string for joypad 1.
80 LET A$ = "" // Set string to NULL.
90 LET B$ = "" // Set string to NULL.
100 Z=PEEK(49243) // Set latch to high to latch in data.
120 Z=PEEK(49242) // Set latch to low so that data can be tranferred serially.
140 B0=PEEK(49249) // Read bit from joypad 0.
150 B1=PEEK(49250) // Read bit from joypad 1.
160 IF B0>127 THEN LET A$=A$ + "1" // If the bit is set then add "1" character to joypad 0 string.
170 IF B1>127 THEN LET B$=B$ + "1" // If the bit is set then add "1 "character to joypad 1 string.
180 IF B0<=127 THEN LET A$=A$ + "0" // If the bit is not set then add "0" character to joypad 0 string.
190 IF B1<=127 THEN LET B$=B$ + "0" // If the bit is not set then add "0" character to joypad 1 string.
200 Z=PEEK(49241) // Set clock bit to clock in next bit.
220 Z=PEEK(49240) // Reset clock bit.
240 LET L0=LEN(A$) // Get the length of the bit string.
260 IF L0>=8 THEN GOTO 60 // If the bit string is eight characters long then you have all the bits. Repeat process. Note: change this number to sixteen if you are reading a SNES joypad.
280 GOTO 140 // Go get the next bit.
Note: If you are going to use a SNES joypad then you need to read in sixteen bits instead of eight.
The interface is just a bunch of wires and connectors. There are no chips and no circuit boards! Also, if you follow my design the interface will work on an IBM PC with the popular SNESKEY.
It has been brought to my attention that the pre Apple IIgs machines use the keyboard to simulate joystick buttons. This combination has the potential to interrupt the NES pad communication at the least and burn it up at the worst. This interface was designed for the Apple IIgs, so using it on earlier machines at your own risk.
Apple II Joystick Interface Block Diagram:
Internal Apple II Joystick Interface Pinout:
NES Connector Pinout:
What wires go where:
Apple II Joystick Connector to 25 Pin D-Sub Connector Female:
25 Pin D-Sub Female
AN0 Pin 15 Pin 2
AN1 Pin 14 Pin 3
PB0 Pin 2 Pin 10
PB1 Pin 3 Pin 12
+5V Pin 1 Pins 7,8,9
GND Pin 8 Pin 19
25 Pin D-Sub Connector Male to NES Joypad:
25 Pin D-Sub Connector Male
Pin 2 Pin 2 CLK
Pin 3 Pin 3 LATCH
Pin 10 Pin 4 Pad 0
Pin 12 Pin 4 Pad 1
Pin 7 Pin 5 +5V
Pin 19 Pin 1 GND
Note: You could go directly from the Joystick Connector to the NES Joypads. However, you would lose PC compatibility and would have to open your computer everytime you wanted to disconnect the Joypads.
The NES joypad is based upon a single 4021 CMOS chip. It is simply
a parallel to serial chip. In order to get data from it
you have to LATCH the data from the buttons into the chip. Then CLK (clock) in the bits.
Bit 0 is button A
Bit 1 is button B
Bit 2 is button SELECT
Bit 3 is button START
Bit 4 is arrow UP
Bit 5 is arrow DOWN
Bit 6 is arrow LEFT
Bit 7 is arrow RIGHT
Here is some sample code is Applesoft BASIC:
60 PRINT A$
80 LET A$ = ""
160 IF B0>127 THEN LET A$=A$ + "1"
180 IF B0<=127 THEN LET A$=A$ + "0"
240 LET L0=LEN(A$)
260 IF L0>=8 THEN GOTO 60
280 GOTO 140
This code will output all 1's if no buttons have been pressed. If a
button has been pressed then the corresponding 1 changes to a 0.
Study the code. Convert it to assembly if you want. Have Fun.
: ) Note: This code only reads joypad 0. You will have to add
code to read joypad 1.