はじめに
PASTA/80 を使って PC-G850 シリーズ用にキーテストプログラムを作ってみたいと思います。
キーテストプログラム
プログラムコードは次の通りです。
KeyTest.pas
program KeyTest;
{$u+}
{$i rtl\g850grph.pas}
type
TPoint = record
x: byte;
y: byte;
end;
const
Data: array [0..53] of array [0..15] of Byte =
(
($FF, $FF, $FF, $FF, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F),
($1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F),
($1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F),
($1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F),
($1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F),
($1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $1F, $FF, $FF, $FF, $FF, $00),
($00, $00, $DF, $51, $51, $51, $51, $DF, $00, $00, $DF, $51, $51, $51, $51, $DF),
($00, $00, $DF, $51, $51, $51, $51, $DF, $00, $00, $DF, $51, $51, $51, $51, $DF),
($00, $00, $DF, $51, $51, $51, $51, $DF, $00, $00, $DF, $51, $51, $51, $51, $DF),
($FF, $FF, $FF, $FF, $00, $00, $00, $41, $7F, $41, $00, $00, $7C, $08, $04, $04),
($78, $00, $7F, $10, $28, $44, $00, $00, $38, $54, $54, $54, $18, $00, $0C, $50),
($50, $3C, $00, $00, $00, $36, $36, $00, $00, $00, $00, $00, $00, $00, $00, $00),
($00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00),
($00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00),
($00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $FF, $FF, $FF, $FF, $00),
($00, $00, $F7, $14, $14, $14, $14, $F7, $00, $00, $F7, $14, $14, $14, $14, $F7),
($00, $00, $F7, $14, $14, $14, $14, $F7, $00, $00, $F7, $14, $14, $14, $14, $F7),
($00, $00, $F7, $14, $14, $14, $14, $F7, $00, $00, $F7, $14, $14, $14, $14, $F7),
($FF, $FF, $FF, $FF, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0),
($C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0),
($C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0),
($C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0),
($C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0),
($C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $C0, $FF, $FF, $FF, $FF, $00),
($00, $00, $7D, $45, $45, $45, $45, $7D, $00, $00, $7D, $45, $45, $45, $45, $7D),
($00, $00, $7D, $45, $45, $45, $45, $7D, $00, $00, $7D, $45, $45, $45, $45, $7D),
($00, $00, $7D, $45, $45, $45, $45, $7D, $00, $00, $7D, $45, $45, $45, $45, $7D),
($BE, $A2, $A2, $A2, $A2, $BE, $80, $80, $3E, $22, $A2, $A2, $A2, $BE, $80, $80),
($3E, $22, $A2, $A2, $A2, $BE, $80, $80, $3E, $22, $A2, $A2, $A2, $BE, $80, $80),
($3E, $22, $A2, $A2, $A2, $BE, $80, $80, $3E, $22, $A2, $A2, $A2, $BE, $80, $80),
($3E, $22, $A2, $A2, $A2, $BE, $80, $80, $3E, $22, $A2, $A2, $A2, $BE, $80, $80),
($3E, $22, $A2, $A2, $A2, $BE, $80, $80, $3E, $22, $A2, $A2, $A2, $BE, $80, $80),
($3E, $22, $A2, $A2, $A2, $BE, $80, $80, $3E, $22, $A2, $A2, $A2, $A2, $BE, $00),
($00, $BE, $A2, $A2, $A2, $A2, $A2, $BE, $00, $00, $00, $BE, $A2, $A2, $A2, $A2),
($A2, $BE, $00, $00, $00, $BE, $A2, $A2, $A2, $A2, $A2, $BE, $00, $00, $00, $BE),
($A2, $A2, $A2, $A2, $A2, $BE, $00, $00, $00, $BE, $A2, $A2, $A2, $A2, $A2, $BE),
($EF, $28, $28, $28, $28, $28, $28, $2F, $20, $20, $EF, $08, $08, $E8, $28, $2F),
($20, $20, $EF, $08, $08, $E8, $28, $2F, $20, $20, $EF, $08, $08, $E8, $28, $2F),
($20, $20, $EF, $08, $08, $E8, $28, $2F, $20, $20, $EF, $08, $08, $E8, $28, $2F),
($20, $20, $EF, $08, $08, $E8, $28, $2F, $20, $20, $EF, $08, $08, $E8, $28, $2F),
($20, $20, $EF, $08, $08, $E8, $28, $2F, $20, $20, $EF, $08, $08, $E8, $28, $2F),
($20, $20, $EF, $08, $08, $E8, $28, $2F, $20, $20, $3F, $00, $00, $00, $FF, $00),
($00, $EF, $28, $28, $28, $28, $28, $EF, $00, $00, $00, $EF, $28, $28, $28, $28),
($28, $EF, $00, $00, $00, $EF, $28, $28, $28, $28, $28, $EF, $00, $00, $00, $EF),
($28, $28, $28, $28, $28, $EF, $00, $00, $00, $EF, $28, $28, $28, $28, $28, $EF),
($03, $02, $02, $22, $72, $22, $02, $02, $02, $FA, $8B, $88, $88, $8B, $8A, $8A),
($8A, $FA, $03, $00, $F8, $8B, $8A, $8A, $8A, $8A, $8B, $88, $88, $8B, $8A, $8A),
($8A, $8A, $8B, $88, $88, $8B, $8A, $8A, $8A, $8A, $8B, $88, $88, $8B, $8A, $8A),
($8A, $8A, $8B, $88, $88, $8B, $8A, $8A, $8A, $8A, $FB, $00, $00, $FB, $8A, $8A),
($8A, $8A, $FB, $00, $00, $FB, $8A, $8A, $8A, $8A, $FB, $00, $00, $FB, $8A, $8A),
($8A, $8A, $FB, $00, $00, $FB, $8A, $8A, $8A, $8A, $FA, $02, $02, $02, $03, $00),
($00, $FB, $8A, $8A, $8A, $8A, $8A, $FB, $00, $00, $00, $FB, $8A, $8A, $8A, $8A),
($8A, $FB, $00, $00, $00, $FB, $8A, $8A, $8A, $8A, $8A, $FB, $00, $00, $00, $FB),
($8A, $8A, $8A, $8A, $8A, $FB, $00, $00, $00, $FF, $80, $80, $80, $80, $80, $FF)
);
Pt: array [0..9] of array [0..7] of TPoint =
(
((x:131;y: 1), (x: 9;y: 26), (x: 17;y: 26), (x: 25;y: 26), (x: 33;y: 26), (x: 41;y: 26), (x: 49;y: 26), (x: 57;y: 26)),
((x: 11;y: 32), (x: 19;y: 32), (x: 27;y: 32), (x: 35;y: 32), (x: 43;y: 32), (x: 51;y: 32), (x: 59;y: 32), (x: 67;y: 32)),
((x: 14;y: 38), (x: 22;y: 38), (x: 30;y: 38), (x: 38;y: 38), (x: 46;y: 38), (x: 54;y: 38), (x: 62;y: 38), (x: 70;y: 38)),
((x: 99;y: 1), (x:107;y: 1), (x: 1;y: 32), (x: 10;y: 44), (x: 1;y: 26), (x: 21;y: 44), (x: 78;y: 44), (x: 78;y: 38)),
((x: 70;y: 44), (x: 86;y: 44), (x:123;y: 1), (x: 98;y: 44), (x:108;y: 44), (x:118;y: 44), (x:128;y: 44), (x:138;y: 44)),
((x: 75;y: 32), (x: 83;y: 32), (x:115;y: 1), (x: 98;y: 38), (x:108;y: 38), (x:118;y: 38), (x:128;y: 38), (x:138;y: 32)),
((x: 65;y: 26), (x: 73;y: 26), (x: 62;y: 44), (x: 98;y: 32), (x:108;y: 32), (x:118;y: 32), (x:128;y: 32), (x:138;y: 26)),
((x: 81;y: 26), (x: 89;y: 26), (x: 99;y: 19), (x: 98;y: 26), (x:108;y: 26), (x:118;y: 26), (x:128;y: 26), (x:139;y: 19)),
((x: 99;y: 13), (x:107;y: 13), (x:107;y: 19), (x:115;y: 19), (x:123;y: 19), (x:131;y: 19), (x:131;y: 13), (x:139;y: 13)),
((x: 99;y: 7), (x:107;y: 7), (x:115;y: 7), (x:115;y: 13), (x:123;y: 13), (x:123;y: 7), (x:131;y: 7), (x:139;y: 7))
);
var
Keys: TKeyArray;
i, l, v: Byte;
begin
FillScreen(clWhite);
SetBGAddr(Addr(Data));
while True do
begin
RestoreBG;
v := Inkey;
if v <> 0 then
begin
GotoXY(7, 1);
Write(v);
end;
ScanKeyboard(Keys);
for l:=0 to 9 do
begin
v := 1;
for i:=0 to 7 do
begin
if (Keys[l] and v) <> 0 then
begin
FillShape(Pt[l, i].x, Pt[l, i].y, clBlack);
if (l = 4) and (v = $80) then
FillShape(91, 32, clBlack);
// GotoXY(10, 1);
// Write('(', i:1, ',', l:1, ')');
end;
v := v shl 1;
end;
end;
RepaintLCD;
end;
end.
実行するとこんな感じになります。押されたキーの場所が黒く表示され、単一のキーを押した場合にはそのキーコード (ASCII コードではない) が表示されます。
おわりに
機械語でキースキャン (OUT(11h) や OUT(12h)) を連続で行なう場合には、IN(10h) で読み出す前にいくらかのウェイトが必要なようです。
具体的には次のようにノーウェイトで設定&読み出しすると、2 回目の読み出し時 (IN(10h)) に前回の値と同じものが入ってくる事があります。
ld a, 01h
out (11h), a
in a, (10h)
...
ld a, 02h
out (11h), a
in a, (10h)
...
11h の bit0 からノーウェイトで読むと同じビットのキーが押されたようになります。例えば上記例だと〔Q〕 を押すと 〔S〕 も押されたようになってしまいます。
| bit | [0] | [1] | [2] | [3] | [4] | [5] | [6] | [7] | [8] | [9] |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | OFF | A | Z | BASIC | ← | L | I | P | nPr | 2ndF |
| 1 | Q | S | X | TEXT | → | ; | O | BS | →DEG | sin |
| 2 | W | D | C | CAPS | ANS | CONST | INS | π | √ | cos |
| 3 | E | F | V | カナ | 0 | 1 | 4 | 7 | x2 | ln |
| 4 | R | G | B | TAB | . | 2 | 5 | 8 | yx^ | log |
| 5 | T | H | N | SPACE | = | 3 | 6 | 9 | ( | tan |
| 6 | Y | J | M | ↓ | + | - | * | / | 1/x | F⇔E |
| 7 | U | K | , | ↑ | Enter | M+ | R・CM | ) | MDF | CLS |
なので、OUT の後、値が正しく反映されるまで少し待つ (ウェイトを入れる) 必要があります。
PASTA/80 で PORT[] 配列を使ってキースキャンを行う分にはウェイトを入れる必要はないと思います。
See also:
