From: Alan Cox Date: Fri, 13 Feb 2015 21:10:24 +0000 (+0000) Subject: zx128: sort out the keyboard driver X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=84e9f70893f37e25270ff9588b9028d77e255e31;p=FUZIX.git zx128: sort out the keyboard driver This adds some of the missing keyboard symbols, arrow key handling etc and also sorts out the inverted handling bug. --- diff --git a/Kernel/platform-zx128/devtty.c b/Kernel/platform-zx128/devtty.c index 0d81c041..afb7ee42 100644 --- a/Kernel/platform-zx128/devtty.c +++ b/Kernel/platform-zx128/devtty.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -10,35 +11,34 @@ char tbuf1[TTYSIZ]; /* buffer for port scan procedure */ uint8_t keybuf[8]; -/* keyboard state on previous execution. Initialized with all 0x1F (everything released) */ -/* FIXME: needs inverting */ -uint8_t keymap[8] = { 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F }; +/* Previous state */ +uint8_t keymap[8]; static uint8_t keybyte, keybit; static uint8_t newkey; static int keysdown = 0; 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' } + {' ', 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 */ uint8_t shiftkeyboard[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 */ + {' ', 0 , '.', ',', '*'}, + {13 , '=', '+', '-', '^'}, + {'"', ';', '@', ']', '['}, + {'_', ')', '(', '\'','&'}, + {'!', '@', '#', '$', '%'}, + {'`', 0 , 0 , '<', '>'}, + {'~' ,'|', '\\','{', '}'}, + {0 , ':', KEY_POUND , '?', '/'} }; @@ -88,18 +88,19 @@ 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 + 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 + cpl + ld(hl), a + rrc b + inc hl + dec e + jr nz, read_halfrow __endasm; } @@ -113,20 +114,23 @@ void tty_pollirq(void) 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; + uint8_t key = keybuf[i] ^ keymap[i]; + if (key) { + uint8_t m = 0x10; + for (n = 4; n >= 0; n--) { + if ((key & m) && (keymap[i] & m)) + if (!(shiftmask[i] & m)) + keysdown--; + + if ((key & m) && !(keymap[i] & m)) { + if (!(shiftmask[i] & m)) + keysdown++; + keybyte = i; + keybit = n; + newkey = 1; + } + m >>= 1; } - m >>= 1; } keymap[i] = keybuf[i]; } @@ -135,28 +139,31 @@ void tty_pollirq(void) keydecode(); } +static uint8_t cursor[4] = { KEY_LEFT, KEY_DOWN, KEY_UP, KEY_RIGHT }; + static void keydecode(void) { uint8_t c; - uint8_t ss = !(keymap[0] & 0x02); /* SYMBOL SHIFT */ - uint8_t cs = !(keymap[7] & 0x01); /* CAPS SHIFT */ + uint8_t ss = keymap[0] & 0x02; /* SYMBOL SHIFT */ + uint8_t cs = keymap[7] & 0x01; /* CAPS SHIFT */ - if (ss) - { + if (ss) { c = shiftkeyboard[keybyte][keybit]; - } - else { + } else { c = keyboard[keybyte][keybit]; - if (cs) - { + if (cs) { if (c >= 'a' && c <= 'z') c -= 'a' - 'A'; - else if (c == '0') /* CS + 0 is backspace) */ + else if (c == '0') /* CS + 0 is backspace) */ c = 0x08; + else if (c == ' ') + c = KEY_STOP; /* ^C map for BREAK */ + else if (c >= '5' && c <= '8') + c = cursor[c - '5']; } } - + if (c != 0) tty_inproc(1, c); @@ -165,4 +172,3 @@ static void keydecode(void) /* This is used by the vt asm code, but needs to live in the kernel */ uint16_t cursorpos; - diff --git a/Kernel/platform-zx128/main.c b/Kernel/platform-zx128/main.c index b6a4cb21..bd4ffcb5 100644 --- a/Kernel/platform-zx128/main.c +++ b/Kernel/platform-zx128/main.c @@ -17,10 +17,9 @@ void pagemap_init(void) for the polled ports */ void platform_idle(void) { - /* We don't want an idle poll and IRQ driven tty poll at the same moment */ - irqflags_t irq = di(); - tty_pollirq(); - irqrestore(irq); + __asm + halt + __endasm; } void platform_interrupt(void)