zxdiv: split out keyboard driver into dev/zx/
authorAlan Cox <alan@linux.intel.com>
Mon, 26 Nov 2018 13:22:41 +0000 (13:22 +0000)
committerAlan Cox <alan@linux.intel.com>
Mon, 26 Nov 2018 13:22:41 +0000 (13:22 +0000)
The clones mostly use the same keyboard mechanics so make it available to
any other future ports

Kernel/dev/zx/zxkeyboard.c [new file with mode: 0644]
Kernel/platform-zxdiv/Makefile
Kernel/platform-zxdiv/devtty.c
Kernel/platform-zxdiv/fuzix.lnk

diff --git a/Kernel/dev/zx/zxkeyboard.c b/Kernel/dev/zx/zxkeyboard.c
new file mode 100644 (file)
index 0000000..7b44551
--- /dev/null
@@ -0,0 +1,185 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <stdbool.h>
+#include <keycode.h>
+#include <vt.h>
+#include <tty.h>
+#include <devtty.h>
+#include <input.h>
+#include <devinput.h>
+
+/* buffer for port scan procedure */
+uint8_t keybuf[8];
+/* Previous state */
+uint8_t keymap[8];
+
+struct vt_repeat keyrepeat;
+static uint8_t kbd_timer;
+
+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'}
+};
+
+/* SYMBOL SHIFT MODE */
+uint8_t shiftkeyboard[8][5] = {
+       {' ', 0 , '.',  ',', '*'},
+       {13 , '=', '+', '-', '^'},
+       {'"', ';', '@', ']', '['},
+       {'_', ')', '(', '\'','&'},
+       {'!', '@', '#', '$', '%'},
+       {'`',  0 ,  0 , '<', '>'},
+       {'~' ,'|', '\\','{', '}'},
+       {0  , ':', KEY_POUND  , '?', '/'}
+};
+
+
+static uint8_t shiftmask[8] = { 0x02, 0, 0, 0, 0, 0, 0, 0x01 };
+
+static uint8_t update_keyboard(void) __naked
+{
+       /*
+        *      This is run 50 time a second so we do it in asm and also return
+        *      0 if nothing changed. That allows us to avoid the main tty
+        *      processing on most interrupt events which saves us a lot of
+        *      clocks.
+        */
+       __asm
+               ld hl,#_keybuf
+               ld c, #0xFE
+               ld b, #0x7f
+               ld de, #8        ; 8 keyboard ports, 7FFE, BFFE, DFFE and so on
+                                ; D to 0 for no change found
+       read_halfrow:
+               in a, (c)
+               cpl
+               cp (hl)
+               jr z,nochange
+               inc d           ; there 8 ports so we cannot overflow
+               ld (hl), a
+       nochange:
+               rrc b
+               inc hl
+               dec e
+               jr nz, read_halfrow
+               ld l,d
+               ret
+       __endasm;
+}
+
+static uint8_t cursor[4] = { KEY_LEFT, KEY_DOWN, KEY_UP, KEY_RIGHT };
+
+static void keydecode(void)
+{
+       uint8_t m = 0;
+       uint8_t c;
+
+       uint8_t ss = keymap[0] & 0x02;  /* SYMBOL SHIFT */
+       uint8_t cs = keymap[7] & 0x01;  /* CAPS SHIFT */
+
+       if (ss && !cs) {
+               m = KEYPRESS_SHIFT;
+               c = shiftkeyboard[keybyte][keybit];
+       } else {
+               c = keyboard[keybyte][keybit];
+               if (cs && !ss) {
+                       if (c >= 'a' && c <= 'z')
+                               c -= 'a' - 'A';
+                       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 (ss && cs) {
+               m |= KEYPRESS_CTRL;
+               c &= 31;
+       }
+       if (c) {
+               switch (keyboard_grab) {
+               case 0:
+                       vt_inproc(1, c);
+                       break;
+               case 1:
+                       if (!input_match_meta(c)) {
+                               vt_inproc(1, c);
+                               break;
+                       }
+                       /* Fall through */
+               case 2:
+                       queue_input(KEYPRESS_DOWN);
+                       queue_input(c);
+                       break;
+               case 3:
+                       /* Queue an event giving the base key (unshifted)
+                          and the state of shift/ctrl/alt */
+                       queue_input(KEYPRESS_DOWN | m);
+                       queue_input(keyboard[keybyte][keybit]);
+                       break;
+               }
+       }
+}
+
+
+void tty_pollirq(void)
+{
+       int i;
+
+       newkey = 0;
+
+       /* Nothing changed - no processing required */
+       if (!update_keyboard())
+               return;
+
+       for (i = 0; i < 8; i++) {
+               int n;
+               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)) {
+                                               if (keyboard_grab == 3) {
+                                                       queue_input(KEYPRESS_UP);
+                                                       queue_input(keyboard[i][n]);
+                                               }
+                                               keysdown--;
+                                       }
+
+                               if ((key & m) && !(keymap[i] & m)) {
+                                       if (!(shiftmask[i] & m)) {
+                                               keysdown++;
+                                               newkey = 1;
+                                               keybyte = i;
+                                               keybit = n;
+                                       }
+                               }
+                               m >>= 1;
+                       }
+               }
+               keymap[i] = keybuf[i];
+       }
+       if (keysdown && keysdown < 3) {
+               if (newkey) {
+                       keydecode();
+                       kbd_timer = keyrepeat.first;
+               } else if (! --kbd_timer) {
+                       keydecode();
+                       kbd_timer = keyrepeat.continual;
+               }
+       }
+
+}
index 578fe86..8728991 100644 (file)
@@ -2,7 +2,7 @@ CSRCS = devtty.c devices.c main.c bank128.c devinput.c
 CDSRCS = discard.c
 DSRCS = ../dev/devide.c ../dev/devsd.c ../dev/blkdev.c
 DDSRCS = ../dev/devide_discard.c ../dev/devsd_discard.c ../dev/mbr.c
