[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[pbsd-mg2] Re: Let me know keyboard I/F driver status.



In message "[pbsd-mg2] Let me know keyboard I/F driver status.",
"Takemura" write:
>
>VR41x1 の keyboard I/F driver はどんな感じですが。
>MC-R500 の serial がうまく動かないので、keyboard を
>使ってみたいのです。

いや、すみません。ほとんど進んでません。
わたしはあと 1週間は忙しい (でそのあとも暇かは...) ので、
とりあえず monitorに組み込んだコードを送っておきます。

ちなみに、あくまで R300でのコードなので、R500でも
動くかどうかはわかりません。

takesi
/*	$Id: kbd.c,v 1.3 1999/02/07 10:44:46 takesi Exp $	*/
#include <sys/types.h>

#define	KIU_BASE	0xAB000000
#define	KIUDAT0		(*(unsigned short *)(KIU_BASE + 0x180))
#define	KIUDAT1		(*(unsigned short *)(KIU_BASE + 0x182))
#define	KIUDAT2		(*(unsigned short *)(KIU_BASE + 0x184))
#define	KIUDAT3		(*(unsigned short *)(KIU_BASE + 0x186))
#define	KIUDAT4		(*(unsigned short *)(KIU_BASE + 0x188))
#define	KIUDAT5		(*(unsigned short *)(KIU_BASE + 0x18a))
#define	KIUSCANREP	(*(unsigned short *)(KIU_BASE + 0x190))
#define	KIUSCANS	(*(unsigned short *)(KIU_BASE + 0x192))
#define	KIUWKS		(*(unsigned short *)(KIU_BASE + 0x194))
#define	KIUWKI		(*(unsigned short *)(KIU_BASE + 0x196))
#define	KIUINT		(*(unsigned short *)(KIU_BASE + 0x198))
#define	KIURST		(*(unsigned short *)(KIU_BASE + 0x19a))
#define	SCANLINE	(*(unsigned short *)(KIU_BASE + 0x19e))

#define NSCANLINE	12
#define KIUDATP		((unsigned short *)(KIU_BASE + 0x180))

static char keytrans[] = {
	-1,  28,  25,  52,  21,  48,  44,  57,  /* - enter p . y b z space */
	-1,  53,  24,  51,  20,  47,  30,  -1,  /* - / o , t v a - */
	-1,  -1,  23,  50,  19,  46,  17,  -1,  /* - - i m r c w - */
	13,  -1,  22,  -1,  18,  45,  16,   2,  /* = - u - e x q 1 */
	-1,  -1,  11,  38,  40,  34,  15,  59,  /* - - 0 l ' g tab f1 */
	-1,  39,  10,  49,   6,  33,   3,  37,  /* - ; 9 n 5 f 2 k */
	-1,  27,   9,  36,   5,  32,   7,  -1,  /* - ] 8 j 4 d 6 - */
	12,  26,   8,  35,   4,  41,  31,  -1,  /* - [ 7 h 3 ` s - */
	58,  -1,  -1,  -1,  14,  -1,  66,  61,  /* caps - - - bs - f8 f3 */
	-1,  56,  -1,  -1,  43,  -1,  65,  62,  /* - alt - - \ - f7 f4 */
	-1,  -1,  29,  -1,  68,  -1,  64,  60,  /* - - ctrl - f10 - f6 f2 */
	-1,  -1,  -1,  42,  -1,  67,  63,   1,  /* - - - shift - f9 f5 esc */
};
/* XXX: fill the field of funct. keys, ex. arrow, fnc, nfer... */

static unsigned short keystat[12]; /* keep key status */

#define	SCROLL		0x0001	/* stop output */
#define	NUM		0x0002	/* numeric shift  cursors vs. numeric */
#define	CAPS		0x0004	/* caps shift -- swaps case of letter */
#define	SHIFT		0x0008	/* keyboard shift */
#define	CTL		0x0010	/* control shift  -- allows ctl function */
#define	ASCII		0x0020	/* ascii code for this key */
#define	ALT		0x0080	/* alternate shift -- alternate chars */
#define	FUNC		0x0100	/* function key */
#define	KP		0x0200	/* Keypad keys */
#define	NONE		0x0400	/* no function */

#define	CODE_SIZE	4		/* Use a max of 4 for now... */

typedef struct {
	u_short	type;
	char unshift[CODE_SIZE];
	char shift[CODE_SIZE];
	char ctl[CODE_SIZE];
} Scan_def;

#define PCCONS_REAL_BS 1
#define CAPS_IS_CONTROL 1

static Scan_def	scan_codes[] = {
	{ NONE,	"",		"",		"" },		/* 0 unused */
	{ ASCII,"\033",		"\033",		"\033" },	/* 1 ESCape */
	{ ASCII,"1",		"!",		"!" },		/* 2 1 */
	{ ASCII,"2",		"@",		"\000" },	/* 3 2 */
	{ ASCII,"3",		"#",		"#" },		/* 4 3 */
	{ ASCII,"4",		"$",		"$" },		/* 5 4 */
	{ ASCII,"5",		"%",		"%" },		/* 6 5 */
	{ ASCII,"6",		"^",		"\036" },	/* 7 6 */
	{ ASCII,"7",		"&",		"&" },		/* 8 7 */
	{ ASCII,"8",		"*",		"\010" },	/* 9 8 */
	{ ASCII,"9",		"(",		"(" },		/* 10 9 */
	{ ASCII,"0",		")",		")" },		/* 11 0 */
	{ ASCII,"-",		"_",		"\037" },	/* 12 - */
	{ ASCII,"=",		"+",		"+" },		/* 13 = */
#ifndef PCCONS_REAL_BS
	{ ASCII,"\177",		"\177",		"\010" },	/* 14 backspace */
#else
	{ ASCII,"\010",		"\010",		"\177" },	/* 14 backspace */
#endif
	{ ASCII,"\t",		"\177\t",	"\t" },		/* 15 tab */
	{ ASCII,"q",		"Q",		"\021" },	/* 16 q */
	{ ASCII,"w",		"W",		"\027" },	/* 17 w */
	{ ASCII,"e",		"E",		"\005" },	/* 18 e */
	{ ASCII,"r",		"R",		"\022" },	/* 19 r */
	{ ASCII,"t",		"T",		"\024" },	/* 20 t */
	{ ASCII,"y",		"Y",		"\031" },	/* 21 y */
	{ ASCII,"u",		"U",		"\025" },	/* 22 u */
	{ ASCII,"i",		"I",		"\011" },	/* 23 i */
	{ ASCII,"o",		"O",		"\017" },	/* 24 o */
	{ ASCII,"p",		"P",		"\020" },	/* 25 p */
	{ ASCII,"[",		"{",		"\033" },	/* 26 [ */
	{ ASCII,"]",		"}",		"\035" },	/* 27 ] */
	{ ASCII,"\r",		"\r",		"\n" },		/* 28 return */
#ifdef CAPS_IS_CONTROL
	{ CAPS,	"",		"",		"" },		/* 29 caps */
#else
	{ CTL,	"",		"",		"" },		/* 29 control */
#endif
	{ ASCII,"a",		"A",		"\001" },	/* 30 a */
	{ ASCII,"s",		"S",		"\023" },	/* 31 s */
	{ ASCII,"d",		"D",		"\004" },	/* 32 d */
	{ ASCII,"f",		"F",		"\006" },	/* 33 f */
	{ ASCII,"g",		"G",		"\007" },	/* 34 g */
	{ ASCII,"h",		"H",		"\010" },	/* 35 h */
	{ ASCII,"j",		"J",		"\n" },		/* 36 j */
	{ ASCII,"k",		"K",		"\013" },	/* 37 k */
	{ ASCII,"l",		"L",		"\014" },	/* 38 l */
	{ ASCII,";",		":",		";" },		/* 39 ; */
	{ ASCII,"'",		"\"",		"'" },		/* 40 ' */
	{ ASCII,"`",		"~",		"`" },		/* 41 ` */
	{ SHIFT,"",		"",		"" },		/* 42 shift */
	{ ASCII,"\\",		"|",		"\034" },	/* 43 \ */
	{ ASCII,"z",		"Z",		"\032" },	/* 44 z */
	{ ASCII,"x",		"X",		"\030" },	/* 45 x */
	{ ASCII,"c",		"C",		"\003" },	/* 46 c */
	{ ASCII,"v",		"V",		"\026" },	/* 47 v */
	{ ASCII,"b",		"B",		"\002" },	/* 48 b */
	{ ASCII,"n",		"N",		"\016" },	/* 49 n */
	{ ASCII,"m",		"M",		"\r" },		/* 50 m */
	{ ASCII,",",		"<",		"<" },		/* 51 , */
	{ ASCII,".",		">",		">" },		/* 52 . */
	{ ASCII,"/",		"?",		"\037" },	/* 53 / */
	{ SHIFT,"",		"",		"" },		/* 54 shift */
	{ KP,	"*",		"*",		"*" },		/* 55 kp * */
	{ ALT,	"",		"",		"" },		/* 56 alt */
	{ ASCII," ",		" ",		"\000" },	/* 57 space */
#ifdef CAPS_IS_CONTROL
	{ CTL,	"",		"",		"" },		/* 58 control */
#else
	{ CAPS,	"",		"",		"" },		/* 58 caps */
#endif
	{ FUNC,	"\033[M",	"\033[Y",	"\033[k" },	/* 59 f1 */
	{ FUNC,	"\033[N",	"\033[Z",	"\033[l" },	/* 60 f2 */
	{ FUNC,	"\033[O",	"\033[a",	"\033[m" },	/* 61 f3 */
	{ FUNC,	"\033[P",	"\033[b",	"\033[n" },	/* 62 f4 */
	{ FUNC,	"\033[Q",	"\033[c",	"\033[o" },	/* 63 f5 */
	{ FUNC,	"\033[R",	"\033[d",	"\033[p" },	/* 64 f6 */
	{ FUNC,	"\033[S",	"\033[e",	"\033[q" },	/* 65 f7 */
	{ FUNC,	"\033[T",	"\033[f",	"\033[r" },	/* 66 f8 */
	{ FUNC,	"\033[U",	"\033[g",	"\033[s" },	/* 67 f9 */
	{ FUNC,	"\033[V",	"\033[h",	"\033[t" },	/* 68 f10 */
	{ NUM,	"",		"",		"" },		/* 69 num lock */
	{ SCROLL,"",		"",		"" },		/* 70 scroll lock */
	{ KP,	"7",		"\033[H",	"7" },		/* 71 kp 7 */
	{ KP,	"8",		"\033[A",	"8" },		/* 72 kp 8 */
	{ KP,	"9",		"\033[I",	"9" },		/* 73 kp 9 */
	{ KP,	"-",		"-",		"-" },		/* 74 kp - */
	{ KP,	"4",		"\033[D",	"4" },		/* 75 kp 4 */
	{ KP,	"5",		"\033[E",	"5" },		/* 76 kp 5 */
	{ KP,	"6",		"\033[C",	"6" },		/* 77 kp 6 */
	{ KP,	"+",		"+",		"+" },		/* 78 kp + */
	{ KP,	"1",		"\033[F",	"1" },		/* 79 kp 1 */
	{ KP,	"2",		"\033[B",	"2" },		/* 80 kp 2 */
	{ KP,	"3",		"\033[G",	"3" },		/* 81 kp 3 */
	{ KP,	"0",		"\033[L",	"0" },		/* 82 kp 0 */
	{ KP,	".",		"\177",		"." },		/* 83 kp . */
	{ NONE,	"",		"",		"" },		/* 84 0 */
	{ NONE,	"100",		"",		"" },		/* 85 0 */
	{ NONE,	"101",		"",		"" },		/* 86 0 */
	{ FUNC,	"\033[W",	"\033[i",	"\033[u" },	/* 87 f11 */
	{ FUNC,	"\033[X",	"\033[j",	"\033[v" },	/* 88 f12 */
	{ NONE,	"102",		"",		"" },		/* 89 0 */
	{ NONE,	"103",		"",		"" },		/* 90 0 */
	{ NONE,	"",		"",		"" },		/* 91 0 */
	{ NONE,	"",		"",		"" },		/* 92 0 */
	{ NONE,	"",		"",		"" },		/* 93 0 */
	{ NONE,	"",		"",		"" },		/* 94 0 */
	{ NONE,	"",		"",		"" },		/* 95 0 */
	{ NONE,	"",		"",		"" },		/* 96 0 */
	{ NONE,	"",		"",		"" },		/* 97 0 */
	{ NONE,	"",		"",		"" },		/* 98 0 */
	{ NONE,	"",		"",		"" },		/* 99 0 */
	{ NONE,	"",		"",		"" },		/* 100 */
	{ NONE,	"",		"",		"" },		/* 101 */
	{ NONE,	"",		"",		"" },		/* 102 */
	{ NONE,	"",		"",		"" },		/* 103 */
	{ NONE,	"",		"",		"" },		/* 104 */
	{ NONE,	"",		"",		"" },		/* 105 */
	{ NONE,	"",		"",		"" },		/* 106 */
	{ NONE,	"",		"",		"" },		/* 107 */
	{ NONE,	"",		"",		"" },		/* 108 */
	{ NONE,	"",		"",		"" },		/* 109 */
	{ NONE,	"",		"",		"" },		/* 110 */
	{ NONE,	"",		"",		"" },		/* 111 */
	{ NONE,	"",		"",		"" },		/* 112 */
	{ NONE,	"",		"",		"" },		/* 113 */
	{ NONE,	"",		"",		"" },		/* 114 */
	{ NONE,	"",		"",		"" },		/* 115 */
	{ NONE,	"",		"",		"" },		/* 116 */
	{ NONE,	"",		"",		"" },		/* 117 */
	{ NONE,	"",		"",		"" },		/* 118 */
	{ NONE,	"",		"",		"" },		/* 119 */
	{ NONE,	"",		"",		"" },		/* 120 */
	{ NONE,	"",		"",		"" },		/* 121 */
	{ NONE,	"",		"",		"" },		/* 122 */
	{ NONE,	"",		"",		"" },		/* 123 */
	{ NONE,	"",		"",		"" },		/* 124 */
	{ NONE,	"",		"",		"" },		/* 125 */
	{ NONE,	"",		"",		"" },		/* 126 */
	{ NONE,	"",		"",		"" },		/* 127 */
};

int
keyinit()
{
	int i;

	KIURST = 1;	/* KIU reset */
	SCANLINE = 0;	/* 96 keys */
	KIUWKS = 0x18a4; /* t3=6 t2 = 5 t1=4 */
	KIUWKI = 450;
	KIUSCANREP = 0x8023; /* KEYEN | STPREP = 2 | ATSTP | ATSCAN */

	for (i = 0; i < NSCANLINE / 2; i++) {
		keystat[i] = 0;
	}

	return 0;
}

#define NSCANBUF	32
static char scanbuf[NSCANBUF];
static int scanbufhead = 0, scanbuftail = 0;

static void
detect_key()
{
	int i, k;

	while (KIUSCANS != 0x3)
		;
	while (KIUSCANS == 0x3)
		;
	for (i = 0; i < NSCANLINE / 2; i++) {
		k = KIUDATP[i] ^ keystat[i];
		keystat[i] = KIUDATP[i];
		while (k) {
			int n, m;
			n = ffs(k) - 1;
			if (n < 0) {
				printf("??");
				break;
			}
			k ^= 1 << n;
			m = n + i * 16;
#if 0
			printf("%d -> %d ", m, keytrans[m]);
#endif
			if (keytrans[m] < 0) continue;

			/* XXX: scanbuf may overflow! */
			scanbuf[scanbufhead++] = 
				(keystat[i] & (1 << n)) ?
				keytrans[m] : (0x80 | keytrans[m]);
			if (scanbufhead >= NSCANBUF) {
				scanbufhead = 0;
			}
		}
		/* XXX: The order of keys can be a problem.
		   If CTRL and normal key are pushed simultaneously,
		   normal key can be entered in queue first. 
		   Same problem would occur in key break. */
	}
	KIUINT = 0x7;
}

static char k_sft, k_alt, k_ctrl;

#define NKEYBUF 32
static char keybuf[NKEYBUF];
static int keybufhead = 0, keybuftail = 0;

static void
process_key() 
{
	int k, brk;
	char *p;

	k = scanbuf[scanbuftail++];
	if (scanbuftail >= NSCANBUF) {
		scanbuftail = 0;
	}
	brk = k & 0x80;
	k &= 0x7f;

	switch (scan_codes[k].type) {
	case ALT:
		k_alt = brk ? 0 : 1;
		break;
	case SHIFT:
		k_sft = brk ? 0 : 1;
		break;
	case CTL:
		k_ctrl = brk ? 0 : 1;
		break;
	case ASCII:
		if (!brk) {
			if (k_ctrl) {
				p = scan_codes[k].ctl;
			} else if (k_sft) {
				p = scan_codes[k].shift;
			} else {
				p = scan_codes[k].unshift;
			}
			keybuf[keybufhead++] = k_alt ? (*p | 0x80) : *p ;
			if (keybufhead >= NKEYBUF) {
				keybufhead = 0;
			}
		}
		break;
	default:
		/* Ignored */
	}
}

int
getkey()
{
	int ret;
	char *p;

	while (keybuftail == keybufhead) {
		while (scanbuftail == scanbufhead) {
			detect_key();
		}
		process_key();
	}
	ret = keybuf[keybuftail++];
	if (keybuftail >= NKEYBUF) {
		keybuftail = 0;
	}
	return ret;
}