にゃごすwiki

techhan/5.3

%第1版第15刷 P.283-292


3章 キーボード・インターフェイス


 MSX2のキーボードはMSX1と同じ構造をしていますが、カナの入力時にローマ字カナ変換方式が使えるようになり、機能的にはたいへん便利になりました。本章ではMSX2のキーボード・インターフェイスについて説明しましょう。
 なお、キーの配列などについては日本仕様のキーボードをもとに説明しますが、海外仕様のMSXではデータが少し異なる部分もあります。

 3.1 キー配列


 MSXのキーボードの配列は、英数字はJIS標準配列を採用しており、カナはJIS標準配列と五十音順配列をジャンパ線により切り換えています。ただし、このジャンパ線による設定はシステム起動時にどちらの配列を選ぶか決めているだけであり、ワークエリアKANAMDの値で任意に変更可能です。

● KANAMD (FCADH, 1)………キー配列 (0=五十音配列, 0以外=JIS配列)

 3.2 キースキャン


 MSXは図5.16のようなキーマトリクスを持っています。このキーマトリクスを調べることによって、キーの押されている状況をリアルタイムに得ることが可能であり、ゲームなどの入力に使用できます。
 キーマトリクスのスキャンは、次のBIOSルーチンを用いて行います。

● SNSMAT (0141H,MAIN)……………キーマトリクスの指定行の読み出し
入力:A←読み出すキーマトリクスの行 (0〜10)
出力:A←指定したキーマトリクスの行の状態(押されているキーのビットが0になる)
機能:図5.16のようにキーマトリクスの1行を指定し、その状態をAレジスタに返す。この時、押されているキーに対応するビットが“0”、押されていないキーに対応するビットは“1”になる。


図5.16 キーマトリクス


リスト5.4 キースキャンルーチンの使用法

;============================================================
;
;  List 5.4   scan key-matrix and display it
;
;============================================================
;
CHPUT	EQU	00A2H
BREAKX	EQU	00B7H
POSIT	EQU	00C6H
SNSMAT	EQU	0141H

	ORG	0B000H

;----- program start -----		キーマトリクスを読んでそのビットパターンを表示する

SCAN:	LD	C,0		;C := line of key matrix

SC1:	LD	A,C
	CALL	SNSMAT		;Read key matrix

	LD	B,8
	LD	HL,BUF		;HL := buffer address
SC2:	LD	D,'.'
	RLA			;Check bit
	JR	C,SC3
	LD	D,'#'
SC3:	LD	(HL),D		;store '.' or '#' to buffer
	INC	HL
	DJNZ	SC2

	LD	H,05H		;x := 5
	LD	L,C		;y := C+1
	INC	L
	CALL	POSIT		;set cursor position

	LD	B,8		;put out bit patterns to CRT
	LD	HL,BUF
SC4:	LD	A,(HL)
	CALL	CHPUT
	INC	HL
	DJNZ	SC4

	CALL	BREAKX		;check Ctrl-STOP
	RET	C

	INC	C		;line No. increment
	LD	A,C
	CP	09
	JR	NZ,SC1
	JR	START

;----- work area -----

BUF:	DS	8

	END

 3.3 文字の入力


 MSXは、タイマ割り込みにより1/60秒ごとにキーマトリクスをスキャンしており、キーが押されていれば、その文字コードを図5.17のようなリング状のキーボードバッファに格納します。なお、MSXのキー入力は、一般にこのキーボードバッファを読むことによって行っています。


図5.17 リング状のキーボードバッファ


 このキーボードバッファを使用したキー入力およびそれに関連する機能を持ったBIOSを以下に示します。タイマ割り込みを禁止すると、当然これらは使用できなくなります。

● CHSNS (009CH/MAIN)……………キーボードバッファの残りのチェック
入力:---
出力:バッファが空なら、Zフラグ=ON
機能:キーボードバッファに文字が残っているかどうかを調べる。キーボードバッファが空であればZフラグを立てる。

