Nights analog pad data format

antime

Extra Hard Mid Boss
Relating to the Playstation-to-Saturn pad converter topic, here's how to read the Nights pad using SH2 direct control:

The pad is what the SMPC manual calls a "3-wire handshake method peripheral". To determine if the controller is of this type, use the following algorithm:

Code:
/* These initialization steps should always be performed. */

DDR1 = 0x60; /* Configure the TH and TR pins as outputs, the rest as inputs. */

IOSEL = 1; /* Configure port 1 for SH2 direct control. */

EXLE = 0; /* Disable the external latch. */

/* Read Megadrive ID. */

PDR1 = 0x60; /* TH = 1, TR = 1 */

/* wait 2 usec */

id1 = PDR1 & 0xF;

PDR1 = 0x20; /* TH = 0, TR = 1 */

/* wait 2 usec */

id2 = PDR1 & 0xF;

if (id1 == 1 && id2 == 1)

    /* 3-wire peripheral */

else

    /* Megadrive pad, Saturn digital pad or other device */

In 3-wire mode, the TH bit acts as an attention or chip select line, TR acts as a data toggle and TL acts as an acknowledge signal. The data is sent in the R, L, D and U bits, and is valid when TR == TL. To end the transaction, set both TH and TR to 1. In code:

Code:
int toggle = 0;

for (ii = 0; ii < ndata; ii++)

{

    PDR1 = (toggle << 5); /* TH = 0, TR = toggle */

    while ((PDR1 & 0x10) >> 4 != toggle)

        ;

    controldata[ii] = PDR1 & 0xF;

    toggle = 1 - toggle;

}

PDR1 = 0x60; /* End transaction. */

According to the SMPC manual, the two first data values form the peripheral's Saturn ID sequence. Furthermore, at least for some peripherals it seems the first value may be the device ID and the second value the number of data bytes following the ID sequence. While this seems to be true for the Nights pad in both modes, at least the Saturn multitap does not seem to follow this format.

Here's the data sent by the Nights pad in "O" mode:

Code:
     R       L       D       U

1:   0       0       0       1

2:   0       1       1       0

3:   Right   Left    Down    Up

4:   Start   A       C       B

5:   R Trg   X       Y       Z

6:   L Trg   1       1       1

7:   AX7     AX6     AX5     AX4

8:   AX3     AX2     AX1     AX0

9:   AY7     AY6     AY5     AY4

10:  AY3     AY2     AY1     AY0

11:  AR7     AR6     AR5     AR4

12:  AR3     AR2     AR1     AR0

13:  AL7     AL6     AL5     AL4

14:  AL3     AL2     AL1     AL0

Here's the data in "+" mode:

Code:
     R       L       D       U

1:   0       0       0       0

2:   0       0       1       0

3:   Right   Left    Down    Up

4:   Start   A       C       B

5:   R Trg   X       Y       Z

6:   L Trg   1       1       1

For all button bits a zero means pressed. The analog trigger values range from 0 (min) to 0xFF (max). If the value goes above around 0x90 the digital button is registered as pressed. The digital button remains pressed until the analog value goes below around 0x56. The thumbstick axes range from 0 (left/up) to 0xFF (right/down) with 0x80 being neutral for both.
 
Nice summary! I really want to make a Saturn->MD adapter so I can use a Saturn analog pad on the MD (with homebrew).
 
Yes, but this was more about documenting the transmission format (the original discussion was about making a DualShock to analog pad interface.)
 
Back
Top