From 6589ede04917da5f5885ad210bd99763b2b69391 Mon Sep 17 00:00:00 2001 From: Toni Wilen Date: Thu, 4 Jan 2024 21:12:20 +0200 Subject: [PATCH] DraCo updates --- cia.cpp | 2 +- devices.cpp | 2 +- draco.cpp | 344 +++-- gfxboard.cpp | 35 +- include/draco.h | 7 +- include/x86.h | 2 +- inputdevice.cpp | 40 +- keybuf.cpp | 5 + newcpu.cpp | 17 +- od-win32/winuae_msvc15/keyboard_at_draco.cpp | 1160 +++++++++++++++++ od-win32/winuae_msvc15/winuae_msvc.vcxproj | 1 + .../winuae_msvc15/winuae_msvc.vcxproj.filters | 3 + pcem/mouse_serial.cpp | 40 +- pcem/serial.cpp | 55 +- rommgr.cpp | 2 +- x86.cpp | 15 +- 16 files changed, 1567 insertions(+), 163 deletions(-) create mode 100644 od-win32/winuae_msvc15/keyboard_at_draco.cpp diff --git a/cia.cpp b/cia.cpp index 9ea46f52..23d0a6d5 100644 --- a/cia.cpp +++ b/cia.cpp @@ -1161,7 +1161,7 @@ void keyboard_connected(bool connect) static void check_keyboard(void) { - if (currprefs.keyboard_connected) { + if (currprefs.keyboard_connected && currprefs.cs_compatible != CP_DRACO) { if ((keys_available() || kbstate < 3) && !kblostsynccnt ) { switch (kbstate) { diff --git a/devices.cpp b/devices.cpp index aaf8444d..74635b16 100644 --- a/devices.cpp +++ b/devices.cpp @@ -353,7 +353,7 @@ void virtualdevice_free(void) ethernet_enumerate_free(); rtarea_free(); #ifdef WITH_DRACO - draco_reset(); + draco_free(); #endif execute_device_items(device_leaves, device_leave_cnt); } diff --git a/draco.cpp b/draco.cpp index 395f3760..cdb2b661 100644 --- a/draco.cpp +++ b/draco.cpp @@ -18,9 +18,12 @@ #include "ncr_scsi.h" #include "draco.h" #include "zfile.h" +#include "keybuf.h" static int maxcnt = 100; +#define ONEWIRE_DEBUG 1 +#define KBD_DEBUG 1 /* .asciz "kbd/soft" | 1: native keyboard, soft ints @@ -133,8 +136,17 @@ void serial_reset(); void serial_write(uint16_t addr, uint8_t val, void *p); uint8_t serial_read(uint16_t addr, void *p); void draco_serial_init(void **s1, void **s2); +void mouse_serial_poll(int x, int y, int z, int b, void *p); +void *mouse_serial_init_draco(); + +void keyboard_at_write(uint8_t val, void *priv); +uint8_t keyboard_at_read(uint16_t port, void *priv); +void *draco_keyboard_init(void); +void draco_key_process(uint16_t scan, int down); +int draco_kbc_translate(uint8_t val); static void *draco_serial[2]; +static void *draco_mouse_base, *draco_keyboard; static uae_u8 draco_intena, draco_intpen, draco_svga_irq_state; static uae_u16 draco_timer, draco_timer_latch; @@ -143,10 +155,17 @@ static bool draco_fdc_intpen; static uae_u8 draco_superio_cfg[16]; static uae_s8 draco_superio_idx; static uae_u8 draco_reg[0x20]; +static int draco_watchdog; +static int draco_scsi_intpen, draco_serial_intpen; static void draco_irq(void) { uae_u16 irq = 0; + if (draco_scsi_intpen) { + draco_intpen |= 2; + } else { + draco_intpen &= ~2; + } if (draco_intena & 1) { uae_u16 mask = draco_intena & draco_intpen; if (mask) { @@ -166,13 +185,13 @@ static void draco_irq(void) if (draco_svga_irq_state) { irq |= 0x0010; // INT3 } - if (draco_fdc_intpen && (draco_reg[1] & DRCNTRL_FDCINTENA)) { + if ((draco_fdc_intpen || draco_serial_intpen) && (draco_reg[1] & DRCNTRL_FDCINTENA)) { irq = 0x1000; // INT5 } if ((draco_reg[7] & DRSTAT2_TMRINTENA) && (draco_reg[7] & DRSTAT2_TMRIRQPEN)) { irq |= 1; } - if ((draco_reg[3] & DRSTAT_KBDRECV) && (draco_reg[1] & DRCNTRL_KBDINTENA)) { + if (draco_reg[3] & DRSTAT_KBDRECV) { irq |= 1; } } @@ -190,79 +209,136 @@ void draco_svga_irq(bool state) draco_irq(); } -static uae_u8 draco_kbd_state, draco_kbd_state2; +static uae_u8 draco_kbd_state; +static uae_s8 draco_kbd_state2, draco_kbd_poll; static uae_u16 draco_kbd_code; -static int draco_kbd_poll; static uae_u8 draco_kbd_buffer[10]; static uae_u8 draco_kbd_buffer_len; +static uae_s8 draco_kdb_params; +static uae_u16 draco_kbd_in_buffer[16]; +static int draco_kbd_in_buffer_len; + +static void draco_keyboard_reset(void) +{ + draco_kbd_buffer_len = 0; + draco_kbd_in_buffer_len = 0; + draco_kbd_state = 0; + draco_kbd_poll = 0; + draco_kbd_code = 0; + draco_kdb_params = 0; + draco_kbd_state2 = -1; +} -static uae_u8 draco_keyboard_read(uae_u8 v) +static void draco_keyboard_read(void) { - if (draco_kbd_state2) { - draco_reg[3] &= ~DRSTAT_KBDCLKIN; + uae_u8 v = draco_reg[3]; + + if (draco_kbd_poll > 0) { + draco_kbd_poll--; + if (draco_kbd_poll == 0) { + draco_reg[3] &= ~DRSTAT_KBDCLKIN; + v &= ~DRSTAT_KBDCLKIN; + draco_kbd_poll = -4; + } + draco_reg[3] = v; + return; + } + if (draco_kbd_poll < 0) { draco_kbd_poll++; - if (draco_kbd_state2 > 0 && draco_kbd_poll >= 4) { - draco_reg[3] |= DRSTAT_KBDCLKIN; + if (draco_kbd_poll == 0) { + draco_kbd_poll = 4; + v |= DRSTAT_KBDCLKIN; + uae_u16 bit = (draco_reg[1] & DRCNTRL_KBDDATOUT) ? 0x8000 : 0; +#if KBD_DEBUG > 1 + write_log("draco keyboard got bit %d: %d\n", draco_kbd_state2, bit ? 1 : 0); +#endif draco_kbd_code >>= 1; - draco_kbd_code |= (draco_reg[1] & DRCNTRL_KBDDATOUT) ? 0x8000 : 0; + draco_kbd_code |= bit; draco_kbd_state2++; - draco_kbd_poll = 0; + + if (draco_kbd_state2 == 11) { + draco_kbd_code >>= 5; + draco_kbd_code &= 0xff; +#if KBD_DEBUG + write_log("draco->keyboard code %02x\n", draco_kbd_code); +#endif + draco_reg[3] = v; + keyboard_at_write((uae_u8)draco_kbd_code, draco_keyboard); + v = draco_reg[3]; + } } } - return v; + + draco_reg[3] = v; } + + static void draco_keyboard_write(uae_u8 v) { v &= DRCNTRL_KBDDATOUT | DRCNTRL_KBDCLKOUT; if (v == draco_kbd_state) { return; } + if ((v & DRCNTRL_KBDDATOUT) != (draco_kbd_state & DRCNTRL_KBDDATOUT)) { +#if KBD_DEBUG > 1 + write_log("DRCNTRL_KBDDATOUT %d -> %d\n", (draco_kbd_state & DRCNTRL_KBDDATOUT) ? 1 : 0, (v & DRCNTRL_KBDDATOUT) ? 1 : 0); +#endif + } + if ((v & DRCNTRL_KBDCLKOUT) != (draco_kbd_state & DRCNTRL_KBDCLKOUT)) { +#if KBD_DEBUG > 1 + write_log("DRCNTRL_KBDCLKOUT %d -> %d\n", (draco_kbd_state & DRCNTRL_KBDCLKOUT) ? 1 : 0, (v & DRCNTRL_KBDCLKOUT) ? 1 : 0); +#endif + } // start receive - if ((v & DRCNTRL_KBDCLKOUT) && !(draco_kbd_state & DRCNTRL_KBDCLKOUT)) { + if (draco_kbd_state2 < 0 && (v & DRCNTRL_KBDCLKOUT) && !(draco_kbd_state & DRCNTRL_KBDCLKOUT)) { draco_reg[3] |= DRSTAT_KBDCLKIN; draco_kbd_code = 0; - draco_kbd_state2 = 1; - draco_kbd_poll = 0; + draco_kbd_state2 = 0; + draco_kbd_poll = 4; } draco_kbd_state = v; } -static void draco_keyboard_done(void) +static void draco_keyboard_send(void) { - - if (draco_kbd_state2 == 12) { - draco_kbd_code >>= 5; - draco_kbd_code &= 0xff; - write_log("draco received keyboard data %04x\n", draco_kbd_code); - if (draco_kbd_code == 0xf2) { - draco_kbd_buffer[0] = 0xab; - draco_kbd_buffer[1] = 0x83; - draco_kbd_buffer_len = 2; + if (draco_kbd_buffer_len > 0 && !(draco_reg[3] & DRSTAT_KBDRECV)) { + uae_u8 code = draco_kbd_buffer[0]; + for (int i = 1; i < draco_kbd_buffer_len; i++) { + draco_kbd_buffer[i - i] = draco_kbd_buffer[i]; } + draco_kbd_buffer_len--; + draco_reg[5] = code; + draco_reg[3] |= DRSTAT_KBDRECV; +#if KBD_DEBUG + write_log("keyboard->draco code %02x\n", code); +#endif + draco_irq(); } +} + +static void draco_keyboard_done(void) +{ +#if KBD_DEBUG > 1 + write_log("draco keyboard interface reset\n"); +#endif draco_reg[3] &= ~DRSTAT_KBDCLKIN; draco_reg[3] &= ~DRSTAT_KBDRECV; - draco_kbd_state2 = 0; + draco_reg[1] &= ~DRCNTRL_KBDDATOUT; + draco_reg[1] &= ~DRCNTRL_KBDCLKOUT; + draco_kbd_state2 = -1; draco_kbd_poll = 0; + draco_keyboard_send(); } -static void draco_keyboard_send(void) +void draco_kdb_queue_add(void *d, uint8_t val, int state) { - if (draco_kbd_buffer_len <= 0) { - return; - } - if (!(draco_reg[3] & DRSTAT_KBDRECV)) { - draco_kbd_buffer_len--; - uae_u8 code = draco_kbd_buffer[draco_kbd_buffer_len]; - draco_reg[5] = code; - draco_reg[3] |= DRSTAT_KBDRECV; - draco_irq(); - } + draco_kbd_buffer[draco_kbd_buffer_len++] = val; } + static uae_u8 draco_1wire_data[40], draco_1wire_state, draco_1wire_dir; static uae_u8 draco_1wire_sram[512 + 32], draco_1wire_scratchpad[32 + 3], draco_1wire_rom[8]; static uae_u8 draco_1wire_cmd, draco_1wire_bytes, draco_1wire_dat; @@ -274,6 +350,8 @@ static bool draco_1wire_bit; #define DS_ROM_SEARCH 0xf0 #define DS_ROM_SKIP 0xcc #define DS_ROM_READ 0x33 + +#define DS_READ_MEMORY 0xf0 #define DS_WRITE_SCRATCHPAD 0x0f #define DS_READ_SCRATCHPAD 0xaa #define DS_COPY_SCRATCHPAD 0x55 @@ -331,18 +409,20 @@ static void draco_1wire_set_bit(void) } } -static uae_u8 draco_1wire_read(uae_u8 v) +static void draco_1wire_read(void) { + uae_u8 v = draco_reg[3]; + if (draco_1wire_bit) { - draco_reg[3] |= DRSTAT_CLKDAT; v |= DRSTAT_CLKDAT; } else { - draco_reg[3] &= ~DRSTAT_CLKDAT; v &= ~DRSTAT_CLKDAT; } - if (draco_1wire_cnt == 8 && !(draco_reg[3] & DRSTAT_CLKBUSY)) { + if (draco_1wire_cnt == 8 && !(v & DRSTAT_CLKBUSY)) { +#if ONEWIRE_DEBUG > 1 write_log("draco read 1-wire SRAM byte %02x, %02x\n", draco_1wire_dat, draco_1wire_bytes); +#endif draco_1wire_cnt = 0; draco_1wire_bytes++; if (draco_1wire_rom_offset >= 0) { @@ -365,14 +445,14 @@ static uae_u8 draco_1wire_read(uae_u8 v) } } - if (draco_reg[3] & DRSTAT_CLKBUSY) { + if (v & DRSTAT_CLKBUSY) { draco_1wire_busycnt--; if (draco_1wire_busycnt < 0) { - draco_reg[3] &= ~DRSTAT_CLKBUSY; + v &= ~DRSTAT_CLKBUSY; } } - return v; + draco_reg[3] = v; } static void draco_1wire_busy(void) @@ -410,22 +490,28 @@ static void draco_1wire_send(int bit) for (int i = sizeof(draco_1wire_data) - 1; i >= 1; i--) { draco_1wire_data[i] = draco_1wire_data[i - 1]; } +#if ONEWIRE_DEBUG > 1 write_log("draco received 1-wire byte %02x, cnt %02x\n", draco_1wire_data[0], draco_1wire_bytes); +#endif draco_1wire_cnt = 0; draco_1wire_bytes++; - // read data command + 2 address bytes? - if (draco_1wire_cmd == DS_ROM_SEARCH && draco_1wire_data[3] == DS_ROM_SEARCH) { + // read data command + 2 address bytes + if (draco_1wire_cmd == DS_READ_MEMORY && draco_1wire_data[3] == DS_READ_MEMORY) { draco_1wire_sram_offset = (draco_1wire_data[1] << 8) | draco_1wire_data[2]; draco_1wire_dir = 1; draco_1wire_bytes = 0; +#if ONEWIRE_DEBUG write_log("draco received 1-wire SRAM read command, offset %04x\n", draco_1wire_sram_offset); +#endif } - // write scratchpad + 2 address bytes? + // write scratchpad + 2 address bytes if (draco_1wire_cmd == DS_WRITE_SCRATCHPAD && draco_1wire_data[3] == DS_WRITE_SCRATCHPAD) { draco_1wire_sram_offset = (draco_1wire_data[1] << 8) | draco_1wire_data[2]; draco_1wire_sram_offset_copy = draco_1wire_sram_offset; memset(draco_1wire_scratchpad, 0, sizeof(draco_1wire_scratchpad)); +#if ONEWIRE_DEBUG write_log("draco received 1-wire SRAM scratchpad write command, offset %04x\n", draco_1wire_sram_offset); +#endif } // read scratchpad if (draco_1wire_cmd == DS_READ_SCRATCHPAD) { @@ -433,7 +519,9 @@ static void draco_1wire_send(int bit) draco_1wire_dir = 1; draco_1wire_bytes = 0; draco_1wire_set_bit(); +#if ONEWIRE_DEBUG write_log("draco received 1-wire SRAM scratchpad read command\n"); +#endif } // copy scratchpad if (draco_1wire_cmd == DS_COPY_SCRATCHPAD && draco_1wire_data[4] == DS_COPY_SCRATCHPAD) { @@ -444,10 +532,14 @@ static void draco_1wire_send(int bit) draco_1wire_data[3] == draco_1wire_scratchpad[0]) { int start = draco_1wire_sram_offset_copy & 31; int offset = draco_1wire_sram_offset_copy & ~31; +#if ONEWIRE_DEBUG write_log("draco received 1-wire SRAM scratchpad copy command, accepted\n"); +#endif for (int i = 0; i < 32; i++) { draco_1wire_sram[offset + start] = draco_1wire_scratchpad[start + 3]; +#if ONEWIRE_DEBUG > 1 write_log("draco 1-wire SRAM scratchpad copy %02x -> %04x\n", draco_1wire_sram[offset + start], offset + start); +#endif if (start == (draco_1wire_scratchpad[2] & 31)) { break; } @@ -459,7 +551,9 @@ static void draco_1wire_send(int bit) draco_1wire_busy(); draco_1wire_bit = 0; } else { +#if ONEWIRE_DEBUG write_log("draco received 1-wire SRAM scratchpad copy command, rejected\n"); +#endif draco_1wire_busy(); } } @@ -485,7 +579,9 @@ static void draco_1wire_reset(void) } else if (len < 32) { draco_1wire_scratchpad[2] |= 0x20; } +#if ONEWIRE_DEBUG write_log("draco received 1-wire SRAM scratchpad write, %d bytes received\n", len); +#endif } } @@ -496,7 +592,9 @@ static void draco_1wire_reset(void) draco_1wire_bytes = 0; draco_1wire_sram_offset = -1; draco_1wire_rom_offset = 0; +#if ONEWIRE_DEBUG write_log("draco 1-wire reset\n"); +#endif } static uae_u32 REGPARAM2 draco_lget(uaecptr addr) @@ -505,12 +603,13 @@ static uae_u32 REGPARAM2 draco_lget(uaecptr addr) if ((addr & 0x07c00000) == 0x04000000) { - write_log("draco scsi lput %08x %08x\n", addr, l); + //write_log("draco scsi lput %08x %08x\n", addr, l); int reg = addr & 0xffff; - l = cpuboard_ncr710_io_bget(reg + 0) << 24; - l |= cpuboard_ncr710_io_bget(reg + 1) << 16; - l |= cpuboard_ncr710_io_bget(reg + 2) << 8; l |= cpuboard_ncr710_io_bget(reg + 3) << 0; + l |= cpuboard_ncr710_io_bget(reg + 2) << 8; + l |= cpuboard_ncr710_io_bget(reg + 1) << 16; + l |= cpuboard_ncr710_io_bget(reg + 0) << 24; + } else { write_log(_T("draco_lget %08x %08x\n"), addr, M68K_GETPC); } @@ -524,6 +623,12 @@ static uae_u32 REGPARAM2 draco_wget(uaecptr addr) return 0; } +void draco_bustimeout(uaecptr addr) +{ + write_log("draco bus timeout %08x\n", addr); + draco_reg[3] |= DRSTAT_BUSTIMO; +} + static uae_u32 REGPARAM2 draco_bget(uaecptr addr) { uae_u8 v = 0; @@ -534,8 +639,7 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr) } if (addr >= 0x20000000) { - write_log("draco bus timeout %08x\n", addr); - draco_reg[3] |= DRSTAT_BUSTIMO; + draco_bustimeout(addr); return 0; } @@ -543,7 +647,7 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr) int reg = addr & 0xffff; v = cpuboard_ncr710_io_bget(reg); - write_log("draco scsi read %08x\n", addr); +// write_log("draco scsi read %08x\n", addr); } else if ((addr & 0x07c00000) == 0x02400000) { @@ -597,6 +701,10 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr) v = serial_read(reg, draco_serial[1]); break; + case 0x278: + // parallel + break; + default: write_log("draco superio read %04x = %02x\n", (addr >> 2) & 0xfff, v); break; @@ -606,16 +714,19 @@ static uae_u32 REGPARAM2 draco_bget(uaecptr addr) } else if ((addr & 0x07c00000) == 0x02000000) { // io - if ((addr & 0xffffff) > 0x1f) - write_log("x"); - int reg = addr & 0x1f; v = draco_reg[reg]; switch(reg) { case 3: - v = draco_keyboard_read(v); - v = draco_1wire_read(v); + draco_keyboard_read(); + draco_1wire_read(); + v = draco_reg[reg]; + break; + case 5: +#if KBD_DEBUG > 1 + write_log("draco keyboard scan code read %02x\n", v); +#endif break; case 9: v = 4; @@ -665,12 +776,12 @@ static void REGPARAM2 draco_lput(uaecptr addr, uae_u32 l) { if ((addr & 0x07c00000) == 0x04000000) { - write_log("draco scsi lput %08x %08x\n", addr, l); + //write_log("draco scsi lput %08x %08x\n", addr, l); int reg = addr & 0xffff; - cpuboard_ncr710_io_bput(reg + 0, l >> 24); + cpuboard_ncr710_io_bput(reg + 3, l >> 0); + cpuboard_ncr710_io_bput(reg + 2, l >> 8); cpuboard_ncr710_io_bput(reg + 1, l >> 16); - cpuboard_ncr710_io_bput(reg + 2, l >> 8); - cpuboard_ncr710_io_bput(reg + 3, l >> 0); + cpuboard_ncr710_io_bput(reg + 0, l >> 24); } else { @@ -696,7 +807,7 @@ static void REGPARAM2 draco_bput(uaecptr addr, uae_u32 b) if ((addr & 0x07c00000) == 0x04000000) { - write_log("draco scsi put %08x\n", addr); +// write_log("draco scsi put %08x\n", addr); int reg = addr & 0xffff; cpuboard_ncr710_io_bput(reg, b); @@ -755,6 +866,11 @@ static void REGPARAM2 draco_bput(uaecptr addr, uae_u32 b) case 0x2ff: serial_write(reg, b, draco_serial[1]); break; + + case 0x278: + // parallel + break; + default: write_log("draco superio write %04x = %02x\n", (addr >> 2) & 0xfff, b); break; @@ -771,12 +887,14 @@ static void REGPARAM2 draco_bput(uaecptr addr, uae_u32 b) int reg = addr & 0x1f; uae_u8 oldval = draco_reg[reg]; draco_reg[reg] = b; - //draco_reg[1] |= DRCNTRL_FDCINTENA; //write_log(_T("draco_bput %08x %02x %08x\n"), addr, b & 0xff, M68K_GETPC); switch(reg) { case 1: + if (b & DRCNTRL_WDOGDAT) { + draco_watchdog = 0; + } draco_irq(); draco_keyboard_write(b); break; @@ -868,9 +986,29 @@ void casablanca_map_overlay(void) map_banks(&draco_bank, 0x03000000 >> 16, 0x01000000 >> 16, 0); } +void draco_ext_interrupt(bool i6) +{ + if (i6) { + draco_intpen |= 8; + } else { + draco_intpen |= 4; + } + draco_irq(); +} + +void draco_keycode(uae_u8 scancode, uae_u8 state) +{ + if (currprefs.cs_compatible == CP_DRACO) { + draco_kbd_in_buffer[draco_kbd_in_buffer_len++] = scancode | (state ? 0x8000 : 0x00); + if (draco_kbd_buffer_len == 0 && !(draco_reg[3] & DRSTAT_KBDRECV)) { + draco_key_process(scancode, state); + } + } +} + static void draco_hsync(void) { - uae_u16 tm = 1, ot; + uae_u16 tm = 5, ot; static int hcnt; ot = draco_timer; @@ -886,31 +1024,49 @@ static void draco_hsync(void) if (draco_kbd_buffer_len > 0) { draco_keyboard_send(); } + + if (draco_kbd_buffer_len == 0 && draco_kbd_in_buffer_len > 0 && !(draco_reg[3] & DRSTAT_KBDRECV)) { + uae_u8 code = (uae_u8)draco_kbd_in_buffer[0]; + uae_u8 state = (draco_kbd_in_buffer[0] & 0x8000) ? 1 : 0; + for (int i = 1; i < draco_kbd_in_buffer_len; i++) { + draco_kbd_in_buffer[i - i] = draco_kbd_in_buffer[i]; + } + draco_kbd_in_buffer_len--; + draco_key_process(code, state); + } + hcnt++; if (hcnt >= 60) { draco_1wire_rtc_count(); hcnt = 0; } + + draco_watchdog++; + if (0 && draco_watchdog > 312 * 50) { + IRQ_forced(7, -1); + activate_debugger(); + draco_watchdog = 0; + } } void draco_set_scsi_irq(int id, int level) { - if (level) { - draco_intpen |= 2; - } else { - draco_intpen &= ~2; - } + draco_scsi_intpen = level; draco_irq(); } static void x86_irq(int irq, bool state) { - draco_fdc_intpen = state; + if (irq == 4) { + draco_serial_intpen = state; + } else { + draco_fdc_intpen = state; + } draco_irq(); } -void draco_reset(void) +void draco_free(void) { TCHAR path[MAX_DPATH]; cfgfile_resolve_path_out_load(currprefs.flashfile, path, MAX_DPATH, PATH_ROM); @@ -922,13 +1078,17 @@ void draco_reset(void) zfile_fwrite(draco_1wire_sram, sizeof(draco_1wire_sram), 1, draco_flashfile); zfile_fclose(draco_flashfile); } + xfree(draco_mouse_base); + draco_mouse_base = NULL; } -void draco_init(void) +void draco_reset(int hardreset) { - if (currprefs.cs_compatible != CP_DRACO) { - return; - } + + x86_initfloppy(x86_irq); + draco_serial_init(&draco_serial[0], &draco_serial[1]); + draco_mouse_base = mouse_serial_init_draco(); + draco_keyboard = draco_keyboard_init(); draco_intena = 0; draco_intpen = 0; @@ -938,8 +1098,9 @@ void draco_init(void) draco_svga_irq_state = 0; draco_fdc_intpen = false; draco_superio_idx = -2; - draco_kbd_buffer_len = 0; - draco_kbd_state2 = 0; + draco_watchdog = 0; + draco_scsi_intpen = 0; + draco_serial_intpen = 0; memset(draco_superio_cfg, 0, sizeof(draco_superio_cfg)); draco_superio_cfg[0] = 0x3b; draco_superio_cfg[1] = 0x9f; @@ -949,7 +1110,9 @@ void draco_init(void) draco_superio_cfg[13] = 0x65; draco_superio_cfg[14] = 1; memset(draco_reg, 0, sizeof(draco_reg)); + draco_reg[1] = DRCNTRL_FDCINTENA | DRCNTRL_KBDINTENA; + draco_keyboard_reset(); draco_1wire_rtc_validate(); draco_1wire_rom[0] = 0x04; draco_1wire_rom[1] = 1; @@ -960,6 +1123,14 @@ void draco_init(void) draco_1wire_rom[6] = 6; draco_1wire_rom[7] = 0xaa; +} + +void draco_init(void) +{ + if (currprefs.cs_compatible != CP_DRACO) { + return; + } + TCHAR path[MAX_DPATH]; cfgfile_resolve_path_out_load(currprefs.flashfile, path, MAX_DPATH, PATH_ROM); struct zfile *draco_flashfile = zfile_fopen(path, _T("rb"), ZFD_NORMAL); @@ -970,11 +1141,22 @@ void draco_init(void) zfile_fclose(draco_flashfile); } - x86_initfloppy(x86_irq); - draco_serial_init(&draco_serial[0], &draco_serial[1]); + draco_reset(1); device_add_rethink(draco_irq); device_add_hsync(draco_hsync); + device_add_reset(draco_reset); +} + +bool draco_mouse(int port, int x, int y, int z, int b) +{ + if (currprefs.cs_compatible == CP_DRACO) { + if (b < 0) + return true; + mouse_serial_poll(x, y, z, b, draco_mouse_base); + return true; + } + return false; } void draco_map_overlay(void) diff --git a/gfxboard.cpp b/gfxboard.cpp index f2cd6b0e..ff2353c8 100644 --- a/gfxboard.cpp +++ b/gfxboard.cpp @@ -57,6 +57,7 @@ static bool memlogw = true; #include "pcem/pcemglue.h" #include "qemuvga/qemuuaeglue.h" #include "qemuvga/vga.h" +#include "draco.h" extern void put_io_pcem(uaecptr, uae_u32, int); extern uae_u32 get_io_pcem(uaecptr, int); @@ -5547,10 +5548,12 @@ static void special_pcem_put(uaecptr addr, uae_u32 v, int size) if (boardnum == GFXBOARD_ID_ALTAIS_Z3) { - addr &= 0xffff; - if (addr >= 0x40) { - gfxboard_bput_io_swap_pcem(addr, v); + if ((addr & 0xffff) < 0x100) { + draco_bustimeout(addr); + return; } + addr &= 0xffff; + gfxboard_bput_io_swap_pcem(addr, v); } else if (boardnum == GFXBOARD_ID_RETINA_Z2) { @@ -5900,28 +5903,12 @@ static uae_u32 special_pcem_get(uaecptr addr, int size) if (boardnum == GFXBOARD_ID_ALTAIS_Z3) { - addr &= 0xffff; - if (addr >= 0x40) { - v = gfxboard_bget_io_swap_pcem(addr); - } else { - switch(addr) - { - case 3: - v = 2 + 4 + 8; - break; - case 7: - v = 19; - break; - case 11: - v = 0x47; - break; - case 15: - v = 0x54; - break; - - - } + if ((addr & 0xffff) < 0x100) { + draco_bustimeout(addr); + return v; } + addr &= 0xffff; + v = gfxboard_bget_io_swap_pcem(addr); } else if (boardnum == GFXBOARD_ID_RETINA_Z2) { diff --git a/include/draco.h b/include/draco.h index d98e7f77..ce98ffa0 100644 --- a/include/draco.h +++ b/include/draco.h @@ -2,5 +2,8 @@ void casablanca_map_overlay(void); void draco_map_overlay(void); void draco_init(void); -void draco_reset(void); - +void draco_free(void); +bool draco_mouse(int port, int x, int y, int z, int b); +void draco_bustimeout(uaecptr addr); +void draco_ext_interrupt(bool); +void draco_keycode(uae_u8 scancode, uae_u8 state); diff --git a/include/x86.h b/include/x86.h index ee2ba110..d153e228 100644 --- a/include/x86.h +++ b/include/x86.h @@ -9,7 +9,7 @@ bool a2386_init(struct autoconfig_info *aci); bool isa_expansion_init(struct autoconfig_info *aci); void x86_bridge_sync_change(void); void x86_update_sound(float); -void x86_mouse(int port, int x, int y, int z, int b); +bool x86_mouse(int port, int x, int y, int z, int b); #define X86_STATE_INACTIVE 0 #define X86_STATE_STOP 1 diff --git a/inputdevice.cpp b/inputdevice.cpp index ec30ab1a..0012dfe1 100644 --- a/inputdevice.cpp +++ b/inputdevice.cpp @@ -50,6 +50,7 @@ #include "cia.h" #include "autoconf.h" #include "x86.h" +#include "draco.h" #ifdef RETROPLATFORM #include "rp.h" #endif @@ -3393,9 +3394,17 @@ static int getvelocity (int num, int subnum, int pct) static void mouseupdate (int pct, bool vsync) { int max = 120; + bool pcmouse = false; static int mxd, myd; if (vsync) { + + if (x86_mouse(0, 0, 0, 0, -1) || draco_mouse(0, 0, 0, 0, -1)) { + pcmouse = true; + pct = 1000; + } + + if (mxd < 0) { if (mouseedge_x > 0) mouseedge_x = 0; @@ -3473,19 +3482,24 @@ static void mouseupdate (int pct, bool vsync) if (!mouse_deltanoreset[i][2]) mouse_delta[i][2] = 0; - if (getbuttonstate(i, JOYBUTTON_1)) - pc_mouse_buttons[i] |= 1; - else - pc_mouse_buttons[i] &= ~1; - if (getbuttonstate(i, JOYBUTTON_2)) - pc_mouse_buttons[i] |= 2; - else - pc_mouse_buttons[i] &= ~2; - if (getbuttonstate(i, JOYBUTTON_3)) - pc_mouse_buttons[i] |= 4; - else - pc_mouse_buttons[i] &= ~4; - x86_mouse(i, v1, v2, v3, pc_mouse_buttons[i]); + if (pcmouse) { + if (getbuttonstate(i, JOYBUTTON_1)) + pc_mouse_buttons[i] |= 1; + else + pc_mouse_buttons[i] &= ~1; + if (getbuttonstate(i, JOYBUTTON_2)) + pc_mouse_buttons[i] |= 2; + else + pc_mouse_buttons[i] &= ~2; + if (getbuttonstate(i, JOYBUTTON_3)) + pc_mouse_buttons[i] |= 4; + else + pc_mouse_buttons[i] &= ~4; + + x86_mouse(0, v1, v2, v3, pc_mouse_buttons[i]); + draco_mouse(0, v1, v2, v3, pc_mouse_buttons[i]); + } + #if OUTPUTDEBUG if (v1 || v2) { diff --git a/keybuf.cpp b/keybuf.cpp index 9f6725bc..b98bb087 100644 --- a/keybuf.cpp +++ b/keybuf.cpp @@ -295,6 +295,11 @@ int record_key_direct(int kc, bool direct) int kpb_next = kpb_first + 1; int kcd = (kc << 7) | (kc >> 1); + if (currprefs.cs_compatible == CP_DRACO) { + inputdevice_draco_key(kc); + return 1; + } + if (!direct) { if (key_swap_hack2) { // $0D <> $0C diff --git a/newcpu.cpp b/newcpu.cpp index c1b5685f..dde2bbfa 100644 --- a/newcpu.cpp +++ b/newcpu.cpp @@ -52,6 +52,7 @@ #include "x86.h" #include "bsdsocket.h" #include "devices.h" +#include "draco.h" #ifdef JIT #include "jit/compemu.h" #include @@ -4274,12 +4275,16 @@ void safe_interrupt_set(int num, int id, bool i6) atomic_or(p, 1 << id); atomic_or(&uae_interrupt, 1); } else { - int inum = i6 ? 13 : 3; - uae_u16 v = 1 << inum; - if (currprefs.cpu_cycle_exact || currprefs.cpu_compatible) { - INTREQ_INT(inum, 0); - } else if (!(intreq & v)) { - INTREQ_0(0x8000 | v); + if (currprefs.cs_compatible == CP_DRACO) { + draco_ext_interrupt(i6); + } else { + int inum = i6 ? 13 : 3; + uae_u16 v = 1 << inum; + if (currprefs.cpu_cycle_exact || currprefs.cpu_compatible) { + INTREQ_INT(inum, 0); + } else if (!(intreq & v)) { + INTREQ_0(0x8000 | v); + } } } } diff --git a/od-win32/winuae_msvc15/keyboard_at_draco.cpp b/od-win32/winuae_msvc15/keyboard_at_draco.cpp new file mode 100644 index 00000000..176ef762 --- /dev/null +++ b/od-win32/winuae_msvc15/keyboard_at_draco.cpp @@ -0,0 +1,1160 @@ +/* + * x86box at keyboard and other stuff mixed and patched here for quick DraCo keyboard emulation.. + */ + +#include +#include +#include +#include +#include +#include +#define HAVE_STDARG_H + +#define STATE_SHIFT_MASK 0x22 +#define STATE_RSHIFT 0x20 +#define STATE_LSHIFT 0x02 + +#define FAKE_LSHIFT_ON 0x100 +#define FAKE_LSHIFT_OFF 0x101 +#define LSHIFT_ON 0x102 +#define LSHIFT_OFF 0x103 +#define RSHIFT_ON 0x104 +#define RSHIFT_OFF 0x105 + + /* Global keyboard mode: + Bits 0 - 1 = scan code set. */ +uint8_t keyboard_mode = 0x02; + +void draco_kdb_queue_add(void *d, uint8_t val, int state); + +void kbc_at_dev_reset(void *d, int r) +{ +} +void keyboard_at_log(const char *txt, ...) +{ +} +void fatalx(const char *txt, ...) +{ +} + +enum { + DEV_STATE_MAIN_1 = 0, + DEV_STATE_MAIN_OUT = 1, + DEV_STATE_MAIN_2 = 2, + DEV_STATE_MAIN_CMD = 3, + DEV_STATE_MAIN_WANT_IN = 4, + DEV_STATE_MAIN_IN = 5, + DEV_STATE_EXECUTE_BAT = 6, + DEV_STATE_MAIN_WANT_EXECUTE_BAT = 7 +}; + +#define FLAG_PS2 0x08 /* dev is AT or PS/2 */ +#define FLAG_AT 0x00 /* dev is AT or PS/2 */ +#define FLAG_TYPE_MASK 0x07 /* mask for type */ + +#define FIFO_SIZE 16 + +enum { + KBD_84_KEY = 0, + KBD_101_KEY, + KBD_102_KEY, + KBD_JIS, + KBD_KOREAN +}; + +#define FLAG_ENABLED 0x10 /* dev is enabled for use */ +#define FLAG_CTRLDAT 0x08 /* ctrl or data mode */ + +static int keyboard_scan; + +typedef struct atkbc_dev_t { + const char *name; /* name of this device */ + + uint8_t type; + uint8_t command; + uint8_t last_scan_code; + uint8_t state; + uint8_t resolution; + uint8_t rate; + uint8_t cmd_queue_start; + uint8_t cmd_queue_end; + uint8_t queue_start; + uint8_t queue_end; + + uint16_t flags; + + /* Internal FIFO, not present on real devices, needed for commands that + output multiple bytes. */ + uint8_t cmd_queue[16]; + + uint8_t queue[64]; + + int fifo_mask; + int mode; + int x; + int y; + int z; + int b; + + int *scan; + + void (*process_cmd)(void *priv); + void (*execute_bat)(void *priv); + + void *port; + +} atkbc_dev_t; + +static atkbc_dev_t draco_kbd; +static atkbc_dev_t *SavedKbd = &draco_kbd; + +typedef struct scancode { + const uint8_t mk[4]; + const uint8_t brk[4]; +} scancode; + +static scancode *scan_table; /* scancode table for keyboard */ + +static uint8_t caps_lock = 0; +static uint8_t num_lock = 0; +static uint8_t scroll_lock = 0; +static uint8_t shift = 0; + + +/* Non - translated to translated scan codes. */ +static const uint8_t nont_to_t[256] = { + 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58, + 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59, + 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a, + 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b, + 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c, + 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d, + 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e, + 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f, + 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60, + 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61, + 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e, + 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76, + 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b, + 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f, + 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45, + 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54, + 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff +}; + +static int dev_sc_or; + +int draco_kbc_translate(uint8_t val) +{ + int translate = 1; + int ret = -1; + + /* Allow for scan code translation. */ + if (translate && (val == 0xf0)) { + dev_sc_or = 0x80; + return ret; + } + + /* Skip break code if translated make code has bit 7 set. */ + if (translate && (dev_sc_or == 0x80) && (nont_to_t[val] & 0x80)) { + dev_sc_or = 0; + return ret; + } + + ret = translate ? (nont_to_t[val] | dev_sc_or) : val; + + if (dev_sc_or == 0x80) + dev_sc_or = 0; + + return ret; +} + +static void kbc_at_dev_queue_add(void *d, uint8_t val, int state) +{ + if (keyboard_mode == 3) { + //val = draco_kbc_translate(val); + } + draco_kdb_queue_add(d, val, state); +} + + +void +keyboard_set_table(const scancode *ptr) +{ + scan_table = (scancode *)ptr; +} + + +const uint8_t id_bytes[16][4] = { { 0x00, 0x00, 0x00, 0x00 }, /* AT 84-key */ + { 0x00, 0x00, 0x00, 0x00 }, /* AT 101/102/106-key */ + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, /* AT Korean */ + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, + { 0x83, 0xab, 0x00, 0x00 }, /* PS/2 101-key */ + { 0x83, 0xab, 0x00, 0x00 }, /* PS/2 102-key */ + { 0xab, 0x90, 0x00, 0x00 }, /* PS/2 106-key JIS */ + /* Japanese keyboard ID - TODO: Find the actual Korean one. */ + { 0xab, 0x90, 0x00, 0x00 }, /* PS/2 Korean */ + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 }, + { 0x00, 0x00, 0x00, 0x00 } }; + +/* Global keyboard flags for scan code set 3: + bit 0 = repeat, bit 1 = makes break code? */ +uint8_t keyboard_set3_flags[512]; +uint8_t keyboard_set3_all_repeat; +uint8_t keyboard_set3_all_break; + +static uint8_t inv_cmd_response = 0xfa; + +static const scancode scancode_set1[512] = { + // clang-format off + { { 0},{ 0} }, { { 0x01,0},{ 0x81,0} }, { { 0x02,0},{ 0x82,0} }, { { 0x03,0},{ 0x83,0} }, /*000*/ + { { 0x04,0},{ 0x84,0} }, { { 0x05,0},{ 0x85,0} }, { { 0x06,0},{ 0x86,0} }, { { 0x07,0},{ 0x87,0} }, /*004*/ + { { 0x08,0},{ 0x88,0} }, { { 0x09,0},{ 0x89,0} }, { { 0x0a,0},{ 0x8a,0} }, { { 0x0b,0},{ 0x8b,0} }, /*008*/ + { { 0x0c,0},{ 0x8c,0} }, { { 0x0d,0},{ 0x8d,0} }, { { 0x0e,0},{ 0x8e,0} }, { { 0x0f,0},{ 0x8f,0} }, /*00c*/ + { { 0x10,0},{ 0x90,0} }, { { 0x11,0},{ 0x91,0} }, { { 0x12,0},{ 0x92,0} }, { { 0x13,0},{ 0x93,0} }, /*010*/ + { { 0x14,0},{ 0x94,0} }, { { 0x15,0},{ 0x95,0} }, { { 0x16,0},{ 0x96,0} }, { { 0x17,0},{ 0x97,0} }, /*014*/ + { { 0x18,0},{ 0x98,0} }, { { 0x19,0},{ 0x99,0} }, { { 0x1a,0},{ 0x9a,0} }, { { 0x1b,0},{ 0x9b,0} }, /*018*/ + { { 0x1c,0},{ 0x9c,0} }, { { 0x1d,0},{ 0x9d,0} }, { { 0x1e,0},{ 0x9e,0} }, { { 0x1f,0},{ 0x9f,0} }, /*01c*/ + { { 0x20,0},{ 0xa0,0} }, { { 0x21,0},{ 0xa1,0} }, { { 0x22,0},{ 0xa2,0} }, { { 0x23,0},{ 0xa3,0} }, /*020*/ + { { 0x24,0},{ 0xa4,0} }, { { 0x25,0},{ 0xa5,0} }, { { 0x26,0},{ 0xa6,0} }, { { 0x27,0},{ 0xa7,0} }, /*024*/ + { { 0x28,0},{ 0xa8,0} }, { { 0x29,0},{ 0xa9,0} }, { { 0x2a,0},{ 0xaa,0} }, { { 0x2b,0},{ 0xab,0} }, /*028*/ + { { 0x2c,0},{ 0xac,0} }, { { 0x2d,0},{ 0xad,0} }, { { 0x2e,0},{ 0xae,0} }, { { 0x2f,0},{ 0xaf,0} }, /*02c*/ + { { 0x30,0},{ 0xb0,0} }, { { 0x31,0},{ 0xb1,0} }, { { 0x32,0},{ 0xb2,0} }, { { 0x33,0},{ 0xb3,0} }, /*030*/ + { { 0x34,0},{ 0xb4,0} }, { { 0x35,0},{ 0xb5,0} }, { { 0x36,0},{ 0xb6,0} }, { { 0x37,0},{ 0xb7,0} }, /*034*/ + { { 0x38,0},{ 0xb8,0} }, { { 0x39,0},{ 0xb9,0} }, { { 0x3a,0},{ 0xba,0} }, { { 0x3b,0},{ 0xbb,0} }, /*038*/ + { { 0x3c,0},{ 0xbc,0} }, { { 0x3d,0},{ 0xbd,0} }, { { 0x3e,0},{ 0xbe,0} }, { { 0x3f,0},{ 0xbf,0} }, /*03c*/ + { { 0x40,0},{ 0xc0,0} }, { { 0x41,0},{ 0xc1,0} }, { { 0x42,0},{ 0xc2,0} }, { { 0x43,0},{ 0xc3,0} }, /*040*/ + { { 0x44,0},{ 0xc4,0} }, { { 0x45,0},{ 0xc5,0} }, { { 0x46,0},{ 0xc6,0} }, { { 0x47,0},{ 0xc7,0} }, /*044*/ + { { 0x48,0},{ 0xc8,0} }, { { 0x49,0},{ 0xc9,0} }, { { 0x4a,0},{ 0xca,0} }, { { 0x4b,0},{ 0xcb,0} }, /*048*/ + { { 0x4c,0},{ 0xcc,0} }, { { 0x4d,0},{ 0xcd,0} }, { { 0x4e,0},{ 0xce,0} }, { { 0x4f,0},{ 0xcf,0} }, /*04c*/ + { { 0x50,0},{ 0xd0,0} }, { { 0x51,0},{ 0xd1,0} }, { { 0x52,0},{ 0xd2,0} }, { { 0x53,0},{ 0xd3,0} }, /*050*/ + { { 0x54,0},{ 0xd4,0} }, { { 0x55,0},{ 0xd5,0} }, { { 0x56,0},{ 0xd6,0} }, { { 0x57,0},{ 0xd7,0} }, /*054*/ + { { 0x58,0},{ 0xd8,0} }, { { 0x59,0},{ 0xd9,0} }, { { 0x5a,0},{ 0xda,0} }, { { 0x5b,0},{ 0xdb,0} }, /*058*/ + { { 0x5c,0},{ 0xdc,0} }, { { 0x5d,0},{ 0xdd,0} }, { { 0x5e,0},{ 0xde,0} }, { { 0x5f,0},{ 0xdf,0} }, /*05c*/ + { { 0x60,0},{ 0xe0,0} }, { { 0x61,0},{ 0xe1,0} }, { { 0x62,0},{ 0xe2,0} }, { { 0x63,0},{ 0xe3,0} }, /*060*/ + { { 0x64,0},{ 0xe4,0} }, { { 0x65,0},{ 0xe5,0} }, { { 0x66,0},{ 0xe6,0} }, { { 0x67,0},{ 0xe7,0} }, /*064*/ + { { 0x68,0},{ 0xe8,0} }, { { 0x69,0},{ 0xe9,0} }, { { 0x6a,0},{ 0xea,0} }, { { 0x6b,0},{ 0xeb,0} }, /*068*/ + { { 0x6c,0},{ 0xec,0} }, { { 0x6d,0},{ 0xed,0} }, { { 0x6e,0},{ 0xee,0} }, { { 0x6f,0},{ 0xef,0} }, /*06c*/ + { { 0x70,0},{ 0xf0,0} }, { { 0x71,0},{ 0xf1,0} }, { { 0x72,0},{ 0xf2,0} }, { { 0x73,0},{ 0xf3,0} }, /*070*/ + { { 0x74,0},{ 0xf4,0} }, { { 0x75,0},{ 0xf5,0} }, { { 0x76,0},{ 0xf6,0} }, { { 0x77,0},{ 0xf7,0} }, /*074*/ + { { 0x78,0},{ 0xf8,0} }, { { 0x79,0},{ 0xf9,0} }, { { 0x7a,0},{ 0xfa,0} }, { { 0x7b,0},{ 0xfb,0} }, /*078*/ + { { 0x7c,0},{ 0xfc,0} }, { { 0x7d,0},{ 0xfd,0} }, { { 0x7e,0},{ 0xfe,0} }, { { 0x7f,0},{ 0xff,0} }, /*07c*/ + + { { 0x80,0},{ 0} }, { { 0x81,0},{ 0} }, { { 0x82,0},{ 0} }, { { 0},{ 0} }, /*080*/ + { { 0},{ 0} }, { { 0x85,0},{ 0} }, { { 0x86,0},{ 0} }, { { 0x87,0},{ 0} }, /*084*/ + { { 0x88,0},{ 0} }, { { 0x89,0},{ 0} }, { { 0x8a,0},{ 0} }, { { 0x8b,0},{ 0} }, /*088*/ + { { 0x8c,0},{ 0} }, { { 0x8d,0},{ 0} }, { { 0x8e,0},{ 0} }, { { 0x8f,0},{ 0} }, /*08c*/ + { { 0x90,0},{ 0} }, { { 0x91,0},{ 0} }, { { 0x92,0},{ 0} }, { { 0x93,0},{ 0} }, /*090*/ + { { 0x94,0},{ 0} }, { { 0x95,0},{ 0} }, { { 0x96,0},{ 0} }, { { 0x97,0},{ 0} }, /*094*/ + { { 0x98,0},{ 0} }, { { 0x99,0},{ 0} }, { { 0x9a,0},{ 0} }, { { 0x9b,0},{ 0} }, /*098*/ + { { 0x9c,0},{ 0} }, { { 0x9d,0},{ 0} }, { { 0x9e,0},{ 0} }, { { 0x9f,0},{ 0} }, /*09c*/ + { { 0xa0,0},{ 0} }, { { 0xa1,0},{ 0} }, { { 0xa2,0},{ 0} }, { { 0xa3,0},{ 0} }, /*0a0*/ + { { 0xa4,0},{ 0} }, { { 0xa5,0},{ 0} }, { { 0xa6,0},{ 0} }, { { 0xa7,0},{ 0} }, /*0a4*/ + { { 0xa8,0},{ 0} }, { { 0xa9,0},{ 0} }, { { 0xaa,0},{ 0} }, { { 0xab,0},{ 0} }, /*0a8*/ + { { 0xac,0},{ 0} }, { { 0xad,0},{ 0} }, { { 0xae,0},{ 0} }, { { 0xaf,0},{ 0} }, /*0ac*/ + { { 0xb0,0},{ 0} }, { { 0xb1,0},{ 0} }, { { 0xb2,0},{ 0} }, { { 0xb3,0},{ 0} }, /*0b0*/ + { { 0xb4,0},{ 0} }, { { 0xb5,0},{ 0} }, { { 0xb6,0},{ 0} }, { { 0xb7,0},{ 0} }, /*0b4*/ + { { 0xb8,0},{ 0} }, { { 0xb9,0},{ 0} }, { { 0xba,0},{ 0} }, { { 0xbb,0},{ 0} }, /*0b8*/ + { { 0xbc,0},{ 0} }, { { 0xbd,0},{ 0} }, { { 0xbe,0},{ 0} }, { { 0xbf,0},{ 0} }, /*0bc*/ + { { 0xc0,0},{ 0} }, { { 0xc1,0},{ 0} }, { { 0xc2,0},{ 0} }, { { 0xc3,0},{ 0} }, /*0c0*/ + { { 0xc4,0},{ 0} }, { { 0xc5,0},{ 0} }, { { 0xc6,0},{ 0} }, { { 0xc7,0},{ 0} }, /*0c4*/ + { { 0xc8,0},{ 0} }, { { 0xc9,0},{ 0} }, { { 0xca,0},{ 0} }, { { 0xcb,0},{ 0} }, /*0c8*/ + { { 0xcc,0},{ 0} }, { { 0xcd,0},{ 0} }, { { 0xce,0},{ 0} }, { { 0xcf,0},{ 0} }, /*0cc*/ + { { 0xd0,0},{ 0} }, { { 0xd1,0},{ 0} }, { { 0xd2,0},{ 0} }, { { 0xd3,0},{ 0} }, /*0d0*/ + { { 0xd4,0},{ 0} }, { { 0xd5,0},{ 0} }, { { 0xd6,0},{ 0} }, { { 0xd7,0},{ 0} }, /*0d4*/ + { { 0xd8,0},{ 0} }, { { 0xd9,0},{ 0} }, { { 0xda,0},{ 0} }, { { 0xdb,0},{ 0} }, /*0d8*/ + { { 0xdc,0},{ 0} }, { { 0xdd,0},{ 0} }, { { 0xde,0},{ 0} }, { { 0xdf,0},{ 0} }, /*0dc*/ + { { 0xe0,0},{ 0} }, { { 0xe1,0},{ 0} }, { { 0xe2,0},{ 0} }, { { 0xe3,0},{ 0} }, /*0e0*/ + { { 0xe4,0},{ 0} }, { { 0xe5,0},{ 0} }, { { 0xe6,0},{ 0} }, { { 0xe7,0},{ 0} }, /*0e4*/ + { { 0xe8,0},{ 0} }, { { 0xe9,0},{ 0} }, { { 0xea,0},{ 0} }, { { 0xeb,0},{ 0} }, /*0e8*/ + { { 0xec,0},{ 0} }, { { 0xed,0},{ 0} }, { { 0xee,0},{ 0} }, { { 0xef,0},{ 0} }, /*0ec*/ + { { 0},{ 0} }, { { 0xf1,0},{ 0} }, { { 0xf2,0},{ 0} }, { { 0xf3,0},{ 0} }, /*0f0*/ + { { 0xf4,0},{ 0} }, { { 0xf5,0},{ 0} }, { { 0xf6,0},{ 0} }, { { 0xf7,0},{ 0} }, /*0f4*/ + { { 0xf8,0},{ 0} }, { { 0xf9,0},{ 0} }, { { 0xfa,0},{ 0} }, { { 0xfb,0},{ 0} }, /*0f8*/ + { { 0xfc,0},{ 0} }, { { 0xfd,0},{ 0} }, { { 0xfe,0},{ 0} }, { { 0xff,0},{ 0} }, /*0fc*/ + + { {0xe1,0x1d,0},{0xe1, 0x9d,0} }, { {0xe0,0x01,0},{0xe0, 0x81,0} }, { {0xe0,0x02,0},{0xe0, 0x82,0} }, { {0xe0,0x03,0},{0xe0, 0x83,0} }, /*100*/ + { {0xe0,0x04,0},{0xe0, 0x84,0} }, { {0xe0,0x05,0},{0xe0, 0x85,0} }, { {0xe0,0x06,0},{0xe0, 0x86,0} }, { {0xe0,0x07,0},{0xe0, 0x87,0} }, /*104*/ + { {0xe0,0x08,0},{0xe0, 0x88,0} }, { {0xe0,0x09,0},{0xe0, 0x89,0} }, { {0xe0,0x0a,0},{0xe0, 0x8a,0} }, { {0xe0,0x0b,0},{0xe0, 0x8b,0} }, /*108*/ + { {0xe0,0x0c,0},{0xe0, 0x8c,0} }, { { 0},{ 0} }, { {0xe0,0x0e,0},{0xe0, 0x8e,0} }, { {0xe0,0x0f,0},{0xe0, 0x8f,0} }, /*10c*/ + { {0xe0,0x10,0},{0xe0, 0x90,0} }, { {0xe0,0x11,0},{0xe0, 0x91,0} }, { {0xe0,0x12,0},{0xe0, 0x92,0} }, { {0xe0,0x13,0},{0xe0, 0x93,0} }, /*110*/ + { {0xe0,0x14,0},{0xe0, 0x94,0} }, { {0xe0,0x15,0},{0xe0, 0x95,0} }, { {0xe0,0x16,0},{0xe0, 0x96,0} }, { {0xe0,0x17,0},{0xe0, 0x97,0} }, /*114*/ + { {0xe0,0x18,0},{0xe0, 0x98,0} }, { {0xe0,0x19,0},{0xe0, 0x99,0} }, { {0xe0,0x1a,0},{0xe0, 0x9a,0} }, { {0xe0,0x1b,0},{0xe0, 0x9b,0} }, /*118*/ + { {0xe0,0x1c,0},{0xe0, 0x9c,0} }, { {0xe0,0x1d,0},{0xe0, 0x9d,0} }, { {0xe0,0x1e,0},{0xe0, 0x9e,0} }, { {0xe0,0x1f,0},{0xe0, 0x9f,0} }, /*11c*/ + { {0xe0,0x20,0},{0xe0, 0xa0,0} }, { {0xe0,0x21,0},{0xe0, 0xa1,0} }, { {0xe0,0x22,0},{0xe0, 0xa2,0} }, { {0xe0,0x23,0},{0xe0, 0xa3,0} }, /*120*/ + { {0xe0,0x24,0},{0xe0, 0xa4,0} }, { {0xe0,0x25,0},{0xe0, 0xa5,0} }, { {0xe0,0x26,0},{0xe0, 0xa6,0} }, { { 0},{ 0} }, /*124*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/ + { {0xe0,0x2c,0},{0xe0, 0xac,0} }, { {0xe0,0x2d,0},{0xe0, 0xad,0} }, { {0xe0,0x2e,0},{0xe0, 0xae,0} }, { {0xe0,0x2f,0},{0xe0, 0xaf,0} }, /*12c*/ + { {0xe0,0x30,0},{0xe0, 0xb0,0} }, { {0xe0,0x31,0},{0xe0, 0xb1,0} }, { {0xe0,0x32,0},{0xe0, 0xb2,0} }, { { 0},{ 0} }, /*130*/ + { {0xe0,0x34,0},{0xe0, 0xb4,0} }, { {0xe0,0x35,0},{0xe0, 0xb5,0} }, { { 0},{ 0} }, { {0xe0,0x37,0},{0xe0, 0xb7,0} }, /*134*/ + { {0xe0,0x38,0},{0xe0, 0xb8,0} }, { { 0},{ 0} }, { {0xe0,0x3a,0},{0xe0, 0xba,0} }, { {0xe0,0x3b,0},{0xe0, 0xbb,0} }, /*138*/ + { {0xe0,0x3c,0},{0xe0, 0xbc,0} }, { {0xe0,0x3d,0},{0xe0, 0xbd,0} }, { {0xe0,0x3e,0},{0xe0, 0xbe,0} }, { {0xe0,0x3f,0},{0xe0, 0xbf,0} }, /*13c*/ + { {0xe0,0x40,0},{0xe0, 0xc0,0} }, { {0xe0,0x41,0},{0xe0, 0xc1,0} }, { {0xe0,0x42,0},{0xe0, 0xc2,0} }, { {0xe0,0x43,0},{0xe0, 0xc3,0} }, /*140*/ + { {0xe0,0x44,0},{0xe0, 0xc4,0} }, { { 0},{ 0} }, { {0xe0,0x46,0},{0xe0, 0xc6,0} }, { {0xe0,0x47,0},{0xe0, 0xc7,0} }, /*144*/ + { {0xe0,0x48,0},{0xe0, 0xc8,0} }, { {0xe0,0x49,0},{0xe0, 0xc9,0} }, { { 0},{ 0} }, { {0xe0,0x4b,0},{0xe0, 0xcb,0} }, /*148*/ + { {0xe0,0x4c,0},{0xe0, 0xcc,0} }, { {0xe0,0x4d,0},{0xe0, 0xcd,0} }, { {0xe0,0x4e,0},{0xe0, 0xce,0} }, { {0xe0,0x4f,0},{0xe0, 0xcf,0} }, /*14c*/ + { {0xe0,0x50,0},{0xe0, 0xd0,0} }, { {0xe0,0x51,0},{0xe0, 0xd1,0} }, { {0xe0,0x52,0},{0xe0, 0xd2,0} }, { {0xe0,0x53,0},{0xe0, 0xd3,0} }, /*150*/ + { { 0},{ 0} }, { {0xe0,0x55,0},{0xe0, 0xd5,0} }, { { 0},{ 0} }, { {0xe0,0x57,0},{0xe0, 0xd7,0} }, /*154*/ + { {0xe0,0x58,0},{0xe0, 0xd8,0} }, { {0xe0,0x59,0},{0xe0, 0xd9,0} }, { {0xe0,0x5a,0},{0xe0, 0xaa,0} }, { {0xe0,0x5b,0},{0xe0, 0xdb,0} }, /*158*/ + { {0xe0,0x5c,0},{0xe0, 0xdc,0} }, { {0xe0,0x5d,0},{0xe0, 0xdd,0} }, { {0xe0,0x5e,0},{0xe0, 0xee,0} }, { {0xe0,0x5f,0},{0xe0, 0xdf,0} }, /*15c*/ + { { 0},{ 0} }, { {0xe0,0x61,0},{0xe0, 0xe1,0} }, { {0xe0,0x62,0},{0xe0, 0xe2,0} }, { {0xe0,0x63,0},{0xe0, 0xe3,0} }, /*160*/ + { {0xe0,0x64,0},{0xe0, 0xe4,0} }, { {0xe0,0x65,0},{0xe0, 0xe5,0} }, { {0xe0,0x66,0},{0xe0, 0xe6,0} }, { {0xe0,0x67,0},{0xe0, 0xe7,0} }, /*164*/ + { {0xe0,0x68,0},{0xe0, 0xe8,0} }, { {0xe0,0x69,0},{0xe0, 0xe9,0} }, { {0xe0,0x6a,0},{0xe0, 0xea,0} }, { {0xe0,0x6b,0},{0xe0, 0xeb,0} }, /*168*/ + { {0xe0,0x6c,0},{0xe0, 0xec,0} }, { {0xe0,0x6d,0},{0xe0, 0xed,0} }, { {0xe0,0x6e,0},{0xe0, 0xee,0} }, { { 0},{ 0} }, /*16c*/ + { {0xe0,0x70,0},{0xe0, 0xf0,0} }, { {0xe0,0x71,0},{0xe0, 0xf1,0} }, { {0xe0,0x72,0},{0xe0, 0xf2,0} }, { {0xe0,0x73,0},{0xe0, 0xf3,0} }, /*170*/ + { {0xe0,0x74,0},{0xe0, 0xf4,0} }, { {0xe0,0x75,0},{0xe0, 0xf5,0} }, { { 0},{ 0} }, { {0xe0,0x77,0},{0xe0, 0xf7,0} }, /*174*/ + { {0xe0,0x78,0},{0xe0, 0xf8,0} }, { {0xe0,0x79,0},{0xe0, 0xf9,0} }, { {0xe0,0x7a,0},{0xe0, 0xfa,0} }, { {0xe0,0x7b,0},{0xe0, 0xfb,0} }, /*178*/ + { {0xe0,0x7c,0},{0xe0, 0xfc,0} }, { {0xe0,0x7d,0},{0xe0, 0xfd,0} }, { {0xe0,0x7e,0},{0xe0, 0xfe,0} }, { {0xe0,0x7f,0},{0xe0, 0xff,0} }, /*17c*/ + + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/ + { { 0},{ 0} }, { {0xe0,0xe1,0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{ 0} }, { { 0},{ 0} }, /*1ec*/ + { { 0},{ 0} }, { {0xe0,0xf1,0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{ 0} }, { {0xe0,0xff,0},{ 0} } /*1fc*/ + // clang-format on +}; + +static const scancode scancode_set2[512] = { + // clang-format off + { { 0},{ 0} }, { { 0x76,0},{ 0xF0,0x76,0} }, { { 0x16,0},{ 0xF0,0x16,0} }, { { 0x1E,0},{ 0xF0,0x1E,0} }, /*000*/ + { { 0x26,0},{ 0xF0,0x26,0} }, { { 0x25,0},{ 0xF0,0x25,0} }, { { 0x2E,0},{ 0xF0,0x2E,0} }, { { 0x36,0},{ 0xF0,0x36,0} }, /*004*/ + { { 0x3D,0},{ 0xF0,0x3D,0} }, { { 0x3E,0},{ 0xF0,0x3E,0} }, { { 0x46,0},{ 0xF0,0x46,0} }, { { 0x45,0},{ 0xF0,0x45,0} }, /*008*/ + { { 0x4E,0},{ 0xF0,0x4E,0} }, { { 0x55,0},{ 0xF0,0x55,0} }, { { 0x66,0},{ 0xF0,0x66,0} }, { { 0x0D,0},{ 0xF0,0x0D,0} }, /*00c*/ + { { 0x15,0},{ 0xF0,0x15,0} }, { { 0x1D,0},{ 0xF0,0x1D,0} }, { { 0x24,0},{ 0xF0,0x24,0} }, { { 0x2D,0},{ 0xF0,0x2D,0} }, /*010*/ + { { 0x2C,0},{ 0xF0,0x2C,0} }, { { 0x35,0},{ 0xF0,0x35,0} }, { { 0x3C,0},{ 0xF0,0x3C,0} }, { { 0x43,0},{ 0xF0,0x43,0} }, /*014*/ + { { 0x44,0},{ 0xF0,0x44,0} }, { { 0x4D,0},{ 0xF0,0x4D,0} }, { { 0x54,0},{ 0xF0,0x54,0} }, { { 0x5B,0},{ 0xF0,0x5B,0} }, /*018*/ + { { 0x5A,0},{ 0xF0,0x5A,0} }, { { 0x14,0},{ 0xF0,0x14,0} }, { { 0x1C,0},{ 0xF0,0x1C,0} }, { { 0x1B,0},{ 0xF0,0x1B,0} }, /*01c*/ + { { 0x23,0},{ 0xF0,0x23,0} }, { { 0x2B,0},{ 0xF0,0x2B,0} }, { { 0x34,0},{ 0xF0,0x34,0} }, { { 0x33,0},{ 0xF0,0x33,0} }, /*020*/ + { { 0x3B,0},{ 0xF0,0x3B,0} }, { { 0x42,0},{ 0xF0,0x42,0} }, { { 0x4B,0},{ 0xF0,0x4B,0} }, { { 0x4C,0},{ 0xF0,0x4C,0} }, /*024*/ + { { 0x52,0},{ 0xF0,0x52,0} }, { { 0x0E,0},{ 0xF0,0x0E,0} }, { { 0x12,0},{ 0xF0,0x12,0} }, { { 0x5D,0},{ 0xF0,0x5D,0} }, /*028*/ + { { 0x1A,0},{ 0xF0,0x1A,0} }, { { 0x22,0},{ 0xF0,0x22,0} }, { { 0x21,0},{ 0xF0,0x21,0} }, { { 0x2A,0},{ 0xF0,0x2A,0} }, /*02c*/ + { { 0x32,0},{ 0xF0,0x32,0} }, { { 0x31,0},{ 0xF0,0x31,0} }, { { 0x3A,0},{ 0xF0,0x3A,0} }, { { 0x41,0},{ 0xF0,0x41,0} }, /*030*/ + { { 0x49,0},{ 0xF0,0x49,0} }, { { 0x4A,0},{ 0xF0,0x4A,0} }, { { 0x59,0},{ 0xF0,0x59,0} }, { { 0x7C,0},{ 0xF0,0x7C,0} }, /*034*/ + { { 0x11,0},{ 0xF0,0x11,0} }, { { 0x29,0},{ 0xF0,0x29,0} }, { { 0x58,0},{ 0xF0,0x58,0} }, { { 0x05,0},{ 0xF0,0x05,0} }, /*038*/ + { { 0x06,0},{ 0xF0,0x06,0} }, { { 0x04,0},{ 0xF0,0x04,0} }, { { 0x0C,0},{ 0xF0,0x0C,0} }, { { 0x03,0},{ 0xF0,0x03,0} }, /*03c*/ + { { 0x0B,0},{ 0xF0,0x0B,0} }, { { 0x83,0},{ 0xF0,0x83,0} }, { { 0x0A,0},{ 0xF0,0x0A,0} }, { { 0x01,0},{ 0xF0,0x01,0} }, /*040*/ + { { 0x09,0},{ 0xF0,0x09,0} }, { { 0x77,0},{ 0xF0,0x77,0} }, { { 0x7E,0},{ 0xF0,0x7E,0} }, { { 0x6C,0},{ 0xF0,0x6C,0} }, /*044*/ + { { 0x75,0},{ 0xF0,0x75,0} }, { { 0x7D,0},{ 0xF0,0x7D,0} }, { { 0x7B,0},{ 0xF0,0x7B,0} }, { { 0x6B,0},{ 0xF0,0x6B,0} }, /*048*/ + { { 0x73,0},{ 0xF0,0x73,0} }, { { 0x74,0},{ 0xF0,0x74,0} }, { { 0x79,0},{ 0xF0,0x79,0} }, { { 0x69,0},{ 0xF0,0x69,0} }, /*04c*/ + { { 0x72,0},{ 0xF0,0x72,0} }, { { 0x7A,0},{ 0xF0,0x7A,0} }, { { 0x70,0},{ 0xF0,0x70,0} }, { { 0x71,0},{ 0xF0,0x71,0} }, /*050*/ + { { 0x84,0},{ 0xF0,0x84,0} }, { { 0x60,0},{ 0xF0,0x60,0} }, { { 0x61,0},{ 0xF0,0x61,0} }, { { 0x78,0},{ 0xF0,0x78,0} }, /*054*/ + { { 0x07,0},{ 0xF0,0x07,0} }, { { 0x0F,0},{ 0xF0,0x0F,0} }, { { 0x17,0},{ 0xF0,0x17,0} }, { { 0x1F,0},{ 0xF0,0x1F,0} }, /*058*/ + { { 0x27,0},{ 0xF0,0x27,0} }, { { 0x2F,0},{ 0xF0,0x2F,0} }, { { 0x37,0},{ 0xF0,0x37,0} }, { { 0x3F,0},{ 0xF0,0x3F,0} }, /*05c*/ + { { 0x47,0},{ 0xF0,0x47,0} }, { { 0x4F,0},{ 0xF0,0x4F,0} }, { { 0x56,0},{ 0xF0,0x56,0} }, { { 0x5E,0},{ 0xF0,0x5E,0} }, /*060*/ + { { 0x08,0},{ 0xF0,0x08,0} }, { { 0x10,0},{ 0xF0,0x10,0} }, { { 0x18,0},{ 0xF0,0x18,0} }, { { 0x20,0},{ 0xF0,0x20,0} }, /*064*/ + { { 0x28,0},{ 0xF0,0x28,0} }, { { 0x30,0},{ 0xF0,0x30,0} }, { { 0x38,0},{ 0xF0,0x38,0} }, { { 0x40,0},{ 0xF0,0x40,0} }, /*068*/ + { { 0x48,0},{ 0xF0,0x48,0} }, { { 0x50,0},{ 0xF0,0x50,0} }, { { 0x57,0},{ 0xF0,0x57,0} }, { { 0x6F,0},{ 0xF0,0x6F,0} }, /*06c*/ + { { 0x13,0},{ 0xF0,0x13,0} }, { { 0x19,0},{ 0xF0,0x19,0} }, { { 0x39,0},{ 0xF0,0x39,0} }, { { 0x51,0},{ 0xF0,0x51,0} }, /*070*/ + { { 0x53,0},{ 0xF0,0x53,0} }, { { 0x5C,0},{ 0xF0,0x5C,0} }, { { 0x5F,0},{ 0xF0,0x5F,0} }, { { 0x62,0},{ 0xF0,0x62,0} }, /*074*/ + { { 0x63,0},{ 0xF0,0x63,0} }, { { 0x64,0},{ 0xF0,0x64,0} }, { { 0x65,0},{ 0xF0,0x65,0} }, { { 0x67,0},{ 0xF0,0x67,0} }, /*078*/ + { { 0x68,0},{ 0xF0,0x68,0} }, { { 0x6A,0},{ 0xF0,0x6A,0} }, { { 0x6D,0},{ 0xF0,0x6D,0} }, { { 0x6E,0},{ 0xF0,0x6E,0} }, /*07c*/ + + { { 0x80,0},{ 0xf0,0x80,0} }, { { 0x81,0},{ 0xf0,0x81,0} }, { { 0x82,0},{ 0xf0,0x82,0} }, { { 0},{ 0} }, /*080*/ + { { 0},{ 0} }, { { 0x85,0},{ 0xf0,0x54,0} }, { { 0x86,0},{ 0xf0,0x86,0} }, { { 0x87,0},{ 0xf0,0x87,0} }, /*084*/ + { { 0x88,0},{ 0xf0,0x88,0} }, { { 0x89,0},{ 0xf0,0x89,0} }, { { 0x8a,0},{ 0xf0,0x8a,0} }, { { 0x8b,0},{ 0xf0,0x8b,0} }, /*088*/ + { { 0x8c,0},{ 0xf0,0x8c,0} }, { { 0x8d,0},{ 0xf0,0x8d,0} }, { { 0x8e,0},{ 0xf0,0x8e,0} }, { { 0x8f,0},{ 0xf0,0x8f,0} }, /*08c*/ + { { 0x90,0},{ 0xf0,0x90,0} }, { { 0x91,0},{ 0xf0,0x91,0} }, { { 0x92,0},{ 0xf0,0x92,0} }, { { 0x93,0},{ 0xf0,0x93,0} }, /*090*/ + { { 0x94,0},{ 0xf0,0x94,0} }, { { 0x95,0},{ 0xf0,0x95,0} }, { { 0x96,0},{ 0xf0,0x96,0} }, { { 0x97,0},{ 0xf0,0x97,0} }, /*094*/ + { { 0x98,0},{ 0xf0,0x98,0} }, { { 0x99,0},{ 0xf0,0x99,0} }, { { 0x9a,0},{ 0xf0,0x9a,0} }, { { 0x9b,0},{ 0xf0,0x9b,0} }, /*098*/ + { { 0x9c,0},{ 0xf0,0x9c,0} }, { { 0x9d,0},{ 0xf0,0x9d,0} }, { { 0x9e,0},{ 0xf0,0x9e,0} }, { { 0x9f,0},{ 0xf0,0x9f,0} }, /*09c*/ + { { 0xa0,0},{ 0xf0,0xa0,0} }, { { 0xa1,0},{ 0xf0,0xa1,0} }, { { 0xa2,0},{ 0xf0,0xa2,0} }, { { 0xa3,0},{ 0xf0,0xa3,0} }, /*0a0*/ + { { 0xa4,0},{ 0xf0,0xa4,0} }, { { 0xa5,0},{ 0xf0,0xa5,0} }, { { 0xa6,0},{ 0xf0,0xa6,0} }, { { 0xa7,0},{ 0xf0,0xa7,0} }, /*0a4*/ + { { 0xa8,0},{ 0xf0,0xa8,0} }, { { 0xa9,0},{ 0xf0,0xa9,0} }, { { 0xaa,0},{ 0xf0,0xaa,0} }, { { 0xab,0},{ 0xf0,0xab,0} }, /*0a8*/ + { { 0xac,0},{ 0xf0,0xac,0} }, { { 0xad,0},{ 0xf0,0xad,0} }, { { 0xae,0},{ 0xf0,0xae,0} }, { { 0xaf,0},{ 0xf0,0xaf,0} }, /*0ac*/ + { { 0xb0,0},{ 0xf0,0xb0,0} }, { { 0xb1,0},{ 0xf0,0xb1,0} }, { { 0xb2,0},{ 0xf0,0xb2,0} }, { { 0xb3,0},{ 0xf0,0xb3,0} }, /*0b0*/ + { { 0xb4,0},{ 0xf0,0xb4,0} }, { { 0xb5,0},{ 0xf0,0xb5,0} }, { { 0xb6,0},{ 0xf0,0xb6,0} }, { { 0xb7,0},{ 0xf0,0xb7,0} }, /*0b4*/ + { { 0xb8,0},{ 0xf0,0xb8,0} }, { { 0xb9,0},{ 0xf0,0xb9,0} }, { { 0xba,0},{ 0xf0,0xba,0} }, { { 0xbb,0},{ 0xf0,0xbb,0} }, /*0b8*/ + { { 0xbc,0},{ 0xf0,0xbc,0} }, { { 0xbd,0},{ 0xf0,0xbd,0} }, { { 0xbe,0},{ 0xf0,0xbe,0} }, { { 0xbf,0},{ 0xf0,0xbf,0} }, /*0bc*/ + { { 0xc0,0},{ 0xf0,0xc0,0} }, { { 0xc1,0},{ 0xf0,0xc1,0} }, { { 0xc2,0},{ 0xf0,0xc2,0} }, { { 0xc3,0},{ 0xf0,0xc3,0} }, /*0c0*/ + { { 0xc4,0},{ 0xf0,0xc4,0} }, { { 0xc5,0},{ 0xf0,0xc5,0} }, { { 0xc6,0},{ 0xf0,0xc6,0} }, { { 0xc7,0},{ 0xf0,0xc7,0} }, /*0c4*/ + { { 0xc8,0},{ 0xf0,0xc8,0} }, { { 0xc9,0},{ 0xf0,0xc9,0} }, { { 0xca,0},{ 0xf0,0xca,0} }, { { 0xcb,0},{ 0xf0,0xcb,0} }, /*0c8*/ + { { 0xcc,0},{ 0xf0,0xcc,0} }, { { 0xcd,0},{ 0xf0,0xcd,0} }, { { 0xce,0},{ 0xf0,0xce,0} }, { { 0xcf,0},{ 0xf0,0xcf,0} }, /*0cc*/ + { { 0xd0,0},{ 0xf0,0xd0,0} }, { { 0xd1,0},{ 0xf0,0xd0,0} }, { { 0xd2,0},{ 0xf0,0xd2,0} }, { { 0xd3,0},{ 0xf0,0xd3,0} }, /*0d0*/ + { { 0xd4,0},{ 0xf0,0xd4,0} }, { { 0xd5,0},{ 0xf0,0xd5,0} }, { { 0xd6,0},{ 0xf0,0xd6,0} }, { { 0xd7,0},{ 0xf0,0xd7,0} }, /*0d4*/ + { { 0xd8,0},{ 0xf0,0xd8,0} }, { { 0xd9,0},{ 0xf0,0xd9,0} }, { { 0xda,0},{ 0xf0,0xda,0} }, { { 0xdb,0},{ 0xf0,0xdb,0} }, /*0d8*/ + { { 0xdc,0},{ 0xf0,0xdc,0} }, { { 0xdd,0},{ 0xf0,0xdd,0} }, { { 0xde,0},{ 0xf0,0xde,0} }, { { 0xdf,0},{ 0xf0,0xdf,0} }, /*0dc*/ + { { 0xe0,0},{ 0xf0,0xe0,0} }, { { 0xe1,0},{ 0xf0,0xe1,0} }, { { 0xe2,0},{ 0xf0,0xe2,0} }, { { 0xe3,0},{ 0xf0,0xe3,0} }, /*0e0*/ + { { 0xe4,0},{ 0xf0,0xe4,0} }, { { 0xe5,0},{ 0xf0,0xe5,0} }, { { 0xe6,0},{ 0xf0,0xe6,0} }, { { 0xe7,0},{ 0xf0,0xe7,0} }, /*0e4*/ + { { 0xe8,0},{ 0xf0,0xe8,0} }, { { 0xe9,0},{ 0xf0,0xe9,0} }, { { 0xea,0},{ 0xf0,0xea,0} }, { { 0xeb,0},{ 0xf0,0xeb,0} }, /*0e8*/ + { { 0xec,0},{ 0xf0,0xec,0} }, { { 0xed,0},{ 0xf0,0xed,0} }, { { 0xee,0},{ 0xf0,0xee,0} }, { { 0xef,0},{ 0xf0,0xef,0} }, /*0ec*/ + { { 0},{ 0} }, { { 0xf1,0},{ 0xf0,0xf1,0} }, { { 0xf2,0},{ 0xf0,0xf2,0} }, { { 0xf3,0},{ 0xf0,0xf3,0} }, /*0f0*/ + { { 0xf4,0},{ 0xf0,0xf4,0} }, { { 0xf5,0},{ 0xf0,0xf5,0} }, { { 0xf6,0},{ 0xf0,0xf6,0} }, { { 0xf7,0},{ 0xf0,0xf7,0} }, /*0f4*/ + { { 0xf8,0},{ 0xf0,0xf8,0} }, { { 0xf9,0},{ 0xf0,0xf9,0} }, { { 0xfa,0},{ 0xf0,0xfa,0} }, { { 0xfb,0},{ 0xf0,0xfb,0} }, /*0f8*/ + { { 0xfc,0},{ 0xf0,0xfc,0} }, { { 0xfd,0},{ 0xf0,0xfd,0} }, { { 0xfe,0},{ 0xf0,0xfe,0} }, { { 0xff,0},{ 0xf0,0xff,0} }, /*0fc*/ + + { {0xe1,0x14,0},{0xe1,0xf0,0x14,0} }, { {0xe0,0x76,0},{0xe0,0xF0,0x76,0} }, { {0xe0,0x16,0},{0xe0,0xF0,0x16,0} }, { {0xe0,0x1E,0},{0xe0,0xF0,0x1E,0} }, /*100*/ + { {0xe0,0x26,0},{0xe0,0xF0,0x26,0} }, { {0xe0,0x25,0},{0xe0,0xF0,0x25,0} }, { {0xe0,0x2E,0},{0xe0,0xF0,0x2E,0} }, { {0xe0,0x36,0},{0xe0,0xF0,0x36,0} }, /*104*/ + { {0xe0,0x3D,0},{0xe0,0xF0,0x3D,0} }, { {0xe0,0x3E,0},{0xe0,0xF0,0x3E,0} }, { {0xe0,0x46,0},{0xe0,0xF0,0x46,0} }, { {0xe0,0x45,0},{0xe0,0xF0,0x45,0} }, /*108*/ + { {0xe0,0x4E,0},{0xe0,0xF0,0x4E,0} }, { { 0},{ 0} }, { {0xe0,0x66,0},{0xe0,0xF0,0x66,0} }, { {0xe0,0x0D,0},{0xe0,0xF0,0x0D,0} }, /*10c*/ + { {0xe0,0x15,0},{0xe0,0xF0,0x15,0} }, { {0xe0,0x1D,0},{0xe0,0xF0,0x1D,0} }, { {0xe0,0x24,0},{0xe0,0xF0,0x24,0} }, { {0xe0,0x2D,0},{0xe0,0xF0,0x2D,0} }, /*110*/ + { {0xe0,0x2C,0},{0xe0,0xF0,0x2C,0} }, { {0xe0,0x35,0},{0xe0,0xF0,0x35,0} }, { {0xe0,0x3C,0},{0xe0,0xF0,0x3C,0} }, { {0xe0,0x43,0},{0xe0,0xF0,0x43,0} }, /*114*/ + { {0xe0,0x44,0},{0xe0,0xF0,0x44,0} }, { {0xe0,0x4D,0},{0xe0,0xF0,0x4D,0} }, { {0xe0,0x54,0},{0xe0,0xF0,0x54,0} }, { {0xe0,0x5B,0},{0xe0,0xF0,0x5B,0} }, /*118*/ + { {0xe0,0x5A,0},{0xe0,0xF0,0x5A,0} }, { {0xe0,0x14,0},{0xe0,0xF0,0x14,0} }, { {0xe0,0x1C,0},{0xe0,0xF0,0x1C,0} }, { {0xe0,0x1B,0},{0xe0,0xF0,0x1B,0} }, /*11c*/ + { {0xe0,0x23,0},{0xe0,0xF0,0x23,0} }, { {0xe0,0x2B,0},{0xe0,0xF0,0x2B,0} }, { {0xe0,0x34,0},{0xe0,0xF0,0x34,0} }, { {0xe0,0x33,0},{0xe0,0xF0,0x33,0} }, /*120*/ + { {0xe0,0x3B,0},{0xe0,0xF0,0x3B,0} }, { {0xe0,0x42,0},{0xe0,0xF0,0x42,0} }, { {0xe0,0x4B,0},{0xe0,0xF0,0x4B,0} }, { { 0},{ 0} }, /*124*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/ + { {0xe0,0x1A,0},{0xe0,0xF0,0x1A,0} }, { {0xe0,0x22,0},{0xe0,0xF0,0x22,0} }, { {0xe0,0x21,0},{0xe0,0xF0,0x21,0} }, { {0xe0,0x2A,0},{0xe0,0xF0,0x2A,0} }, /*12c*/ + { {0xe0,0x32,0},{0xe0,0xF0,0x32,0} }, { {0xe0,0x31,0},{0xe0,0xF0,0x31,0} }, { {0xe0,0x3A,0},{0xe0,0xF0,0x3A,0} }, { { 0},{ 0} }, /*130*/ + { {0xe0,0x49,0},{0xe0,0xF0,0x49,0} }, { {0xe0,0x4A,0},{0xe0,0xF0,0x4A,0} }, { { 0},{ 0} }, { {0xe0,0x7C,0},{0xe0,0xF0,0x7C,0} }, /*134*/ + { {0xe0,0x11,0},{0xe0,0xF0,0x11,0} }, { { 0},{ 0} }, { {0xe0,0x58,0},{0xe0,0xF0,0x58,0} }, { {0xe0,0x05,0},{0xe0,0xF0,0x05,0} }, /*138*/ + { {0xe0,0x06,0},{0xe0,0xF0,0x06,0} }, { {0xe0,0x04,0},{0xe0,0xF0,0x04,0} }, { {0xe0,0x0C,0},{0xe0,0xF0,0x0C,0} }, { {0xe0,0x03,0},{0xe0,0xF0,0x03,0} }, /*13c*/ + { {0xe0,0x0B,0},{0xe0,0xF0,0x0B,0} }, { {0xe0,0x02,0},{0xe0,0xF0,0x02,0} }, { {0xe0,0x0A,0},{0xe0,0xF0,0x0A,0} }, { {0xe0,0x01,0},{0xe0,0xF0,0x01,0} }, /*140*/ + { {0xe0,0x09,0},{0xe0,0xF0,0x09,0} }, { { 0},{ 0} }, { {0xe0,0x7E,0},{0xe0,0xF0,0x7E,0} }, { {0xe0,0x6C,0},{0xe0,0xF0,0x6C,0} }, /*144*/ + { {0xe0,0x75,0},{0xe0,0xF0,0x75,0} }, { {0xe0,0x7D,0},{0xe0,0xF0,0x7D,0} }, { { 0},{ 0} }, { {0xe0,0x6B,0},{0xe0,0xF0,0x6B,0} }, /*148*/ + { {0xe0,0x73,0},{0xe0,0xF0,0x73,0} }, { {0xe0,0x74,0},{0xe0,0xF0,0x74,0} }, { {0xe0,0x79,0},{0xe0,0xF0,0x79,0} }, { {0xe0,0x69,0},{0xe0,0xF0,0x69,0} }, /*14c*/ + { {0xe0,0x72,0},{0xe0,0xF0,0x72,0} }, { {0xe0,0x7A,0},{0xe0,0xF0,0x7A,0} }, { {0xe0,0x70,0},{0xe0,0xF0,0x70,0} }, { {0xe0,0x71,0},{0xe0,0xF0,0x71,0} }, /*150*/ + { { 0},{ 0} }, { {0xe0,0x60,0},{0xe0,0xF0,0x60,0} }, { { 0},{ 0} }, { {0xe0,0x78,0},{0xe0,0xF0,0x78,0} }, /*154*/ + { {0xe0,0x07,0},{0xe0,0xF0,0x07,0} }, { {0xe0,0x0F,0},{0xe0,0xF0,0x0F,0} }, { {0xe0,0x17,0},{0xe0,0xF0,0x17,0} }, { {0xe0,0x1F,0},{0xe0,0xF0,0x1F,0} }, /*158*/ + { {0xe0,0x27,0},{0xe0,0xF0,0x27,0} }, { {0xe0,0x2F,0},{0xe0,0xF0,0x2F,0} }, { {0xe0,0x37,0},{0xe0,0xF0,0x37,0} }, { {0xe0,0x3F,0},{0xe0,0xF0,0x3F,0} }, /*15c*/ + { { 0},{ 0} }, { {0xe0,0x4F,0},{0xe0,0xF0,0x4F,0} }, { {0xe0,0x56,0},{0xe0,0xF0,0x56,0} }, { {0xe0,0x5E,0},{0xe0,0xF0,0x5E,0} }, /*160*/ + { {0xe0,0x08,0},{0xe0,0xF0,0x08,0} }, { {0xe0,0x10,0},{0xe0,0xF0,0x10,0} }, { {0xe0,0x18,0},{0xe0,0xF0,0x18,0} }, { {0xe0,0x20,0},{0xe0,0xF0,0x20,0} }, /*164*/ + { {0xe0,0x28,0},{0xe0,0xF0,0x28,0} }, { {0xe0,0x30,0},{0xe0,0xF0,0x30,0} }, { {0xe0,0x38,0},{0xe0,0xF0,0x38,0} }, { {0xe0,0x40,0},{0xe0,0xF0,0x40,0} }, /*168*/ + { {0xe0,0x48,0},{0xe0,0xF0,0x48,0} }, { {0xe0,0x50,0},{0xe0,0xF0,0x50,0} }, { {0xe0,0x57,0},{0xe0,0xF0,0x57,0} }, { { 0},{ 0} }, /*16c*/ + { {0xe0,0x13,0},{0xe0,0xF0,0x13,0} }, { {0xe0,0x19,0},{0xe0,0xF0,0x19,0} }, { {0xe0,0x39,0},{0xe0,0xF0,0x39,0} }, { {0xe0,0x51,0},{0xe0,0xF0,0x51,0} }, /*170*/ + { {0xe0,0x53,0},{0xe0,0xF0,0x53,0} }, { {0xe0,0x5C,0},{0xe0,0xF0,0x5C,0} }, { { 0},{ 0} }, { {0xe0,0x62,0},{0xe0,0xF0,0x62,0} }, /*174*/ + { {0xe0,0x63,0},{0xe0,0xF0,0x63,0} }, { {0xe0,0x64,0},{0xe0,0xF0,0x64,0} }, { {0xe0,0x65,0},{0xe0,0xF0,0x65,0} }, { {0xe0,0x67,0},{0xe0,0xF0,0x67,0} }, /*178*/ + { {0xe0,0x68,0},{0xe0,0xF0,0x68,0} }, { {0xe0,0x6A,0},{0xe0,0xF0,0x6A,0} }, { {0xe0,0x6D,0},{0xe0,0xF0,0x6D,0} }, { {0xe0,0x6E,0},{0xe0,0xF0,0x6E,0} }, /*17c*/ + + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/ + { { 0},{ 0} }, { {0xe0,0xe1,0},{0xe0,0xF0,0xE1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{0xe0,0xF0,0xEE,0} }, { { 0},{ 0} }, /*1ec*/ + { { 0},{ 0} }, { {0xe0,0xf1,0},{0xe0,0xF0,0xF1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{0xe0,0xF0,0xFE,0} }, { {0xe0,0xff,0},{0xe0,0xF0,0xFF,0} } /*1fc*/ + // clang-format on +}; + +static const scancode scancode_set3[512] = { + // clang-format off + { { 0},{ 0} }, { { 0x08,0},{ 0xf0,0x08,0} }, { { 0x16,0},{ 0xf0,0x16,0} }, { { 0x1E,0},{ 0xf0,0x1E,0} }, /*000*/ + { { 0x26,0},{ 0xf0,0x26,0} }, { { 0x25,0},{ 0xf0,0x25,0} }, { { 0x2E,0},{ 0xf0,0x2E,0} }, { { 0x36,0},{ 0xf0,0x36,0} }, /*004*/ + { { 0x3D,0},{ 0xf0,0x3D,0} }, { { 0x3E,0},{ 0xf0,0x3E,0} }, { { 0x46,0},{ 0xf0,0x46,0} }, { { 0x45,0},{ 0xf0,0x45,0} }, /*008*/ + { { 0x4E,0},{ 0xf0,0x4E,0} }, { { 0x55,0},{ 0xf0,0x55,0} }, { { 0x66,0},{ 0xf0,0x66,0} }, { { 0x0D,0},{ 0xf0,0x0D,0} }, /*00c*/ + { { 0x15,0},{ 0xf0,0x15,0} }, { { 0x1D,0},{ 0xf0,0x1D,0} }, { { 0x24,0},{ 0xf0,0x24,0} }, { { 0x2D,0},{ 0xf0,0x2D,0} }, /*010*/ + { { 0x2C,0},{ 0xf0,0x2C,0} }, { { 0x35,0},{ 0xf0,0x35,0} }, { { 0x3C,0},{ 0xf0,0x3C,0} }, { { 0x43,0},{ 0xf0,0x43,0} }, /*014*/ + { { 0x44,0},{ 0xf0,0x44,0} }, { { 0x4D,0},{ 0xf0,0x4D,0} }, { { 0x54,0},{ 0xf0,0x54,0} }, { { 0x5B,0},{ 0xf0,0x5B,0} }, /*018*/ + { { 0x5A,0},{ 0xf0,0x5A,0} }, { { 0x11,0},{ 0xf0,0x11,0} }, { { 0x1C,0},{ 0xf0,0x1C,0} }, { { 0x1B,0},{ 0xf0,0x1B,0} }, /*01c*/ + { { 0x23,0},{ 0xf0,0x23,0} }, { { 0x2B,0},{ 0xf0,0x2B,0} }, { { 0x34,0},{ 0xf0,0x34,0} }, { { 0x33,0},{ 0xf0,0x33,0} }, /*020*/ + { { 0x3B,0},{ 0xf0,0x3B,0} }, { { 0x42,0},{ 0xf0,0x42,0} }, { { 0x4B,0},{ 0xf0,0x4B,0} }, { { 0x4C,0},{ 0xf0,0x4C,0} }, /*024*/ + { { 0x52,0},{ 0xf0,0x52,0} }, { { 0x0E,0},{ 0xf0,0x0E,0} }, { { 0x12,0},{ 0xf0,0x12,0} }, { { 0x5C,0},{ 0xf0,0x5C,0} }, /*028*/ + { { 0x1A,0},{ 0xf0,0x1A,0} }, { { 0x22,0},{ 0xf0,0x22,0} }, { { 0x21,0},{ 0xf0,0x21,0} }, { { 0x2A,0},{ 0xf0,0x2A,0} }, /*02c*/ + { { 0x32,0},{ 0xf0,0x32,0} }, { { 0x31,0},{ 0xf0,0x31,0} }, { { 0x3A,0},{ 0xf0,0x3A,0} }, { { 0x41,0},{ 0xf0,0x41,0} }, /*030*/ + { { 0x49,0},{ 0xf0,0x49,0} }, { { 0x4A,0},{ 0xf0,0x4A,0} }, { { 0x59,0},{ 0xf0,0x59,0} }, { { 0x7E,0},{ 0xf0,0x7E,0} }, /*034*/ + { { 0x19,0},{ 0xf0,0x19,0} }, { { 0x29,0},{ 0xf0,0x29,0} }, { { 0x14,0},{ 0xf0,0x14,0} }, { { 0x07,0},{ 0xf0,0x07,0} }, /*038*/ + { { 0x0F,0},{ 0xf0,0x0F,0} }, { { 0x17,0},{ 0xf0,0x17,0} }, { { 0x1F,0},{ 0xf0,0x1F,0} }, { { 0x27,0},{ 0xf0,0x27,0} }, /*03c*/ + { { 0x2F,0},{ 0xf0,0x2F,0} }, { { 0x37,0},{ 0xf0,0x37,0} }, { { 0x3F,0},{ 0xf0,0x3F,0} }, { { 0x47,0},{ 0xf0,0x47,0} }, /*040*/ + { { 0x4F,0},{ 0xf0,0x4F,0} }, { { 0x76,0},{ 0xf0,0x76,0} }, { { 0x5F,0},{ 0xf0,0x5F,0} }, { { 0x6C,0},{ 0xf0,0x6C,0} }, /*044*/ + { { 0x75,0},{ 0xf0,0x75,0} }, { { 0x7D,0},{ 0xf0,0x7D,0} }, { { 0x84,0},{ 0xf0,0x84,0} }, { { 0x6B,0},{ 0xf0,0x6B,0} }, /*048*/ + { { 0x73,0},{ 0xf0,0x73,0} }, { { 0x74,0},{ 0xf0,0x74,0} }, { { 0x7C,0},{ 0xf0,0x7C,0} }, { { 0x69,0},{ 0xf0,0x69,0} }, /*04c*/ + { { 0x72,0},{ 0xf0,0x72,0} }, { { 0x7A,0},{ 0xf0,0x7A,0} }, { { 0x70,0},{ 0xf0,0x70,0} }, { { 0x71,0},{ 0xf0,0x71,0} }, /*050*/ + { { 0x57,0},{ 0xf0,0x57,0} }, { { 0x60,0},{ 0xf0,0x60,0} }, { { 0},{ 0} }, { { 0x56,0},{ 0xf0,0x56,0} }, /*054*/ + { { 0x5E,0},{ 0xf0,0x5E,0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*058*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*05c*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*060*/ + { { 0},{ 0} }, { { 0x10,0},{ 0xf0,0x10,0} }, { { 0x18,0},{ 0xf0,0x18,0} }, { { 0x20,0},{ 0xf0,0x20,0} }, /*064*/ + { { 0x28,0},{ 0xf0,0x28,0} }, { { 0x30,0},{ 0xf0,0x30,0} }, { { 0x38,0},{ 0xf0,0x38,0} }, { { 0x40,0},{ 0xf0,0x40,0} }, /*068*/ + { { 0x48,0},{ 0xf0,0x48,0} }, { { 0x50,0},{ 0xf0,0x50,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*06c*/ + { { 0x87,0},{ 0xf0,0x87,0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0x51,0},{ 0xf0,0x51,0} }, /*070*/ + { { 0x53,0},{ 0xf0,0x53,0} }, { { 0x5C,0},{ 0xf0,0x5C,0} }, { { 0},{ 0} }, { { 0x62,0},{ 0xf0,0x62,0} }, /*074*/ + { { 0x63,0},{ 0xf0,0x63,0} }, { { 0x86,0},{ 0xf0,0x86,0} }, { { 0},{ 0} }, { { 0x85,0},{ 0xf0,0x85,0} }, /*078*/ + { { 0x68,0},{ 0xf0,0x68,0} }, { { 0x13,0},{ 0xf0,0x13,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*07c*/ + + { { 0x80,0},{ 0xf0,0x80,0} }, { { 0x81,0},{ 0xf0,0x81,0} }, { { 0x82,0},{ 0xf0,0x82,0} }, { { 0},{ 0} }, /*080*/ + { { 0},{ 0} }, { { 0x85,0},{ 0xf0,0x54,0} }, { { 0x86,0},{ 0xf0,0x86,0} }, { { 0x87,0},{ 0xf0,0x87,0} }, /*084*/ + { { 0x88,0},{ 0xf0,0x88,0} }, { { 0x89,0},{ 0xf0,0x89,0} }, { { 0x8a,0},{ 0xf0,0x8a,0} }, { { 0x8b,0},{ 0xf0,0x8b,0} }, /*088*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0x8e,0},{ 0xf0,0x8e,0} }, { { 0x8f,0},{ 0xf0,0x8f,0} }, /*08c*/ + { { 0x90,0},{ 0xf0,0x90,0} }, { { 0x91,0},{ 0xf0,0x91,0} }, { { 0x92,0},{ 0xf0,0x92,0} }, { { 0x93,0},{ 0xf0,0x93,0} }, /*090*/ + { { 0x94,0},{ 0xf0,0x94,0} }, { { 0x95,0},{ 0xf0,0x95,0} }, { { 0x96,0},{ 0xf0,0x96,0} }, { { 0x97,0},{ 0xf0,0x97,0} }, /*094*/ + { { 0x98,0},{ 0xf0,0x98,0} }, { { 0x99,0},{ 0xf0,0x99,0} }, { { 0x9a,0},{ 0xf0,0x9a,0} }, { { 0x9b,0},{ 0xf0,0x9b,0} }, /*098*/ + { { 0x9c,0},{ 0xf0,0x9c,0} }, { { 0x9d,0},{ 0xf0,0x9d,0} }, { { 0x9e,0},{ 0xf0,0x9e,0} }, { { 0x9f,0},{ 0xf0,0x9f,0} }, /*09c*/ + { { 0xa0,0},{ 0xf0,0xa0,0} }, { { 0xa1,0},{ 0xf0,0xa1,0} }, { { 0xa2,0},{ 0xf0,0xa2,0} }, { { 0xa3,0},{ 0xf0,0xa3,0} }, /*0a0*/ + { { 0xa4,0},{ 0xf0,0xa4,0} }, { { 0xa5,0},{ 0xf0,0xa5,0} }, { { 0xa6,0},{ 0xf0,0xa6,0} }, { { 0xa7,0},{ 0xf0,0xa7,0} }, /*0a4*/ + { { 0xa8,0},{ 0xf0,0xa8,0} }, { { 0xa9,0},{ 0xf0,0xa9,0} }, { { 0xaa,0},{ 0xf0,0xaa,0} }, { { 0xab,0},{ 0xf0,0xab,0} }, /*0a8*/ + { { 0xac,0},{ 0xf0,0xac,0} }, { { 0xad,0},{ 0xf0,0xad,0} }, { { 0xae,0},{ 0xf0,0xae,0} }, { { 0xaf,0},{ 0xf0,0xaf,0} }, /*0ac*/ + { { 0xb0,0},{ 0xf0,0xb0,0} }, { { 0xb1,0},{ 0xf0,0xb1,0} }, { { 0xb2,0},{ 0xf0,0xb2,0} }, { { 0xb3,0},{ 0xf0,0xb3,0} }, /*0b0*/ + { { 0xb4,0},{ 0xf0,0xb4,0} }, { { 0xb5,0},{ 0xf0,0xb5,0} }, { { 0xb6,0},{ 0xf0,0xb6,0} }, { { 0xb7,0},{ 0xf0,0xb7,0} }, /*0b4*/ + { { 0xb8,0},{ 0xf0,0xb8,0} }, { { 0xb9,0},{ 0xf0,0xb9,0} }, { { 0xba,0},{ 0xf0,0xba,0} }, { { 0xbb,0},{ 0xf0,0xbb,0} }, /*0b8*/ + { { 0xbc,0},{ 0xf0,0xbc,0} }, { { 0xbd,0},{ 0xf0,0xbd,0} }, { { 0xbe,0},{ 0xf0,0xbe,0} }, { { 0xbf,0},{ 0xf0,0xbf,0} }, /*0bc*/ + { { 0xc0,0},{ 0xf0,0xc0,0} }, { { 0xc1,0},{ 0xf0,0xc1,0} }, { { 0xc2,0},{ 0xf0,0xc2,0} }, { { 0xc3,0},{ 0xf0,0xc3,0} }, /*0c0*/ + { { 0xc4,0},{ 0xf0,0xc4,0} }, { { 0xc5,0},{ 0xf0,0xc5,0} }, { { 0xc6,0},{ 0xf0,0xc6,0} }, { { 0xc7,0},{ 0xf0,0xc7,0} }, /*0c4*/ + { { 0xc8,0},{ 0xf0,0xc8,0} }, { { 0xc9,0},{ 0xf0,0xc9,0} }, { { 0xca,0},{ 0xf0,0xca,0} }, { { 0xcb,0},{ 0xf0,0xcb,0} }, /*0c8*/ + { { 0xcc,0},{ 0xf0,0xcc,0} }, { { 0xcd,0},{ 0xf0,0xcd,0} }, { { 0xce,0},{ 0xf0,0xce,0} }, { { 0xcf,0},{ 0xf0,0xcf,0} }, /*0cc*/ + { { 0xd0,0},{ 0xf0,0xd0,0} }, { { 0xd1,0},{ 0xf0,0xd0,0} }, { { 0xd2,0},{ 0xf0,0xd2,0} }, { { 0xd3,0},{ 0xf0,0xd3,0} }, /*0d0*/ + { { 0xd4,0},{ 0xf0,0xd4,0} }, { { 0xd5,0},{ 0xf0,0xd5,0} }, { { 0xd6,0},{ 0xf0,0xd6,0} }, { { 0xd7,0},{ 0xf0,0xd7,0} }, /*0d4*/ + { { 0xd8,0},{ 0xf0,0xd8,0} }, { { 0xd9,0},{ 0xf0,0xd9,0} }, { { 0xda,0},{ 0xf0,0xda,0} }, { { 0xdb,0},{ 0xf0,0xdb,0} }, /*0d8*/ + { { 0xdc,0},{ 0xf0,0xdc,0} }, { { 0xdd,0},{ 0xf0,0xdd,0} }, { { 0xde,0},{ 0xf0,0xde,0} }, { { 0xdf,0},{ 0xf0,0xdf,0} }, /*0dc*/ + { { 0xe0,0},{ 0xf0,0xe0,0} }, { { 0xe1,0},{ 0xf0,0xe1,0} }, { { 0xe2,0},{ 0xf0,0xe2,0} }, { { 0xe3,0},{ 0xf0,0xe3,0} }, /*0e0*/ + { { 0xe4,0},{ 0xf0,0xe4,0} }, { { 0xe5,0},{ 0xf0,0xe5,0} }, { { 0xe6,0},{ 0xf0,0xe6,0} }, { { 0xe7,0},{ 0xf0,0xe7,0} }, /*0e4*/ + { { 0xe8,0},{ 0xf0,0xe8,0} }, { { 0xe9,0},{ 0xf0,0xe9,0} }, { { 0xea,0},{ 0xf0,0xea,0} }, { { 0xeb,0},{ 0xf0,0xeb,0} }, /*0e8*/ + { { 0xec,0},{ 0xf0,0xec,0} }, { { 0xed,0},{ 0xf0,0xed,0} }, { { 0xee,0},{ 0xf0,0xee,0} }, { { 0xef,0},{ 0xf0,0xef,0} }, /*0ec*/ + { { 0},{ 0} }, { { 0xf1,0},{ 0xf0,0xf1,0} }, { { 0xf2,0},{ 0xf0,0xf2,0} }, { { 0xf3,0},{ 0xf0,0xf3,0} }, /*0f0*/ + { { 0xf4,0},{ 0xf0,0xf4,0} }, { { 0xf5,0},{ 0xf0,0xf5,0} }, { { 0xf6,0},{ 0xf0,0xf6,0} }, { { 0xf7,0},{ 0xf0,0xf7,0} }, /*0f4*/ + { { 0xf8,0},{ 0xf0,0xf8,0} }, { { 0xf9,0},{ 0xf0,0xf9,0} }, { { 0xfa,0},{ 0xf0,0xfa,0} }, { { 0xfb,0},{ 0xf0,0xfb,0} }, /*0f8*/ + { { 0xfc,0},{ 0xf0,0xfc,0} }, { { 0xfd,0},{ 0xf0,0xfd,0} }, { { 0xfe,0},{ 0xf0,0xfe,0} }, { { 0xff,0},{ 0xf0,0xff,0} }, /*0fc*/ + + { { 0x62,0},{ 0xF0,0x62,0} }, { {0xe0,0x76,0},{0xe0,0xF0,0x76,0} }, { {0xe0,0x16,0},{0xe0,0xF0,0x16,0} }, { {0xe0,0x1E,0},{0xe0,0xF0,0x1E,0} }, /*100*/ + { {0xe0,0x26,0},{0xe0,0xF0,0x26,0} }, { {0xe0,0x25,0},{0xe0,0xF0,0x25,0} }, { {0xe0,0x2E,0},{0xe0,0xF0,0x2E,0} }, { {0xe0,0x36,0},{0xe0,0xF0,0x36,0} }, /*104*/ + { {0xe0,0x3D,0},{0xe0,0xF0,0x3D,0} }, { {0xe0,0x3E,0},{0xe0,0xF0,0x3E,0} }, { {0xe0,0x46,0},{0xe0,0xF0,0x46,0} }, { {0xe0,0x45,0},{0xe0,0xF0,0x45,0} }, /*108*/ + { {0xe0,0x4E,0},{0xe0,0xF0,0x4E,0} }, { { 0},{ 0} }, { {0xe0,0x66,0},{0xe0,0xF0,0x66,0} }, { {0xe0,0x0D,0},{0xe0,0xF0,0x0D,0} }, /*10c*/ + { {0xe0,0x15,0},{0xe0,0xF0,0x15,0} }, { {0xe0,0x1D,0},{0xe0,0xF0,0x1D,0} }, { {0xe0,0x24,0},{0xe0,0xF0,0x24,0} }, { {0xe0,0x2D,0},{0xe0,0xF0,0x2D,0} }, /*110*/ + { {0xe0,0x2C,0},{0xe0,0xF0,0x2C,0} }, { {0xe0,0x35,0},{0xe0,0xF0,0x35,0} }, { {0xe0,0x3C,0},{0xe0,0xF0,0x3C,0} }, { {0xe0,0x43,0},{0xe0,0xF0,0x43,0} }, /*114*/ + { {0xe0,0x44,0},{0xe0,0xF0,0x44,0} }, { {0xe0,0x4D,0},{0xe0,0xF0,0x4D,0} }, { {0xe0,0x54,0},{0xe0,0xF0,0x54,0} }, { {0xe0,0x5B,0},{0xe0,0xF0,0x5B,0} }, /*118*/ + { { 0x79,0},{ 0xf0,0x79,0} }, { { 0x58,0},{ 0xf0,0x58,0} }, { {0xe0,0x1C,0},{0xe0,0xF0,0x1C,0} }, { {0xe0,0x1B,0},{0xe0,0xF0,0x1B,0} }, /*11c*/ + { {0xe0,0x23,0},{0xe0,0xF0,0x23,0} }, { {0xe0,0x2B,0},{0xe0,0xF0,0x2B,0} }, { {0xe0,0x34,0},{0xe0,0xF0,0x34,0} }, { {0xe0,0x33,0},{0xe0,0xF0,0x33,0} }, /*120*/ + { {0xe0,0x3B,0},{0xe0,0xF0,0x3B,0} }, { {0xe0,0x42,0},{0xe0,0xF0,0x42,0} }, { {0xe0,0x4B,0},{0xe0,0xF0,0x4B,0} }, { { 0},{ 0} }, /*124*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*128*/ + { {0xe0,0x1A,0},{0xe0,0xF0,0x1A,0} }, { {0xe0,0x22,0},{0xe0,0xF0,0x22,0} }, { {0xe0,0x21,0},{0xe0,0xF0,0x21,0} }, { {0xe0,0x2A,0},{0xe0,0xF0,0x2A,0} }, /*12c*/ + { {0xe0,0x32,0},{0xe0,0xF0,0x32,0} }, { {0xe0,0x31,0},{0xe0,0xF0,0x31,0} }, { {0xe0,0x3A,0},{0xe0,0xF0,0x3A,0} }, { { 0},{ 0} }, /*130*/ + { {0xe0,0x49,0},{0xe0,0xF0,0x49,0} }, { { 0x77,0},{ 0xf0,0x77,0} }, { { 0},{ 0} }, { { 0x57,0},{ 0xf0,0x57,0} }, /*134*/ + { { 0x39,0},{ 0xf0,0x39,0} }, { { 0},{ 0} }, { {0xe0,0x58,0},{0xe0,0xF0,0x58,0} }, { {0xe0,0x05,0},{0xe0,0xF0,0x05,0} }, /*138*/ + { {0xe0,0x06,0},{0xe0,0xF0,0x06,0} }, { {0xe0,0x04,0},{0xe0,0xF0,0x04,0} }, { {0xe0,0x0C,0},{0xe0,0xF0,0x0C,0} }, { {0xe0,0x03,0},{0xe0,0xF0,0x03,0} }, /*13c*/ + { {0xe0,0x0B,0},{0xe0,0xF0,0x0B,0} }, { {0xe0,0x02,0},{0xe0,0xF0,0x02,0} }, { {0xe0,0x0A,0},{0xe0,0xF0,0x0A,0} }, { {0xe0,0x01,0},{0xe0,0xF0,0x01,0} }, /*140*/ + { {0xe0,0x09,0},{0xe0,0xF0,0x09,0} }, { { 0},{ 0} }, { {0xe0,0x7E,0},{0xe0,0xF0,0x7E,0} }, { { 0x6E,0},{ 0xf0,0x6E,0} }, /*144*/ + { { 0x63,0},{ 0xf0,0x63,0} }, { { 0x6F,0},{ 0xf0,0x6F,0} }, { { 0},{ 0} }, { { 0x61,0},{ 0xf0,0x61,0} }, /*148*/ + { {0xe0,0x73,0},{0xe0,0xF0,0x73,0} }, { { 0x6A,0},{ 0xf0,0x6A,0} }, { {0xe0,0x79,0},{0xe0,0xF0,0x79,0} }, { { 0x65,0},{ 0xf0,0x65,0} }, /*14c*/ + { { 0x60,0},{ 0xf0,0x60,0} }, { { 0x6D,0},{ 0xf0,0x6D,0} }, { { 0x67,0},{ 0xf0,0x67,0} }, { { 0x64,0},{ 0xf0,0x64,0} }, /*150*/ + { { 0xd4,0},{ 0xf0,0xD4,0} }, { {0xe0,0x60,0},{0xe0,0xF0,0x60,0} }, { { 0},{ 0} }, { {0xe0,0x78,0},{0xe0,0xF0,0x78,0} }, /*154*/ + { {0xe0,0x07,0},{0xe0,0xF0,0x07,0} }, { {0xe0,0x0F,0},{0xe0,0xF0,0x0F,0} }, { {0xe0,0x17,0},{0xe0,0xF0,0x17,0} }, { { 0x8B,0},{ 0xf0,0x8B,0} }, /*158*/ + { { 0x8C,0},{ 0xf0,0x8C,0} }, { { 0x8D,0},{ 0xf0,0x8D,0} }, { { 0},{ 0} }, { { 0x7F,0},{ 0xf0,0x7F,0} }, /*15c*/ + { { 0},{ 0} }, { {0xe0,0x4F,0},{0xe0,0xF0,0x4F,0} }, { {0xe0,0x56,0},{0xe0,0xF0,0x56,0} }, { { 0},{ 0} }, /*160*/ + { {0xe0,0x08,0},{0xe0,0xF0,0x08,0} }, { {0xe0,0x10,0},{0xe0,0xF0,0x10,0} }, { {0xe0,0x18,0},{0xe0,0xF0,0x18,0} }, { {0xe0,0x20,0},{0xe0,0xF0,0x20,0} }, /*164*/ + { {0xe0,0x28,0},{0xe0,0xF0,0x28,0} }, { {0xe0,0x30,0},{0xe0,0xF0,0x30,0} }, { {0xe0,0x38,0},{0xe0,0xF0,0x38,0} }, { {0xe0,0x40,0},{0xe0,0xF0,0x40,0} }, /*168*/ + { {0xe0,0x48,0},{0xe0,0xF0,0x48,0} }, { {0xe0,0x50,0},{0xe0,0xF0,0x50,0} }, { {0xe0,0x57,0},{0xe0,0xF0,0x57,0} }, { { 0},{ 0} }, /*16c*/ + { {0xe0,0x13,0},{0xe0,0xF0,0x13,0} }, { {0xe0,0x19,0},{0xe0,0xF0,0x19,0} }, { {0xe0,0x39,0},{0xe0,0xF0,0x39,0} }, { {0xe0,0x51,0},{0xe0,0xF0,0x51,0} }, /*170*/ + { {0xe0,0x53,0},{0xe0,0xF0,0x53,0} }, { {0xe0,0x5C,0},{0xe0,0xF0,0x5C,0} }, { { 0},{ 0} }, { {0xe0,0x62,0},{0xe0,0xF0,0x62,0} }, /*174*/ + { {0xe0,0x63,0},{0xe0,0xF0,0x63,0} }, { {0xe0,0x64,0},{0xe0,0xF0,0x64,0} }, { {0xe0,0x65,0},{0xe0,0xF0,0x65,0} }, { {0xe0,0x67,0},{0xe0,0xF0,0x67,0} }, /*178*/ + { {0xe0,0x68,0},{0xe0,0xF0,0x68,0} }, { {0xe0,0x6A,0},{0xe0,0xF0,0x6A,0} }, { {0xe0,0x6D,0},{0xe0,0xF0,0x6D,0} }, { {0xe0,0x6E,0},{0xe0,0xF0,0x6E,0} }, /*17c*/ + + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*180*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*184*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*188*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*18c*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*190*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*194*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*198*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*19c*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1a8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1ac*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1c8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1cc*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1d8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1dc*/ + { { 0},{ 0} }, { {0xe0,0xe1,0},{0xe0,0xF0,0xE1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1e8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xee,0},{0xe0,0xF0,0xEE,0} }, { { 0},{ 0} }, /*1ec*/ + { { 0},{ 0} }, { {0xe0,0xf1,0},{0xe0,0xF0,0xF1,0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f0*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f4*/ + { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, { { 0},{ 0} }, /*1f8*/ + { { 0},{ 0} }, { { 0},{ 0} }, { {0xe0,0xfe,0},{0xe0,0xF0,0xFE,0} }, { {0xe0,0xff,0},{0xe0,0xF0,0xFF,0} } /*1fc*/ + // clang-format on +}; + +static void +keyboard_at_set_scancode_set(void) +{ + switch (keyboard_mode) { + default: + case 0x01: + keyboard_set_table(scancode_set1); + break; + + case 0x02: + keyboard_set_table(scancode_set2); + break; + + case 0x03: + keyboard_set_table(scancode_set3); + break; + } +} + +static void +add_data_vals(atkbc_dev_t *dev, uint8_t *val, uint8_t len) +{ + for (uint8_t i = 0; i < len; i++) + kbc_at_dev_queue_add(dev, val[i], 1); +} + +static void +add_data_kbd(uint16_t val) +{ + atkbc_dev_t *dev = SavedKbd; + uint8_t fake_shift[4]; + uint8_t num_lock = 0; + uint8_t shift_states = 0; + + //keyboard_get_states(NULL, &num_lock, NULL); + shift_states = 0; // keyboard_get_shift() &STATE_SHIFT_MASK; + + switch (val) { + case FAKE_LSHIFT_ON: + keyboard_at_log("%s: Fake left shift on, scan code: ", dev->name); + if (num_lock) { + if (shift_states) { + keyboard_at_log("N/A (one or both shifts on)\n"); + break; + } else { + /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ + switch (keyboard_mode & 0x02) { + case 1: + fake_shift[0] = 0xe0; + fake_shift[1] = 0x2a; + add_data_vals(dev, fake_shift, 2); + break; + + case 2: + fake_shift[0] = 0xe0; + fake_shift[1] = 0x12; + add_data_vals(dev, fake_shift, 2); + break; + + default: + keyboard_at_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); + break; + } + } + } else { + if (shift_states & STATE_LSHIFT) { + /* Num lock off and left shift pressed. */ + switch (keyboard_mode & 0x02) { + case 1: + fake_shift[0] = 0xe0; + fake_shift[1] = 0xaa; + add_data_vals(dev, fake_shift, 2); + break; + + case 2: + fake_shift[0] = 0xe0; + fake_shift[1] = 0xf0; + fake_shift[2] = 0x12; + add_data_vals(dev, fake_shift, 3); + break; + + default: + keyboard_at_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); + break; + } + } + if (shift_states & STATE_RSHIFT) { + /* Num lock off and right shift pressed. */ + switch (keyboard_mode & 0x02) { + case 1: + fake_shift[0] = 0xe0; + fake_shift[1] = 0xb6; + add_data_vals(dev, fake_shift, 2); + break; + + case 2: + fake_shift[0] = 0xe0; + fake_shift[1] = 0xf0; + fake_shift[2] = 0x59; + add_data_vals(dev, fake_shift, 3); + break; + + default: + keyboard_at_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); + break; + } + } + keyboard_at_log(shift_states ? "" : "N/A (both shifts off)\n"); + } + break; + + case FAKE_LSHIFT_OFF: + keyboard_at_log("%s: Fake left shift on, scan code: ", dev->name); + if (num_lock) { + if (shift_states) { + keyboard_at_log("N/A (one or both shifts on)\n"); + break; + } else { + /* Num lock on and no shifts are pressed, send non-inverted fake shift. */ + switch (keyboard_mode & 0x02) { + case 1: + fake_shift[0] = 0xe0; + fake_shift[1] = 0xaa; + add_data_vals(dev, fake_shift, 2); + break; + + case 2: + fake_shift[0] = 0xe0; + fake_shift[1] = 0xf0; + fake_shift[2] = 0x12; + add_data_vals(dev, fake_shift, 3); + break; + + default: + keyboard_at_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); + break; + } + } + } else { + if (shift_states & STATE_LSHIFT) { + /* Num lock off and left shift pressed. */ + switch (keyboard_mode & 0x02) { + case 1: + fake_shift[0] = 0xe0; + fake_shift[1] = 0x2a; + add_data_vals(dev, fake_shift, 2); + break; + + case 2: + fake_shift[0] = 0xe0; + fake_shift[1] = 0x12; + add_data_vals(dev, fake_shift, 2); + break; + + default: + keyboard_at_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); + break; + } + } + if (shift_states & STATE_RSHIFT) { + /* Num lock off and right shift pressed. */ + switch (keyboard_mode & 0x02) { + case 1: + fake_shift[0] = 0xe0; + fake_shift[1] = 0x36; + add_data_vals(dev, fake_shift, 2); + break; + + case 2: + fake_shift[0] = 0xe0; + fake_shift[1] = 0x59; + add_data_vals(dev, fake_shift, 2); + break; + + default: + keyboard_at_log("N/A (scan code set %i)\n", keyboard_mode & 0x02); + break; + } + } + keyboard_at_log(shift_states ? "" : "N/A (both shifts off)\n"); + } + break; + + default: + kbc_at_dev_queue_add(dev, (uint8_t)val, 1); + break; + } +} + +void +keyboard_at_clear_data(void *priv) +{ + atkbc_dev_t *dev = (atkbc_dev_t *)priv; + + dev->flags &= ~FLAG_CTRLDAT; +} + +static void +keyboard_at_set_defaults(atkbc_dev_t *dev) +{ + dev->rate = 1; + + keyboard_set3_all_break = 0; + keyboard_set3_all_repeat = 0; + memset(keyboard_set3_flags, 0, 512); + + keyboard_mode = 0x02; + keyboard_at_set_scancode_set(); +} + +static void +keyboard_at_bat(void *priv) +{ + atkbc_dev_t *dev = (atkbc_dev_t *)priv; + + keyboard_at_set_defaults(dev); + + keyboard_scan = 1; + + kbc_at_dev_queue_add(dev, 0xaa, 0); +} + +static void +keyboard_at_invalid_cmd(atkbc_dev_t *dev) +{ + keyboard_at_log("%s: Invalid command\n", dev->name); + kbc_at_dev_queue_add(dev, inv_cmd_response, 0); +} + + +void keyboard_at_write(uint8_t val, void *priv) +{ + atkbc_dev_t *dev = (atkbc_dev_t *)priv; + //uint8_t val; + + //if (dev->port == NULL) + // return; + + //val = dev->port->dat; + + dev->state = DEV_STATE_MAIN_OUT; + + if ((val < 0xed) && (dev->flags & FLAG_CTRLDAT)) { + dev->flags &= ~FLAG_CTRLDAT; + + switch (dev->command) { + + case 0xfb: + case 0xfc: + case 0xfd: + // not implemented, ignore value, return ack to keep DraCo happy */ + kbc_at_dev_queue_add(dev, 0xfa, 0); + break; + + case 0xed: /* Set/reset LEDs */ + kbc_at_dev_queue_add(dev, 0xfa, 0); + keyboard_at_log("%s: Set/reset LEDs [%02X]\n", dev->name, val); + break; + + case 0xf0: /* Get/set scancode set */ + kbc_at_dev_queue_add(dev, (val > 3) ? 0xfe : 0xfa, 0); + switch (val) { + case 0x00: + keyboard_at_log("%s: Get scan code set [%02X]\n", dev->name, keyboard_mode); + kbc_at_dev_queue_add(dev, keyboard_mode, 0); + break; + case 0x01: + case 0x02: + case 0x03: + keyboard_mode = val; + keyboard_at_log("%s: Set scan code set [%02X]\n", dev->name, keyboard_mode); + keyboard_at_set_scancode_set(); + break; + default: + /* Fatal so any instance of anything attempting to set scan code > 3 can be reported to us. */ + fatalx("%s: Scan code set [%02X] invalid, resend\n", dev->name, val); + dev->flags |= FLAG_CTRLDAT; + dev->state = DEV_STATE_MAIN_WANT_IN; + break; + } + break; + + case 0xf3: /* set typematic rate/delay */ + if (val & 0x80) { + keyboard_at_log("%s: Set typematic rate/delay [%02X] has bit 7 set - invalid\n", dev->name, val); + dev->flags |= FLAG_CTRLDAT; /* Resend = keep waiting for parameter. */ + kbc_at_dev_queue_add(dev, 0xfe, 0); /* Command response */ + dev->state = DEV_STATE_MAIN_WANT_IN; + } else { + dev->rate = val; + kbc_at_dev_queue_add(dev, 0xfa, 0); /* Command response */ + keyboard_at_log("%s: Set typematic rate/delay [%02X]\n", dev->name, val); + } + break; + + default: + fatalx("%s: Parameter [%02X] for invalid command [%02X] - possibly memory corruption!\n", dev->name, val, dev->command); + kbc_at_dev_queue_add(dev, 0xfe, 0); + } + } else { + if (dev->flags & FLAG_CTRLDAT) { + /* Special case - another command during another command that wants input - proceed + as normal but do not cancel the command (so keep waiting for input), unless the + command in progress is ED (Set/reset LEDs). */ + if (val == 0xed) { + keyboard_scan = 1; + dev->flags &= ~FLAG_CTRLDAT; + } else + dev->state = DEV_STATE_MAIN_WANT_IN; + } + + switch (val) { + case 0xed: /* set/reset LEDs */ + dev->command = val; + keyboard_at_log("%s: set/reset LEDs\n", dev->name); + dev->flags |= FLAG_CTRLDAT; + kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */ + dev->state = DEV_STATE_MAIN_WANT_IN; + break; + + case 0xee: /* diagnostic echo */ + keyboard_at_log("%s: ECHO\n", dev->name); + kbc_at_dev_queue_add(dev, 0xee, 0); + break; + + case 0xef: /* Invalid command */ + case 0xf1: /* Invalid command */ + keyboard_at_log("%s: Invalid command\n", dev->name); + kbc_at_dev_queue_add(dev, inv_cmd_response, 0); + break; + + case 0xf0: /* get/set scan code set */ + if (dev->type & FLAG_PS2) { + dev->command = val; + keyboard_at_log("%s: scan code set\n", dev->name); + dev->flags |= FLAG_CTRLDAT; + kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */ + dev->state = DEV_STATE_MAIN_WANT_IN; + } else + keyboard_at_invalid_cmd(dev); + break; + + case 0xf2: /* read ID */ + keyboard_at_log("%s: read keyboard id\n", dev->name); + /* TODO: After keyboard type selection is implemented, make this + return the correct keyboard ID for the selected type. */ + kbc_at_dev_queue_add(dev, 0xfa, 0); + for (uint8_t i = 0; i < 4; i++) { + if (id_bytes[dev->type][i] == 0) + break; + + kbc_at_dev_queue_add(dev, id_bytes[dev->type][i], 0); + } + break; + + case 0xf3: /* set command mode */ + dev->command = val; + keyboard_at_log("%s: set typematic rate/delay\n", dev->name); + dev->flags |= FLAG_CTRLDAT; + kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */ + dev->state = DEV_STATE_MAIN_WANT_IN; + break; + + case 0xf4: /* enable */ + keyboard_at_log("%s: enable keyboard\n", dev->name); + keyboard_scan = 1; + kbc_at_dev_queue_add(dev, 0xfa, 0); + break; + + case 0xf5: /* set defaults and disable keyboard */ + case 0xf6: /* set defaults */ + keyboard_at_log("%s: set defaults%s\n", (val == 0xf6) ? "" : " and disable keyboard"); + keyboard_scan = !(val & 0x01); + keyboard_at_log("%s: val = %02X, keyboard_scan = %i\n", + dev->name, val, keyboard_scan); + kbc_at_dev_queue_add(dev, 0xfa, 0); + + keyboard_set3_all_break = 0; + keyboard_set3_all_repeat = 0; + memset(keyboard_set3_flags, 0, 512); + + keyboard_mode = 0x02; + keyboard_at_set_scancode_set(); + break; + + case 0xf7: /* set all keys to repeat */ + if (dev->type & FLAG_PS2) { + keyboard_at_log("%s: set all keys to repeat\n", dev->name); + kbc_at_dev_queue_add(dev, 0xfa, 0); + keyboard_set3_all_break = 1; + } else + keyboard_at_invalid_cmd(dev); + break; + + case 0xf8: /* set all keys to give make/break codes */ + if (dev->type & FLAG_PS2) { + keyboard_at_log("%s: set all keys to give make/break codes\n", dev->name); + kbc_at_dev_queue_add(dev, 0xfa, 0); + keyboard_set3_all_break = 1; + } else + keyboard_at_invalid_cmd(dev); + break; + + case 0xf9: /* set all keys to give make codes only */ + if (dev->type & FLAG_PS2) { + keyboard_at_log("%s: set all keys to give make codes only\n", dev->name); + kbc_at_dev_queue_add(dev, 0xfa, 0); + keyboard_set3_all_break = 0; + } else + keyboard_at_invalid_cmd(dev); + break; + + case 0xfa: /* set all keys to repeat and give make/break codes */ + if (dev->type & FLAG_PS2) { + keyboard_at_log("%s: set all keys to repeat and give make/break codes\n", dev->name); + kbc_at_dev_queue_add(dev, 0xfa, 0); + keyboard_set3_all_repeat = 1; + keyboard_set3_all_break = 1; + } else + keyboard_at_invalid_cmd(dev); + break; + + /* TODO: Actually implement these commands. */ + case 0xfb: /* set some keys to repeat */ + keyboard_at_log("%s: set some keys to repeat\n", dev->name); + dev->flags |= FLAG_CTRLDAT; + kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */ + dev->state = DEV_STATE_MAIN_WANT_IN; + dev->command = val; + break; + + case 0xfc: /* set some keys to give make/break codes */ + keyboard_at_log("%s: set some keys to give make/break codes\n", dev->name); + dev->flags |= FLAG_CTRLDAT; + kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */ + dev->state = DEV_STATE_MAIN_WANT_IN; + dev->command = val; + break; + + case 0xfd: /* set some keys to give make codes only */ + keyboard_at_log("%s: set some keys to give make codes only\n", dev->name); + dev->flags |= FLAG_CTRLDAT; + kbc_at_dev_queue_add(dev, 0xfa, 0); /* ACK for command byte */ + dev->state = DEV_STATE_MAIN_WANT_IN; + dev->command = val; + break; + + /* TODO: This is supposed to resend multiple bytes after some commands. */ + case 0xfe: /* resend last scan code */ + keyboard_at_log("%s: resend last scan code\n", dev->name); + kbc_at_dev_queue_add(dev, 0xfa, 0); + kbc_at_dev_queue_add(dev, dev->last_scan_code, 0); + break; + + case 0xff: /* reset */ + kbc_at_dev_reset(dev, 1); + break; + + default: + kbc_at_dev_queue_add(dev, 0xfe, 0); + } + } +} + + +static int oldkey[512]; + +static uint8_t +fake_shift_needed(uint16_t scan) +{ + switch (scan) { + case 0x137: /* Yes, Print Screen requires the fake shifts. */ + case 0x147: + case 0x148: + case 0x149: + case 0x14a: + case 0x14b: + case 0x14d: + case 0x14f: + case 0x150: + case 0x151: + case 0x152: + case 0x153: + return 1; + default: + return 0; + } +} + +void +draco_key_process(uint16_t scan, int down) +{ + const scancode *codes = scan_table; + int c; + + if (!codes) + return; + + if (!keyboard_scan) + return; + + oldkey[scan] = down; + + if (down && (codes[scan].mk[0] == 0)) + return; + + if (!down && (codes[scan].brk[0] == 0)) + return; + + /* TODO: The keyboard controller needs to report the AT flag to us here. */ + if (((keyboard_mode & 3) == 3)) { + if (!keyboard_set3_all_break && !down && !(keyboard_set3_flags[codes[scan].mk[0]] & 2)) + return; + } + + c = 0; + if (down) { + /* Send the special code indicating an opening fake shift might be needed. */ + if (fake_shift_needed(scan)) + add_data_kbd(0x100); + while (codes[scan].mk[c] != 0) + add_data_kbd(codes[scan].mk[c++]); + } else { + while (codes[scan].brk[c] != 0) + add_data_kbd(codes[scan].brk[c++]); + /* Send the special code indicating a closing fake shift might be needed. */ + if (fake_shift_needed(scan)) + add_data_kbd(0x101); + } +} +void *draco_keyboard_init(void) +{ + draco_kbd.type = 10; + memset(oldkey, 0, sizeof(oldkey)); + return &draco_kbd; +} diff --git a/od-win32/winuae_msvc15/winuae_msvc.vcxproj b/od-win32/winuae_msvc15/winuae_msvc.vcxproj index 5782f181..02048453 100644 --- a/od-win32/winuae_msvc15/winuae_msvc.vcxproj +++ b/od-win32/winuae_msvc15/winuae_msvc.vcxproj @@ -1569,6 +1569,7 @@ + diff --git a/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters b/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters index 50433bf1..c1b68ddf 100644 --- a/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters +++ b/od-win32/winuae_msvc15/winuae_msvc.vcxproj.filters @@ -1003,6 +1003,9 @@ pcem + + pcem + diff --git a/pcem/mouse_serial.cpp b/pcem/mouse_serial.cpp index 2d81dea4..635d843f 100644 --- a/pcem/mouse_serial.cpp +++ b/pcem/mouse_serial.cpp @@ -21,7 +21,7 @@ void mouse_serial_poll(int x, int y, int z, int b, void *p) if (!(serial->ier & 1)) return; - if (!x && !y && b == mouse->oldb) + if (!x && !y && b == mouse->oldb && !b) return; mouse->oldb = b; @@ -48,25 +48,26 @@ void mouse_serial_poll(int x, int y, int z, int b, void *p) } } +void mousecallback(void *p) +{ + mouse_serial_t *mouse = (mouse_serial_t *)p; + + if (mouse->mousepos == -1) + { + mouse->mousepos = 0; + serial_write_fifo(mouse->serial, 'M'); + } +} + void mouse_serial_rcr(struct SERIAL *serial, void *p) { mouse_serial_t *mouse = (mouse_serial_t *)p; mouse->mousepos = -1; - timer_set_delay_u64(&mouse->mousedelay_timer, TIMER_USEC * 5000); + mousecallback(p); +// timer_set_delay_u64(&mouse->mousedelay_timer, TIMER_USEC * 5000); } -void mousecallback(void *p) -{ - mouse_serial_t *mouse = (mouse_serial_t *)p; - - if (mouse->mousepos == -1) - { - mouse->mousepos = 0; - serial_write_fifo(mouse->serial, 'M'); - } -} - void *mouse_serial_init() { mouse_serial_t *mouse = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); @@ -80,6 +81,19 @@ void *mouse_serial_init() return mouse; } +void *mouse_serial_init_draco() +{ + mouse_serial_t *mouse = (mouse_serial_t *)malloc(sizeof(mouse_serial_t)); + memset(mouse, 0, sizeof(mouse_serial_t)); + + mouse->serial = &serial2; + serial2.rcr_callback = mouse_serial_rcr; + serial2.rcr_callback_p = mouse; + + return mouse; +} + + void mouse_serial_close(void *p) { mouse_serial_t *mouse = (mouse_serial_t *)p; diff --git a/pcem/serial.cpp b/pcem/serial.cpp index 30dc5f56..c2b004c1 100644 --- a/pcem/serial.cpp +++ b/pcem/serial.cpp @@ -15,6 +15,9 @@ enum SERIAL serial1, serial2; +static bool draco_serial; +void x86_clearirq(uint8_t irqnum); +void x86_doirq(uint8_t irqnum); void serial_reset() { @@ -22,6 +25,8 @@ void serial_reset() serial2.iir = serial2.ier = serial2.lcr = 0; serial1.fifo_read = serial1.fifo_write = 0; serial2.fifo_read = serial2.fifo_write = 0; + serial1.iir = 1; + serial2.iir = 1; } void serial_update_ints(SERIAL *serial) @@ -51,10 +56,31 @@ void serial_update_ints(SERIAL *serial) serial->iir = 0; } - if (stat && ((serial->mctrl & 8) || PCJR)) - picintlevel(1 << serial->irq); - else + if (stat && ((serial->mctrl & 8) || PCJR)) { + if (draco_serial) { + x86_doirq(serial->irq); + } else { + picintlevel(1 << serial->irq); + } + } else { + if (draco_serial) { + x86_clearirq(serial->irq); + } else { picintc(1 << serial->irq); + } + } +} + +void serial_receive_callback(void *p) +{ + SERIAL *serial = (SERIAL *)p; + + if (serial->fifo_read != serial->fifo_write) + { + serial->lsr |= 1; + serial->int_status |= SERIAL_INT_RECEIVE; + serial_update_ints(serial); + } } void serial_write_fifo(SERIAL *serial, uint8_t dat) @@ -185,8 +211,13 @@ uint8_t serial_read(uint16_t addr, void *p) serial->int_status &= ~SERIAL_INT_RECEIVE; serial_update_ints(serial); temp = serial_read_fifo(serial); - if (serial->fifo_read != serial->fifo_write) + if (serial->fifo_read != serial->fifo_write) { + if (draco_serial) { + serial_receive_callback(p); + } else { timer_set_delay_u64(&serial->receive_timer, 1000 * TIMER_USEC); + } + } break; case 1: if (serial->lcr & 0x80) @@ -235,18 +266,6 @@ uint8_t serial_read(uint16_t addr, void *p) return temp; } -void serial_receive_callback(void *p) -{ - SERIAL *serial = (SERIAL *)p; - - if (serial->fifo_read != serial->fifo_write) - { - serial->lsr |= 1; - serial->int_status |= SERIAL_INT_RECEIVE; - serial_update_ints(serial); - } -} - /*Tandy might need COM1 at 2f8*/ void serial1_init(uint16_t addr, int irq, int has_fifo) { @@ -257,6 +276,7 @@ void serial1_init(uint16_t addr, int irq, int has_fifo) serial1.rcr_callback = NULL; timer_add(&serial1.receive_timer, serial_receive_callback, &serial1, 0); serial1.has_fifo = has_fifo; + draco_serial = false; } void serial1_set(uint16_t addr, int irq) { @@ -305,7 +325,10 @@ void draco_serial_init(void **s1, void **s2) serial_reset(); serial1.has_fifo = 1; serial2.has_fifo = 1; + serial1.irq = 4; + serial2.irq = 4; *s1 = &serial1; *s2 = &serial2; + draco_serial = true; } diff --git a/rommgr.cpp b/rommgr.cpp index 910356ad..0dc0ffe3 100644 --- a/rommgr.cpp +++ b/rommgr.cpp @@ -300,7 +300,7 @@ static struct romdata roms[] = { { _T("DraCo Boot ROM v1.3"), 1, 3, 1, 3, _T("DRACO\0"), 131072, 234, 2 | 4, 0, ROMTYPE_EXTCDTV, 0, 0, NULL, 0x0e9c5899,0x82151324,0x01207554,0x60c8a068,0x4793ec18,0x3f744d74, NULL, NULL, 4 }, { _T("DraCo Boot ROM v1.5"), 1, 5, 1, 5, _T("DRACO\0"), 131072, 311, 2 | 4, 0, ROMTYPE_EXTCDTV, 0, 0, NULL, - 0x0f2959d5,0xe8fd5d15,0x08797693,0x99f1df97,0x2fe792fd,0x8146cf1d, NULL, NULL, 4 }, + 0x7b4cdd4a,0x4d383adb,0x85c681a3,0xb625dcda,0x7a229a17,0x6af4d161, NULL, NULL, 4 }, { _T("CD32 KS ROM v3.1"), 3, 1, 40, 60, _T("CD32\0"), 524288, 18, 1, 0, ROMTYPE_KICKCD32, 0, 0, NULL, 0x1e62d4a5, 0x3525BE88,0x87F79B59,0x29E017B4,0x2380A79E,0xDFEE542D, NULL, NULL, 1 }, diff --git a/x86.cpp b/x86.cpp index 074feef5..a25232be 100644 --- a/x86.cpp +++ b/x86.cpp @@ -3303,6 +3303,8 @@ int is_x86_cpu(struct uae_prefs *p) } if (!xb || xb->x86_reset) return X86_STATE_STOP; + if (xb && xb->type < 0) + return X86_STATE_INACTIVE; return X86_STATE_ACTIVE; } @@ -3575,22 +3577,27 @@ static void set_vga(struct x86_bridge *xb) void mouse_serial_poll(int x, int y, int z, int b, void *p); void mouse_ps2_poll(int x, int y, int z, int b, void *p); -void x86_mouse(int port, int x, int y, int z, int b) +bool x86_mouse(int port, int x, int y, int z, int b) { struct x86_bridge *xb = bridges[0]; if (!xb || !xb->mouse_port || !xb->mouse_base || xb->mouse_port != port + 1) - return; + return false; switch (xb->mouse_type) { case 0: default: + if (b < 0) + return true; mouse_serial_poll(x, y, z, b, xb->mouse_base); - break; + return true; case 1: case 2: + if (b < 0) + return true; mouse_ps2_poll(x, y, z, b, xb->mouse_base); - break; + return true; } + return false; } void *mouse_serial_init(); -- 2.47.3