Files
x1key/src.original/keyconv.c
Philip Smart 6ac7fa5563 First push
2022-02-17 13:17:58 +00:00

234 lines
5.5 KiB
C

/*
PS/2 キーボードを SHARP X1 につなぐ
キーコード変換処理
2014年7月23日作成
佐藤恭一 http://kyoutan.jpn.org/
無保証です。
佐藤恭一が作成した部分は用途に制限を設けません。商用・非商用にかかわらず自由に使用して頂いて構いません。
勝手に複製したり、改造したり、配布したり、売ったりしても良いということです。
連絡不要です。
*/
#include "keyconv.h"
#include "keytable.h"
#include "ps2.h"
#include "x1key.h"
volatile unsigned short x1shift=0xFF; // X1 シフト状態保存 0で有効
#define TENKEY ((unsigned char)(1<<7))
#define PRESS ((unsigned char)(1<<6))
#define REPEAT ((unsigned char)(1<<5))
#define GRAPH ((unsigned char)(1<<4))
#define CAPS ((unsigned char)(1<<3))
#define KANA ((unsigned char)(1<<2))
#define SHIFT ((unsigned char)(1<<1))
#define CTRL ((unsigned char)(1<<0))
volatile unsigned char ps2ex=0; // PS2キーボード 拡張キーフラグ
#define EXKEY ((unsigned char)(1<<0))
#define RELEASE ((unsigned char)(1<<1))
#define PAUSE_BREAK ((unsigned char)(1<<2))
unsigned char codeconv(unsigned char data);
unsigned char checkbreak(void);
unsigned char x1code(unsigned char data);
void x1trans(unsigned char data);
void keyconv(void)
{
unsigned char data;
data=ps2get(); // PS/2キーボードから受信するまで待って、1バイト読み込む
switch(data)
{
case 0xE0: // 拡張キー
ps2ex|=EXKEY; // 拡張キーフラグセット
break;
case 0xF0: // 離した
ps2ex|=RELEASE; // 離したフラグセット
break;
default:
// PS/2 のコードから内部コードに変換
if(0xE1==data) data=checkbreak(); // PAUSE/BREAK キーの判別
if(0==(ps2ex & EXKEY))
{ // 通常キー
if(0x8F<data) data=0x00;
data=KEY106[data];
}
else
{ // 拡張キー
if(0x5F<data) data=KEY106[data + 0x30];
else data=KEY106[data];
}
ps2ex&=~EXKEY; // 拡張キーフラグリセット
x1trans(x1code(data)); // 内部コードからX1のコードに変換して送信
break;
}
}
// 内部コードからX1のコードに変換
unsigned char x1code(unsigned char data)
{
x1shift|=TENKEY; // 特殊キーフラグリセット
// テンキーやファンクションキー SHIFT CTRL なんかの特殊キーかチェック
if(((0x3A<data)&&(0x59>data))||(0x5A<data)) x1shift&=~TENKEY; // 特殊キーフラグセット
switch(data) // 内部コードで分岐
{
case GRAPH_CODE1:
case GRAPH_CODE2:
if(0==(ps2ex&RELEASE)) x1shift&=~GRAPH; // 押した
else x1shift|=GRAPH; // 離した
data=0;
break;
case CAPS_CODE:
if(0!=(ps2ex&RELEASE)) x1shift=(x1shift|CAPS)&(~(x1shift&CAPS)); // 離すたびトグル
data=0;
break;
case KANA_CODE:
if(0!=(ps2ex&RELEASE)) x1shift=(x1shift|KANA)&(~(x1shift&KANA)); // 離すたびトグル
data=0;
break;
case SHIFTL_CODE:
case SHIFTR_CODE:
if(0==(ps2ex&RELEASE)) x1shift&=~SHIFT; // 押した
else x1shift|=SHIFT; // 離した
data=0;
break;
case CTRL_CODE:
if(0==(ps2ex&RELEASE)) x1shift&=~CTRL; // 押した
else x1shift|=CTRL; // 離した
data=0;
break;
case UP_CODE:
data=0x1E;
break;
case DOWN_CODE:
data=0x1F;
break;
case LEFT_CODE:
data=0x1D;
break;
case RIGHT_CODE:
data=0x1C;
break;
case INS_CODE:
data=0x12;
break;
case DEL_CODE: // BSは通常キーのテーブルに入っている
data=0x08;
break;
case HOME_CODE:
x1shift&=~SHIFT; // +SHIFT
data=0x0B;
break;
default: // 通常キー 内部コードからX1のコードに変換
data=codeconv(data);
break;
}
return data;
}
// PAUSE/BREAK キーは通常と違うコードで始まるので、別処理で判別
unsigned char checkbreak(void)
{
unsigned char a;
for(a=1; a<8; a++)
{
if(ps2get()!=BREAK_CODE[a]) break;
}
if(8==a) // BREAKキー だった
{
ps2ex|=PAUSE_BREAK;
return 0x80;
}
return 0x00; // BREAKキー じゃなかった
}
// X1に送信
void x1trans(unsigned char data)
{
static unsigned char lastshift=0xFF;
if(0==(ps2ex&RELEASE))
{ // 押した
x1shift&=~PRESS;
// ゼロじゃ無い時とシフト状態変化した時送信
if((0x00!=data)||(x1shift!=lastshift)) X1_send(((unsigned short)x1shift << 8) | data);
if(0!=(ps2ex&PAUSE_BREAK)) // PAUSE/BREAKの時リリースコードも送る
{
x1shift|=TENKEY; // 特殊キーフラグクリア
X1_send(((unsigned short)x1shift << 8) | 0x00);
ps2ex&=~PAUSE_BREAK;
}
}
else
{ // 離した
x1shift|=PRESS;
X1_send(((unsigned short)x1shift << 8) | 0x00);
ps2ex&=~RELEASE; // 離したフラグクリア
if(0x0B==data) x1shift|=SHIFT; // HOMEの時 -SHIFT
}
lastshift=x1shift;
}
unsigned char codeconv(unsigned char data)
{
unsigned char status;
status=(x1shift & (CAPS | GRAPH | KANA | SHIFT | CTRL));
if((KANA | GRAPH | SHIFT | CTRL )==status) // CAPS
{
unsigned char ret;
ret=CHR_TBL0[data];
if((0x60 < ret)&&(0x7b > ret)) ret-=0x20; // アルファベット大文字に
return ret;
}
if((KANA | GRAPH | CTRL )==status) // CAPS+SHIFT
{
unsigned char ret;
ret=CHR_TBL1[data];
if((0x40 < ret)&&(0x5b > ret)) ret+=0x20; // アルファベット小文字に
return ret;
}
status&=(GRAPH | KANA | SHIFT | CTRL);
if((GRAPH | KANA | CTRL )==status) return CHR_TBL1[data]; // SHIFT
if((GRAPH | KANA | SHIFT)==status) return CHR_TBL3[data]; // CTRL
if((KANA | SHIFT | CTRL )==status) return CHR_TBL2[data]; // GRAPH
if(( SHIFT | CTRL )==status) return CHR_TBL2[data]; // GRAPH+KANA
if((GRAPH | SHIFT | CTRL )==status) return CHR_TBL4[data]; // KANA
if((GRAPH | CTRL )==status) return CHR_TBL5[data]; // KANA+SHIFT
return CHR_TBL0[data]; // シフトなし
}