見出し画像

X68000版パックランド専用コントローラー兼キャメルトライ・アルカノイド用パドルコントローラー作ってみた。

とあるオタクは考えた。
電波新聞社のパックランド専用コントローラーって小さくない?
とあるオタクは考えた。
ATARIコントローラー作るのって簡単だし作ればよくない?
とあるオタクは考えた。
だったらついでにマウス端子つけて真ん中にパドルもつければよくない?

ということでできました。

3ボタン+パドルコントローラー

主要材料(すべて秋月電子で買えます)

・ゲームスイッチ@¥150×3(これは他の店でアケコン用のを買ったほうがよさそう)
・ロータリーエンコーダー@¥110×1
・メタルツマミ@¥460×1(地味に一番高額な部品)
・Dサブコネクター9Pオス@¥80×1
・ミニDIN6ピンコネクター変換キット@¥150×1
・PIC12F1822-I/P @¥200×1
計 1450円

その他材料

・抵抗4本(エンコーダーのノイズフィルタ)
・配線部材
・貰い物の大吟醸の桐箱
・ミニDIN6ピンオスーオスケーブル(アマゾンで600円くらい)
・シリアル9ピンメス-メスケーブル(同上)

パックランド専用コントローラーを作る。

1.ケーブルの結線確認

シリアル通信用のケーブルは信号の衝突を避けるため、両側の同じピンが配線されているとは限りません。
ということでテスタか何かでチェックしましょう。
私が使ったケーブルの場合のピン同士の配線は下記でした。
1-1
2-3
3-2
4-6
5-5
6-4
7-8
8-7
9-9

2.作成

ATARI仕様ジョイスティックで左は3,右は4、ボタン1は6、コモンは8
本体側の3,4,6,8を1のピン配線で変化して、
Dサブコネクター9Pの2番ピンを左ボタン,6番ピンを右ボタン、4番ピンをジャンプボタンに接続。
スイッチのもう片方に7番を接続すれば完了です。
(もともとONになっている方の端子はなにも接続しなくて大丈夫)

正直箱の工作の方が時間がかかるくらい簡単な作業です。
使用感は大きくした分、ボタンを押しやすくなって良好です。
(アーケードの当時は知らないのですが、結構それっぽい感じだと思います。)
これとREVIVE USBのような製品を組み合わせれば、STEAM版パックランドを3ボタンコントローラーで遊ぶことも可能です。

パドルコントローラーを作る

こっちはマウスの信号を再現する必要がある分難易度が上がります。
低電力な5V対応マイコンが必要で、本体との通信2ピン(うち1つはUART)、ロータリーエンコーダーで2ピン、左右のクリックで2ピンの計6ピンIOがあれば最低限OKです。
今回は適当にPIC12F1822を使いました。

送信仕様