● CHGET (009FH/MAIN)……………キーボードバッファから1文字入力
入力:---
出力:A←文字コード
機能:キーボードバッファから1文字読み出してAレジスタに格納する。バッファに文字が入っていない場合には、カーソルを表示してキー入力があるまで待つ。キー入力待ちの間、CAPロック、カナロック、ローマ字カナ変換ロックも有効である。関係のあるワークエリアは以下に示すとおりである。このうち、SCNCNTとREPCNTはCHGETルーチン実行後に初期化されてしまうので、オートリピートの時間間隔を変えるためにはCHGETコールのたびにこのワークを設定する必要がある。

ワークエリア

CLIKSW	(F3DBH,1)	キークリック音 (0=OFF, 0以外=ON)
SCNCNT	(F3F6H,1)	キースキャンの時間間隔 (通常は1)
REPCNT	(F3F7H,1)	オートリピート開始までの時間 (通常は50)
MODE	(FAFCH,1)	ローマ字カナ変換のモード (図5.18参照)
CSTYLE	(FCAAH,1)	カーソルの形 (0=■, 0以外=_)
CAPST	(FCABH,1)	CAPSロック (0=OFF, 0以外=ON)
KANAST	(FCACH,1)	カナロック (0=OFF, 0以外=ON)


図5.18 ローマ字カナ変換モードの設定


● KILBUF (0156H/MAIN)……………キーボードバッファを空にする
入力:---
出力:---
機能:キーボードバッファを空にする。

リスト5.5 1文字入力ルーチンの使用法

;============================================================
;
;   List 5.5    get key code
;
;               this routine dosen't wait key hit
;
;============================================================
;
CHSNS	EQU	009CH		;check keyboard buffer
CHGET	EQU	009FH		;get a character from buffer
CHPUT	EQU	00A2H		;put a character to screen
BREAKX	EQU	00B7H		;check Ctrl-STOP
KILBUF	EQU	0156H		;clear keyboard buffer
REPCNT	EQU	0F3F7H		;time interval until key-repeat
KEYBUF	EQU	0FBF0H		;keyboard buffer address

	ORG	0B000H

;----- program start -----	CHGETを使ったリアルタイムキー入力

KEY:	CALL	CHSNS		;check kerboard buffer
	JR	C,KEY1

	LD	A,1
	LD	(PEPCNT),1	;not to wait until repeat
	CALL	CHGET		;get a character (if exists)
	JR	KEY2

KEY1:	LD	A,'-'		;A := '-'

KEY2:	CALL	CHPUT		;put the character
	CALL	KILBUF		;clear keyboard buffer
	CALL	BREAKX		;check Ctrl-STOP
	JR	NC,KEY

	END

● CNVCHR (00ABH/MAIN)…………グラフィック文字の処理
入力:A←文字コード
出力:A←グラフィック文字は変換される (通常文字ならば変換されない)
   CYフラグ=OFF (入力はグラフィックヘッダバイト01Hだった)
   CYフラグ=ON, Zフラグ=ON (入力はグラフィック文字なので変換された)
   CYフラグ=ON, Zフラグ=OFF (入力は通常の文字なので変換されなかった)
機能:CHGETの後にこのCNVCHRを実行すると、グラフィック文字は図5.19のような1バイトコードに変換し、グラフィック文字以外は無変換でそのまま返す。グラフィック文字はグラフィックヘッダバイト(01H)を伴う2バイトの変則的なコードで表されるため文字処理の時にめんどうな手続きが必要だが、このルーチンによって多少は手間が省ける。

● PINLIN (00AEH/MAIN)……………1行入力
入力:---
出力:HL←F55EH
   [F55EH]←入力した文字列 (行末は00Hで示される)
   CYフラグ←STOPで終了した場合=ON, RETURNで終了した場合=OFF


図5.19 グラフィック文字のコード変換表


機能:入力した文字列をラインバッファBUF(F55EH)に格納する。文字列の入力時にはスクリーンエディットのすべての機能が有効である。RETURNキーまたはSTOPキーを押すと入力動作を終了する。なお、ワークエリアは以下に示すとおりである。

