ベーシックマスターのソフトウェア(4)続々々カセットテープ
カセットテープルーチン(3)の続き。今回も BASICMASTERの300bps カセットルーチンについて調べてみる。
カセットフォーマットの詳細は BASICMASTER/documents/tape_format.md at main · zu2/BASICMASTER を参照のこと。
その他のテープ形式
BASICとモニタ以外でもテープへの保存は使われていた。その形式を見てみよう。
日立アセンブラ
拡張子は “.S"、ブロック種別は $10(可変アドレス)。 ソースコード全体が1つのファイルとして保存される。

ソースプログラム全体をベタ保存している。
可変アドレスなので、保存時と違うアドレスへの読み込みが行える。アセンブラソースの格納アドレスは、(BASICとは異なり)起動時に指定するのでどこになるかわからない。
ソースプログラム途中への読み込みもできるので、これを使って Mコマンド(MERGE,結合)操作を行なっている。
MERGEとなっているが実際の動作は途中から上書きであり、挿入・併合されるわけではない。
(マニュアルでは、Mコマンドは「修正行の次に」カセットの内容を読むと書かれているが、実際には修正行も上書きされる)
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 10 00 20 41 53 4d 20 20 2e 53 01 00 30 00 .... ASM .S..0. 0050: fd 2a 20 50 52 49 4d 45 2d 31 20 4d 41 52 2e 31 .* PRIME-1 MAR.1 0060: 34 2e 31 39 38 30 0d 2a 0d 4e 3d 24 34 30 30 30 4.1980.*.N=$4000 0070: 20 51 3d 31 30 30 30 2a 32 2b 4e 0d 49 3d 32 2c Q=1000*2+N.I=2, 0080: 31 30 30 30 0d 20 20 20 4e 28 49 29 3d 30 0d 5c 1000. N(I)=0.\ 0090: 0d 4b 3d 30 0d 50 3d 32 2c 31 30 30 30 0d 20 20 .K=0.P=2,1000. 00a0: 3b 3d 4e 28 50 29 3c 30 20 23 3d 4c 39 30 3b 0d ;=N(P)<0 #=L90;. 00b0: 20 20 4b 3d 4b 2b 31 0d 20 20 51 28 4b 29 3d 50 K=K+1. Q(K)=P 00c0: 0d 20 20 3b 3d 50 3e 33 31 20 23 3d 4c 39 30 3b . ;=P>31 #=L90; 00d0: 0d 20 20 49 3d 50 0d 20 20 40 0d 20 20 20 20 20 . I=P. @. 00e0: 4e 28 49 29 3d 2d 31 0d 20 20 20 20 20 49 3d 49 N(I)=-1. I=I 00f0: 2b 50 0d 20 20 40 3d 49 3e 31 30 30 30 0d 4c 39 +P. @=I>1000.L9 0100: 30 2e 0d 5c 0d 2a 20 50 52 49 4e 54 20 50 52 49 0..\.* PRINT PRI 0110: 4d 45 53 0d 2f 22 50 52 49 4d 45 53 20 28 55 4e MES./"PRIMES (UN 0120: 44 45 52 20 31 30 30 30 29 3a 22 2f 0d 49 3d 31 DER 1000):"/.I=1 0130: 2c 4b 0d 20 20 3f 28 34 29 3d 51 28 49 29 0d 20 ,K. ?(4)=Q(I). 0140: 20 3b 3d 49 2d 28 28 49 2f 38 29 2a 38 29 3d 30 ;=I-((I/8)*8)=0 0150: 20 69 00 ff ff ff ff ff ff ff ff ff ff ff ff ff i.............. 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 ff 01 10 00 20 41 53 4d 20 20 2e 53 02 ....... ASM .S. 01a0: 12 31 00 e9 2f 20 3b 0d 5c 0d 41 3d 24 0d 3e 3d .1../ ;.\.A=$.>= 01b0: 24 46 30 30 30 0d cf 00 ff ff ff ff ff ff ff ff $F000........... 01c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 01d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 01e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 01f0: ff ff ff ff ff ff ff ff ff 01 00 00 20 41 53 4d ............ ASM 0200: 20 20 2e 53 02 01 30 00 0b 2a d6 00 .S..0..*..
L1 BASIC
同じく、ソースコード全体をベタ保存している。

