ベーシックマスターのソフトウェア(1)カセットテープ(1)

BASICMASTER, 昔のパソコン

BASICMASTERは標準で300bps(カンサスシティスタンダード)のカセットインターフェイスを搭載している。

BASIMCASTER Jr. のT型番(MB-6885T)からは1200bpsに高速化された。ハードウェアは(ほぼ)同一で、高速化はソフトウェア的に行われている。

Jr以前の機種でもソフトウェア的に1200bpsを読み書きするルーチンは開発されていた(こちらがJrのTurbo ROMよりも時期は早い)。

ここでは、BASICMASTERの300bps カセットルーチンについて調べてみよう。

カセットフォーマットの詳細

カセットフォーマットの詳細は BASICMASTER/documents/tape_format.md at main · zu2/BASICMASTER を参照のこと。


以下、例として TinyGalaxyをカセットテープに保存したフォーマット(.cmt)を用いる。


0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0040: ff 01 01 07 47 41 4c 41 58 59 2e 42 01 ff 10 00  ....GALAXY.B....
0050: b2 ce 01 7f a6 00 81 86 26 06 a7 20 86 20 a7 00  ........&.. . ..
0060: 09 8c 01 1f 26 ee 39 00 00 00 00 00 00 00 00 00  ....&.9.........
0070: 66 ce 03 9f a6 00 81 7c 26 06 a7 01 86 20 a7 00  f......|&.... ..
0080: 09 8c 01 1f 26 ee 39 00 00 00 00 00 00 00 00 00  ....&.9.........
0090: 00 ce 01 20 a6 01 81 7b 26 06 a7 00 86 20 a7 01  ... ...{&.... ..
00a0: 08 8c 03 9f 26 ee 39 ff ff ff ff ff ff ff ff ff  ....&.9.........
00b0: ff b6 10 1f 48 48 b8 10 1f 4c b7 10 1f 39 ff ff  ....HH...L...9..
00c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00d0: d8 ce 03 7f a6 00 81 20 27 15 81 86 27 11 bd 10  ....... '...'...
00e0: 60 91 00 24 0a a6 20 81 86 27 04 86 86 a7 20 09  `..$.. ..'.... .
00f0: 8c 01 3f 26 df 39 00 00 00 00 00 00 00 00 00 00  ..?&.9..........
0100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0110: 00 ce 03 80 a6 00 81 86 26 04 86 20 a7 00 08 8c  ........&.. ....
0120: 03 a0 26 f0 39 01 01 01 01 01 01 01 01 01 01 01  ..&.9...........
0130: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0150: 8b 00 ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0160: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0170: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0190: ff ff ff 01 00 07 47 41 4c 41 58 59 2e 42 01 01  ......GALAXY.B..
01a0: 10 00 b1 ce 32 00                                ....2.


ファイル名

ファイル名は 6.1 形式。拡張子は1文字で標準では .S と .B が使える。下の例では、"GALAXY.B" である。


0040: ff 01 01 07 47 41 4c 41 58 59 2e 42 01 ff 10 00  ....GALAXY.B....
	:
0190: ff ff ff 01 00 07 47 41 4c 41 58 59 2e 42 01 01  ......GALAXY.B..

この例では ファイルサイズが256バイトに満たないので、データのあるブロックは1つだけで、続けて最終ブロックがくる。
(SAVE/LOAD時にブロック番号が表示されていないのが 最終ブロック)




ブロック種別

パラメータを設定後、BYTOUTサブルーチン($0031,$F01B,F619)を呼び出すと、拡張子に応じて ファイル種別が設定される。

ブロック種別は プリアンブル(FFの連続)と開始マーク(01)の直後の1バイトで、00(最終),01(固定),10(可変)の3種。この例では 01と00 である。


0040: ff 01 01 07 47 41 4c 41 58 59 2e 42 01 ff 10 00  ....GALAXY.B....
	:
0190: ff ff ff 01 00 07 47 41 4c 41 58 59 2e 42 01 01  ......GALAXY.B..



最終ブロックは種別 $00 のブロックであり、ファイルの終わりを表わす。データは0バイト。LOAD時にブロック番号が表示されないブロックが最終ブロックである。

種別 $01 のブロックは、SAVE時と同じアドレスに読み込まれる。下記の例ではブロックサイズ(ff)とアドレス($1000)がファイル名の後にある。

ブロックサイズが$00のときは、256バイトを表す。


0040: ff 01 01 07 47 41 4c 41 58 59 2e 42 01 ff 10 00  ....GALAXY.B....
0050: b2 ce 01 7f a6 00 81 86 26 06 a7 20 86 20 a7 00  ........&.. . ..



種別 $10 のブロックは、LOAD時にLDTOPで指定したアドレスに読み込まれる。下記の例ではブロックサイズ(fc)とSAVE時に指定したアドレス($0600)がファイル名の後にある。


0040: ff 01 10 01 47 41 4c 41 58 59 2e 53 01 fc 06 00  ....GALAXY.S....
0050: a5 20 20 20 31 30 20 4d 55 53 49 43 20 54 32 50  .   10 MUSIC T2P


ブロック種別の設定

モニタのテープ保存ルーチン(BYTOUT)では、ファイルの拡張子が .B の時はブロック種別 $01、 .S のときは $10 を書き込む。

BやS以外の拡張子を指定すると BYTOUT呼び出し時の AccB の値が書き込まれる。

簡単なプログラムを書いて試してみよう。モニタのサブルーチンを使ってファイル名と保存範囲を指定した後で、拡張子を"A"($41)に、AccBを$02にしてBYTOUTを呼ぶ。

上記のダンプを入力後、G1000 で実行。下記のように拡張子 .A で保存される。

SAVEされた中味を見ても、ちゃんと指定した通り .A と $02 が保存されている。


0000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0040: ff 01 02 00 54 45 53 54 20 20 2e 41 01 13 10 00  ....TEST  .A....
0050: eb bd f6 82 bd f4 cf c6 41 d7 4a c6 02 bd 00 31  ........A.J....1
0060: bd 00 28 3f 49 00 ff ff ff ff ff ff ff ff ff ff  ..(?I...........
0070: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0080: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
0090: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff  ................
00a0: ff ff ff ff ff ff ff 01 00 00 54 45 53 54 20 20  ..........TEST  
00b0: 2e 41 01 01 10 00 ff bd 43 00                    .A......C.


'.’ も変更できる

実は '.’ の部分は読み込み時にチェックされていない。 '.’ 以外に変更しても そのまま読み込まれる。

これを使えば、8文字のファイル名を付けられるが、チェックされるのは先頭の6文字なので混乱するだけかも。



勝手に作ったファイル種別は読めるのか?

上記のファイル TEST.A を読むと、元のアドレス($1000)から読み込まれる。

モニタのBYTINルーチンでは、以下の処理を行なっている。

上の例では種別を$02にしたので 固定ブロックの扱いとなり、保存時のアドレスに読まれたわけだ。

ブロック種別

処理
$00

最終ブロック
$01-$09

固定ブロック
$0A-$7F

可変ブロック
$80-$FF

特殊ブロック



種別が$80-$FFの特殊ブロックの処理は L1/L2のモニタ(V1.1)とL2II/Jrのモニタ(V1.2)で処理が異なっている。

V1.1では $F6D6- のルーチンでブロック種別をチェックし、bit7==1のとき($80-$FF)は $FEED に分岐している。

$FEEDでは何やら複雑な処理をしていて、こちらは まだ解析できていない(ブロック種別$AA,$ABがありそうだが、不明)。

V1.2でも $F6DB- のルーチンから $FEED に分岐するのは同じだが、$FEEDにはサブルーチンが存在しない。MUSIC用のデータで潰されている。

謎である。