From 00af8cb29a4efd0d88828d07ac1638b04a65a18e Mon Sep 17 00:00:00 2001 From: beeanyew Date: Tue, 12 Jan 2021 15:57:07 +0100 Subject: [PATCH] Add working keyboard forwarding for Amiga --- emulator.c | 76 ++++++++++++++++++++++++++++++++------- gpio/gpio.h | 2 ++ input/input.c | 98 +++++++++++++++++++++++++++++++++++++++++++-------- input/input.h | 11 +++++- 4 files changed, 159 insertions(+), 28 deletions(-) diff --git a/emulator.c b/emulator.c index 88e2433..d02dd58 100644 --- a/emulator.c +++ b/emulator.c @@ -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; diff --git a/gpio/gpio.h b/gpio/gpio.h index 3dc09ed..e61eecf 100644 --- a/gpio/gpio.h +++ b/gpio/gpio.h @@ -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 diff --git a/input/input.c b/input/input.c index 4f80794..32a5191 100644 --- a/input/input.c +++ b/input/input.c @@ -1,17 +1,36 @@ #include #include #include +#include +#include #include +#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; +} diff --git a/input/input.h b/input/input.h index ea2e482..d4810ec 100644 --- a/input/input.h +++ b/input/input.h @@ -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); -- 2.39.2