拡張子は “.S"、ブロック種別は $10(可変アドレス)。 ソースコード全体が1つのファイルとして保存される。
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 10 00 4c 31 54 45 53 54 2e 53 01 00 05 c0 ....L1TEST.S.... 0050: ec 00 c8 0c 20 50 4f 4b 45 20 24 30 41 2c 30 0d .... POKE $0A,0. 0060: 00 c9 0c 20 50 4f 4b 45 20 24 30 42 2c 30 0d 00 ... POKE $0B,0.. 0070: ca 0c 20 50 4f 4b 45 20 24 30 43 2c 30 0d 01 2c .. POKE $0C,0.., 0080: 0e 20 50 52 49 4e 54 22 53 54 41 52 54 22 0d 01 . PRINT"START".. 0090: 90 05 20 4b 3d 30 0d 01 ae 0a 20 44 49 4d 20 4d .. K=0.... DIM M 00a0: 28 35 29 0d 01 f4 07 20 4b 3d 4b 2b 31 0d 01 fe (5).... K=K+1... 00b0: 0d 20 41 3d 4b 2f 32 2a 33 2b 34 2d 35 0d 02 08 . A=K/2*3+4-5... 00c0: 0b 20 47 4f 53 55 42 20 38 32 30 0d 02 12 0e 20 . GOSUB 820.... 00d0: 46 4f 52 20 4c 3d 31 20 54 4f 20 35 0d 02 17 08 FOR L=1 TO 5.... 00e0: 20 4d 28 4c 29 3d 41 0d 02 1c 08 20 4e 45 58 54 M(L)=A.... NEXT 00f0: 20 4c 0d 02 58 14 20 49 46 20 4b 3c 31 30 30 30 L..X. IF K<1000 0100: 20 47 4f 54 4f 20 35 30 30 0d 02 bc 0c 20 50 52 GOTO 500.... PR 0110: 49 4e 54 22 45 4e 44 22 0d 02 ee 29 20 50 52 49 INT"END"...) PRI 0120: 4e 54 20 50 45 45 4b 28 24 30 41 29 2a 32 35 36 NT PEEK($0A)*256 0130: 2b 50 45 45 4b 28 24 30 42 29 2c 50 45 45 4b 28 +PEEK($0B),PEEK( 0140: 24 30 43 29 0d 03 20 05 20 45 4e 44 0d 03 34 08 $0C).. . END..4. 0150: 20 12 00 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 ff 01 10 00 4c 31 54 45 53 54 2e 53 02 .......L1TEST.S. 01a0: 0f 06 c0 db 52 45 54 55 52 4e 0d ff ff 04 45 4e ....RETURN....EN 01b0: 44 0d ff 2e 00 ff ff ff ff ff ff ff ff ff ff ff D............... 01c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 01d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 01e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 01f0: ff ff ff ff ff ff 01 00 00 4c 31 54 45 53 54 2e .........L1TEST. 0200: 53 02 01 05 c0 fa 00 00 00 S........
そもそも カセットの保存機能そのものが L1 BASICのために作られたと思われるので、素直に実装されている。
GAME-BM
GAME言語のBASICMASTER移植版。 [=0 で独自モニタに飛び、そこでSAVEする。

こちらも 拡張子は “.S"、ブロック種別は $10(可変アドレス)。 ソースコード全体が1つのファイルとして保存される。
読み込むソースプログラムの位置を変更したい場合は、事前に == でアドレスを指定すれば良い。LOADの際は =(開始ポインタ) で指定したアドレスに読まれる。
00000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000040: ff 01 10 00 47 41 4d 45 20 20 2e 53 01 00 1a 00 ....GAME .S.... 00000050: fa 00 c8 20 56 3d 24 30 41 20 56 28 30 29 3d 30 ... V=$0A V(0)=0 00000060: 20 56 3a 32 29 3d 30 20 56 28 30 29 3d 30 00 01 V:2)=0 V(0)=0.. 00000070: 2c 20 22 53 54 41 52 54 22 00 01 90 20 4b 3d 30 , "START"... K=0 00000080: 00 01 ae 20 4d 3d 26 00 01 f4 20 4b 3d 4b 2b 31 ... M=&... K=K+1 00000090: 00 01 fe 20 41 3d 4b 2f 32 2a 33 2b 34 2d 35 00 ... A=K/2*3+4-5. 000000a0: 02 08 20 21 3d 38 32 30 00 02 12 20 4c 3d 31 2c .. !=820... L=1, 000000b0: 35 00 02 15 20 4d 28 4c 29 3d 30 00 02 17 20 40 5... M(L)=0... @ 000000c0: 3d 4c 2b 31 00 02 1c 20 3b 3d 4b 3c 31 30 30 30 =L+1... ;=K<1000 000000d0: 20 23 3d 35 30 30 00 02 bc 20 22 45 4e 44 22 00 #=500... "END". 000000e0: 02 c6 20 57 3d 56 28 30 29 20 58 3d 56 3a 32 29 .. W=V(0) X=V:2) 000000f0: 20 2f 20 22 54 49 4d 45 3d 22 20 3f 3d 57 20 22 / "TIME=" ?=W " 00000100: 2e 22 20 3f 28 32 29 3d 28 58 2a 31 30 30 29 2f ." ?(2)=(X*100)/ 00000110: 36 30 00 03 20 20 23 3d 2d 31 00 03 34 20 5d 00 60.. #=-1..4 ]. 00000120: 03 e5 2a 00 03 e6 2a 20 47 41 4d 45 2d 42 4d 20 ..*...* GAME-BM 00000130: 54 45 53 54 20 50 52 4f 47 52 41 4d 00 03 e7 2a TEST PROGRAM...* 00000140: 20 4b 49 4c 4f 42 41 55 44 2f 41 53 43 49 49 20 KILOBAUD/ASCII 00000150: 42 05 00 ff ff ff ff ff ff ff ff ff ff ff ff ff B............... 00000160: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000170: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000190: ff ff ff ff 01 10 00 47 41 4d 45 20 20 2e 53 02 .......GAME .S. 000001a0: 09 1b 00 ef 45 4e 43 48 4d 41 52 4b 00 b7 00 ff ....ENCHMARK.... 000001b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 000001c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 000001d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 000001e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 000001f0: 01 00 00 47 41 4d 45 20 20 2e 53 02 01 1a 00 08 ...GAME .S..... 00000200: 00 00 00 ...
GAME68/BM
GAME言語のもう一つの移植版。
LOAD/SAVEは L2 BASICと同様にテキスト形式になっている。

