始めに
ポケコンの、BASIC には INKEY$ があるのに、C言語には、getch() と kbhit() しかないんじゃ? というわけで、第一回のC言語 講座は、キー入力を扱うことにします。
其の壱
まず、getch() と kbhit() を組み合わせて、
int inkey()
{
if(kbhit())
return getch();
return 0;
}
main()
{
int c;
while(1) {
c = inkey();
printf("KEY = %c[%02X] \n", c, c);
}
}
として、キーを入力しようとしても、なぜキーを入力すると表示がとまってしまうのかというと、 おそらく getch() が内部でキー入力を待っているので停止しているからなのだと考えられます。
其の弐
そこで、C言語でキーを入力するために call() 命令を使ってみようという事になります。
以下は、「未完成な張りぼて」からの引用です ^_^;
main() は上のプログラムを使ってください。
char inkeyt1(void){ /*キー入力関数軽量型(不都合あり)*/
static char *p="へSセヘVセ2ェ□ノ"; /*□はスペース*/
call((unsigned)p ,0);
return (peek(0x20aa));
}
「未完成な張りぼて」では詳しく触れられていないようなので、逆アセして解析してみます。
call() で呼び出している、p が一番肝心なプログラムです。
ORG 100H CALL 0BE53H ; 0xBE53 をコール CALL 0BE56H ; 0xBE56 をコール LD (20AAH),A ; 0x20AA 番地に A レジスタ値を書き出し RET ; 戻る END
てな具合です。
0xBE53 は キー入力 の ROM 内関数で、
0xBE56 は 0xBE53 からの戻り値を "アスキーコードに変換" する ROM 内関数のようです。
(‥のようです、というのは、どこにも記載がないからです。結果からするとおそらく、ということです。)
(2005/02/06)教員用の指導書に記載がありました。
で、どんな不具合が発生するかというと、0x20AA 番地に書き出すことが曲者であって、 もし 0x20AA 番地に他のプログラムがあった場合にはそれと書きつぶしてしまうことが問題なのです。
そこで、LD (20AAH),A を LD (0FFH),A にしてみたら、
int inkey()
{
static char *p="へSセヘVセ2\xff\0ノ";
call((unsigned)p ,0);
return peek(0x20aa);
}
こうなりました。
しかし、これでもまだ、不安が残ります。 もし、0xFF 番地にステータスを記録するプログラムだった場合は?
其の参
そこで、call() をおさらいしてみます。
unsigned call(unsigned adr, void * arg_HL); adr : 機械語の先頭アドレス arg_HL : HL レジスタに渡される値 戻り値 : HL レジスタの値
だそうです。
そこで、この戻り値を利用し値を返すことにします。
まず、アセンブラソースです。
ORG 100H CALL 0BE53H ; 0xBE53 をコール CALL 0BE56H ; 0xBE56 をコール LD L,A ; L レジスタに A レジスタ値を書き出し RET ; 戻る END
根本的には、変化していないのですが、LD (0FFH),A の部分を変更しました。
なんか使い方が間違っているような気もしますが、C言語のソースは、こうなりました。
int inkey()
{
static char *p="ヘSセヘVセoノ"; /* 全て全角にしてあります */
return call((unsigned)p,0);
}
結構すっきりしたと思います。
ちなみに、このプログラムは、同時にはキーを取得できません。
call() で機械語を呼び出し、結果を HL レジスタを戻り値としてキーコードを返しています。
H レジスタは、呼び出し時に 0 になっているので結果的に L レジスタの値が戻ってくるわけです。
最後に
長々と書いた割には、重要なのは、上のプログラムだけ(しかも、他人のふんどしで相撲を取っているし)。
まあ、第一回の講座は、これでお開きです。
最後に、プログラムとキーコード表をのせたいと思います。
長々とお付き合いありがとうございました。
プログラム inkey.h
名前を inkey.h に変え、
#include "inkey.h"
として読込むか、直接記述してお使いください。
| 下位\上位 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | ~ | D | ~ | F | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 入力なし | 2ndF | スペース | @ | P | p | ASMBL | ||||||
| 1 | BASIC | カナ | ! | 1 | A | Q | a | q | BASE-n | |||
| 2 | TEXT | INS | " | 2 | B | R | b | r | コントラスト | |||
| 3 | C | DRG | # | 3 | C | S | c | s | ||||
| 4 | STAT | CAPS | $ | 4 | D | T | d | t | ||||
| 5 | ANS | % | 5 | E | U | e | u | |||||
| 6 | OFF | (-) | & | 6 | F | V | f | v | ||||
| 7 | P⇔NP | CONST | ' | 7 | G | W | g | w | ||||
| 8 | BS | (CONST) | ( | 8 | H | X | h | x | ||||
| 9 | DEL | R・CM | ) | 9 | I | Y | i | y | ||||
| A | TAB | M+ | * | : | J | Z | j | z | ||||
| B | CA | M- | + | ; | K | [ | k | { | ” | |||
| C | CLS | → | , | < | L | \ | l | | | ||||
| D | ← | - | = | M | ] | m | } | |||||
| E | DIGIT | ↑ | . | > | N | ^ | n | ~ | 他のキー | |||
| F | F⇔E | ↓ | / | ? | O | _ | o | ゜ |
※色文字 特殊なキーの名前
※色文字 [2ndF] または [SHIFT] を押したときの名前
履歴
- 2004/02/24
- 公開
- 2005/02/06
- 注釈追加
構成変更