pcw8256: Example (in progress) devinput device
authorAlan Cox <alan@linux.intel.com>
Thu, 12 Apr 2018 10:46:00 +0000 (11:46 +0100)
committerAlan Cox <alan@linux.intel.com>
Thu, 12 Apr 2018 10:46:00 +0000 (11:46 +0100)
- Mice need changing to do their work each vblank and accumulate
- No suport for all up/down events yet
- Still need to work out what mode 1 will mean and define in a globally meaningful way - or add a matches ioctl for say up to 8 'grabbed' keycodes

Hopefully enough of a sketch to start getting joystick support into platforms
at least.

Note: the basic idea of all of this is to bind together all the input events
into a single device so that we don't need all the overhead of poll and big
unixisms. Thus a game can grab the keyboard, and get keyboard/joystick/mouse
events all down one channel

Alan

Kernel/platform-pcw8256/Makefile
Kernel/platform-pcw8256/config.h
Kernel/platform-pcw8256/devinput.c [new file with mode: 0644]
Kernel/platform-pcw8256/devinput.h [new file with mode: 0644]
Kernel/platform-pcw8256/devtty.c
Kernel/platform-pcw8256/fuzix.lnk

index bb5ea2d..98c16b7 100644 (file)
@@ -1,5 +1,5 @@
 
-CSRCS = devlpr.c devtty.c devfd.c devfhd.c fidhd.c
+CSRCS = devlpr.c devtty.c devfd.c devfhd.c fidhd.c devinput.c
 CSRCS += devices.c main.c
 
 DSRCS = ../dev/devide.c ../dev/blkdev.c ../dev/mbr.c
index 96f812c..7224adc 100644 (file)
@@ -31,6 +31,8 @@
 #define VT_RIGHT       89
 #define VT_BOTTOM      31
 
+#define CONFIG_INPUT
+#define CONFIG_INPUT_GRABMAX 2 /* We could in theory do full up/down but later */
 #define MAX_BLKDEV     1       /* UIDE or FIDHD never both */
 #define CONFIG_IDE     /* Has an IDE controller - maybe anyway: UIDE */
 