ソースコードがそのまま保存されているので、テープからプログラムを抜き出すのが簡単。MERGE(APPEND)も行えるのが利点。
GAME-MBのテープ形式では行番号が見えないし、行末は$00である。GAME68/BMは行番号が見えて、行末は$0D。
GAME-MBと非互換にするメリットがあるかどうか。互換バージョンがあった方が良いのかな?
(多くの人は emulator上で操作しているだろうから、そもそもSAVE操作なんかしていないのかも)
00000000: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000010: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000020: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000030: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000040: ff 01 10 01 47 41 4d 45 36 38 2e 53 01 00 08 00 ....GAME68.S.... 00000050: dd 32 30 30 20 56 3d 24 30 41 20 56 28 30 29 3d .200 V=$0A V(0)= 00000060: 30 20 56 3a 32 29 3d 30 20 56 28 30 29 3d 30 0d 0 V:2)=0 V(0)=0. 00000070: 33 30 30 20 22 53 54 41 52 54 22 0d 34 30 30 20 300 "START".400 00000080: 4b 3d 30 0d 34 33 30 20 4d 3d 26 0d 35 30 30 20 K=0.430 M=&.500 00000090: 4b 3d 4b 2b 31 0d 35 31 30 20 41 3d 4b 2f 32 2a K=K+1.510 A=K/2* 000000a0: 33 2b 34 2d 35 0d 35 32 30 20 21 3d 38 32 30 0d 3+4-5.520 !=820. 000000b0: 35 33 30 20 4c 3d 31 2c 35 0d 35 33 33 20 4d 28 530 L=1,5.533 M( 000000c0: 4c 29 3d 30 0d 35 33 35 20 40 3d 4c 2b 31 0d 35 L)=0.535 @=L+1.5 000000d0: 34 30 20 3b 3d 4b 3c 31 30 30 30 20 23 3d 35 30 40 ;=K<1000 #=50 000000e0: 30 0d 37 30 30 20 22 45 4e 44 22 0d 37 31 30 20 0.700 "END".710 000000f0: 57 3d 56 28 30 29 20 58 3d 56 3a 32 29 20 2f 20 W=V(0) X=V:2) / 00000100: 22 54 49 4d 45 3d 22 20 3f 3d 57 20 22 2e 22 20 "TIME=" ?=W "." 00000110: 3f 28 32 29 3d 28 58 2a 31 30 30 29 2f 36 30 0d ?(2)=(X*100)/60. 00000120: 38 30 30 20 23 3d 2d 31 0d 38 32 30 20 5d 0d 39 800 #=-1.820 ].9 00000130: 39 37 2a 0d 39 39 38 2a 20 47 41 4d 45 2d 42 4d 97*.998* GAME-BM 00000140: 20 54 45 53 54 20 50 52 4f 47 52 41 4d 0d 39 39 TEST PROGRAM.99 00000150: 39 0d 00 ff ff ff ff ff ff ff ff ff ff ff ff ff 9............... 00000160: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000170: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000180: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000190: ff ff ff ff 01 00 01 47 41 4d 45 36 38 2e 53 01 .......GAME68.S. 000001a0: 01 08 00 ec 32 ce 00 ff ff ff ff ff ff ff ff ff ....2........... 000001b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 000001c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 000001d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 000001e0: ff ff ff ff ff ff ff ff 01 10 02 47 41 4d 45 36 ...........GAME6 000001f0: 38 2e 53 01 12 08 00 ca 2a 20 4b 49 4c 4f 42 41 8.S.....* KILOBA 00000200: 55 44 2f 41 53 43 49 49 0d 00 c6 00 ff ff ff ff UD/ASCII........ 00000210: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000220: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000230: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................ 00000240: ff ff ff ff ff ff ff ff ff ff ff ff ff 01 00 02 ................ 00000250: 47 41 4d 45 36 38 2e 53 01 01 08 00 eb 2a d6 00 GAME68.S.....*..
余談
BASICMASTERに先行する 日立のワンボードマイコン「H68/TR」にもカセットインターフェイスがあった。
保存形式についての簡単な解説が、「H68/TR+TV01 オート・スタートのテープを作ろう」I/O誌1978年6月号 pp.132-133 に掲載されている。
この記事によると、H68/TRのテープ形式は以下の通り。
- 680個の$FF
- ブロック種別 'B', データ長1バイト, データ先頭アドレス2バイト、データ実体、レコード間GAP 25個の$FF
- 複数ブロックがある場合は、'B' から GAP を繰り返す
- ブロック種別 'G', フィーダー $FF (任意個)
BASICMASTERのヘッダ部分(ファイル名やブロック種別、チェックサム)に相当する部分は存在しない。
このI/O誌の記事ではオートスタートを実現するために、PIAのコントロールレジスタを叩いている(当該アドレスをブロックとしてSAVEする)。
これによりNMIがかかるので、あらかじめ先導ブロックでNMIの飛び先を設定する。実に豪快である。





ディスカッション
コメント一覧
まだ、コメントがありません