The joypad 3 buttons is the first one released with the Genesis.
Later, the 6 buttons version came back. I'll do something similar for it in the future, I hope.
My goal here is the provide informations about how this joypad work.
With this, you will be able to
- understand how to talk with in code
- make or modify your own (turbo!!)
- convert from/to another joypad
- ...
let me know!
► Components
Quantity
Number
Description
Datasheet
1
74LS157
QUAD 2-INPUT MULTIPLEXER
This component have 8 input for 4 output : each output is one of the 2 associated input, according the select signal
► Schematic
This animated schema explains how, according the SELECT line, the output is Start/A/Down/Up or C/B/Right/Left/Down/Up
The SELECT line is controlled via software, YOU need to ask for Start/... , wait 2 cycles, read data then ask for C/B/..., wait for 2 cycles, read data...
If you saw the schematic, you are now able to write the code to read the joypad status, no ?
Here is the way to do that :
Be sure SELECT is output ( MD->Joypad) and others are input (MD<-Joypad)
Set the SELECT pin to high
Read high-state : C button/B button/Right/Left/Down/Up
Set the SELECT pin to low
Read low-state : Start/A button/Down/Up
A little tech help :
0xA10003/0xA10005/0xA10007 are the DATA ports, which read from/write to joypad 0xA10009/0xA1000B/0xA1000D are the CTRL ports, which set the input/ouput
So the same thing, but more technical speach way :
Write 0x40 to CTRL port
Write 0x40 to DATA port
Read DATA port
Write 0x00 to DATA port
Read DATA port
See? easy no ? Well...you must know 2 things to complete this
1/ It's not needed to write to CTRL port each time but it's more secure, as you wish
2/ If you read the datasheet of the 74LS157 which is inside the joypad, you read something about 'propagation delay'. Don't ignore it and add some delays between read and write to the DATA port.
Final code in C for joypad 1 (all my stuff use this code since the beginning)
void Joy1_Init( ) // Init input/output of joypad 1 port
{
register volatile unsigned char *pb;
pb = (unsigned char *) 0xA10009;
*pb = 0x40;
}
unsigned short Joy1_Read( ) // Read joypad 1 port
{
register volatile unsigned char *pb;
unsigned short i, j;
pb = (unsigned char *) 0xA10003;
*pb = 0x40; // Ask High-state
asm("nop");
asm("nop");
i = *pb & 0x3f; // get C button, B button, Right, Left, Down, Up
*pb = 0; // Ask Low-state
asm("nop");
asm("nop");
j = (*pb & 0x30) << 2; // get Start and A button (we already have Down & Up)
return( ~(i|j) ); // return 'SACBRLDU'
}
► Examples
3rd party : with turbo any of the 3 buttons (use a NE555P, a GD74S04 and a PAL16R6-25)
3rd party : glue chip
► Mod
To convert the joypad to something else, I think you must, first of all, find a way to bypass the use of the SELECT line then convert the 2-pass call on 5 pins to a unique call to 8 pins.