-DZSRCS = ../dev/zx/divide.c ../dev/zx/divmmc.c
+DZSRCS = ../dev/zx/divide.c ../dev/zx/divmmc.c ../dev/zx/zxkeyboard.c
 DDZSRCS =
 ASRCS = crt0.s zx128.s zxvideo.s
 ASRCS += tricks.s commonmem.s loader-divide.s
index aba7c2e..e3bfabb 100644 (file)
@@ -15,8 +15,6 @@ char tbuf1[TTYSIZ];
 uint8_t vtattr_cap = VTA_INVERSE|VTA_FLASH|VTA_UNDERLINE;
 uint8_t vtborder;
 uint8_t curattr = 7;
-struct vt_repeat keyrepeat;
-static uint8_t kbd_timer;
 
 static tcflag_t console_mask[4] = {
        _ISYS,
@@ -30,40 +28,6 @@ tcflag_t *termios_mask[NUM_DEV_TTY + 1] = {
        console_mask
 };
 
-/* buffer for port scan procedure */
-uint8_t keybuf[8];
-/* 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'}
-};
-
-/* SYMBOL SHIFT MODE */
-uint8_t shiftkeyboard[8][5] = {
-       {' ', 0 , '.',  ',', '*'},
-       {13 , '=', '+', '-', '^'},
-       {'"', ';', '@', ']', '['},
-       {'_', ')', '(', '\'','&'},
-       {'!', '@', '#', '$', '%'},
-       {'`',  0 ,  0 , '<', '>'},
-       {'~' ,'|', '\\','{', '}'},
-       {0  , ':', KEY_POUND  , '?', '/'}
-};
-
-
-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},
@@ -113,142 +77,6 @@ void tty_data_consumed(uint8_t minor)
 {
 }
 
