「MSXのROMカートリッジを持っているので、それを吸い出してPCに保存したい!」
そう思っていても、具体的にどうすれば良いのか全く分からず、ついネットでダウn(略)という人も多いのではないでしょうか。
そういう方のために、最低限の機材&最低限の知識 で、ROMカートリッジのデータを PCに転送して保存する方法を書いてみました。
とにかくROMイメージを吸い出せれば良い、という方は、ここに書かれている通りにやれば大丈夫だと思います。
技術的なことや応用編についてはページの後半に書いてあるので、もっと詳しく知りたかったり、逆によく分からなかったり、うまくいかなかったりしたときは、各項目の [詳しく] というリンクをクリックしてください。
ROMを吸い出すには、MSX本体の電源を入れた後にROMカートリッジを差す、いわゆる「後差し」をする必要があります。
「後差し」は本体やカートリッジを破壊する可能性があるので(私は30年間で一度もありませんが…)、くれぐれも自己責任で行ってください。
PAUSEキーがついている機種は、PAUSE状態にしてからROMカートリッジを差すと成功しやすいようです。
また、カートリッジを差すと自動的に電源がOFFになる機種は後差しができません。スロット拡張ユニットや延長ケーブルを使うことで回避できます。
10 SCREEN,,,2
20 A=&HF750:DEFUSR=A
30 FOR I=A TO A+&H3A:READ A$:POKE I,VAL("&H"+A$):NEXT
40 PRINT"PUSH ANY KEY TO SAVE";:A$=INPUT$(1)
50 B=USR(&H1)
60 DATA 3A,FF,FF,2F,F5,DB,A8,F5,23,23,7E,F5,26,40,CD,24
70 DATA 00,F1,26,80,CD,24,00,3E,FF,CD,EA,00,21,00,40,01
80 DATA 00,80,7E,C5,E5,CD,ED,00,E1,C1,23,0B,78,B1,20,F2
90 DATA CD,F0,00,F1,D3,A8,F1,32,FF,FF,C9
波形が加工されてしまうと正しく変換ができないので、音質補正やエフェクトなどのオプションがある場合はすべてOFFにしてください。
(WaveClipper を使う場合は、「ファイル」→「サンプリング設定」のチェックボックスを全て外してください)
【参考】8.~12.の動画
「ざっくり説明」の補足です。
よくわからなかったり、うまくいかなかったり、お時間がある人は、この先を読んでください。
PC側で必要なツールは、「入力された音声をwav形式で保存できるツール」と、「テープセーブ用に出力されたwavファイルをバイナリー変換できるツール」です。
最近の Windows では、wav形式で音声を保存するツールが付属していないので、何らかの外部ツールを使用することになります。
特にこだわりがなければ、シンプルでインストールの必要もない WaveClipper をおすすめします。
また、wavファイルをバイナリー変換するツールについても色々ありますが、なんでもピーガーmkII(NandemoPiGa2)は(作った自分で言うのもアレですが)なかなか使いやすいと思います。
今回の方法では、本体のカートリッジスロットA からROMデータを吸い出しますが、一部、正しく動作しない機種があります。
日本国内で流通していたMSXの多くは、カートリッジスロットA が内部的に「基本スロット1-0」という扱いになっているのですが、例えばナショナルの CF-3000 のスロットAは「基本スロット2-0」となっており、このまま実行すると別のスロットのデータを吸い出してしまいます。
そのような機種を使用する場合、4.のプログラムの50行の 「&H1」の部分を、内部的なスロット番号に合わせて変更してください。
50 B=USR(&H1) ←ここを書き換える
スロットを拡張していない場合 | x-0 |
---|---|
基本スロット 0 | &H0 |
基本スロット 1 | &H1 |
基本スロット 2 | &H2 |
基本スロット 3 | &H3 |
スロットを拡張している場合 | x-0 | x-1 | x-2 | x-3 |
---|---|---|---|---|
拡張スロット 0 | &H80 | &H84 | &H88 | &H8C |
拡張スロット 1 | &H81 | &H85 | &H89 | &H8D |
拡張スロット 2 | &H82 | &H86 | &H8A | &H8E |
拡張スロット 3 | &H83 | &H87 | &H8B | &H8F |
各機種のスロットが内部的にどういう扱いになっているのかは、MSX Slot Info Viewer を使うと簡単に分かります。
CF-3000 のカートリッジスロットA を使用する場合、内部的には「基本スロット 2-0」になるので、「&H1」を「&H2」に変更する必要があります。
また、拡張スロットを使う場合についても同様にプログラムの修正が必要です。
例えば、以下の画像のような環境では、スロットA に拡張アダプタを差して手前から2番目のスロットである「拡張スロット1-1」を使用しているので、「&H1」の部分を「&H85」に変更することになります。
プログラムについて、簡単に説明していきます。
10 SCREEN,,,2
このプログラムでは、ROMデータをデータレコーダーの高速モード(2400ボー)で出力するようにしているため "SCREEN,,,2" としています。
カセットテープを介さずに直接PCで録音するため、高速にしたからといって信頼性が落ちることはほとんどありません。(逆に言えば、低速にしても信頼性が上がることはないと思います)
それでもあえて通常モード(1200ボー)で録音したいという方は、"SCREEN,,,1" に変更してください。
20 A=&HF750:DEFUSR=A
マシン語データを書き込むアドレスを指定します。
デフォルトでは、システムワークエリアの F750H に置いていますが、プログラム自体はリロケータブルなので、自由なアドレスに置いても問題ありません。
30 FOR I=A TO A+&H3A:READ A$:POKE I,VAL("&H"+A$):NEXT
マシン語データを書き込みます。
少しでも短いリストにするため、エラーチェック等はしていないので、打ち込む際にはミスのないようにしてください。
40 PRINT"PUSH ANY KEY TO SAVE";:A$=INPUT$(1)
PC側を録音状態にして、何かキーを押してください。すぐにピーガー出力を開始します。
また、ROMデータをセーブする部分は完全マシン語で、しかもプログラム短縮のためにSTOP処理なども入れていません。
ここでキーを押すと 32KB すべて出力し終わるまで何もできなくなってしまうので注意してください。すみませんm(_ _)m
50 B=USR(&H1)
USRの引数にはROMカートリッジの差されているスロットによって決められた値を指定してください。
指定する値(&H1)については ROMを差すスロットについて を参照してください。
60 DATA 3A,FF,FF,2F,F5,DB,A8,F5,23,23,7E,F5,26,40,CD,24
70 DATA 00,F1,26,80,CD,24,00,3E,FF,CD,EA,00,21,00,40,01
80 DATA 00,80,7E,C5,E5,CD,ED,00,E1,C1,23,0B,78,B1,20,F2
90 DATA CD,F0,00,F1,D3,A8,F1,32,FF,FF,C9
以下、マシン語プログラムについての説明です。
大まかにいうと「4000H-BFFFHをROMカートリッジの差してあるスロットに切り替える→1バイトずつ読み出してテープにセーブする→全て終わったらテープを止めて4000H-BFFFHを元のスロットに戻す」という流れです。
プログラム短縮のために、スロット切り替え処理(戻す処理)を簡略化しているので、セーブした後にBASICに戻って来られない場合もあるかもしれません。すみません m(_ _)m
ENASLT, TAPOON, TAPOUT, TAPOOF など、各BIOSルーチン の詳細については テクハンwiki などを参考にしてください。
機械語 | ニーモニック | コメント | |||
---|---|---|---|---|---|
START: | ラベル "START" | ||||
0000 | 3A FF FF | LD | A,(0FFFFH) | BASIC実行時の拡張スロットの状態をAに入れておく | |
0003 | 2F | CPL | A(拡張スロットの状態)は反転して保存されているので元に戻す | ||
0004 | F5 | PUSH | AF | A(拡張スロットの状態)を保存 | |
0005 | DB A8 | IN | A,(0A8H) | BASIC実行時の基本スロットの状態(ポートA8H)をAに入れておく | |
0007 | F5 | PUSH | AF | A(基本スロットの状態)を保存 | |
0008 | 23 | INC | HL | HL=HL+1 | |
0009 | 23 | INC | HL | HL=HL+1 | |
000A | 7E | LD | A,(HL) | USR命令の引数は(HL+2)に保存されているのでここでAに入れる | |
000B | F5 | PUSH | AF | A(USR命令の引数)を保存 | |
000C | 26 40 | LD | H,40H | スロットを切り替えるページを指定(4000H-7FFFH) | |
000E | CD 24 00 | CALL | ENASLT(0024H) | Hで指定されたページ(4000H-7FFFH)をA(USR命令の引数)に対応するスロットに切り替える | |
0011 | F1 | POP | AF | A(USR命令の引数)を復帰 | |
0012 | 26 80 | LD | H,80H | スロットを切り替えるページを指定(8000H-BFFFH) | |
0014 | CD 24 00 | CALL | ENASLT(0024H) | Hで指定されたページ(8000H-BFFFH)をA(USR命令の引数)に対応するスロットに切り替える | |
0017 | 3E FF | LD | A,0FFH | 次のTAPOONでロングヘッダを書き込むよう指定 | |
0019 | CD EA 00 | CALL | TAPOON(00EAH) | カセットのモーターONの後、ヘッダ・ブロックを書き込む(Aが0のときショートヘッダ・0以外のときロングヘッダ) | |
001C | 21 00 40 | LD | HL,4000H | HL=ROMアドレス | |
001F | 01 00 80 | LD | BC,8000H | BC=転送サイズ(32KBを想定。16KBのROMなら4000HにしてもOK) | |
LOOP: | ラベル "LOOP" | ||||
0022 | 7E | LD | A,(HL) | HL(ROMアドレス)のデータを1バイト読みAに入れる | |
0023 | C5 | PUSH | BC | BC保存 | |
0024 | E5 | PUSH | HL | HL保存 | |
0025 | CD ED 00 | CALL | TAPOUT(00EDH) | テープにAの値を書き込む(HL,BC破壊) | |
0026 | E1 | POP | HL | HL復帰 | |
0027 | C1 | POP | BC | BC復帰 | |
002A | 23 | INC | HL | HL(ROMアドレス)を+1 | |
002B | 0B | DEC | BC | BC(転送サイズ)を-1 | |
002C | 78 | LD | A,B | A=B(BC=0かどうかチェックしたい) | |
002D | B1 | OR | C | A=A OR C(BC=0かどうかチェックしたい) | |
002E | 20 F2 | JR | NZ,LOOP | Aが0以外なら(BCが0以外なら) ラベル"LOOP" にジャンプ | |
0030 | CD F0 00 | CALL | TAPOOF(00F0H) | テープへの書き込みをストップ | |
0033 | F1 | POP | AF | A(基本スロットの状態)を復帰 | |
0034 | D3 A8 | OUT | (0A8H),A | 基本スロットの状態(ポートA8H)を元通りにする | |
0036 | F1 | POP | AF | A(拡張スロットの状態)を復帰 | |
0037 | 32 FF FF | LD | (0FFFFH),A | 拡張スロットの状態(0FFFFH)を元通りにする | |
003A | C9 | RET | BASICに戻る |
WaveClipper
http://t-ishii.la.coocan.jp/hp/wc/index.html
PCで WaveClipper を起動して、「ファイル」→「新規録音」で、保存するファイル名を入力してください。
「ファイル」→「サンプリング設定」で、「モノラル」を選び、各オプションをすべてOFFにしてください。
「入力のモニタリング」をONにすると、実際に録音されている音が聴こえるようになるので安心です。
環境によっては「ループバック録音」しかできない場合もあるかもしれません。これでも録音は可能ですが、PCで再生される音が全て録音されることになるので、録音中は他の音が鳴らないように注意してください。
「ざっくり説明」のツールはメガROMには非対応でしたが、やろうと思えばメガROMをPCに転送することもできます。
ただし、以下のことに注意してください。
10 SCREEN,,,2
20 IF PEEK(&HFC49)=&HE0 THEN CLEAR50,&HF000:A=&HF000 ELSE CLEAR50,&HD000:A=&HD000
30 DEFUSR=A:FOR I=A TO A+&H8F:READ A$:D=VAL("&H"+A$):POKE I,D:C=C+D:NEXT
40 IF C<>14064 THEN PRINT"CHECKSUM ERROR!":END
50 PRINT"SELECT ROM TYPE"
60 FOR I=0 TO 5:READ R$(I),R(I):PRINT I;":";R$(I):NEXT
70 INPUT M$:IF M$<"0" OR M$>"5" THEN 70 ELSE M=VAL(M$)
80 POKE A+&H1D,R(M)-&H1E:IF M<=1 THEN 130
90 PRINT"SELECT ROM SIZE"
100 PRINT" 1:1M 2:2M 3:3M 4:4M"
110 INPUT S$:IF S$<"1" OR S$>"8" THEN 110 ELSE S=VAL(S$)
120 POKE A+&H76,S*16:POKE A+&H86,S*8
130 PRINT"PUSH ANY KEY TO SAVE";:A$=INPUT$(1)
140 IF M>0 THEN B=USR(&H1) ELSE B=USR(PEEK(&HFCC1))
150 DATA 3A,FF,FF,2F,F5,DB,A8,F5,23,23,7E,F5,26,40,CD,24
160 DATA 00,F1,26,80,CD,24,00,AF,CD,EA,00,AF,18,20,F5,2E
170 DATA 00,4D,7E,C5,E5,CD,ED,00,E1,C1,23,0B,78,B1,20,F2
180 DATA F1,38,E9,CD,F0,00,F1,D3,A8,F1,32,FF,FF,C9,3E,FF
190 DATA 18,2F,32,00,60,3C,32,00,80,3C,26,60,06,40,18,25
200 DATA 32,00,50,3C,32,00,70,3C,32,00,90,3C,32,00,B0,18
210 DATA 0F,32,00,60,3C,32,00,68,3C,32,00,70,3C,32,00,78
220 DATA 3C,26,40,06,80,FE,10,18,A5,32,00,60,3C,32,00,70
230 DATA 3C,26,40,06,80,FE,08,18,95,3E,FF,26,00,18,E4,00
240 DATA"BIOS(32KB)",137
250 DATA"NORMAL(32KB)",62
260 DATA"MEGA-ASC8",97
270 DATA"MEGA-ASC16",121
280 DATA"MEGA-KONAMI",66
290 DATA"MEGA-KONAMI-SCC",80