OSDN Git Service

[VM][FM7][WIP] Start to implement keyboard.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 11 Feb 2015 18:18:28 +0000 (03:18 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Wed, 11 Feb 2015 18:18:28 +0000 (03:18 +0900)
source/src/vm/fm7/keyboard.cpp [new file with mode: 0644]

diff --git a/source/src/vm/fm7/keyboard.cpp b/source/src/vm/fm7/keyboard.cpp
new file mode 100644 (file)
index 0000000..4ba1123
--- /dev/null
@@ -0,0 +1,328 @@
+/*
+ * Common Source code Project -> VM -> FM-7/77AV -> Keyboard
+ * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
+ * 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;
+    }
+  }
+}