Subscribe to me on YouTube 
Icons by neorelic

► Presentation

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

Number Description



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...



► Software

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 ? 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
i = *pb & 0x3f; // get C button, B button, Right, Left, Down, Up

*pb = 0; // Ask Low-state
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.

Here are components-based works:
Genesis to Jamma (mirror)
Megadrive to Jamma (mirror)

Here are PIC-based works:
Genesis to USB (too expensive for me)
Raphnet DB9 to USB (support multitap!)
DCEmulation's Genesis decoding (mirror)


► Links

Charles Mac Donald's Hardware tech (mirror)
Charles Mac Donald's IO tech (mirror)
Raphnet's multitap information
Eke's menacer/justifier information (mirror)