テクハンwiki

2章 カセット・インターフェイスの変更点

  • 追加された行はこのように表示されます。
  • 削除された行はこのように表示されます。
,{c H},{BGCOLOR:FFFFFF|BOLD|CENTER}
,{c C},{CENTER}
,{c L},{LEFT}
// 第1版第15刷 P.275-282
// !!!2章 カセット・インターフェイス
 カセットテープレコーダは、MSXの最も安価な外部記憶装置です。このカセットテープ上の情報をマシン語中で取り扱うためには、カセット・インターフェイスの使用法を知らなくてはなりません。本章では、このために必要となる情報を説明します。

!!2.1 ボーレート

 MSXのカセット・インターフェイスは以下の2種類のボーレートを使用できます(表5.2)。なお、BASICのスタート時にはデフォルトで1200ボーが設定されています。

,{t},{CENTER}
,{c},{H},{H}
,ボーレート,特徴
,{c},{C},{L}
,1200ボー,低スピード/高信頼性
,2400ボー,高スピード/低信頼性
{{div_begin style='text-align:center;'}}
'''表5.2 MSXのボーレート'''
{{div_end}}

 ボーレートの指定は、SCREEN命令の第4パラメータまたはCSAVE命令の第2パラメータで行います。一度指定すると以後そのボーレートが引き続いて使用されます。

 SCREEN   ,,,<ボーレート>
 CSAVE    "ファイル名",<ボーレート>
 (<ボーレート>は両者とも、1で1200ボー、2で2400ボー)

