Arduinoにメガドライブのパッドをつなげてみる

MDPAD
こんなです。

昔、X68000というPCでゲームをよくやっていたので、ウチにはメガドライブのパッドがなんかたくさんあります。
あのマシンを使ってない人からすれば「昔のパソコンとゲーム機のパッドに何の関係が?」という感じでしょうが、X68000というのは当時のゲーム専用機(スーパーファミコンやメガドライブ、PCエンジンなど)よりも飛び抜けてアーケードゲームの移植が多く、出来も完全と言っていいほど素晴らしいものだったのです。
コントローラも拡張ボードなしで標準でつながる上に、メガドライブのパッドもそのまま接続可能。ちょっとしたアダプタを間にかまして、ソフト側が対応していれば、6ボタンパッドも使用可能でした。
(この辺を詳しく知りたい方は「ATARI仕様」「チェルノブアダプタ」「SFXVI」とかで検索かければ色々出てくるかと)

話が逸れました。昔話はまたそのうち。
今回はその有り余ってるメガドライブのパッドをArduinoにつなげてみます。
必要になってくるのは
DSUBコネクタDIP化基板(オス・メス兼用): 組み立てキット
Dサブコネクタ 9P オス 基板取付用 Lタイプ
この2つ。
コネクタを基板にはんだ付けして、例によってブレッドボードに挿し、メガドラパッドをつなげます。
MDPAD

回路図はこんなですが、これ見て果たして参考になるのか。
MDPAD_circuit

  • D-subの5ピンに5V、8ピンにGND
  • D-subの1~4,6,9ピンにArduinoのDigital端子2~7ピン(入力用)
  • D-subの7ピンにArduinoのDigital端子8ピン(出力用)

これがつながってればOKです。
(配線とパッドの入力内容についてはMechanism of MD 6Button Controlerを参考にさせて頂きました)

スケッチはこんな

// Pins
const byte pinSelect = 8;

// Data
byte oldData[2];  // Last Input
byte newData[2];  // Current Input
byte tempData[2];  // Diff

void setup()
{
  Serial.begin(9600);
  
  // pin2-7 are D0-D5 Input
  DDRD = DDRD | B00000000;
  
  // pin8 is Select OutPut
  pinMode(pinSelect, OUTPUT);
  digitalWrite(pinSelect, HIGH);
  delay(1);
  
  // Input Data Initialize
  for (int i = 0; i < sizeof(oldData); i++){
    oldData[i] = tempData[i] = newData[i] = 0;
  }
}

char str[] = "        ";
bool isChange = false;

void loop()
{
  digitalWrite(pinSelect, LOW);
  delay(1);
  newData[0] = ((~PIND) & B11001100);

  digitalWrite(pinSelect, HIGH);
  delay(1);
  newData[1] = ((~PIND) & B11111100);

  for (int i = 0; i < sizeof(oldData); i++){
    tempData[i] = ((newData[i] ^ oldData[i]) & newData[i]);
    if (tempData[i]){
      isChange = true;
    }
  }

  if (isChange)
  {
    str[0] = (newData[0] & B00000100)? 'U': ' ';
    str[1] = (newData[0] & B00001000)? 'D': ' ';
    str[2] = (newData[1] & B00010000)? 'L': ' ';
    str[3] = (newData[1] & B00100000)? 'R': ' ';
    str[4] = (newData[0] & B01000000)? 'A': ' ';
    str[5] = (newData[1] & B01000000)? 'B': ' ';
    str[6] = (newData[1] & B10000000)? 'C': ' ';
    str[7] = (newData[0] & B10000000)? 'S': ' ';
    Serial.println(str);

    for (int i = 0; i < sizeof(oldData); i++){
      oldData[i] = newData[i];
    }
    isChange = false;
  }
}

我ながら、C言語からプログラミングを始めたとは思えないほど残念なコードで恥ずかしい。もうちょっとスマートな書き方があるとは思うんだけど。
先ほど参考にさせて頂いたページでは6ボタンの対応方法も載っていましたが、なんだか手に負えなさそうなのでとりあえず3ボタンだけ対応してます。
上下左右(UDLR)とABCボタン(ABC)とスタートボタン(S)が押されたら、USBでつながってるPC側にSerial経由で入力情報を送ります。
3BPAD
(新たに押されたボタンの検出(XORしてANDしてるところ)は、パッド入力 – 魔法使いの森を参考にさせて頂きました)

次は6ボタンにも対応させるとして、これ一体何かの役に立つのかどうか……思いつきませんが、とりあえず対応させてから考えますか。

コメントを残す