-static uint8_t update_keyboard(void) __naked
-{
-       /*
-        *      This is run 50 time a second so we do it in asm and also return
-        *      0 if nothing changed. That allows us to avoid the main tty
-        *      processing on most interrupt events which saves us a lot of
-        *      clocks.
-        */
-       __asm
-               ld hl,#_keybuf
-               ld c, #0xFE
-               ld b, #0x7f
-               ld de, #8        ; 8 keyboard ports, 7FFE, BFFE, DFFE and so on
-                                ; D to 0 for no change found
-       read_halfrow:
-               in a, (c)
-               cpl
-               cp (hl)
-               jr z,nochange
-               inc d           ; there 8 ports so we cannot overflow
-               ld (hl), a
-       nochange:
-               rrc b
-               inc hl
-               dec e
-               jr nz, read_halfrow
-               ld l,d
-               ret
-       __endasm;
-}
-
-void tty_pollirq(void)
-{
-       int i;
-
-       newkey = 0;
-
-       /* Nothing changed - no processing required */
-       if (!update_keyboard())
-               return;
-
-       for (i = 0; i < 8; i++) {
-               int n;
-               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)) {
-                                               if (keyboard_grab == 3) {
-                                                       queue_input(KEYPRESS_UP);
-                                                       queue_input(keyboard[i][n]);
-                                               }
-                                               keysdown--;
-                                       }
-
-                               if ((key & m) && !(keymap[i] & m)) {
-                                       if (!(shiftmask[i] & m)) {
-                                               keysdown++;
-                                               newkey = 1;
-                                               keybyte = i;
-                                               keybit = n;
-                                       }
-                               }
-                               m >>= 1;
-                       }
-               }
-               keymap[i] = keybuf[i];
-       }
-       if (keysdown && keysdown < 3) {
-               if (newkey) {
-                       keydecode();
-                       kbd_timer = keyrepeat.first;
-               } else if (! --kbd_timer) {
-                       keydecode();
-                       kbd_timer = keyrepeat.continual;
-               }
-       }
-
-}
-
-static uint8_t cursor[4] = { KEY_LEFT, KEY_DOWN, KEY_UP, KEY_RIGHT };
-
-static void keydecode(void)
-{
-       uint8_t m = 0;
-       uint8_t c;
-
-       uint8_t ss = keymap[0] & 0x02;  /* SYMBOL SHIFT */
-       uint8_t cs = keymap[7] & 0x01;  /* CAPS SHIFT */
-
-       if (ss && !cs) {
-               m = KEYPRESS_SHIFT;
-               c = shiftkeyboard[keybyte][keybit];
-       } else {
-               c = keyboard[keybyte][keybit];
-               if (cs && !ss) {
-                       if (c >= 'a' && c <= 'z')
-                               c -= 'a' - 'A';
-                       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 (ss && cs) {
-               m |= KEYPRESS_CTRL;
-               c &= 31;
-       }
-       if (c) {
-               switch (keyboard_grab) {
-               case 0:
-                       vt_inproc(1, c);
-                       break;
-               case 1:
-                       if (!input_match_meta(c)) {
-                               vt_inproc(1, c);
-                               break;
-                       }
-                       /* Fall through */
-               case 2:
-                       queue_input(KEYPRESS_DOWN);
-                       queue_input(c);
-                       break;
-               case 3:
-                       /* Queue an event giving the base key (unshifted)
-                          and the state of shift/ctrl/alt */
-                       queue_input(KEYPRESS_DOWN | m);
-                       queue_input(keyboard[keybyte][keybit]);
-                       break;
-               }
-       }
-}
-
 
 /* This is used by the vt asm code, but needs to live in the kernel */
 uint16_t cursorpos;
index 4e65d77..cbb26f8 100644 (file)
@@ -56,4 +56,5 @@ platform-zxdiv/divmmc.rel
 platform-zxdiv/mbr.rel
 platform-zxdiv/blkdev.rel
 platform-zxdiv/devinput.rel
+platform-zxdiv/zxkeyboard.rel
 -e