!!2.2 1ビットの構成

 入出力の基本となる1ビットのデータは図5.11のように記録されます。パルスの幅はCPUのT-STATEをカウントして決められるため、カセット・インターフェイス作動中はすべての割り込みが禁止されています。
 なお、カセットから入力されるビットデータは、汎用入出力インターフェイスのポートB(PSGのレジスタ#14)の第7ビットを通して読み取ることが可能です。第5部1章リスト5.2のプログラム例の中で、この機能を使用していますので、参照してください。
{{div_begin style='text-align:center;'}}
{{svg 図5.11.svg,,size:530x450}}
'''図5.11 1ビットの構成'''
{{div_end}}

!!2.3 1バイトの構成

 1バイトのデータは図5.12のようなビット列で記録されます。スタートビットとして“0”のビットがひとつ、次にデータ本体が最下位ビットから最上位ビットの順で8ビット、最後にストップビットとして“1”のビットが2つ続き、合計11ビットを使用します。
{{div_begin style='text-align:center;'}}
{{svg 図5.12.svg,,size:560x100}}
'''図5.12 1バイトの構成'''
{{div_end}}

!!2.4 ヘッダの構成

 ヘッダとはセーブまたはロード時に、カセットテープが動き出してから回転が安定するまでの時間待ちや、ファイル間に区切りをつけるために、ある特定の周波数の信号を一定時間テープに記録させた部分のことです。ロングヘッダとショートヘッダの2種類があり、ロングヘッダはモータの回転が安定するまでの時間待ちに使用されます。また、テープリード時のボーレートは、ロングヘッダを読んで決定されます。ショートヘッダはファイルボディ間の区切りに使用されます。

,{t},{CENTER}
,{c},{H},{H},{H}
,ボーレート,ヘッダの種類,ヘッダの構成
,{c},{C},{L},{L}
,1200bps{ROWS 2},ロングヘッダ,2400Hz×16000波(約6.7秒)
,,ショートヘッダ,2400Hz×4000波(約1.7秒)
,2400bps{ROWS 2},ロングヘッダ,2400Hz×32000波(約6.7秒)
,,ショートヘッダ,2400Hz×8000波(約1.7秒)
{{div_begin style='text-align:center;'}}
'''表5.3 ヘッダの構成'''
{{div_end}}

!!2.5 ファイルのフォーマット

 MSXのBASICは次の3タイプのカセットフォーマットのファイルをサポートしています。

'''(1)BASICテキストファイル'''

 CSAVE命令でバイナリセーブしたBASICプログラムは、このフォーマットにしたがって記録されます。なお、ファイルは前半のファイルヘッダと後半のファイルボディに分けられます。
{{div_begin style='text-align:center;'}}
{{svg 図5.13.svg,,size:690x300}}
'''図5.13 バイナリファイルのフォーマット'''
{{div_end}}

 ファイルヘッダは、ロングヘッダの後にOD3Hという値が10バイト続き、その後に6バイトのファイル名が置かれます。ファイルボディはショートヘッダの後にプログラム本体が続き、7バイトの00Hでファイルエンドを示します。
 ファイルヘッダは、ロングヘッダの後に0D3Hという値が10バイト続き、その後に6バイトのファイル名が置かれます。ファイルボディはショートヘッダの後にプログラム本体が続き、7バイトの00Hでファイルエンドを示します。

'''(2)ASCIIテキストファイル'''

 SAVE命令でアスキーセーブされたBASICプログラム、およびOPEN命令によって作られたデータファイルは、このフォーマットにしたがって記録されます。
 ファイルヘッダは、ロングヘッダの後に0EAHという値が10バイト続き、その後に6バイトのファイル名が置かれます。
 データ本体は256バイトごとのブロックに分けられ、それぞれのブロックの前にはショートヘッダが置かれます。ファイルエンドはCtrl-Z(1AH)で示されます。このため、1AHという値を含むデータファイルを作ることはできません。
{{div_begin style='text-align:center;'}}
{{svg 図5.14.svg,,size:690x400}}
'''図5.14 アスキーファイルのフォーマット'''
{{div_end}}

'''(3)マシン語ファイル'''

 BSAVE命令でセーブされたマシン語ファイルは、このフォーマットにしたがって記録されます。ファイルヘッダは、ロングヘッダの後に0D0Hという値が10バイト続き、その後ろに6バイトのファイル名が置かれます。
 ファイルボディは、ショートヘッダの後に、先頭アドレス、最終アドレス、実行開始アドレスの順に3つのアドレスが記録され、その次にマシン語本体が続きます。データの量は先頭アドレスと最終アドレスから計算できますから、特別なファイルエンドマークはありません。実行開始アドレスとは、BLOAD命令のRオプション使用時に、プログラムが実行されるアドレスです。
{{div_begin style='text-align:center;'}}
{{svg 図5.15.svg,,size:690x300}}
'''図5.15 マシン語ファイルのフォーマット'''
{{div_end}}

!!2.6 カセットファイルのアクセス

 カセットファイルをアクセスするために、以下のBIOSルーチンが用意されています。

'''● TAPION (OOE1H/MAIN)'''……………読み込みOPEN
'''入力''':---
'''出力''':異常終了時CYフラグ=ON
'''機能''':テープレコーダのモータを起動し、ロングヘッダまたはショートヘッダを読み込む。同時にそのファイルが記録されたボーレートを判別し、ワークエリアをそれに合わせて設定する。なお、割り込みは禁止される。

'''● TAPIN (00E4H/MAIN)'''……………1バイトの読み込み
'''入力''':---
'''出力''':A←読み込んだデータ
   異常終了時CYフラグ=ON
'''機能''':テープからデータを1バイト読み込み、Aレジスタに格納する。

'''● TAPIOF (00E7H/MAIN)'''……………読み込みCLOSE
'''入力''':---
'''出力''':---
'''機能''':テープからの読み込み動作を終了する。同時に割り込みは再開される。

'''● TAPOON (00EAH/MAIN)'''……………書き出しOPEN
'''入力''':A←ヘッダの種類(0=ショートヘッダ, 0以外=ロングヘッダ)
'''出力''':異常終了時CYフラグ=ON
'''機能''':デープレコーダのモータを起動し、Aレジスタで指定された種類のヘッダをテープに書き出す。なお、割り込みは禁止される。


'''● TAPOUT (00EDH/MAIN)'''……………1バイトの書き出し
'''入力''':A←書き込みデータ
'''出力''':異常終了時CYフラグ=ON
'''機能''':Aレジスタの内容をテープに書き込む。

'''● TAPOOF (00F0H/MAIN)'''……………書き込みCLOSE
'''入力''':---
'''出力''':---
'''機能''':テープへの書き込み動作を終了する。同時に割り込みは再開される。

'''● STMOTR (00F3H/MAIN)'''……………モータの動作指定
'''入力''':A←動作の指定(0=停止, 1=起動, 255=現在と反対の状態にする)
'''出力''':---
'''機能''':Aレジスタで指定した値にしたがって、モータの動作状態を設定する。

 これらのBIOSを使用してカセットファイルのREAD/WRITEルーチンを作成する際に、なるべく無駄な動作をせずに、ただひたすらREADまたはWRITEのみに専念するようにしてください。たとえば、テープからデータを読み込みながらそのデータをCRTに表示させたりすると、READエラーを生じることがあります。
 リスト5.3にBIOSルーチンを使用したサンプルプログラムを示します。

{{div_begin style='text-align:right;'}}
'''リスト5.3 カセットにセーブされたファイル名の表示'''
{{div_end}}
 ;============================================================
 ;
 ;  List 5.3      Cassette files
 ;
 ;       Set cassette tape into recorder and run this program.
 ;       Then the all names and atributes of the programs
 ;       in that tape are listed out.
 ;
 ;============================================================
 ;
 CHPUT	EQU	00A2H
 TAPION	EQU	00E1H
 TAPIN	EQU	00E4H
 TAPIOF	EQU	00E7H
 
 	ORG	0C000H
 
 ;----- program start -----		カセットテープ内のプログラム名一覧を表示する
 
 START:	CALL	TAPION			;motor on and read header
 
 	LD	B,16
 	LD	HL,WORK			;work area address
 LBL01:	PUSH	HL
 	PUSH	BC
 	CALL	TAPIN			;read a byte of data from tape
 	POP	BC
 	POP	HL
 	JR	C,ERROR			;set carry flag if read error
 	LD	(HL),A
 	INC	HL
 	DJNZ	LBL01
 
 	LD	HL,FILNAM		;write file name
 	CALL	PUTSTR
 	LD	HL,WORK+10
 	CALL	PUTSTR
 	CALL	CRLF
 
 	LD	A,(WORK)		;check file attributes
 
 	LD	HL,BINFIL
 	CP	0D3H			;check binary file
 	JR	Z,LBL03
 
 	LD	HL,ASCFIL
 	CP	0EAH			;check ascii file
 	JR	Z,LBL03
 
 	LD	HL,MACFIL
 	CP	0D0H			;check machine code file
 	JR	Z,LBL03
 
 ERROR:	LD	HL,ERRSTR
 
 LBL03:	CALL	PUTSTR
 	CALL	TAPIOF
 	RET
 
 ;----- put CRLF -----
 
 CRLF:	LD	HL,STCRLF
 	CALL	PUTSTR
 	RET
 
 ;----- put string -----
 
 PUTSTR:	LD	A,(HL)			;get a character from strings
 	CP	'$'			;check end of strings
 	RET	Z
 	CALL	CHPUT			;write a character to CRT
 	INC	HL
 	JR	PUTSTR
 
 ;----- strings data -----
 
 FILNAM:	DB	'FILE NAME :$'
 ASCFIL:	DB	'ASCII FILE',0DH,0AH,'$'
 BINFIL:	DB	'BINARY FILE',0DH,0AH,'$'
 MACFIL:	DB	'BSAVE FILE',0DH,0AH,'$'
 ERRSTR:	DB	'TAPE READ ERROR',0DH,0AH,'$'
 STCRLF	DB	ODH,0AH,'$'
 STCRLF:	DB	0DH,0AH,'$'
 
 ;----- WORK AREA -----
 
 WORK:	DS	16,0
 	DB	'$'			;end of strings
 
 	END