細かい信号やタイミングはP6つくろうブログさまの記事(http://sbeach.seesaa.net/article/474936043.html)が参考になるかと思います。

まとめると非同期シリアル通信 4800bps パリティは常にHIGH
具体的な信号としては1バイト事に下記の信号が出るようにすればOKで、3バイト分連続させればOK、みたいな感じです。
スタートビット(LOW)-データ8Bit(LSB,1=HIGH)-パリティ(HIGH)-ストップビット(HIGH)

PICプログラミング

P6つくろうブログさまとはじめてのPICさま(http://machoto2.g2.xrea.com/page/P1822/P12_00.htm)の記事を参考に、下記のようなコードを作成。
送信部分を割り込みで書いて、その分ロータリーエンコーダーのチャタリング対策を長くした方がいいのですが、PICを使うのが久しぶりで面倒だったので省略しました。

#include <xc.h>
#include <stdio.h>
#include <stdlib.h>
#define _XTAL_FREQ 4000000  //4Mhzで動作
#define PushSW RA5   //本体からのマウス信号要求信号
#define  A_pin RA1  //ロータリーエンコーダーA
#define  B_pin RA2  //ロータリーエンコーダーB
#define  LCL RA3  //左クリック相当ボタン
#define  RCL RA4  //左クリック相当ボタン
#pragma config FOSC  = INTOSC   #pragma config WDTE  = OFF 
#pragma config PWRTE = ON  #pragma config MCLRE = OFF   
#pragma config CP    = OFF  #pragma config CPD   = OFF   #pragma config BOREN = ON   
#pragma config CLKOUTEN = OFF  #pragma config IESO  = OFF  
#pragma config FCMEN = OFF  #pragma config WRT  = OFF   
#pragma config PLLEN  = OFF    #pragma config STVREN = ON  
#pragma config BORV = LO       #pragma config LVP  = OFF 
void putch(char ch) {
   while (!TXIF);  
    TXREG = ch;
}

void main(void) {
OSCCON = 0b01101010;               // 4Mhz
PORTA  = 0x00;
TRISA  = 0b11111111;
ANSELA = 0x00; 
WPUA   = 0xff;
ONnWPUEN = 0;
RCSTA   = 0b10000000;     
TXSTA   = 0b01100101;
BAUDCON = 0b00001000;
SPBRGH  = 0;
SPBRG   = 207;

char ch[3]={0b00000000,0b00000000,0b00000000};  //送信データ
int Flag=0;  //信号送信フラグ
char cnt=0;  //ロータリーエンコーダーカウント
char BA0=0;  //ロータリーエンコーダーAの現在の状況
char BA1=0;  //ロータリーエンコーダーAの現在の過去の変化時の状況
char BB0=0;  //ロータリーエンコーダーAの現在の状況
char BB1=0; //ロータリーエンコーダーAの現在の過去の変時の状況
char muki=0;  //回転向き
char SP=3;  //移動速度
char SPF=0;  //両方のボタンを押してスピード変化させたフラグ

while(1){                     
     if(PushSW &&(Flag==0) ){    
         ch[0]=0;
         if(!LCL) //左クリック相当
               ch[0]+=2;
         if(!RCL) //右クリック相当
            ch[0]+=1;
         if(!LCL&&!RCL &&SPF==0)  //両方おしたらスピード変更
         {
             SPF=1;
             SP+=3;
             if(SP==12)
                 SP=3;
         }
         if(LCL&&RCL)  //一回両方話さないとスピードは変わらない
             SPF=0;
         if(cnt<127/SP) 
             cnt=cnt*SP;
         else
             cnt=127;
         if(muki==1)
             ch[1]=cnt;
         else if(muki==2)
             ch[1]=~cnt+1;
         else
             ch[1]=0;
         __delay_us(300);        // 400uSくらいらしいが、気持ち早めに
        putch(ch[0]);
        putch(ch[1]);
       putch(ch[2]); 
         Flag=1;
         cnt=0;
         muki=0;
     }
     if((!PushSW) && (Flag==1))
      Flag=0;

     if(A_pin)
         BA0=1;
     else
         BA0=0;
      if(B_pin)
         BB0=1;
     else
         BB0=0;
     if(BA0!=BA1)
     {
         if(muki==0 && ((BA0!=BB0 && BB0==BB1) ||(BB0==BA0&& BB0!=BB1)))
             muki=1;
         cnt++;
          __delay_us(1200);  //チャタリング対策、多いほうが安定だが、通信と被るとよくなさそう
         BA1=BA0;
     }
    if(BB0!=BB1 )
     {
         if(muki==0&& ((BB0!=BA0&& BA0==BA1) ||(BB0==BA0&& BA0!=BA1)))
             muki=2;
         cnt++;
          __delay_us(1200); //チャタリング対策、多いほうが安定だが、通信と被るとよくなさそう
         BB1=BB0;
     }
}
return;
}

配線

(ミニDINコネクタの該当ピンはテスターで確認してください)
PICのRA0をマウスからの信号に当たるミニDINコネクタPINに接続
ロータリーエンコーダーとPICのRA1,RA2
左右のクリックに割り当てたい部分のスイッチとPICのRA3,RA4
マウスへの信号要求に当たるミニDINコネクタPINに。
+5VとGNDもマウスケーブルからとります。
スイッチの片側にGNDをつなぐのを忘れずに。

その他注意

・マウスコネクタはミニDIN5ピンですが、ミニDIN6ピンからピンを1つ折れば使えます。シールドの長さが合わなかったりするので、コネクタ部分は加工が必要な場合も。
・チャタリングが起きると右に回しているのに左に動いたりします。フィルタ回路や待ち時間の調整をお願いします。
・ロータリーエンコーダーのABが逆かもしれません。向きは仮配線して確認してください。
・アルカノイドはゲーム開始後f4キーを2回押すとマウス操作=パドルが有効になります。キャメルトライと動かしやすい速度に差があるので、左右クリック同時押しによる変更機能を付けました。

まとめ

1500円でX68000版パックランド専用コントローラー兼キャメルトライ・アルカノイド用パドルコントローラーを作れました。
パックランド専用コントローラーは数千円、キャメルトライのパドルはマウスが必要で、マウスだけでも1万円超で取引されているなど、どちらもまともに買おうとすると高額なので自作する価値は結構あるのではないかと思います。
週末にざっくり作ったためプログラムは改善の余地は大きいと思いますので、適当にいじってみてください。

お約束
素人が適当に作ったものですので、利用・改造は自己責任で。
本体に異常がでても責任はとれません。


修正履歴
10/14 一部誤ったコードを修正
10/17 仮で試してみて安定したので、チャタリング対策を800→1200に修正