ワークエリア

BUF	(F55EH, 258)	文字列が格納されるラインバッファ
LINTTB	(FBB2H, 24)	物理的1行が、上の行の機能であれば00H

● INLINE (00B1H/MAIN)……………1行入力 (プロンプト使用可)
入力:---
出力:PINLINと同じ
機能:PINLINルーチンと同様に、入力した文字列をラインバッファBUF(F55EH)に格納する。ただし、こちらはルーチン実行開始時のカーソル位置より前の部分は入力されない。両者の違いをリスト5.6に示す。

;============================================================
;
;  List 5.6   INLIN and PINLIN
;
;============================================================
;
CHPUT	EQU	00A2H
INLIN	EQU	00B1H
PINLIN	EQU	00AEH
KILBUF	EQU	0156H

BUF	EQU	0F55EH

	ORG	0B000H

;----- program start -----

	LD	HL,PRMPT1
	CALL	PUTMSG		;pur prompt message
	CALL	INLIN		;use INLIN routine
	LD	HL,BUF
	CALL	PUTMSG

	LD	HL,PRMPT2
	CALL	PUTMSG		;put prompt message
	CALL	PINLIN		;use PINLIN routine
	LD	HL,BUF
	CALL	PUTMSG

	RET

;----- put a string -----

PUTMSG:	LD	A,(HL)
	CP	'$'
	RET	Z
	CALL	CHPUT
	INC	HL
	JR	PUTMSG

;----- string data -----

PRMPT1:	DB	0DH,0AH,'INLIN:$'
RPMPT2:	DB	0DH,0AH,'PINLIN:$'

	END

 3.4 ファンクションキー


 MSXには10個のファンクションキーが存在し、ユーザーが自由に定義して使うことができます。ファンクションキーの定義を行うために、ワークエリアが各キーについて16バイトずつ割り当てられています。そのアドレスを以下に示します。

FNKSTR	(F87FH,16)	F・1キーの定義用領域
+10H	(F88FH,16)	F・2キーの定義用領域
+20H	(F89FH,16)	F・3キーの定義用領域
+30H	(F8AFH,16)	F・4キーの定義用領域
+40H	(F8BFH,16)	F・5キーの定義用領域
+50H	(F8CFH,16)	F・6キーの定義用領域
+60H	(F8DFH,16)	F・7キーの定義用領域
+70H	(F8EFH,16)	F・8キーの定義用領域
+80H	(F8FFH,16)	F・9キーの定義用領域
+90H	(F90FH,16)	F・10キーの定義用領域

 1つのファンクションキーを押すと、それぞれの領域に定義された文字列が[KEYBUF]に格納されます。文字列の最後は00Hで示され、最大15文字まで定義可能です(16文字を超えた分は、複数のファンションキー定義領域にまたがって定義される)。ファンクションキーを初期設定の状態に戻すには、次のBIOSルーチンを利用するとよいでしょう。

● INIFNK (003EH/MAIN)……ファンクションキーの初期化
入力:---
出力:---
機能:ファンクションキーの定義をBASICスタート時の設定に戻す。

 3.5 割り込み中のSTOPキー


 3.3で説明した1文字入力ルーチンCHGETは、どのキーが押されているかの判断をタイマ割り込みの処理ルーチン内で行っています。したがって、たとえばカセットデータの入出力時などタイマ割り込みが禁止されている状態では、どんなキーが押されていても読み取ることができません。しかし、次に述べるBIOSルーチンを使用すると、割り込みが禁止されている場合でも、CTRLキー+STOPキーが押されていることを判定できます。

● BREAKX (00B7H/MAIN)……………CTRL+STOPの判定
入力:---
出力:CTRL+STOPが押されていれば、CYフラグ=ON
   キースキャンを行い、CTRLキーとSTOPキーが同時に押されているか否かを判定する。もし両キーが押されていれば、CYフラグを“1”にセットして戻る。CTRL+STOPが押されていなければ、CYフラグを“0”にリセットして戻る。このルーチンは、割り込み禁止中でも使用可能。