]> git.sesse.net Git - pistorm/commitdiff
Add working keyboard forwarding for Amiga
authorbeeanyew <beeanyew@gmail.com>
Tue, 12 Jan 2021 14:57:07 +0000 (15:57 +0100)
committerbeeanyew <beeanyew@gmail.com>
Tue, 12 Jan 2021 14:57:07 +0000 (15:57 +0100)
emulator.c
gpio/gpio.h
input/input.c
input/input.h

index 88e243393dd08b6f43efbdf6f4437eb4f45698c8..d02dd58b6d7de641b84e637cd24e9143fabe5a3d 100644 (file)
@@ -218,7 +218,7 @@ int main(int argc, char *argv[]) {
     m68k_set_reg(M68K_REG_PC, 0x0);
   }
 
-  char c = 0;
+  char c = 0, c_code = 0, c_type = 0;
 
   pthread_t id;
   int err;
@@ -247,7 +247,6 @@ disasm_run:;
     if (irq) {
       unsigned int status = read_reg();
       m68k_set_irq((status & 0xe000) >> 13);
-      //printf("There was an IRQ: %d\n", (status & 0xe000) >> 13);
     }
     else if (gayleirq) {
       write16(0xdff09c, 0x8000 | (1 << 3));
@@ -260,16 +259,40 @@ disasm_run:;
 
   //usleep(0);
     // FIXME: Rework this to use keyboard events instead.
-    while (get_key_char(&c)) {
+    while (get_key_char(&c, &c_code, &c_type)) {
+
       if (c == cfg->keyboard_toggle_key && !kb_hook_enabled) {
         kb_hook_enabled = 1;
         printf("Keyboard hook enabled.\n");
       }
-      else if (c == 0x1B && kb_hook_enabled) {
-        kb_hook_enabled = 0;
-        printf("Keyboard hook disabled.\n");
+      else if (kb_hook_enabled) {
+        if (c == 0x1B && c_type) {
+          kb_hook_enabled = 0;
+          printf("Keyboard hook disabled.\n");
+        }
+        else {
+          /*printf("Key code: %.2X - ", c_code);
+          switch (c_type) {
+            case 0:
+              printf("released.\n");
+              break;
+            case 1:
+              printf("pressed.\n");
+              break;
+            case 2:
+              printf("repeat.\n");
+              break;
+            default:
+              printf("unknown.\n");
+              break;
+          }*/
+          if (queue_keypress(c_code, c_type, cfg->platform->id)) {
+            m68k_set_irq(2);
+          }
+        }
       }
-      if (!kb_hook_enabled) {
+
+      if (!kb_hook_enabled && c_type) {
         if (c == cfg->mouse_toggle_key) {
           mouse_hook_enabled ^= 1;
           printf("Mouse hook %s.\n", mouse_hook_enabled ? "enabled" : "disabled");
@@ -336,6 +359,7 @@ int cpu_irq_ack(int level) {
 }
 
 static unsigned int target = 0;
+static uint8_t send_keypress = 0;
 
 #define PLATFORM_CHECK_READ(a) \
   if (address >= cfg->custom_low && address < cfg->custom_high) { \
@@ -373,6 +397,31 @@ unsigned int m68k_read_memory_8(unsigned int address) {
           return (unsigned int)result;
     }
   }
+  if (kb_hook_enabled) {
+    unsigned char result = (unsigned int)read8((uint32_t)address);
+    if (address == CIAAICR) {
+      if (get_num_kb_queued() && (!send_keypress || send_keypress == 1)) {
+        result |= 0x08;
+        if (!send_keypress)
+          send_keypress = 1;
+      }
+      if (send_keypress == 2) {
+        result |= 0x02;
+        send_keypress = 0;
+      }
+      return result;
+    }
+    if (address == CIAADAT) {
+      if (send_keypress) {
+        uint8_t c = 0, t = 0;
+        pop_queued_key(&c, &t);
+        t ^= 0x01;
+        result = ((c << 1) | t) ^ 0xFF;
+        send_keypress = 2;
+      }
+      return result;
+    }
+  }
 
   address &=0xFFFFFF;
   return read8((uint32_t)address);
@@ -406,9 +455,9 @@ unsigned int m68k_read_memory_16(unsigned int address) {
   }
 
   address &=0xFFFFFF;
-  /*if (address & 0x01) {
+  if (address & 0x01) {
     return ((read8(address) << 8) | read8(address + 1));
-  }*/
+  }
   return (unsigned int)read16((uint32_t)address);
 }
 
@@ -416,11 +465,12 @@ unsigned int m68k_read_memory_32(unsigned int address) {
   PLATFORM_CHECK_READ(OP_TYPE_LONGWORD);
 
   address &=0xFFFFFF;
-  /*if (address & 0x01) {
-    uint32_t c = be32toh(read32(address));
-    c = (c >> 8) | (read8(address + 3) << 24);
+  if (address & 0x01) {
+    uint32_t c = read8(address);
+    c |= (be16toh(read16(address+1)) << 8);
+    c |= (read8(address + 3) << 24);
     return htobe32(c);
-  }*/
+  }
   uint16_t a = read16(address);
   uint16_t b = read16(address + 2);
   return (a << 16) | b;
index 3dc09edc11de7fc8ca3e970d87bc1ca23d730847..e61eecf5c18391f5b8491026da9123f9c1df130d 100644 (file)
@@ -49,6 +49,8 @@
 #define JOY0DAT 0xDFF00A
 #define JOY1DAT 0xDFF00C
 #define CIAAPRA 0xBFE001
+#define CIAADAT 0xBFEC01
+#define CIAAICR 0xBFED01
 #define POTGOR  0xDFF016
 
 // GPIO setup macros. Always use INP_GPIO(x) before using OUT_GPIO(x) or
index 4f8079433185c92664de4a3939eb067b30ce2968..32a51915e8e62e3816d4b752aa0a2f25c1b07715 100644 (file)
@@ -1,17 +1,36 @@
 #include <termios.h>
 #include <unistd.h>
 #include <stdint.h>
+#include <stdio.h>
+#include <string.h>
 #include <linux/input.h>
+#include "../platforms/platforms.h"
+#include "input.h"
+
+#define NONE 0x80
 
 static int lshift = 0, rshift = 0, lctrl = 0, rctrl = 0, lalt = 0, altgr = 0;
 extern int mouse_fd;
 extern int keyboard_fd;
 
-enum keypress_type {
-  KEYPRESS_RELEASE,
-  KEYPRESS_PRESS,
-  KEYPRESS_REPEAT,
-};
+char keymap_amiga[256] = { \
+/*      00    01    02    03    04    05    06    07    08    09    0A    0B    0C    0D    0E    0F */ \
+/*00*/ 0x80, 0x45, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x41, 0x42, \
+/*10*/ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x44, 0x63, 0x20, 0x21, \
+/*20*/ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x00, 0x60, 0x2B, 0x31, 0x32, 0x33, 0x34, \
+/*30*/ 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x61, 0x5D, 0x64, 0x40, NONE, 0x50, 0x51, 0x52, 0x53, 0x54, \
+/*40*/ 0x55, 0x56, 0x57, 0x58, 0x69, 0x5B, NONE, 0x3D, 0x3E, 0x3F, 0x4A, 0x2D, 0x2E, 0x2F, 0x4E, 0x1D, \
+/*50*/ 0x1E, 0x1F, 0x0F, 0x3C, NONE, NONE, 0x30, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \
+/*60*/ 0x43, NONE, 0x5C, NONE, NONE, NONE, 0x5F, 0x4C, 0x5A, 0x4F, 0x4E, NONE, 0x4D, NONE, 0x0D, 0x46, \
+/*70*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, 0x66, 0x67, NONE, \
+/*80*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \
+/*90*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \
+/*A0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \
+/*B0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \
+/*C0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \
+/*D0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \
+/*E0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, \
+/*F0*/ NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE }; \
 
 int handle_modifier(struct input_event *ev) {
   int *target_modifier = NULL;
@@ -90,7 +109,7 @@ char char_from_input_event(struct input_event *ev) {
   }
 }
 
-int get_key_char(char *c)
+int get_key_char(char *c, char *code, char *event_type)
 {
   if (keyboard_fd == -1)
     return 0;
@@ -98,15 +117,12 @@ int get_key_char(char *c)
   struct input_event ie;
   while(read(keyboard_fd, &ie, sizeof(struct input_event)) != -1) {
     if (ie.type == EV_KEY) {
-      if (handle_modifier(&ie))
-        continue;
+      handle_modifier(&ie);
       char ret = char_from_input_event(&ie);
-      if (ie.value == 1 || ie.value == 2) {
-        if (ret != 0) {
-          *c = ret;
-          return 1;
-        }
-      }
+      *c = ret;
+      *code = ie.code;
+      *event_type = ie.value;
+      return 1;
     }
   }
 
@@ -128,3 +144,57 @@ int get_mouse_status(char *x, char *y, char *b) {
 
   return 0;
 }
+
+static uint8_t queued_keypresses = 0, queue_output_pos = 0, queue_input_pos = 0;
+static uint8_t queued_keys[256];
+static uint8_t queued_events[256];
+
+void clear_keypress_queue() {
+  memset(queued_keys, 0x80, 256);
+  memset(queued_events, 0x80, 256);
+  queued_keypresses = 0;
+  queue_output_pos = 0;
+  queue_input_pos = 0;
+}
+
+int queue_keypress(uint8_t keycode, uint8_t event_type, uint8_t platform) {
+  char *keymap = NULL;
+  switch (platform) {
+    case PLATFORM_AMIGA:
+      if (event_type != KEYPRESS_REPEAT)
+        keymap = keymap_amiga;
+      break;
+    default:
+      break;
+  }
+  if (keymap != NULL) {
+    if (keymap[keycode] != NONE) {
+      if (queued_keypresses < 255) {
+        printf("Keypress queued, matched %.2X to host key code %.2X\n", keycode, keymap[keycode]);
+        queued_keys[queue_output_pos] = keymap[keycode];
+        queued_events[queue_output_pos] = event_type;
+        queue_output_pos++;
+        queued_keypresses++;
+        return 1;
+      }
+    }
+  }
+  return 0;
+}
+
+int get_num_kb_queued() {
+  return queued_keypresses;
+}
+
+void pop_queued_key(uint8_t *c, uint8_t *t) {
+  if (queued_keypresses == 0) {
+    *c = NONE;
+    *t = NONE;
+    return;
+  }
+  *c = queued_keys[queue_input_pos];
+  *t = queued_events[queue_input_pos];
+  queue_input_pos++;
+  queued_keypresses--;
+  return;
+}
index ea2e482577967ef9cbecbed48086a4bc245a1837..d4810ecdd4bb1e29acf873174e341cc8af25987f 100644 (file)
@@ -1,2 +1,11 @@
+enum keypress_type {
+  KEYPRESS_RELEASE,
+  KEYPRESS_PRESS,
+  KEYPRESS_REPEAT,
+};
+
 int get_mouse_status(char *x, char *y, char *b);
-int get_key_char(char *c);
+int get_key_char(char *c, char *code, char *event_type);
+int queue_keypress(uint8_t keycode, uint8_t event_type, uint8_t platform);
+int get_num_kb_queued();
+void pop_queued_key(uint8_t *c, uint8_t *t);