diff --git a/Kernel/platform-pcw8256/devinput.c b/Kernel/platform-pcw8256/devinput.c
new file mode 100644 (file)
index 0000000..94c2162
--- /dev/null
@@ -0,0 +1,111 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <input.h>
+#include <devinput.h>
+
+__sfr __at 0xA0 amx_v;
+__sfr __at 0xA1 amx_h;
+__sfr __at 0xA2 amx_button;
+__sfr __at 0xA3 amx_ctrl;
+
+__sfr __at 0xD0 kemp_x;
+__sfr __at 0xD1 kemp_y;
+__sfr __at 0xD4 kemp_button;
+
+static uint8_t has_amx, has_kemp;
+static uint8_t okx, oky;
+
+static char buf[32];
+static struct s_queue kqueue = {
+ buf, buf, buf, sizeof(buf), 0, sizeof(buf) / 2
+};
+
+/* Queue a character to the input device */
+void queue_input(uint8_t c)
+{
+    insq(&kqueue, c);
+    wakeup(&kqueue);
+}
+
+static uint8_t delta(uint8_t old, uint8_t new)
+{
+    /* Rolled over positive */
+    if (old > 0xE0 && new < 0x20)
+       return new + (0x100 - old);
+    /* Rolled over negative */
+    if (old < 0x20 && new > 0xE0)
+       return -((0x100 - new) + old);
+    else
+        /* Actully this is signed 8bit but it doesn't matter here */
+        return new - old;
+}
+        
+/* First cut - we really should do the mouse delta accumulation in the
+   vblank interrupt and just ouput the sum here */
+int platform_input_read(uint8_t *slot)
+{
+    uint8_t r;
+    if (remq(&kqueue, &r)) {
+       *slot++ = KEYPRESS_CODE | KEYPRESS_UP;
+       *slot++ = r;
+       return 2;
+    }
+    if (has_amx) {
+        *slot++ = MOUSE_REL|BUTTONS(2);
+        r = amx_v;
+        *slot++ = (r >> 4) - (r & 0x0F);
+        *slot++ = (r & 0x0F) - (r >> 4);
+        *slot++ = amx_button & 3;
+        return 4;
+    }
+    if (has_kemp) {
+        uint8_t kx = kemp_x;
+        uint8_t ky = kemp_y;            
+        *slot++ = MOUSE_REL|BUTTONS(2);
+        *slot++ = delta(okx, kx);
+        *slot++ = delta(oky, ky);
+        /* Need to think about this eg 0xF0 -> 0x0F is a positive move
+           of 0x1F while 0x0F->0xF0 is a negative move of 0x1F */
+        *slot++ = kemp_button;
+        oky = ky;
+        okx = kx;
+        return 4;
+    }
+    return 0;
+}
+
+/* All our devices are polled */
+
+/* On an IRQ based system this routine is internally responsible for avoiding
+   races between event wakeup and sleep */
+void platform_input_wait(void)
+{
+    /* Mice need polling every vblank, for a typical tty only machine however
+       we can do less wakeups. Really we need to move the mouse to the timer
+       and do a wakeup only if there is a delta */
+    if (has_amx||has_kemp)
+       psleep(&vblank);
+    else
+       psleep(&kqueue);
+}
+
+int platform_input_write(uint8_t flag)
+{
+    flag;
+    udata.u_error = EINVAL;
+    return -1;
+}
+
+uint8_t platform_input_init(void)
+{
+    if (kemp_x != 0xFF || kemp_y != 0xFF || kemp_button != 0xFF)
+        has_kemp = 1;
+    else if (amx_ctrl != 0xFF && amx_button != 0x10) {
+        amx_ctrl = 0x93;
+        amx_button = 0xFF;
+        amx_button = 0x00;
+        has_amx = 1;
+    } else
+        return 0;
+    return 1;
+}
diff --git a/Kernel/platform-pcw8256/devinput.h b/Kernel/platform-pcw8256/devinput.h
new file mode 100644 (file)
index 0000000..17d3132
--- /dev/null
@@ -0,0 +1,3 @@
+
+extern void queue_input(uint8_t c);
+extern uint8_t vblank;
index 7a83ebc..0940670 100644 (file)
@@ -5,6 +5,8 @@
 #include <devtty.h>
 #include <tty.h>
 #include <vt.h>
+#include <input.h>
+#include <devinput.h>
 
 #undef  DEBUG            /* UNdefine to delete debug code sequences */
 
@@ -251,9 +253,24 @@ static void keydecode(void)
        if (capslock && c >= 'a' && c <= 'z')
                c -= 'a' - 'A';
 /*        kprintf("ttyinproc %d\n", (int) c); */
-       vt_inproc(1, c);
+       switch(keyboard_grab) {
+               case 1:
+                       /* FIXME: proper rule needed */
+                       if (c >= 0x84)
+                               queue_input(c);
+                       /* Fall through */
+               case 0:
+                       vt_inproc(1, c);
+                       return;
+               case 2:
+                       queue_input(c);
+                       return;
+       }
 }
 
+/* Vblank ticker */
+uint8_t vblank;
+
 /* FIXME: keyboard repeat
           floppy motor etc */
 void platform_interrupt(void) 
@@ -269,5 +286,8 @@ void platform_interrupt(void)
                        kbd_timer = keyrepeat.continual;
                }
        }
+       vblank++;
+       wakeup(&vblank);
+       /* Should also run the mouse accumulator here FIXME */
        timer_interrupt();
 }
index ea74c7b..4fadff7 100644 (file)
@@ -34,6 +34,7 @@ mm.rel
 bank16k.rel
 swap.rel
 devsys.rel
+devinput.rel
 platform-pcw8256/devlpr.rel
 platform-pcw8256/devtty.rel
 vt.rel
@@ -44,5 +45,6 @@ platform-pcw8256/devide.rel
 platform-pcw8256/devide_discard.rel
 platform-pcw8256/devfhd.rel
 platform-pcw8256/fidhd.rel
+platform-pcw8256/devinput.rel
 
 -e