PC-6001用のROMカートリッジを、Arduino Mega2560 R3で吸い出してみました。
Arduino Mega2560 R3は純正品ではなく安価な互換品を使いましたが問題なく動きました。
ピンヘッダやピンケーブルも何でもOKですが、オスメスを間違えないでください。
ユニバーサル基板にカードエッジコネクタとピンヘッダを並べて、そのまま平行に繋げるようにハンダ付けしていきます。シール基板とかジャンパ線とかなんでもOKです。
十字配線ユニバーサル基板を使って配線をカットする方が楽かもですね(私は使ったことがないのですが)
PC-6001側のピンと、Arduino側のピンを繋いでいきます。
ROMカートリッジを立てた状態で真上から見た時の配置です。
+5V | +5V | GND | GND | D7 | D5 | D3 | D1 | A5 | A3 | A1 | A12 | A7 | A11 | A9 | ||||||||||
PC-6001 エッジコネクタ | ||||||||||||||||||||||||
D6 | D4 | D2 | D0 | A4 | A2 | A0 | A13 | A8 | A6 | A10 | ROM1 | ROM2 |
番号 | PC-6001 | Arduino PORT名 |
---|---|---|
22 | A0 | PORT-A |
23 | A1 | |
24 | A2 | |
25 | A3 | |
26 | A4 | |
27 | A5 | |
28 | A6 | |
29 | A7 | |
37 | A8 | PORT-C |
36 | A9 | |
35 | A10 | |
34 | A11 | |
33 | A12 | |
32 | A13 | |
31 | ||
30 | ||
49 | D0 | PORT-L |
48 | D1 | |
47 | D2 | |
46 | D3 | |
45 | D4 | |
44 | D5 | |
43 | D6 | |
42 | D7 | |
2 | ROM1 | |
3 | ROM2 | |
GND | GND | |
+5V | +5V |
ArduinoのIDEを使ってコードをコンパイル&書き込みします。通信速度は57600bpsにしていますが、PC側と速度が合っていれば115200bpsに書き換えてもOKです。
//
// PC-6001 ROM Cart Reader
//
const int PIN_ROM1 = 2;
const int PIN_ROM2 = 3;
word ReadAddr;
const int START_ADDR = 0x0000;
const int END_CHECK_ADDR = 0x2000;
void setup()
{
// all output(Address Bus Lower, A0-A7)
DDRA = B11111111;
PORTA = B00000000;
// all output(Address Bus Higher, A8-A14)
DDRC = B11111111;
PORTC = B00000000;
// all input(Data Bus, D0-D7)
DDRL = B00000000;
pinMode(PIN_ROM1, OUTPUT);
pinMode(PIN_ROM2, OUTPUT);
digitalWrite(PIN_ROM1, HIGH);
digitalWrite(PIN_ROM2, HIGH);
Serial.begin(57600, SERIAL_8N1);
Serial.flush();
ReadAddr = START_ADDR;
//Serial.println( "start loop. wait..." );
// 開始待ち
Serial.flush();
while (true)
{
if (Serial.available() > 0)
{
int incomingByte = Serial.read();
Serial.flush();
delay(100);
break;
}
}
}
void ReadRom(byte PortPin)
{
while(true)
{
PORTA = ReadAddr & 0xff; // low addr
PORTC = ReadAddr >> 8; // high addr
delayMicroseconds(1);
digitalWrite(PortPin, LOW);
delayMicroseconds(1);
int v = PINL;
Serial.write(v);
digitalWrite(PortPin, HIGH);
ReadAddr++;
if (ReadAddr == END_CHECK_ADDR)
{
ReadAddr = START_ADDR;
break;
}
}
}
void loop()
{
ReadRom(PIN_ROM1);
ReadRom(PIN_ROM2);
while(true){}
}
PC側からArduinoに何でもいいのでデータを送ると、Arduinoから読み込んだROMの内容を送り返してきます。
(例)PC側通信ソフトにAcknowrichを使った場合
Arduinoは一般的に各端子のON/OFFや状態の読込みは1端子単位で行います。アドレスバスが16本ある場合、A0-A15それぞれをON/OFF設定することになるのですが、それだと面倒なので、ArduinoのCPUであるATMEGAのポートを直接コントロールすることで、8本単位で信号を読み書きする事が出来るようになっています。
具体的には、以下のページを参考にしました。(ページ内の表示記述ミスがあるので注意)
この表(ポートからみたArduinoのピン番号)によると、8ビット単位で制御できるのは、PA0-7, PB0-7, PC0-7, PL0-7です。PF0-7とPK0-7も使えるのですが、デフォルト設定がアナログ用なので除外します。また、ピン番号の方をみると、ポートPB0-7はピン番号が離れたところにあります(D53,D52,D51,D50,D10,D11,D12,D13)。これは配線する時のミスになりそうですから除外します。
となると、残りはPA0-7, PC0-7, PL0-7で、ちょうどいい感じにアドレスバス16本+データバス8本に割り当てられますね。
ROM1とROM2信号がありますが、これはROMカートリッジ内にROMが2個あり、それぞれを選択するための信号です。Active Lowです。両方を同時にLowにすると良くないことが起きます。
C000-FFFF | 内部RAM |
8000-BFFF | 外部RAM |
6000-7FFF | 外部ROM2 |
4000-5FFF | 外部ROM1 |
0000-3FFF | BASIC ROM |
Z80からROMにアクセスする時は、MREQ、RD、アドレスバスといったZ80の信号をやりくりする必要があるのですが、PC-6001は内部の回路で外部ROM選択用の信号を生成していて、それが拡張コネクタに出ています。ただし、この信号に対応していないROMカートリッジの場合は、この信号を使うことは出来ません。PC-6001mkII以降専用のROMカートリッジが該当すると思われます(未確認)。そのようなカートリッジの場合は、MREQやRD信号を使ってROMにアクセスすることになります。(下図参照)
+5V | +5V | GND | GND | D7 | D5 | D3 | D1 | A5 | A3 | A1 | A14 | A12 | A7 | A11 | A9 | |||||||||
PC-6001 エッジコネクタ | ||||||||||||||||||||||||
D6 | D4 | D2 | D0 | A4 | A2 | A0 | A13 | A8 | A6 | A10 | A15 | RD | MREQ | ROM1 | ROM2 |