秋月H8-3069ネット対応マイコンでbisonを利用した整数電卓、PS/2キーボードのテンキー対応

「秋月H8-3069ネット対応マイコンでbisonを利用した整数電卓、PS/2キーボードで入力」
PS/2キーボードから入力できるようにした。H8/OS のシステムコールはテンキーに未対応のようなので、
「秋月H8-3069ネット対応マイコンに接続したPS/2キーボード読み込み用コードの作成」前編後編
書いたコードをもとにPS/2キーボードのテンキーに対応してみた。

画像


動作環境

  • 秋月 H8-3069 ネット対応マイコン エコノミーLANボードキット
  • PS/2 接続ボード(「秋月H8-3069ネット対応マイコンにPS/2キーボードを接続」で作成)
  • PS/2 109キーボード
  • PS/2 テンキー
  • Vine 3.2
  • USB to シリアルケーブル(秋月で売られていた USB-シリアル変換器)
  • 秋月のUSB-シリアル変換器に付属していたシリアル延長ケーブル
  • キットに付属していた 5V のACアダプター
  • グランド接続用ミノムシクリップ

プログラムの作成


以下のようなコードを書いた。

整数電卓部
%{
#include <stdio.h>

#include <h8/reg3067.h>
#include <h8/syscall.h>

#define USE_PS2

void yyerror(char *s);
int yylex(void);

#ifdef USE_PS2
void my_ps2_setup(void);
int my_key_read(unsigned char *buffer);
#endif

static int buf_c = -2;
%}

%token NUM
%left '-' '+'
%left '*' '/'
%left NEG
%right '^'

%%

input:
| input line
;

line: '\r'
| exp '\r' { printf("\t%d\n", $1); }
;

exp: NUM { $$ = $1; }
| exp '+' exp { $$ = $1 + $3; }
| exp '-' exp { $$ = $1 - $3; }
| exp '*' exp { $$ = $1 * $3; }
| exp '/' exp { $$ = $1 / $3; }
| '-' exp %prec NEG { $$ = -$2; }
| exp '^' exp { $$ = my_pow($1, $3); }
| '(' exp ')' { $$ = $2; }
;
%%

void yyerror(char *s)
{
printf("%s\n", s);
}

