タイニーゼビウスのローダー部分を読んでみます。CAS形式のテープイメージはこのようになっています。
これを最初から読み解いていきますが、その前にタイニーゼビウスを実際にエミュレータでCLOADして、どのような動きをしているのか確認しておきます。
エミュレータで確認すると、テープイメージを1667Byteまで読み取ったこと、list命令でBASIC部分のプログラムが表示できること、10030行目まであることがわかります。
改めて、テープイメージのバイナリを追っていきます。PC-6001の32K RAMモードでは、BASICのプログラムを8401Hから読み込みます。
格納アドレス | データ | 内容 |
---|---|---|
D3 D3 D3 D3 D3 D3 D3 D3 D3 D3 | BASICプログラム識別ヘッダ | |
4C 4F 41 44 45 52 | ファイル名 | |
8401h | 07 84 | 次の行のアドレス(8407h) |
8403h | 0A 00 | 行番号(10) |
8405h | 8B | RESTORE命令の中間コード |
8406h | 00 | 行終端コード |
8407h | 24 84 | 次の行のアドレス(8424h) |
8409h | 64 00 | 行番号(100) |
840Bh | 83 | DATA命令の中間コード |
840Ch | 43 44 2C 36 31... | CD,61...(DATA命令の中身) |
これといって説明することがないくらい、BASICのCLOAD命令の仕様の通りの構造になっています。
続けて、BASICプログラムの終わりの辺りをみてみます。バイナリデータはこちら。
見所は00が並んでいる箇所です。エミュレータで表示されてるテープの読み込み位置が1667(16進数で0683h)でしたから、この辺まで読んだところでCLOAD命令が終了していることになります。CLOAD命令の仕様も、00hを10回読み取ったら終了となっています。
その前にある、30 30 30がASCIIコードだと000なので、プログラムの最終行のEXEC;&HF000だとわかります。その辺を前に辿っていくと、最終行10030(16進数で272Eh)を表すデータもあります。
また、次の行へのアドレスが8A6Bhとなっていて、8A6Bhが00h 00hなのでプログラム終了となります。
BASICプログラム部分の要点をまとめるとこのようになっています。
FOR I=&HF000 TO &HF027:READ A$:POKE I,VAL("&h"+A$):NEXT EXEC&H1A61:EXEC&HF000
DATA文のマシン語箇所を&HF000から28Byte書き込んで、&HF000で実行しています。その前にあるEXEC&H1A61ですが、これはBASIC ROMのルーチンで、テープ周りの初期化処理とテープのリモート端子をON(リレーON)を実行するものです。
マシン語部分をF000hから逆アセンブルしてみます。
ORG 0F000H ; CMT LOAD INIT CALL 01A61H ;F000 CD 61 1A LD HL,09C80H ;F003 21 80 9C LD B,0DBH ;F006 06 DB Z0000: ; CMT read 1byte CALL 01A70H ;F008 CD 70 1A CP 0C9H ;F00B FE C9 JR NZ,Z0000 ;F00D 20 F9 Z0001: ; CMT read 1byte CALL 01A70H ;F00F CD 70 1A CP 0C9H ;F012 FE C9 JR Z,Z0001 ;F014 28 F9 Z0002: ; CMT read 1byte CALL 01A70H ;F016 CD 70 1A LD (HL),A ;F019 77 INC HL ;F01A 23 LD A,B ;F01B 78 CP H ;F01C BC JR NZ,Z0002 ;F01D 20 F7 CALL 01AAAH ;F01F CD AA 1A JP 0D4F9H ;F022 C3 F9 D4
1A70hはBASIC ROMのテープからの1バイト読み取りで、1AAAHはテープ読み込みの終了処理です。
最初にC9Hが現れるまで読み捨てして、C9H以外のデータが現れるまでC9Hを読み捨てして、そこからHLレジスタ(9C80h~)に書き込みをしています。
PC-6001のテープ読み込みは、SUB CPUがテープから読み込んだ情報をZ80側に送ります。テープに記録された信号が適切であれば、その内容に関係なく、SUB CPUはZ80にデータを送るので、なんらかのマーカーを用いたヘッダ検出をしないと、読み取りに失敗することになります。タイニーゼビウスのマシン語ローダーはC9Hをマーカーとして使っているのですね。
また、タイニーゼビウスのローダーはSUB CPUから送られてくるデータをメモリに書き込んで、D4F9hからプログラムを実行しています。読み取ったデータのチェックはしていないこともわかります。ゲームによっては、チェックサムなどを用いてエラーチェックをしているものもあります。
余談ですが、WAV形式からCAS形式に変換すると無音部分の情報が失われます。複数回に分けてテープを読み込むようなゲームでは、テープの無音部分の走行時間中にZ80がなんらかの処理を実行している事があり、エミュレータ+CAS形式だと、本来は無音部分で何も読み取らないはずなのに、CAS形式のファイルからデータを読み進めてしまって、読み取りに失敗することがあります。そのような場合は、無音に該当する箇所に無駄なデータを入れておくことで対処できます。これはP6エミュレータで昔からあるテクニックで(1990年代...)、T&E Softのゲームが起動しないにも書かれています。