From 7938242dd37cb932d11e8da587cf8a531a1f38c0 Mon Sep 17 00:00:00 2001 From: "K.Ohta" Date: Thu, 12 Feb 2015 03:18:28 +0900 Subject: [PATCH] [VM][FM7][WIP] Start to implement keyboard. --- source/src/vm/fm7/keyboard.cpp | 328 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 328 insertions(+) create mode 100644 source/src/vm/fm7/keyboard.cpp diff --git a/source/src/vm/fm7/keyboard.cpp b/source/src/vm/fm7/keyboard.cpp new file mode 100644 index 000000000..4ba112332 --- /dev/null +++ b/source/src/vm/fm7/keyboard.cpp @@ -0,0 +1,328 @@ +/* + * Common Source code Project -> VM -> FM-7/77AV -> Keyboard + * (C) 2015 K.Ohta + * Licence: GPLv2 + * History : + * Feb 12, 2015 : Initial + */ + +#include "../../fifo.h" +#include "../device.h" +#include "keyboard.h" + +enum { + SIG_FM7KEY_KEY_UP = 0x800, + SIG_FM7KEY_KEY_DOWN, + SIG_FM7KEY_READ, // D400 = high , D401 = low + SIG_FM7KEY_LED_ONOFF, // D40D: Write = OFF / Read = ON + // D431 + SIG_FM7KEY_PUSH_TO_ENCODER, +}; +// + +struct key_tbl_t { + uint16 vk; + uint16 code; +}; + +// Key tables value from XM7. +const struct key_tbl_t ctrl_key[] = { + {0x0c, 0x1e}, + {0x0d, 0x1c}, + {0x11, 0x11}, + {0x12, 0x17}, + {0x13, 0x05}, + {0x14, 0x12}, + {0x15, 0x14}, + {0x16, 0x19}, + {0x17, 0x15}, + {0x18, 0x09}, + {0x19, 0x0f}, + {0x1a, 0x10}, + {0x1b, 0x00}, + {0x1c, 0x1b}, + {0x1e, 0x01}, + {0x1f, 0x13}, + {0x20, 0x04}, + {0x21, 0x06}, + {0x22, 0x07}, + {0x23, 0x08}, + {0x24, 0x0a}, + {0x25, 0x0b}, + {0x26, 0x0c}, + {0x29, 0x1d}, + {0x2a, 0x1a}, + {0x2b, 0x18}, + {0x2c, 0x03}, + {0x2d, 0x16}, + {0x2e, 0x02}, + {0x2f, 0x0e}, + {0x30, 0x0d}, + {0x34, 0x1f}, + {0xffff, 0xffff} +}; + +const struct key_tbl_t graph_key[] = { + {0x5d, 0x101}, + {0x5e, 0x102}, + {0x5f, 0x103}, + {0x60, 0x104}, + {0x61, 0x105}, + {0x62, 0x106}, + {0x63, 0x107}, + {0x64, 0x108}, + {0x65, 0x109}, + {0x66, 0x10a}, + + {0x01, 0x1b}, + {0x02, 0xf9}, + {0x03, 0xfa}, + {0x04, 0xfb}, + {0x05, 0xfc}, + {0x06, 0xf2}, + {0x07, 0xf3}, + {0x08, 0xf4}, + {0x09, 0xf5}, + {0x0a, 0xf6}, + {0x0b, 0xf7}, + {0x0c, 0x8c}, + {0x0d, 0x8b}, + {0x0e, 0xf1}, + {0x0f, 0x08}, + + {0x10, 0x09}, + {0x11, 0xfd}, + {0x12, 0xf8}, + {0x13, 0xe4}, + {0x14, 0xe5}, + {0x15, 0x9c}, + {0x16, 0x9d}, + {0x17, 0xf0}, + {0x18, 0xe8}, + {0x19, 0xe9}, + {0x1a, 0x8d}, + {0x1b, 0x8a}, + {0x1c, 0xed}, + {0x1d, 0x0d}, + {0x1e, 0x95}, + {0x1f, 0x96}, + +}; +/* + * I/O API (subio) + */ +// 0xd431 : Read +uint8 KEYBOARD::read_data_reg(void) +{ + if(rxrdy->read_signal(0) != 0) { + if(!data_fifo->empty()) { + datareg = data_fifo->read() & 0xff; + } + rxrdy->write_signal(0x01, 0x00, 0x01); + } + return datareg; +} + +// 0xd432 +uint8 KEYBOARD::read_stat_reg(void) +{ + uint8 data = 0x7f; + if(rxrdy->read_signal(0x00) != 0) { + data |= 0x80; + } + // Digityze : bit0 = '0' when waiting, +} + +// 0xd400(SUB) or 0xfd00(MAIN) +uint8 KEYBOARD::get_keycode_high(void) +{ + uint8 data = 0x00; + if((keycode_7 & 0x0100) != 0) data |= 0x01; + return data; +} + +// 0xd401(SUB) or 0xfd01(MAIN) +uint8 KEYBOARD::get_keycode_low(void) +{ + uint8 data = keycode_7 & 0xff; + maincpu->write_signal(SIG_CPU_IRQ, 0, 1); + subcpu->write_signal(SIG_CPU_FIRQ, 0, 1); + return data; +} + + + +// UI Handler. +void KEYBOARD::key_up(uint32 vk) +{ + vk = vk & 0x1ff; + if(event_ids[vk] >= 0){ + cancel_event(this, event_ids[vk]); + event_ids[vk] = -1; + } + if(this->isModifiers(vk)) { + set_modifiers(vk, false); + } + if(isBreakKey(vk)) { + break_line->write_signal(0x01, 0, 1); + maincpu->write_signal(SIG_CPU_FIRQ, 0, 1); + } + key_pressed_flag[vk] = false; +} + +void KEYBOARD::key_down(uint32 vk) +{ + double usec = (double)repeat_time_long * 1000.0; + vk = vk & 0x1ff; + key_pressed_flag[vk] = true; + if(!this->isModifiers(vk)) { + keycode_7 = vk2fmkeycode(vk); + maincpu->write_signal(SIG_CPU_IRQ, 1, 1); + subcpu->write_signal(SIG_CPU_FIRQ, 1, 1); + if(repeat_mode) register_event(this, ID_KEYBOARD_AUTOREPEAT + vk, usec, false, &event_ids[vk]); + } else { + set_modifiers(vk, true); + } + if(isBreakKey(vk)) { + break_line->write_signal(0x01, 1, 1); + maincpu->write_signal(SIG_CPU_FIRQ, 1, 1); + } +} + +void KEYBOARD::event_callback(int event_id, int err) +{ + if((event_id >= ID_KEYBOARD_AUTOREPEAT) && (event_id <= (ID_KEYBOARD_AUTOREPEAT + 0x1ff))){ + // Key repeat. + uint32 vk = event_id - ID_KEYBOARD_AUTOREPEAT; + double usec = (double)repeat_time_short * 1000.0; + key_pressed_flag[vk] = true; + if(!this->isModifiers(vk)) { + maincpu->write_signal(SIG_CPU_IRQ, 1, 1); + subcpu->write_signal(SIG_CPU_FIRQ, 1, 1); + if(repeat_mode) register_event(this, ID_KEYBOARD_AUTOREPEAT + vk, usec, false, &event_ids[vk]); + } + } +} + +// Commands +void KEYBOARD::reset_keyboard(void) +{ + repeat_time_short = 70; // mS + repeat_time_long = 700; // mS + repeat_on = true; + caps_led = false; + kana_led = false; + ins_led = false; + key_code = 0x00; + + lshift = false; + rshift = false; + ctrl = false; + graph = false; + cmd_fifo->clear(); + data_fifo->clear(); + datareg = 0x00; + rxrdy->write_signal(0x01, 0x00, 0x01); +} + +void KEYBOARD::set_mode(void) +{ + int count = cmd_fifo->count(); + int cmd; + if(count < 2) return; + cmd = cmd_fifo->read(); + key_format = cmd_fifo->read(); + reset_keyboard(); +} + +void KEYBOARD::get_mode(void) +{ + int cmd; + int dummy; + cmd = cmd_fifo->read(); + if(data_fifo->full()) { + dummy = data_fifo->read(); + } + data_fifo->write(key_format); + rxrdy->write_signal(0x01, 0x01, 0x01); +} + + + + +void KEYBOARD::write_signal(int id, uint32 data, uint32 mask) +{ + + if(id == SIG_FM7KEY_PUSH_TO_ENCODER) { + /* + * I refered XM7's sourcecode : VM/keyboard.c act of key-encoder. + * Thanks to Ryu.Takegami and PI. + */ + int count; + + if(cmd_fifo->full()) { + cmd_fifo->clear(); + } + if(cmd_fifo->empty()) { + cmd_phase = data & 0xff; + } + + cmd_fifo->write(data & 0xff); + count = cmd_fifo->count(); + + switch(cmd_phase) { + case 0: // Set mode + if(count >= 2) set_mode(); + break; + case 1: // Get mode + get_mode(); + break; + case 2: // Set LED Phase + if(count >= 2) set_leds(); + break; + case 3: // Get LED Phase + get_leds(); + break; + case 4: + if(count >= 2) set_repeat_type(); + break; + case 5: + if(count >= 3) set_repeat_time(); + break; + case 0x80: // Communicate to/from RTC. + if(count == 1) { + rtc_set = false; + } + if(count == 2) { + if((data & 0xff) == 0) { // Get + get_rtc(); + } else if((data & 0xff) == 1) { // Set + rtc_set_flag = true; + } else { // Illegal + cmd_fifo->clear(); + } + } + if(rtc_set_flag) { + if(count >= 9) { + set_rtc(); + } + } + break; + case 0x81: // Digitize. + if(count >= 2) do_digitize(); // WILL Implement? + break; + case 0x82: + if(count >= 2) set_screen_mode(); + break; + case 0x83: + get_screen_mode(); + break; + case 0x84: + if(count >= 2) set_brightness(); + break; + default: + cmd_fifo->clear(); + break; + } + } +} -- 2.11.0