int my_getchar(void)
{
unsigned char c;

if (buf_c != -2) {
c = buf_c;
buf_c = -2;
return c;
}

while (1) {
#ifdef USE_PS2
if (my_key_read(&c)) {
#else
if (sys_read(&c, 1)) {
#endif
return c;
}
}
}

void my_ungetc(int c)
{
buf_c = c;
}

int my_pow(int x, int y)
{
int i, r;

if (y < 1) {
return 1;
} else {
r = x;
for (i = 0; i < y - 1; i++) {
r *= x;
}
}

return r;
}

int yylex(void)
{
int c;

while ((c = my_getchar()) == ' ' || c == '\t')
printf("%c", c);

if (c >= '0' && c <= '9') {
yylval = 0;
while (c >= '0' && c <= '9') {
printf("%c", c);
yylval *= 10;
yylval += c - '0';
c = my_getchar();
}
my_ungetc(c);

return NUM;
}

if (c == EOF) return 0;

if (c == '\r') {
printf("\n");
} else {
printf("%c", c);
}

return c;
}

int main()
{
#ifdef USE_PS2
my_ps2_setup();
#endif

printf("\n");
return yyparse();
}

PS/2キーボード読み込み部
#include <h8/reg3067.h>
#include <h8/syscall.h>
#include "key_tbl.h"

#define KEY_L_SHIFT 0x12
#define KEY_R_SHIFT 0x59

#define KEY_BUFFER_SIZE 16
static unsigned char key_buffer[KEY_BUFFER_SIZE];
static signed char key_buffer_index = -1;

static void push_key(unsigned char data)
{
static char is_keyup = 0;
static shift_key = 0;
unsigned char ascii;

if (is_keyup) {
if (data == KEY_L_SHIFT ||
data == KEY_R_SHIFT) {
shift_key = 0;
}
is_keyup = 0;
} else {
if (data == 0xf0) {
is_keyup = 1;
} else if (data == KEY_L_SHIFT ||
data == KEY_R_SHIFT) {
shift_key |= 1;
} else if (data == 0xe0) {
} else {
if (shift_key) {
ascii = shift_key_tbl[data];
} else {
ascii = key_tbl[data];
}

if (key_buffer_index < (KEY_BUFFER_SIZE - 1)) {
key_buffer[++key_buffer_index] = ascii;
}
}
}
}

static void my_key_interrupt(void)
{
static char bit_cnt = 0;
static unsigned char data = 0;
unsigned char data_bit;

data_bit = PADR & 0x01;
switch (bit_cnt) {
case 0:
if (data_bit) return;

break;
case 9: /* parity bit */
break;
case 10:
push_key(data);

bit_cnt = 0;
data = 0;
return;
default:
data |= (data_bit << (bit_cnt-1));
}

bit_cnt++;
}

void my_ps2_setup()
{
#define NMI 7

PADDR = 0x06;

nmi_edge(DownEdge);
int_regist(NMI, my_key_interrupt);

key_buffer_index = -1;
}

int my_key_read(unsigned char *buffer)
{
char ret;

if (key_buffer_index < 0) {
return 0;
} else {
*buffer = key_buffer[key_buffer_index--];
return 1;
}
}

スキャンコードと ASCII コードの対応テーブル(key_tbl.h、未完成)
unsigned char key_tbl[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x31, 0x00, /* 1 */
0x00, 0x00, 0x00, 0x73, 0x61, 0x00, 0x32, 0x00,
0x00, 0x63, 0x00, 0x00, 0x00, 0x34, 0x33, 0x00, /* 2 */
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x35, 0x00,
0x00, 0x00, 0x62, 0x00, 0x00, 0x00, 0x36, 0x00, /* 3 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x39, 0x00, /* 4 */
0x00, 0x2e, 0x2f, 0x00, 0x00, 0x00, 0x2d, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, /* 5 */
0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 */
0x00, 0x31, 0x00, 0x34, 0x37, 0x00, 0x00, 0x00,
0x30, 0x00, 0x32, 0x35, 0x36, 0x38, 0x00, 0x00, /* 7 */
0x00, 0x2b, 0x33, 0x2d, 0x2a, 0x39, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* A */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* B */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* D */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* E */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};

unsigned char shift_key_tbl[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, /* 1 */
0x00, 0x00, 0x00, 0x53, 0x41, 0x00, 0x22, 0x00,
0x00, 0x43, 0x00, 0x00, 0x00, 0x24, 0x23, 0x00, /* 2 */
0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00,
0x00, 0x00, 0x42, 0x00, 0x00, 0x00, 0x26, 0x00, /* 3 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x27, 0x28, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x29, 0x00, /* 4 */
0x00, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x00, 0x00,
0x00, 0x00, 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 5 */
0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 6 */
0x00, 0x31, 0x00, 0x34, 0x37, 0x00, 0x00, 0x00,
0x30, 0x00, 0x32, 0x35, 0x36, 0x38, 0x00, 0x00, /* 7 */
0x00, 0x2b, 0x33, 0x2d, 0x2a, 0x39, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* A */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* B */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* C */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* D */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* E */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* F */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};


テンキーで数式を入力すると、以下のようになった

H8/OS >exec ffde40
1+2
3
2-3
-1
2*3
6
10/3
3
-56+2
-54


フルキーで数式を入力すると、以下のようになった

H8/OS >exec ffde40
1+2
3
4+5-(34 / (8 * 3 + -3))
8
3^2
9

まとめ


構文解析器生成ツール bison を利用した整数電卓のPS/2 キーボード入力をテンキーに対応してみた。

ブログ気持玉

クリックして気持ちを伝えよう!

ログインしてクリックすれば、自分のブログへのリンクが付きます。

→ログインへ

なるほど(納得、参考になった、ヘー)
驚いた
面白い
ナイス
ガッツ(がんばれ!)
かわいい

気持玉数 : 0

この記事へのコメント

この記事へのトラックバック