- ベストアンサー
キーバッフアクリア:効果的なキーボードバッファクリアの方法
- キーバッフアクリアの方法に関する質問です。P.Nortonの書籍には、キーボードバッファをクリアするためのルーチンが掲載されていますが、問題があるようです。
- 現在のルーチンでは、キー入力があるまでプログラムがフリーズしてしまうため、キーボードバッファを正しくクリアできません。
- 正しいキーボードバッファクリアの方法を教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
BIOSの戻り値判定は、やはりバッファ空でZフラグが立つ仕様のようです。 http://arl.wustl.edu/~lockwood/class/cse306-s04/books/artofasm/Chapter_13/CH13-3.html >なお、このプログラムはコマンドプロンプトで実行しています。 可能なら、フロッピーから起動した状態で、または Windows95かWindows98で実行してみてください。 コマンドプロンプトということは、OSはWindowsNT系なので キーボード入力はOSに横取りされている可能性があります。
その他の回答 (4)
- Hayashi_Trek
- ベストアンサー率44% (366/818)
BIOSのコードを解析したことは無いが、 メモリマップの説明からキーボードバッファは リングバッファ形式で使用されていると推測される。 従って、読み出されたキーコードがバッファ上から削除されたりはしません。 バッファが一回りしたら新しいキーコードで上書きされるが、 それまでは古いキーコードが残っていることになる。 1985年当時と1993年当時でBIOSの仕様が変わったとも思えないので Nortonの例は、ミスプリントと思われます。 ところで、このプログラムはMS-DOS上で動かしているのでしょうか? Windows上で動かした場合、Windowsが勝手にキーボード入力を取り込んでいる可能性があります。 Windowsは取り込んだキーボード入力を、フォーカスが有るタスクに振り分けます。
お礼
Hayashi_Trek 様 ご回答有り難うございました。 Nortonの本には、二カ所にわたり同じ内容のプログラムが Basic と Asm の両方で与えてあるので、とてもミスプリントとは思えないのですが、このルーチンを含むプログラム(turbo pascal)を走らせると、このルーチンのところで(暴走して)抜けられなくなってしまいます。私自身は、昔のマシンと今のとで、どこかが違ってきているのではないかと思い始めています。JNE を JE に変えると、暴走はしませんが全体のプログラムの始め(keybuffer を flush した上で文字入力を求める)部分が実行されなくなってしまいます。(前にも書いたように PC9801 では簡単に実行させられた部分です。) なお、このプログラムはコマンドプロンプトで実行しています。
- Hayashi_Trek
- ベストアンサー率44% (366/818)
BIOSのメモリマップによると キーボードバッファの使用状況は 40:1A キーボードバッファ先頭ポインタ(Buffer_Head) 40:1C キーボードバッファ末尾ポインタ(Buffer_Tail) 40:1E キーボードバッファ となっていて、Buffer_Head=Buffer_Tailならバッファは空です。 この部分も確認済みでしょうか? なお、この回答は 『プログラマーズPCソースブック』 著者:トム ホーガン 発行:株式会社インプレス 初版:1993年7月21日 を見ながら書いてます。
お礼
Hayashi_Trek 様 度々のご回答有り難うございます。AH,00 の直後で 40:1A, 40:1C と 40:1E 以下を見ますと、確かに Buffer_Head=Buffer_Tail となっている(つまり、見るために最後に RET を押したので Head=Tail となった)のですが この状態で、40:1E 以下には character が入っています。(質問 1: Buffer clear の状態とは、ここに 00 が並んだ状態と考えるのは間違いでしょうか。) もし、そのあとで INT 22 を実行したとき、それが Buf_Head=Buf_Tail に対応して入力待ちになるのなら、最初の質問に書いた(Norton の)ルーチンに対応する反応は分かるのですが、私の疑問は、なぜ、そこで入力待ちなどにはならず、ルーチン通り AH,01 INT 22 へと進んで、JNE でジャンプして抜けてから入力待ちにならないのかと言うことです。(質問 2: やっぱり Norton の buffer-flush のルーチンは正しくなく、JNE を JE とすべきなのでしょうか。) 私の目的は「バッファをクリヤし、その状態で数文字を入力し、(Ret を押すとHead=Tailとなるから) RETを押さないで Buf_Head と Buf_Tail が入力文字数を反映した違いを示すような状態を実現したい」ということです。PC9801 のときは、keyboard-interface 初期化の INT 18H がありましたので、これは簡単でした。
- Hayashi_Trek
- ベストアンサー率44% (366/818)
いきなり RETURN に飛ぶと何が困るのでしょうか? このルーチンは、 キーバッファをチェックして 空になるまでキーバッファを読みます。 もし最初からキーバッファが空なら 何もせずに戻ります。
お礼
Hayashi_Trek 様 キーバッファが空でないことを確かめてある(0000:041E)のに 抜けるので困ります。 yst80
- Hayashi_Trek
- ベストアンサー率44% (366/818)
MOV AH, 1 INT 22 は、キーボードバッファに文字が無いときは Zフラグがセットされるので WHILE: JNZ RETURN を WHILE: JZ RETURN に修正。
お礼
Hayashi_Trek 様 ご回答有り難うございました。 早速試してみましたが、JNE RETURN を JE RETURN に変えたところ こんどは MOV AH,1 INT 22 の後、MOV AH,0 には進まず、いきなり RETURN に飛んで終了してしまいます。 ということでこれも困ります。
お礼
Hayashi_Trek 様 ご回答有り難うございました。 Hyde の本は私も参照しました。私の理解では AH,01 INT 16H 実行のの結果は、buffer に文字があれば ZF=0, これ以上受け入れられなければ(Norton は no input is ready と書いています) ZF=1 ということでしたが、Hyde の例では逆のようにも見えますね。もう少し考えて見ます。 フロッピーから起動することは試して見ます。Windows95 や 98 は利用出来る PC が身近にないものですから。