//%第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”になる。 {{div_begin style='text-align:center;'}} {{svg 図5.16.svg,,size:500x750}} '''図5.16 キーマトリクス''' {{div_end}} {{div_begin style='text-align:right;'}} '''リスト5.4 キースキャンルーチンの使用法''' {{div_end}} ;============================================================ ; ; 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 SCAN ;----- work area ----- BUF: DS 8 END !!3.3 文字の入力  MSXは、タイマ割り込みにより1/60秒ごとにキーマトリクスをスキャンしており、キーが押されていれば、その文字コードを図5.17のようなリング状のキーボードバッファに格納します。なお、MSXのキー入力は、一般にこのキーボードバッファを読むことによって行っています。 {{div_begin style='text-align:center;'}} {{svg 図5.17.svg,,size:600x380}} '''図5.17 リング状のキーボードバッファ''' {{div_end}}  このキーボードバッファを使用したキー入力およびそれに関連する機能を持った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) {{div_begin style='text-align:center;'}} {{svg 図5.18.svg,,size:480x140}} '''図5.18 ローマ字カナ変換モードの設定''' {{div_end}} '''● KILBUF (0156H/MAIN)'''……………キーボードバッファを空にする '''入力''':--- '''出力''':--- '''機能''':キーボードバッファを空にする。 {{div_begin style='text-align:right;'}} '''リスト5.5 1文字入力ルーチンの使用法''' {{div_end}} ;============================================================ ; ; 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 {{div_begin style='text-align:center;'}} {{svg 図5.19.svg,,size:370x390}} '''図5.19 グラフィック文字のコード変換表''' {{div_end}} '''機能''':入力した文字列をラインバッファ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”にリセットして戻る。このルーチンは、割り込み禁止中でも使用可能。