#include <sys/param.h>
#include <sys/systm.h>
#include <lib/libsa/stand.h>
#include <lib/libkern/libkern.h>
#include <machine/sbd.h>
#include "console.h"
struct zskbd zskbd;
int zskbd_common_getc(int);
void zskbd_busy(void);
static const uint8_t map_normal[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '-', '^', '\\', ':', '.', '/',
'@', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '[', ',', ']', ';', 0x00,
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00,
'\r', '\r', 0x00, 0x00, '\r', 0x00, '-', '.',
0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x0c, 0x7f, 0x12, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00,
'+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const uint8_t map_shift[] = {
'0', '!', '\"', '#', '$', '%', '&', '\'',
'(', ')', '=', '^', '|', '*', '>', '?',
'~', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '{', '<', '}', '+', '_',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00,
'\r', '\r', 'B', 'C', '\r', 'E', '-', '.',
0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x0b, 0x7f, 0x12, 0x09, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00,
'+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const uint8_t map_ctrl[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xa4, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00,
'\r', '\r', 0x00, 0x00, '\r', 0x00, '-', '.',
0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x00, 0x7f, 0x12, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00,
'+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
static const uint8_t map_capslock[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', '-', '^', '\\', ':', '.', '/',
'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', ',', ']', ';', 0x00,
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', ' ', ',', 0x00, 0x00, 0x00, 0x00,
'\r', '\r', 0x00, 0x00, '\r', 0x00, '-', '.',
0xa3, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x08, 0x00, 0x0c, 0x7f, 0x12, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xa0, 0xa1, 0x00, 0x00, 0x00, 0x00,
'+', '*', '/', 0x1b, 0x01, '=', '\t', 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
void
zskbd_set_addr(uint32_t status, uint32_t data)
{
zskbd.status = (volatile uint8_t *)status;
zskbd.data = (volatile uint8_t *)data;
zskbd.normal = map_normal;
zskbd.shift = map_shift;
zskbd.ctrl = map_ctrl;
zskbd.capslock = map_capslock;
cons.getc = zskbd_getc;
cons.scan = zskbd_scan;
}
void
zskbd_print_keyscan(int on)
{
zskbd.print = on;
}
int
zskbd_getc(void)
{
return zskbd_common_getc(0);
}
int
zskbd_scan(void)
{
return zskbd_common_getc(1);
}
int
zskbd_common_getc(int scan)
{
#ifdef CHECK_KEY_RELEASE
static int released = 1;
int push;
#endif
int v, c;
for (;;) {
if (scan) {
if ((*zskbd.status & 0x01) != 0x01)
return -1;
} else {
while ((*zskbd.status & 0x01) != 0x01)
continue;
}
v = *zskbd.data;
if (zskbd.print)
printf("scancode = 0x%x\n", v);
switch (v) {
case 123:
case 124:
zskbd.keymap |= 0x01;
break;
case 251:
case 252:
zskbd.keymap &= ~0x01;
break;
case 120:
zskbd.keymap |= 0x02;
break;
case 248:
zskbd.keymap &= ~0x02;
break;
case 121:
if (zskbd.keymap & 0x04) {
zskbd.keymap &= ~0x04;
zskbd_busy();
*zskbd.data = 0x90;
} else {
zskbd.keymap |= 0x04;
zskbd_busy();
*zskbd.data = 0x92;
}
break;
default:
#ifdef CHECK_KEY_RELEASE
push = (v & 0x80) == 0;
if (push && released) {
released = 0;
goto exit_loop;
}
if (!push)
released = 1;
#else
if ((v & 0x80) == 0)
goto exit_loop;
#endif
break;
}
}
exit_loop:
c = v & 0x7f;
if (zskbd.keymap & 0x01)
return *(zskbd.shift + c);
if (zskbd.keymap & 0x02)
return *(zskbd.ctrl + c);
if (zskbd.keymap & 0x04)
return *(zskbd.capslock + c);
return *(zskbd.normal + c);
}
void
zskbd_busy(void)
{
#if 0
do {
while ((*zskbd.status & 0x20) != 0x20)
;
} while ((*zskbd.status & 0x4) != 0x4);
#endif
}