From ec720a908b757bf928101bef2178f67f38fff191 Mon Sep 17 00:00:00 2001 From: Alexander Tsidaev Date: Mon, 10 Nov 2014 18:40:08 +0500 Subject: [PATCH] zx128: keyboard support for tty --- Kernel/platform-zx128/devtty.c | 108 ++++++++++++++++++++++++++++++++- Kernel/platform-zx128/devtty.h | 1 + 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/Kernel/platform-zx128/devtty.c b/Kernel/platform-zx128/devtty.c index 79f23005..c2d7713f 100644 --- a/Kernel/platform-zx128/devtty.c +++ b/Kernel/platform-zx128/devtty.c @@ -8,6 +8,41 @@ char tbuf1[TTYSIZ]; +/* buffer for port scan procedure */ +uint8_t keybuf[8]; +/* keyboard state on previous execution. Initialized with all 0x1F (everything released) */ +uint8_t keymap[8] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; + +static uint8_t keybyte, keybit; +static uint8_t newkey; +static int keysdown = 0; + +static uint8_t keyboard[8][5] = { + { ' ', 0, 'm', 'n', 'b' }, + { 13, 'l', 'k', 'j', 'h',}, + { 'p', 'o', 'i', 'u', 'y',}, + { '0', '9', '8', '7', '6' }, + { '1', '2', '3', '4', '5' }, + { 'q', 'w', 'e', 'r', 't' }, + { 'a', 's', 'd', 'f', 'g' }, + { 0, 'z', 'x', 'c', 'v' } +}; + +/* SYMBOL SHIFT MODE */ +static uint8_t keyboard_ss[8][5] = { + { ' ', 0, '.', ',', '*' }, + { 13, '=', '+', '-', '^',}, + { '"', ';', 0 , 0 , 0 ,}, + { '_', ')', '(', '\'', '&' }, + { '!', '@', '#', '$', '%' }, + { 0 , 0 , 0 , '<', '>' }, + { 0 , 0 , 0 , 0 , 0 }, + { 0, ':', 0 , '?', '/' } /* 'x' key should actually contain British pound sign here if "big" font is used */ +}; + + +static uint8_t shiftmask[8] = { 0x02, 0, 0, 0, 0, 0, 0, 0x01 }; + struct s_queue ttyinq[NUM_DEV_TTY + 1] = { /* ttyinq[0] is never used */ {NULL, NULL, NULL, 0, 0, 0}, {tbuf1, tbuf1, tbuf1, TTYSIZ, 0, TTYSIZ / 2}, @@ -47,15 +82,86 @@ void tty_setup(uint8_t minor) minor; } +void update_keyboard(void) +{ + /* We need this assembler code because SDCC __sfr cannot handle 16-bit addresses. And because it is much faster, of course */ + /* TODO: make it naked? */ + __asm + ld hl, #_keybuf + ld c, #0xFE + ld b, #0x7f + ld e, #8 ; 8 keyboard ports, 7FFE, BFFE, DFFE and so on +read_halfrow: + in a, (c) +; and #0 + ld (hl), a + rrc b + inc hl + dec e + jr nz, read_halfrow + __endasm; +} + void tty_pollirq(void) { + int i; + + update_keyboard(); + + newkey = 0; + + for (i = 0; i < 8; i++) { + int n; + uint8_t m = 0x10; + for (n = 4; n >= 0; n--) { + if ((keybuf[i] & m) && !(keymap[i] & m)) + if (!shiftmask[i] & m) + keysdown--; + + if (!(keybuf[i] & m) && (keymap[i] & m)) { + if (!(shiftmask[i] & m)) + keysdown++; + keybyte = i; + keybit = n; + newkey = 1; + } + m >>= 1; + } + keymap[i] = keybuf[i]; + } + if (keysdown < 3 && newkey) + keydecode(); } -void tty_interrupt(void) +static void keydecode(void) { + uint8_t c; + + uint8_t ss = !(keymap[0] & 0x02); /* SYMBOL SHIFT */ + uint8_t cs = !(keymap[7] & 0x01); /* CAPS SHIFT */ + + if (ss) + { + c = keyboard_ss[keybyte][keybit]; + } + else { + c = keyboard[keybyte][keybit]; + if (cs) + { + if (c >= 'a' && c <= 'z') + c -= 'a' - 'A'; + else if (c == '0') /* CS + 0 is backspace) */ + c = 0x08; + } + } + + + if (c != 0) + tty_inproc(1, c); } + /* This is used by the vt asm code, but needs to live in the kernel */ uint16_t cursorpos; diff --git a/Kernel/platform-zx128/devtty.h b/Kernel/platform-zx128/devtty.h index de0eaf73..f96542ff 100644 --- a/Kernel/platform-zx128/devtty.h +++ b/Kernel/platform-zx128/devtty.h @@ -2,5 +2,6 @@ #define __DEVTTY_DOT_H__ void tty_pollirq(void); +static void keydecode(void); #endif -- 2.34.1