OSDN Git Service

[VM] TRY:Use namespace {VMNAME} to separate around VMs. This feature still apply...
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / keyboard.cpp
index 4b72e49..f479e55 100644 (file)
  *  Feb 12, 2015 : Initial 
  */
 
+#include "vm.h"
+#include "emu.h"
 #include "../../fifo.h"
 #include "../device.h"
-#include "fm7_keyboard.h"
-
-//
-const uint16 vk_matrix_106[0x68] = { // VK
-       // +0, +1, +2, +3, +4, +5, +6, +7
-       /* 0x00, ESC, 1 , 2, 3, 4, 5, 6 */
-       0x00,            VK_KANJI,      '1',            '2',            '3',            '4',            '5',            '6',            // +0x00
-       /* 7, 8, 9, 0, - , ^, \|, BS */
-       '7',            '8',            '9',            '0',            0xbd,           0xde,           0xdc,           VK_BACK,        // +0x08
-       /* TAB, Q, W, E, R, T, Y, U */
-       VK_TAB,         'Q',            'W',            'E',            'R',            'T',            'Y',            'U',            // +0x10
-       /* I, O, P, @, [, [RET], A, S */
-       'I',            'O',            'P',            0xc0,           0xdb,           VK_RETURN,      'A',            'S',            //+0x18
-       /* D, F, G, H, J, K, L, ; */
-       'D',            'F',            'G',            'H',            'J',            'K',            'L',            0xbb,           // +0x20
-       /* :, ], Z, X, C, V, B, N */
-       0xba,           0xdd,           'Z',            'X',            'C',            'V',            'B',            'N',            // +0x28
-       /* M, , , ., / , \, RSPACE=RWIN , * , / */
-       'M',            0xbc,           0xbe,           0xbf,           0xe2,           VK_RWIN,        VK_MULTIPLY,    VK_DIVIDE,      // +0x30
-       /* + , - , 7, 8, 9, = , 4, 5 */
-       VK_ADD,         VK_SUBTRACT,    VK_NUMPAD7,     VK_NUMPAD8,     VK_NUMPAD9,     0x00,           VK_NUMPAD4,     VK_NUMPAD5,     // +0x38
-       /* 6, NUMPADCOMMA=RMENU , 1, 2, 3, NUMPADENTER=RETURN,0, . */
-       VK_NUMPAD6,     VK_RMENU,       VK_NUMPAD1,     VK_NUMPAD2,     VK_NUMPAD3,     VK_RETURN,      VK_NUMPAD0,     VK_DECIMAL,     // +0x40
-       /* INS, HOME, PRIOR, DEL, END, ↑, ↓,← */
-       VK_INSERT,      VK_HOME,        VK_PRIOR,       VK_DELETE,      VK_END,         VK_UP,          VK_NEXT,        VK_LEFT,        // +0x48
-       /* PAgeDown, →, LCTRL, LSHIFT, RSHIFT, CAPS, Graph=Muhenkan, Lspace=LALT */
-       VK_DOWN,        VK_RIGHT,       0x11,           0x10,           VK_RSHIFT,      0x14,           0x1d,   0xf3,   // +0x50
-       /* Cspace=Space, *Unknown*, KANA, *Unknown* , ESC(Break), F1, F2, F3 */
-       VK_SPACE,       0x00,           0x15,           0x00,           0x1b,           VK_F1,          VK_F2,  VK_F3,  // +0x58
-       /* F4, F5, F6, F7, F8, F9, F10 , *END* */
-       VK_F4,          VK_F5,          VK_F6,          VK_F7,          VK_F8,          VK_F9,          VK_F10,         0xffff  // +0x60
-};
-
-struct key_tbl_t {
-       uint16 phy;
-       uint16 code;
-};
-
-// Key tables value from XM7.
-const key_tbl_t standard_key[] = {
-       {0x01, 0x1b},
-       {0x02, 0x31},
-       {0x03, 0x32},
-       {0x04, 0x33},
-       {0x05, 0x34},
-       {0x06, 0x35},
-       {0x07, 0x36},
-       {0x08, 0x37},
-       {0x09, 0x38},
-       {0x0a, 0x39},
-       {0x0b, 0x30},
-       {0x0c, 0x2d},
-       {0x0d, 0x5e},
-       {0x0e, 0x5c},
-       {0x0f, 0x08},
-       
-       {0x10, 0x09},
-       {0x11, 0x71},
-       {0x12, 0x77},
-       {0x13, 0x65},
-       {0x14, 0x72},
-       {0x15, 0x74},
-       {0x16, 0x79},
-       {0x17, 0x75},
-       {0x18, 0x69},
-       {0x19, 0x6f},
-       {0x1a, 0x70},
-       {0x1b, 0x40},
-       {0x1c, 0x5b},
-       {0x1d, 0x0d},
-       {0x1e, 0x61},
-       {0x1f, 0x73},
-       
-       {0x20, 0x64},
-       {0x21, 0x66},
-       {0x22, 0x67},
-       {0x23, 0x68},
-       {0x24, 0x6a},
-       {0x25, 0x6b},
-       {0x26, 0x6c},
-       {0x27, 0x3b},
-       {0x28, 0x3a},
-       {0x29, 0x5d},
-       {0x2a, 0x7a},
-       {0x2b, 0x78},
-       {0x2c, 0x63},
-       {0x2d, 0x76},
-       {0x2e, 0x62},
-       {0x2f, 0x6e},
-       
-       {0x30, 0x6d},
-       {0x31, 0x2c},
-       {0x32, 0x2e},
-       {0x33, 0x2f},
-       {0x34, 0x22},
-       {0x35, 0x20},
-       {0x36, 0x2a},
-       {0x37, 0x2f},
-       {0x38, 0x2b},
-       {0x39, 0x2d},
-       {0x3a, 0x37},
-       {0x3b, 0x38},
-       {0x3c, 0x39},
-       {0x3d, 0x3d},
-       {0x3e, 0x34},
-       {0x3f, 0x35},
-       
-       {0x40, 0x36},
-       {0x41, 0x2c},
-       {0x42, 0x31},
-       {0x43, 0x32},
-       {0x44, 0x33},
-       {0x45, 0x0d},
-       {0x46, 0x30},
-       {0x47, 0x2e},
-       {0x48, 0x12},
-       {0x49, 0x05},
-       {0x4a, 0x0c},
-       {0x4b, 0x7f},
-       {0x4c, 0x11},
-       {0x4d, 0x1e},
-       {0x4e, 0x0b},
-       {0x4f, 0x1d},
-       
-       {0x50, 0x1f},
-       {0x51, 0x1c},
-       
-       {0x57, 0x20},
-       {0x58, 0x20},
-       
-       {0x5d, 0x0101},
-       {0x5e, 0x0102},
-       {0x5f, 0x0103},
-       {0x60, 0x0104},
-       {0x61, 0x0105},
-       {0x62, 0x0106},
-       {0x63, 0x0107},
-       {0x64, 0x0108},
-       {0x65, 0x0109},
-       {0x66, 0x010a},
-       
-       {0xffff, 0xffff}
-};
 
-const key_tbl_t standard_shift_key[] = {
-       {0x01, 0x1b},
-       {0x02, 0x21},
-       {0x03, 0x22},
-       {0x04, 0x23},
-       {0x05, 0x24},
-       {0x06, 0x25},
-       {0x07, 0x26},
-       {0x08, 0x27},
-       {0x09, 0x28},
-       {0x0a, 0x29},
-       
-       {0x0c, 0x3d},
-       {0x0d, 0x7e},
-       {0x0e, 0x7c},
-       {0x0f, 0x08},
-       
-       {0x10, 0x09},
-       {0x11, 0x51},
-       {0x12, 0x57},
-       {0x13, 0x45},
-       {0x14, 0x52},
-       {0x15, 0x54},
-       {0x16, 0x59},
-       {0x17, 0x55},
-       {0x18, 0x49},
-       {0x19, 0x4f},
-       {0x1a, 0x50},
-       {0x1b, 0x60},
-       {0x1c, 0x7b},
-       {0x1d, 0x0d},
-       {0x1e, 0x41},
-       {0x1f, 0x53},
-       
-       {0x20, 0x44},
-       {0x21, 0x46},
-       {0x22, 0x47},
-       {0x23, 0x48},
-       {0x24, 0x4a},
-       {0x25, 0x4b},
-       {0x26, 0x4c},
-       {0x27, 0x2b},
-       {0x28, 0x2a},
-       {0x29, 0x7d},
-       {0x2a, 0x5a},
-       {0x2b, 0x58},
-       {0x2c, 0x43},
-       {0x2d, 0x56},
-       {0x2e, 0x42},
-       {0x2f, 0x4e},
-       
-       {0x30, 0x4d},
-       {0x31, 0x3c},
-       {0x32, 0x3e},
-       {0x33, 0x3f},
-       {0x34, 0x5f},
-       {0x35, 0x20},
-       {0x36, 0x2a},
-       {0x37, 0x2f},
-       {0x38, 0x2b},
-       {0x39, 0x2d},
-       {0x3a, 0x37},
-       {0x3b, 0x38},
-       {0x3c, 0x39},
-       {0x3d, 0x3d},
-       {0x3e, 0x34},
-       {0x3f, 0x35},
-
-       {0x40, 0x36},
-       {0x41, 0x2c},
-       {0x42, 0x31},
-       {0x43, 0x32},
-       {0x44, 0x33},
-       {0x45, 0x0d},
-       {0x46, 0x30},
-       {0x47, 0x2e},
-       {0x48, 0x12},
-       {0x49, 0x05},
-       {0x4a, 0x0c},
-       {0x4b, 0x7f},
-       {0x4c, 0x11},
-       {0x4d, 0x19},
-       {0x4e, 0x0b},
-       {0x4f, 0x02},
-       
-       {0x50, 0x1a},
-       {0x51, 0x06},
-
-       {0x57, 0x20},
-       {0x58, 0x20},
-       {0xffff, 0xffff}
-};
-
-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}, // 09
-       {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 ctrl_shift_key[] = {
-       {0x0c, 0x1e},
-       {0x0d, 0x1c},
-       
-       {0x11, 0x11},
-       {0x12, 0x17},
-       {0x13, 0x05},
-       {0x14, 0x12},
-       {0x15, 0x14},
-       {0x16, 0x19},
-       {0x17, 0x15},
-       {0x18, 0x09},
-       {0x19, 0x09},
-       {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}
-};
+#include "fm7_keyboard.h"
+#include "keyboard_tables.h"
 
-const struct key_tbl_t graph_key[] = {
-       {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},
-  
-       {0x20, 0xe6},
-       {0x21, 0xe7},
-       {0x22, 0x9e},
-       {0x23, 0x9f},
-       {0x24, 0xea},
-       {0x25, 0xeb},
-       {0x26, 0x8e},
-       {0x27, 0x99},
-       {0x28, 0x94},
-       {0x29, 0xec},
-       {0x2a, 0x80},
-       {0x2b, 0x81},
-       {0x2c, 0x82},
-       {0x2d, 0x83},
-       {0x2e, 0x84},
-       {0x2f, 0x85},
-       
-       {0x30, 0x86},
-       {0x31, 0x87},
-       {0x32, 0x88},
-       {0x33, 0x97},
-       {0x34, 0xe0},
-       {0x35, 0x20},
-       {0x36, 0x98},
-       {0x37, 0x91},
-       {0x38, 0x99},
-       {0x39, 0xee},
-       {0x3a, 0xe1},
-       {0x3b, 0xe2},
-       {0x3c, 0xe3},
-       {0x3d, 0xef},
-       {0x3e, 0x93},
-       {0x3f, 0x8f},
-
-       {0x40, 0x92}, 
-       
-       {0x42, 0x9a},
-       {0x43, 0x90},
-       {0x44, 0x9b},
-       {0x45, 0x0d},
-       {0x48, 0x12},
-       {0x49, 0x05},
-       {0x4a, 0x0c},
-       {0x4b, 0x7f},
-       {0x4c, 0x11},
-       {0x4d, 0x1e},
-       {0x4e, 0x0b},
-       {0x4f, 0x1d},
-  
-       {0x50, 0x1f},
-       {0x51, 0x1c},
-
-       {0x57, 0x20},
-       {0x58, 0x20},
-       /* Belows is none when shift */
-       {0x5d, 0x101},
-       {0x5e, 0x102},
-       {0x5f, 0x103},
-       {0x60, 0x104},
-       {0x61, 0x105},
-       {0x62, 0x106},
-       {0x63, 0x107},
-       {0x64, 0x108},
-       {0x65, 0x109},
-       {0x66, 0x10a},
-       {0xffff, 0xffff}
-};
-const struct key_tbl_t graph_shift_key[] = {
-       {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},
-  
-       {0x20, 0xe6},
-       {0x21, 0xe7},
-       {0x22, 0x9e},
-       {0x23, 0x9f},
-       {0x24, 0xea},
-       {0x25, 0xeb},
-       {0x26, 0x8e},
-       {0x27, 0x99},
-       {0x28, 0x94},
-       {0x29, 0xec},
-       {0x2a, 0x80},
-       {0x2b, 0x81},
-       {0x2c, 0x82},
-       {0x2d, 0x83},
-       {0x2e, 0x84},
-       {0x2f, 0x85},
-  
-       {0x30, 0x86},
-       {0x31, 0x87},
-       {0x32, 0x88},
-       {0x33, 0x97},
-       {0x34, 0xe0},
-       {0x35, 0x20},
-       {0x36, 0x98},
-       {0x37, 0x91},
-       {0x38, 0x99},
-       {0x39, 0xee},
-       {0x3a, 0xe1},
-       {0x3b, 0xe2},
-       {0x3c, 0xe3},
-       {0x3d, 0xef},
-       {0x3e, 0x93},
-       {0x3f, 0x8f},
-
-       {0x40, 0x92}, 
-       
-       {0x42, 0x9a},
-       {0x43, 0x90},
-       {0x44, 0x9b},
-       {0x45, 0x0d},
-       
-       {0x48, 0x12},
-       {0x49, 0x05},
-       {0x4a, 0x0c},
-       {0x4b, 0x7f},
-       {0x4c, 0x11},
-       {0x4d, 0x19},
-       {0x4e, 0x0b},
-       {0x4f, 0x02},
-  
-       {0x50, 0x1a},
-       {0x51, 0x06},
-       
-       {0x57, 0x20},
-       {0x58, 0x20},
-       {0xffff, 0xffff}
-};
+#if defined(_FM77AV_VARIANTS)
+#include "../beep.h"
 
-const struct key_tbl_t kana_key[] = {
-       {0x01, 0x1b},
-       {0x02, 0xc7},
-       {0x03, 0xcc},
-       {0x04, 0xb1},
-       {0x05, 0xb3},
-       {0x06, 0xb4},
-       {0x07, 0xb5},
-       {0x08, 0xd4},
-       {0x09, 0xd5},
-       {0x0a, 0xd6},
-       {0x0b, 0xdc},
-       {0x0c, 0xce},
-       {0x0d, 0xcd},
-       {0x0e, 0xb0},
-       {0x0f, 0x08},
-       
-       {0x10, 0x09},
-       {0x11, 0xc0},
-       {0x12, 0xc3},
-       {0x13, 0xb2},
-       {0x14, 0xbd},
-       {0x15, 0xb6},
-       {0x16, 0xdd},
-       {0x17, 0xc5},
-       {0x18, 0xc6},
-       {0x19, 0xd7},
-       {0x1a, 0xbe},
-       {0x1b, 0xde},
-       {0x1c, 0xdf},
-       {0x1d, 0x0d},
-       {0x1e, 0xc1},
-       {0x1f, 0xc4},
-       
-       {0x20, 0xbc},
-       {0x21, 0xca},
-       {0x22, 0xb7},
-       {0x23, 0xb8},
-       {0x24, 0xcf},
-       {0x25, 0xc9},
-       {0x26, 0xd8},
-       {0x27, 0xda},
-       {0x28, 0xb9},
-       {0x29, 0xd1},
-       {0x2a, 0xc2},
-       {0x2b, 0xbb},
-       {0x2c, 0xbf},
-       {0x2d, 0xcb},
-       {0x2e, 0xba},
-       {0x2f, 0xd0},
-                 
-       {0x30, 0xd3},
-       {0x31, 0xc8},
-       {0x32, 0xd9},
-       {0x33, 0xd2},
-       {0x34, 0xdb},
-       {0x35, 0x20},
-       {0x36, 0x2a},
-       {0x37, 0x2f},
-       {0x38, 0x2b},
-       {0x39, 0x2d},
-       {0x3a, 0x37},
-       {0x3b, 0x38},
-       {0x3c, 0x39},
-       {0x3d, 0x3d},
-       {0x3e, 0x34},
-       {0x3f, 0x35},
-                 
-       {0x40, 0x36},
-       {0x41, 0x2c},
-       {0x42, 0x31},
-       {0x43, 0x32},
-       {0x44, 0x33},
-       {0x45, 0x0d},
-       {0x46, 0x30},
-       {0x47, 0x2e},
-  
-       {0x48, 0x12},
-       {0x49, 0x05},
-       {0x4a, 0x0c},
-       {0x4b, 0x7f},
-       {0x4c, 0x11},
-       {0x4d, 0x1e},
-       
-       {0x4e, 0x0b},
-       {0x4f, 0x1d},
-       {0x50, 0x1f},
-       {0x51, 0x1c},
-       
-       
-       {0x57, 0x20},
-       {0x58, 0x20},
-       
-       {0x5d, 0x0101},
-       {0x5e, 0x0102},
-       {0x5f, 0x0103},
-       {0x60, 0x0104},
-       {0x61, 0x0105},
-       {0x62, 0x0106},
-       {0x63, 0x0107},
-       {0x64, 0x0108},
-       {0x65, 0x0109},
-       {0x66, 0x010a},
-
-       {0xffff, 0xffff}
-};
+namespace FM7 {
+       #include "fm77av_hidden_message_keyboard.h"
+}
+#endif
 
-const struct key_tbl_t kana_shift_key[] = {
-       {0x01, 0x1b},
-       {0x04, 0xa7},
-       {0x05, 0xa9},
-       {0x06, 0xaa},
-       {0x07, 0xab},
-       {0x08, 0xac},
-       {0x09, 0xad},
-       {0x0a, 0xae},
-       {0x0b, 0xa6},
-       {0x0f, 0x08},
-       
-       {0x10, 0x09},
-       {0x13, 0xa8},
-       {0x1c, 0xa2},
-       {0x1d, 0x0d},
-       
-       {0x29, 0xa3},
-       {0x2a, 0xaf},
-       
-       {0x31, 0xa4},
-       {0x32, 0xa1},
-       {0x33, 0xa5},
-       
-       {0x35, 0x20},
-       {0x36, 0x2a},
-       {0x37, 0x2f},
-       {0x38, 0x2b},
-       {0x39, 0x2d},
-       {0x3a, 0x37},
-       {0x3b, 0x38},
-       {0x3c, 0x39},
-       {0x3d, 0x3d},
-       {0x3e, 0x34},
-       {0x3f, 0x35},
-       
-       {0x40, 0x36},
-       {0x41, 0x2c},
-       {0x42, 0x31},
-       {0x43, 0x32},
-       {0x44, 0x33},
-       {0x45, 0x0d},
-       {0x46, 0x30},
-       {0x47, 0x2e},
-  
-       {0x48, 0x12},
-       {0x49, 0x05},
-       {0x4a, 0x0c},
-       {0x4b, 0x7f},
-       {0x4c, 0x11},
-       {0x4d, 0x19},
-
-       {0x4e, 0x0b},
-       {0x4f, 0x02},
-       {0x50, 0x1a},
-       {0x51, 0x06},
-       
-       {0x57, 0x20},
-       {0x58, 0x20},
+namespace FM7 {
 
-       {0xffff, 0xffff}
+enum {
+       ID_KEYBOARD_RXRDY_OK = 1,
+       ID_KEYBOARD_ACK,
+       ID_KEYBOARD_RXRDY_BUSY,
+       ID_KEYBOARD_RTC_COUNTUP,
+       ID_KEYBOARD_INT,
+       ID_KEYBOARD_AUTOREPEAT_FIRST,
+       ID_KEYBOARD_AUTOREPEAT,
+       ID_KEYBOARD_HIDDENMESSAGE_AV,
+       ID_KEYBOARD_HIDDEN_BEEP_ON,
+       ID_KEYBOARD_HIDDEN_BEEP_OFF,
+       ID_KEYBOARD_AUTO_8KEY_START,
+       ID_KEYBOARD_AUTO_8KEY_END,
+       ID_KEYBOARD_AUTO_5KEY_START,
+       ID_KEYBOARD_AUTO_5KEY_END,
+       ID_KEYBOARD_BREAK_ONESHOT,
 };
 
+//
 /*
  * I/O API (subio)
  */
 // 0xd400(SUB) or 0xfd00(MAIN)
-uint8 KEYBOARD::get_keycode_high(void)
+uint8_t KEYBOARD::get_keycode_high(void)
 {
-       uint8 data = 0x00;
-       if((keycode_7 & 0x0100) != 0) data |= 0x01;
+       uint8_t data = 0x00;
+       if((keycode_7 & 0x0100) != 0) data = 0x80;
        return data;
 }
 
 // 0xd401(SUB) or 0xfd01(MAIN)
-uint8 KEYBOARD::get_keycode_low(void)
+uint8_t KEYBOARD::get_keycode_low(void)
 {
-       uint8 data = keycode_7 & 0xff;
-       mainio->write_signal(FM7_MAINIO_KEYBOARDIRQ, 0, 1);
-       display->write_signal(SIG_FM7_SUB_KEY_FIRQ, 0, 1);
+       uint8_t data = keycode_7 & 0xff;
+       this->write_signals(&int_line, 0x00000000);
        return data;
 }
 
 // 0xd40d : R
 void KEYBOARD::turn_on_ins_led(void)
 {
-       this->write_signals(&ins_led, 0xff);
+       ins_led_status = true;
 }
 
 // 0xd40d : W
 void KEYBOARD::turn_off_ins_led(void)
 {
-       this->write_signals(&ins_led, 0x00);
+       ins_led_status = false;
 }
 
 // UI Handler. 
-uint16 KEYBOARD::vk2scancode(uint32 vk)
+uint16_t KEYBOARD::vk2scancode(uint32_t vk)
 {
-       uint16 i;
+       uint16_t i;
        i = 0;
+       if(vk == VK_PAUSE) vk = VK_KANJI; // Workaround some desktop environments for [ESC].
        do {
                if(vk_matrix_106[i] == vk) return i;
                i++;
@@ -732,36 +87,30 @@ uint16 KEYBOARD::vk2scancode(uint32 vk)
        return 0x0000;
 }
 
-bool KEYBOARD::isModifier(uint16 scancode)
+bool KEYBOARD::isModifier(uint8_t sc)
 {
-       if(((scancode >= 0x52) && (scancode <= 0x56)) || // CTRL LSHIFT RSHIFT CAPS GRPH
-               (scancode == 0x5a) || (scancode == 0x5c)) { // KANA BREAK
+       if(((sc >= 0x52) && (sc <= 0x56)) || // CTRL LSHIFT RSHIFT CAPS GRPH
+               (sc == 0x5a) || (sc == 0x5c)) { // KANA BREAK
                return true;
        }
        return false;
 }
 
-void KEYBOARD::set_modifiers(uint16 scancode, bool flag)
+void KEYBOARD::set_modifiers(uint8_t sc, bool flag)
 {
-       if(scancode == 0x52) { // CTRL
+       if(sc == 0x52) { // CTRL
                ctrl_pressed = flag; 
-       } else if(scancode == 0x53) { // LSHIFT
+       } else if(sc == 0x53) { // LSHIFT
                lshift_pressed = flag;
-               if(rshift_pressed) {
-                       shift_pressed = true;
-               } else {
-                       shift_pressed = flag;
-               }
-       } else if(scancode == 0x54) { // RSHIFT
+               shift_pressed = lshift_pressed | rshift_pressed;
+               //printf("LSHIFT : %d\n", flag ? 1 : 0);
+       } else if(sc == 0x54) { // RSHIFT
                rshift_pressed = flag;
-               if(lshift_pressed) {
-                 shift_pressed = true;
-               } else {
-                 shift_pressed = flag;
-               }
-       } else if(scancode == 0x56) { // GRPH
+               shift_pressed = lshift_pressed | rshift_pressed;
+               //printf("RSHIFT : %d\n", flag ? 1 : 0);
+       } else if(sc == 0x56) { // GRPH
                graph_pressed = flag;
-       } else if(scancode == 0x55) { // CAPS
+       } else if(sc == 0x55) { // CAPS
                // Toggle on press.
                if(flag) {
                        if(caps_pressed) {
@@ -769,9 +118,9 @@ void KEYBOARD::set_modifiers(uint16 scancode, bool flag)
                        } else {
                                caps_pressed = true;
                        }
-                       if(keymode == KEYMODE_STANDARD) this->write_signals(&caps_led, caps_pressed ? 0xff : 0x00);
+                       if(keymode == KEYMODE_STANDARD) caps_led_status = caps_pressed;
                }
-       } else if(scancode == 0x5a) { // KANA
+       } else if(sc == 0x5a) { // KANA
                // Toggle on press.
                if(flag) {
                        if(kana_pressed) {
@@ -779,34 +128,35 @@ void KEYBOARD::set_modifiers(uint16 scancode, bool flag)
                        } else {
                                kana_pressed = true;
                        }
-                       if(keymode == KEYMODE_STANDARD) this->write_signals(&kana_led, kana_pressed ? 0xff : 0x00);
+                       if(keymode == KEYMODE_STANDARD) kana_led_status = kana_pressed;
+               }
+       } else if(sc == 0x5c) { // Break
+               if(!override_break_key) {
+                       break_pressed = flag;
                }
-       } else if(scancode == 0x5c) { // Break
-               break_pressed = flag;
        }
 }
 
-uint16 KEYBOARD::scan2fmkeycode(uint16 scancode)
+uint16_t KEYBOARD::scan2fmkeycode(uint8_t sc)
 {
-       const struct key_tbl_t *keyptr;
-       uint16 code;
+       const struct key_tbl_t *keyptr = NULL;
        bool stdkey = false;
        int i;
-       uint16 retval;
+       uint16_t retval;
        
-       if((scancode == 0) || (scancode >= 0x67)) return 0xffff;
+       if((sc == 0) || (sc >= 0x67)) return 0xffff;
        // Set repeat flag(s)
        if(shift_pressed && ctrl_pressed) {
-               switch(scancode) {
+               switch(sc) {
                        case 0x02: // 1
                        case 0x42: // 1
                                repeat_mode = true;
-                               //return 0xffff;
+                               return 0xffff;
                                break;
                        case 0x0b: // 0
                        case 0x46: // 0
                                repeat_mode = false;
-                               //return 0xffff;
+                               return 0xffff;
                                break;
                }
        }
@@ -837,7 +187,6 @@ uint16 KEYBOARD::scan2fmkeycode(uint16 scancode)
                                keyptr = standard_key;
                        }
                }
-               if(keyptr == NULL) return 0xffff;
        }
 #if defined(_FM77AV_VARIANTS)
        else    if(shift_pressed) {
@@ -848,22 +197,48 @@ uint16 KEYBOARD::scan2fmkeycode(uint16 scancode)
          // F10: TV
        }
        if(keymode == KEYMODE_SCAN) {
-               retval = scancode;
+               retval = (uint16_t)sc;
                return retval;
        } else if(keymode == KEYMODE_16BETA) { // Will Implement
-               return 0xffff;
+               if(ctrl_pressed) {
+                       if(shift_pressed) {
+                               keyptr = ctrl_shift_key_16beta;
+                       } else {
+                               keyptr = ctrl_key_16beta;
+                       }
+               } else if(graph_pressed) {
+                       if(shift_pressed) {
+                               keyptr = graph_shift_key_16beta;
+                       } else {
+                               keyptr = graph_key_16beta;
+                       }
+               } else if(kana_pressed) {
+                       if(shift_pressed) {
+                               keyptr = kana_shift_key_16beta;
+                       } else {
+                               keyptr = kana_key_16beta;
+                       }
+               } else { // Standard
+                       stdkey = true;
+                       if(shift_pressed) {
+                               keyptr = standard_shift_key_16beta;
+                       } else {
+                               keyptr = standard_key_16beta;
+                       }
+               }
        }
 #endif //_FM77AV_VARIANTS      
        i = 0;
        retval = 0xffff;
+       if (keyptr == NULL) return 0xffff;
        do {
-               if(keyptr[i].phy == scancode) {
+               if(keyptr[i].phy == (uint16_t)sc) {
                        retval = keyptr[i].code;
                        break;
                }
                i++;
        } while(keyptr[i].phy != 0xffff);
-
+       if(keyptr[i].phy == 0xffff) return 0x00;
        if(stdkey) {
                if((retval >= 'A') && (retval <= 'Z')) {
                        if(caps_pressed) {
@@ -878,177 +253,456 @@ uint16 KEYBOARD::scan2fmkeycode(uint16 scancode)
        return retval;
 }
 
-void KEYBOARD::key_up(uint32 vk)
+void KEYBOARD::key_up_main(uint8_t bak_scancode)
 {
-       uint16 scancode = vk2scancode(vk);
        bool stat_break = break_pressed;
-       uint32 code_7;
-
-       if(scancode == 0) return;
-       if(event_ids[scancode] >= 0){
-               cancel_event(this, event_ids[scancode]);
-               event_ids[scancode] = -1;
+       older_vk = 0;
+       if(bak_scancode == 0) return;
+       if((event_keyrepeat >= 0) && (repeat_keycode == bak_scancode)) { // Not Break
+               cancel_event(this, event_keyrepeat);
+               event_keyrepeat = -1;
+               repeat_keycode = 0;
        }
-       if(this->isModifier(scancode)) {
-               set_modifiers(scancode, false);
-               if(break_pressed != stat_break) { // Break key UP.
-                       //mainio->write_signal(FM7_MAINIO_PUSH_BREAK, 0x00, 0xff);
-                       this->write_signals(&break_line, 0x00);
+       if(keymode != KEYMODE_SCAN) {
+               if(this->isModifier(bak_scancode)) {
+                       set_modifiers(bak_scancode, false);
+                       if(break_pressed != stat_break) { // Break key UP.
+                               this->write_signals(&break_line, 0x00);
+                       }
                }
-       }
-       if(keymode == KEYMODE_SCAN) {
-               code_7 = scan2fmkeycode(scancode);
-               if(code_7 < 0x200) {
-                       keycode_7 = code_7;
-                       //mainio->write_signal(FM7_MAINIO_PUSH_KEYBOARD, code_7, 0x1ff);
-                       //mainio->write_signal(FM7_MAINIO_KEYBOARDIRQ, 0, 1);
-                       //display->write_signal(SIG_FM7_SUB_KEY_FIRQ, 0, 1);
+               if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
+                       if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
+                               switch(bak_scancode) {
+                                       case 0x42: // 1
+                                       case 0x43: // 2
+                                       case 0x44: // 3
+                                       case 0x3f: // 5
+                                       case 0x46: // 0
+                                               register_event(this,
+                                                                          ID_KEYBOARD_AUTO_8KEY_START,
+                                                                          10.0 * 1000.0, false, NULL);
+                                               break;
+                                       default:
+                                               if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
+                                               break;
+                               }
+                       } else { // Auto 5
+                               switch(bak_scancode) {
+                                       case 0x42: // 1
+                                       case 0x43: // 2
+                                       case 0x44: // 3
+                                       case 0x3e: // 4
+                                       case 0x40: // 6
+                                       case 0x3a: // 7
+                                       case 0x3b: // 8
+                                       case 0x3c: // 9
+                                               register_event(this,
+                                                                          ID_KEYBOARD_AUTO_5KEY_START,
+                                                                          10.0 * 1000.0, false, NULL);
+                                               break;
+                                       default:
+                                               if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
+                                               break;
+                               }
+                       }                               
+               }
+       } else {
+               //scancode = 0;
+               if(bak_scancode != 0) { // Notify even key-up, when using SCAN mode.
+                       uint8_t code = (bak_scancode & 0x7f) | 0x80;
+                       if(this->isModifier(bak_scancode)) {
+                               set_modifiers(bak_scancode, false);
+                       }
+#if defined(_FM77AV_VARIANTS)     
+                       if(bak_scancode != 0x5c) {
+                               if(beep_phase == 1) {
+                                       if(break_pressed) this->write_signals(&break_line, 0x00);
+                                       break_pressed = false;
+                                       beep_phase++;
+                                       bak_scancode = 0x7f;
+                                       code = 0xff;
+                               } else if(beep_phase == 2) {
+                                       beep_phase = 0;
+                                       register_event(this,
+                                                                  ID_KEYBOARD_HIDDEN_BEEP_ON,
+                                                                  100.0, false, NULL); // 100.0 us is dummy.
+                                       bak_scancode = 0x7f;
+                                       code = 0xff;
+                               }
+                       } else { // 0x5c : BREAK is up.
+                               beep_phase = 0;
+                               if(stat_break) this->write_signals(&break_line, 0x00);
+                       }
+#endif            
+                       if(code != 0x80) {
+                               key_fifo->write(code);
+                               scancode = bak_scancode;
+                       }
                }
-       }         
-       key_pressed_flag[scancode] = false; 
+       }
 }
 
-void KEYBOARD::key_down(uint32 vk)
+void KEYBOARD::key_up(uint32_t vk)
 {
-       double usec = (double)repeat_time_long * 1000.0;
-       uint32 code_7;
-       uint16 scancode = vk2scancode(vk);
-       bool stat_break = break_pressed;
-       //printf("VK=%04x SCAN=%04x break=%d\n", vk, scancode, stat_break);
+       uint8_t bak_scancode = (uint8_t)(vk2scancode(vk) & 0x00ff);
+       key_up_main(bak_scancode);
+}
 
-       if(scancode == 0) return;
-       key_pressed_flag[scancode] = true;
+void KEYBOARD::key_down(uint32_t vk)
+{
+       if(older_vk == vk) return;
+       older_vk = vk;
        
-       if(this->isModifier(scancode)) {  // modifiers
-               set_modifiers(scancode, true);
-               if(break_pressed != stat_break) { // Break key Down.
-                       //mainio->write_signal(FM7_MAINIO_PUSH_BREAK, 0xff, 0xff);
-                       this->write_signals(&break_line, 0xff);
+       scancode = (uint8_t)vk2scancode(vk);
+#if defined(_FM77AV_VARIANTS)
+       // Below are FM-77AV's hidden message , see :
+       // https://twitter.com/maruan/status/499558392092831745
+       //if(caps_pressed && kana_pressed) {
+       //      if(ctrl_pressed && lshift_pressed && rshift_pressed && graph_pressed) {
+       if(caps_pressed && kana_pressed && graph_pressed && shift_pressed && ctrl_pressed && !did_hidden_message_av_1) { // IT's deprecated key pressing
+               if(scancode == 0x15) { // "T"
+                       if(event_hidden1_av < 0) {
+                               hidden1_ptr = 0;
+                               did_hidden_message_av_1 = true;
+                               register_event(this,
+                                               ID_KEYBOARD_HIDDENMESSAGE_AV,
+                                               130.0 * 1000, true, &event_hidden1_av);
+                       }
+                       return;
                }
        }
-       code_7 = scan2fmkeycode(scancode);
-       if(code_7 < 0x200) {
-               keycode_7 = code_7;
-               mainio->write_signal(FM7_MAINIO_PUSH_KEYBOARD, code_7, 0x1ff);
-               mainio->write_signal(FM7_MAINIO_KEYBOARDIRQ, 1, 1);
-               display->write_signal(SIG_FM7_SUB_KEY_FIRQ, 1, 1);
-       }
-       // If repeat && !(PF) && !(BREAK) 
-       if((repeat_mode) && (scancode < 0x5c) && (scancode != 0)) {
-               register_event(this,
-                              ID_KEYBOARD_AUTOREPEAT_FIRST + scancode,
-                              usec, false, &event_ids[scancode]);
+#endif 
+       key_down_main(true);
+}
+
+void KEYBOARD::key_down_main(bool repeat_auto_key)
+{
+       bool stat_break = break_pressed;
+       uint32_t code;
+       if(scancode == 0) return;
+       if(keymode == KEYMODE_SCAN) {
+               code = scancode & 0x7f;
+               if(this->isModifier(scancode)) {  // modifiers
+                       set_modifiers(scancode, true);
+               }
+#if defined(_FM77AV_VARIANTS)
+               if(break_pressed) {
+                       if(!stat_break) {
+                               beep_phase = 1;
+                               // It's dirty hack for AMNORK ; Set dead zone for FIRQ to 0.25sec.
+                               // I wish to replace this solution to more simple. 
+                               register_event(this,
+                                                          ID_KEYBOARD_BREAK_ONESHOT,
+                                                          250.0 * 1000.0, false, NULL);
+                       } else if(beep_phase == 1) {
+                               if(code != 0x5c) {
+                                       if(break_pressed) this->write_signals(&break_line, 0x00);
+                                       break_pressed = false;
+                                       beep_phase++;
+                                       code = 0x7f; // Special
+                                       scancode = 0x7f;        
+                               }
+                       }
+               }
+#endif
+
+               if(code != 0) {
+                       key_fifo->write(code);
+                       // NOTE: With scan key code mode, auto repeat seems to be not effectable.
+                       // See : http://hanabi.2ch.net/test/read.cgi/i4004/1430836648/607
+                       // 20160409 K.Ohta
+               }
        } else {
-               event_ids[scancode] = -1;
+               if(this->isModifier(scancode)) {  // modifiers
+                       set_modifiers(scancode, true);
+                       if(break_pressed != stat_break) { // Break key Down.
+                               this->write_signals(&break_line, 0xff);
+                       }
+                       return;
+               }
+               code = scan2fmkeycode(scancode);
+               if((code > 0x3ff) || (code == 0)) return;
+               if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
+                       if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
+                               switch(scancode) {
+                                       case 0x42: // 1
+                                       case 0x43: // 2
+                                       case 0x44: // 3
+                                       case 0x3f: // 5
+                                       case 0x46: // 0
+                                               autokey_backup = scancode;
+                                               break;
+                               }
+                       } else { // Auto 5
+                               switch(scancode) {
+                                       case 0x42: // 1
+                                       case 0x43: // 2
+                                       case 0x44: // 3
+                                       case 0x3e: // 4
+                                       case 0x40: // 6
+                                       case 0x3a: // 7
+                                       case 0x3b: // 8
+                                       case 0x3c: // 9
+                                               autokey_backup = scancode;
+                                               break;
+                               }
+                       }                               
+               } else {
+                       autokey_backup = 0x00;
+               }
+               if(code != 0) {
+                       key_fifo->write(code);
+                       if((scancode < 0x5c) && repeat_auto_key) {
+                               double usec = (double)repeat_time_long * 1000.0;
+                               if((repeat_keycode == 0) && repeat_mode) {
+                                       if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
+                                       event_keyrepeat = -1;
+                                       register_event(this,
+                                                                  ID_KEYBOARD_AUTOREPEAT_FIRST,
+                                                                  usec, false, &event_keyrepeat);
+                               }
+                               repeat_keycode = scancode;
+                       }
+               }
        }
-       key_pressed_flag[scancode] = true;
+}
+
+#if defined(_FM77AV_VARIANTS)
+void KEYBOARD::adjust_rtc(void)
+{
+       get_host_time(&cur_time);
+       rtc_yy = cur_time.year % 100;
+       rtc_mm = cur_time.month;
+       rtc_dd = cur_time.day;
 
+       rtc_dayofweek = cur_time.day_of_week;
+       if(rtc_count24h) {
+               rtc_ispm = (cur_time.hour >= 12) ? true : false;
+               rtc_hour = cur_time.hour % 12;
+       } else {
+               rtc_ispm = false;
+               rtc_hour = cur_time.hour;
+       }
+       rtc_minute = cur_time.minute;
+       rtc_sec = cur_time.second;
+       if(event_key_rtc >= 0) {
+               cancel_event(this, event_key_rtc);
+       }
+       register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
 }
+#endif
 
-void KEYBOARD::do_repeatkey(uint16 scancode)
+void KEYBOARD::do_repeatkey(uint8_t sc)
 {
-       uint16 code_7;
-       if((scancode == 0) || (scancode >= 0x67)) return; // scancode overrun.
+       uint16_t code;
+       if((sc == 0) || (sc >= 0x5c)) return; // scancode overrun.
        if(!repeat_mode) {
-               if(event_ids[scancode] >= 0) {
-                       cancel_event(this, event_ids[scancode]);
-                       event_ids[scancode] = -1;
+               if(event_keyrepeat >= 0) {
+                       cancel_event(this, event_keyrepeat);
+                       event_keyrepeat = -1;
                }
                return;
        }
-       key_pressed_flag[scancode] = true;
-       code_7 = scan2fmkeycode(scancode);
-       if(code_7 < 0x200) {
-               keycode_7 = code_7;
-               mainio->write_signal(FM7_MAINIO_PUSH_KEYBOARD, code_7, 0x1ff);
-               mainio->write_signal(FM7_MAINIO_KEYBOARDIRQ, 1, 1);
-               display->write_signal(SIG_FM7_SUB_KEY_FIRQ, 1, 1);
+       if(keymode == KEYMODE_SCAN) {
+               code = (uint16_t)(sc & 0x7f);
+               key_fifo->write((uint32_t)code); // Make
+               //key_fifo->write((uint32_t)(code | 0x80)); // Break
+       } else {
+               code = scan2fmkeycode(sc);
+               if(code < 0x400) {
+                       key_fifo->write((uint32_t)code);
+               }
        }
-       //if(this->isModifiers(scancode)) {  // modifiers
-         //if(break_pressed != stat_break) { // Break key Down.
-         //            break_line->write_signal(0x00, 1, 1);
-         //            maincpu->write_signal(SIG_CPU_FIRQ, 1, 1);
-         //    }
-       //}
 }
 
 void KEYBOARD::event_callback(int event_id, int err)
 {
-       if(event_id == ID_KEYBOARD_RXRDY_OK) {
+#if defined(_FM77AV_VARIANTS)
+       if(event_id == ID_KEYBOARD_RXRDY_OK) {
+               rxrdy_status = true;
                write_signals(&rxrdy, 0xff);
        } else if(event_id == ID_KEYBOARD_RXRDY_BUSY) {
+               rxrdy_status = false;
                write_signals(&rxrdy, 0x00);
        } else if(event_id == ID_KEYBOARD_ACK) {
+               key_ack_status = true;
                write_signals(&key_ack, 0xff);
-       } else if((event_id >= ID_KEYBOARD_AUTOREPEAT_FIRST) && (event_id <= (ID_KEYBOARD_AUTOREPEAT_FIRST + 0x1ff))) {
-               uint32 scancode = event_id - ID_KEYBOARD_AUTOREPEAT_FIRST;
+       } else if(event_id == ID_KEYBOARD_RTC_COUNTUP) {
+               rtc_count();
+       } else if(event_id == ID_KEYBOARD_HIDDENMESSAGE_AV) {
+               if(hidden_message_77av_1[hidden1_ptr] == 0x00) {
+                       cancel_event(this, event_hidden1_av);
+                       event_hidden1_av = -1;
+                       hidden1_ptr = 0;
+               } else {
+                       key_fifo->write(hidden_message_77av_1[hidden1_ptr++]);
+               }
+               beep->write_signal(SIG_BEEP_MUTE, 0, 1);
+               beep->write_signal(SIG_BEEP_ON, 1, 1);
+               register_event(this,
+                      ID_KEYBOARD_HIDDEN_BEEP_OFF,
+                      25.0 * 1000.0, false, NULL);
+       } else  if(event_id == ID_KEYBOARD_HIDDEN_BEEP_ON) {
+               beep->write_signal(SIG_BEEP_MUTE, 0, 1);
+               beep->write_signal(SIG_BEEP_ON, 1, 1);
+               register_event(this,
+                      ID_KEYBOARD_HIDDEN_BEEP_OFF,
+                      25.0 * 1000.0, false, NULL);
+
+       } else  if(event_id == ID_KEYBOARD_HIDDEN_BEEP_OFF) {
+               beep->write_signal(SIG_BEEP_MUTE, 0, 1);
+               beep->write_signal(SIG_BEEP_ON, 0, 1);
+       } else if(event_id == ID_KEYBOARD_BREAK_ONESHOT) {
+               if(break_pressed) this->write_signals(&break_line, 0xff);
+       } else
+#endif
+       if(event_id == ID_KEYBOARD_AUTOREPEAT_FIRST) {
                double usec = (double)repeat_time_short * 1000.0;
 
-               if((scancode >= 0x67) || (scancode == 0)) return;
-               do_repeatkey((uint16)scancode);
+               do_repeatkey(repeat_keycode);
                register_event(this,
-                              ID_KEYBOARD_AUTOREPEAT + scancode,
-                              usec, true, &event_ids[scancode]);
+                              ID_KEYBOARD_AUTOREPEAT,
+                              usec, true, &event_keyrepeat);
                // Key repeat.
-       } else if((event_id >= ID_KEYBOARD_AUTOREPEAT) && (event_id <= (ID_KEYBOARD_AUTOREPEAT + 0x1ff))){
-               uint32 scancode = event_id - ID_KEYBOARD_AUTOREPEAT;
-               do_repeatkey((uint16)scancode);
+       } else if(event_id == ID_KEYBOARD_AUTOREPEAT){
+               if(repeat_keycode != 0) {
+                       do_repeatkey(repeat_keycode);
+               } else {
+                       cancel_event(this, event_keyrepeat);
+                       event_keyrepeat = -1;
+               }
+       } else if(event_id == ID_KEYBOARD_INT) {
+               if(!(key_fifo->empty())) {
+                       keycode_7 = key_fifo->read();
+                       this->write_signals(&int_line, 0xffffffff);
+               }
+       } else if(event_id == ID_KEYBOARD_AUTO_8KEY_START) {
+               if(keymode != KEYMODE_SCAN) {
+                       scancode = 0x3b; // 8
+                       autokey_backup = 0x00;
+                       key_down_main(false);
+                       register_event(this,
+                                                  ID_KEYBOARD_AUTO_8KEY_END,
+                                                  50.0 * 1000.0, false, NULL);
+               }
+       } else if(event_id == ID_KEYBOARD_AUTO_8KEY_END) {
+               key_up_main(0x3b); // 8
+       } else if(event_id == ID_KEYBOARD_AUTO_5KEY_START) {
+               if(keymode != KEYMODE_SCAN) {
+                       scancode = 0x3f; // 5
+                       autokey_backup = 0x00;
+                       key_down_main(false);
+                       register_event(this,
+                                                  ID_KEYBOARD_AUTO_5KEY_END,
+                                                  50.0 * 1000.0, false, NULL);
+               }
+       } else if(event_id == ID_KEYBOARD_AUTO_5KEY_END) {
+               key_up_main(0x3f); // 5
        }
 }
 
 // Commands
-void KEYBOARD::reset(void)
+void KEYBOARD::reset_unchange_mode(void)
 {
        repeat_time_short = 70; // mS
        repeat_time_long = 700; // mS
        repeat_mode = true;
-       keycode_7 = 0x00;
-       
+       older_vk = 0;
+
        lshift_pressed = false;
        rshift_pressed = false;
+       shift_pressed = false;
        ctrl_pressed   = false;
        graph_pressed = false;
-       //      ins_pressed = false;
+       kana_pressed = false;
+       caps_pressed = false;
+       ins_led_status = false;
+       kana_led_status = false;
+       caps_led_status = false;
+       datareg = 0x00;
+       repeat_keycode = 0x00;
+       autokey_backup = 0x00;
+
+       if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
+       key_fifo->clear();
+#if defined(_FM77AV_VARIANTS)
        cmd_fifo->clear();
        data_fifo->clear();
-       datareg = 0x00;
+       if(event_key_rtc >= 0) {
+               cancel_event(this, event_key_rtc);
+       }
+       register_event(this,ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
+
+       cmd_phase = 0;
+       if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
+       event_keyrepeat = -1;
+   
+       if(event_hidden1_av >= 0) cancel_event(this, event_hidden1_av);
+       event_hidden1_av = -1;
+       hidden1_ptr = 0;
+#endif
        // Bus
-       this->write_signals(&break_line, 0x00);           
+       this->write_signals(&break_line, 0x00);
+#if defined(_FM77AV_VARIANTS)
+       rxrdy_status = false;
+       key_ack_status = true;
        this->write_signals(&rxrdy, 0x00);                
-       this->write_signals(&key_ack, 0x00);              
-       this->write_signals(&kana_led, 0x00);             
-       this->write_signals(&caps_led, 0x00);             
-       this->write_signals(&ins_led, 0x00);              
+       this->write_signals(&key_ack, 0xff);              
+#endif
+}
+
+
+void KEYBOARD::reset(void)
+{
+       keymode = KEYMODE_STANDARD;
+       scancode = 0x00;
 
+       keycode_7 = 0xffffffff; 
+       //keycode_7 = 0; 
+       reset_unchange_mode();
+       this->write_signals(&int_line, 0x00000000);
+
+#if defined(_FM77AV_VARIANTS)  
+       adjust_rtc();
+       did_hidden_message_av_1 = false;
+       beep_phase = 0;
+#endif
+
+       if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
+
+       if(event_int >= 0) cancel_event(this, event_int);
+       register_event(this,
+                                  ID_KEYBOARD_INT,
+                                  20000.0, true, &event_int);
 }
+
+
 #if defined(_FM77AV_VARIANTS)  
 // 0xd431 : Read
-uint8 KEYBOARD::read_data_reg(void)
+uint8_t KEYBOARD::read_data_reg(void)
 {
-       if(rxrdy->read_signal(0) != 0) {
-               if(!data_fifo->empty()) {
-                       datareg = data_fifo->read() & 0xff;
-               }
+       if(!data_fifo->empty()) {
+               datareg = data_fifo->read() & 0xff;
        }
-       if(data_fifo->empty()) {
-               rxrdy->write_signal(0x00, 0x00, 0x01);
+       if(!data_fifo->empty()) {
+               rxrdy_status = true;
+               write_signals(&rxrdy, 0xff);
        } else {
-               rxrdy->write_signal(0x00, 0x01, 0x01);
+               rxrdy_status = false;
+               write_signals(&rxrdy, 0x00);
        }
        return datareg;
 }
 
 // 0xd432
-uint8 KEYBOARD::read_stat_reg(void)
+uint8_t KEYBOARD::read_stat_reg(void)
 {
-       uint8 data = 0xff;
-       
-       if(!data_fifo->empty()) {
-               rxrdy->write_signal(0x00, 0x01, 0x01);
+       uint8_t data = 0xff;
+       if(rxrdy_status) {
                data &= 0x7f;
        }
-       if(key_ack->read_signal(0) == 0x00) {
-         data &= 0xfe;
+       if(!key_ack_status) {
+               data &= 0xfe;
        }
        // Digityze : bit0 = '0' when waiting,
        return data;
@@ -1058,13 +712,23 @@ void KEYBOARD::set_mode(void)
 {
        int count = cmd_fifo->count();
        int cmd;
+       int mode;
        if(count < 2) return;
        cmd = cmd_fifo->read();
-       keymode = cmd_fifo->read();
-       if(keymode <= KEYMODE_SCAN) reset();
+       mode = cmd_fifo->read();
+       if(mode <= KEYMODE_SCAN) {
+               keymode = mode;
+               //printf("Keymode : %d\n", keymode);
+               //reset_unchange_mode();
+               beep_phase = 0;
+               autokey_backup = 0x00;
+               this->write_signals(&break_line, 0x00);
+               if(scancode != 0) key_down_main(true); 
+       }
        cmd_fifo->clear();
        data_fifo->clear(); // right?
-       rxrdy->write_signal(0x00, 0x00, 0x01);
+       rxrdy_status = false;
+       write_signals(&rxrdy, 0x00);
 }
 
 void KEYBOARD::get_mode(void)
@@ -1076,7 +740,8 @@ void KEYBOARD::get_mode(void)
                dummy = data_fifo->read();
        }
        data_fifo->write(keymode);
-       rxrdy->write_signal(0x01, 0x01, 0x01);
+       rxrdy_status = true;
+       write_signals(&rxrdy, 0xff);
 }
 
 void KEYBOARD::set_leds(void)
@@ -1091,27 +756,29 @@ void KEYBOARD::set_leds(void)
                if((ledvar & 0x02) != 0) {
                        // Kana
                        kana_pressed = ((ledvar & 0x01) == 0);
-                       kana_led.write_signal(0x00, ~ledvar, 0x01);
+                       kana_led_status = kana_pressed;
                } else {
                        // Caps
                        caps_pressed = ((ledvar & 0x01) == 0);
-                       caps_led.write_signal(0x00, ~ledvar, 0x01);
+                       caps_led_status = caps_pressed;
                }
        }
        cmd_fifo->clear();
        data_fifo->clear(); // right?
-       rxrdy->write_signal(0x01, 0x00, 0x01);
+       rxrdy_status = false;
+       write_signals(&rxrdy, 0x00);
 }
 
 void KEYBOARD::get_leds(void)
 {
-       uint8 ledvar = 0x00;
+       uint8_t ledvar = 0x00;
        data_fifo->clear();
        ledvar |= caps_pressed ? 0x01 : 0x00;
        ledvar |= kana_pressed ? 0x02 : 0x00;
        data_fifo->write(ledvar);
        cmd_fifo->clear();
-       rxrdy->write_signal(0x01, 0x01, 0x01);
+       rxrdy_status = true;
+       write_signals(&rxrdy, 0xff);
 }
 
 void KEYBOARD::set_repeat_type(void)
@@ -1120,37 +787,45 @@ void KEYBOARD::set_repeat_type(void)
        int modeval;
 
        cmd = cmd_fifo->read();
-       if(cmd_fifo->empty()) return;
-       modeval = cmd_fifo->read();
-       if((modeval >= 2) || (modeval < 0)) return;
-       repeat_mode = (modeval == 0);
+       if(!cmd_fifo->empty()) {
+               modeval = cmd_fifo->read();
+               if((modeval < 2) && (modeval >= 0)) {
+                       repeat_mode = (modeval == 0);
+                       if(repeat_mode) {
+                               //scancode = 0x00;
+                               //keycode_7 = 0x00;
+                               key_fifo->clear();
+                       }
+               }
+       }
        data_fifo->clear();
        cmd_fifo->clear();
-       rxrdy->write_signal(0x01, 0x00, 0x01);
+       rxrdy_status = false;
+       write_signals(&rxrdy, 0x00);
 }
 
 void KEYBOARD::set_repeat_time(void)
 {
        int cmd;
-       int time_high;
-       int time_low;
+       uint32_t time_high = 0;
+       uint32_t time_low = 0;
        cmd = cmd_fifo->read();
-       if(cmd_fifo->empty()) return;
+       if(cmd_fifo->empty()) goto _end;
        time_high = cmd_fifo->read();
-       if(cmd_fifo->empty()) return;
+       if(cmd_fifo->empty()) goto _end;
        time_low = cmd_fifo->read();
-       if(cmd_fifo->empty()) return;
-       
+_end:
        if((time_high == 0) || (time_low == 0)) {
-         repeat_time_long = 700;
-         repeat_time_short = 70;
+               repeat_time_long = 700;
+               repeat_time_short = 70;
        } else {
-         repeat_time_long = time_high * 10;
-         repeat_time_short = time_low * 10;
+               repeat_time_long = (int)time_high * 10;
+               repeat_time_short = (int)time_low * 10;
        }
        data_fifo->clear();
        cmd_fifo->clear();
-       rxrdy->write_signal(0x01, 0x00, 0x01);
+       rxrdy_status = false;
+       write_signals(&rxrdy, 0x00);
 }
 
 void KEYBOARD::set_rtc(void)
@@ -1177,12 +852,12 @@ void KEYBOARD::set_rtc(void)
                rtc_ispm = ((tmp & 0x04) != 0);
        }
        rtc_dayofweek = (tmp >> 4) % 0x07;
-       rtc_hh = ((tmp & 0x03) * 10);
+       rtc_hour = ((tmp & 0x03) * 10);
        // Low
        tmp = cmd_fifo->read();
-       rtc_hh = rtc_hh | (tmp >> 4);
+       rtc_hour = rtc_hour | (tmp >> 4);
        if(rtc_count24h) {
-         rtc_ispm = (rtc_hh >= 12);
+         rtc_ispm = (rtc_hour >= 12);
        }
        rtc_minute = (tmp & 0x0f) * 10;
        
@@ -1195,14 +870,17 @@ void KEYBOARD::set_rtc(void)
        
        data_fifo->clear();
        cmd_fifo->clear();
-       rxrdy->write_signal(0x01, 0x00, 0x01);
+       if(event_key_rtc >= 0) {
+               cancel_event(this, event_key_rtc);
+       }
+       register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
+       rxrdy_status = false;
+       write_signals(&rxrdy, 0x00);
 }
 
 void KEYBOARD::get_rtc(void)
 {
-       int cmd;
        int tmp;
-       int localcmd;
        data_fifo->clear();
        // YY
        tmp = ((rtc_yy / 10) << 4) | (rtc_yy % 10);
@@ -1216,7 +894,7 @@ void KEYBOARD::get_rtc(void)
        data_fifo->write(tmp);
        // DayOfWeek + Hour
        tmp = rtc_dayofweek << 4;
-       tmp = tmp | (rtc_hh / 10);
+       tmp = tmp | (rtc_hour / 10);
        if(rtc_count24h) {
          tmp = tmp | 0x08;
        } else {
@@ -1226,8 +904,8 @@ void KEYBOARD::get_rtc(void)
        }
        data_fifo->write(tmp);
        // Low
-       tmp = (rtc_hh % 10) << 4;
-       tmp = tmp | (rtc_mm / 10);
+       tmp = (rtc_hour % 10) << 4;
+       tmp = tmp | (rtc_minute / 10);
        data_fifo->write(tmp);
        
        tmp = (rtc_minute % 10) << 4;
@@ -1238,7 +916,8 @@ void KEYBOARD::get_rtc(void)
        data_fifo->write(tmp);
        
        cmd_fifo->clear();
-       rxrdy->write_signal(0x01, 0x01, 0x01);
+       rxrdy_status = true;
+       write_signals(&rxrdy, 0xff);
 }
 
 const int rtc_month_days[12] = {
@@ -1288,15 +967,29 @@ void KEYBOARD::rtc_count(void)
                }
        }
 }
-void KEYBOARD::rtc_adjust(void)
+#endif // FM77AV_VARIANTS
+
+uint32_t KEYBOARD::read_signal(int id)
 {
+       if(id == SIG_FM7KEY_BREAK_KEY) {
+               return break_pressed ? 0xfffffff : 0x00000000;
+       } else if(id == SIG_FM7KEY_LED_STATUS) {
+               uint32_t _l;
+               _l  = (ins_led_status) ? 0x00000001 : 0;
+               _l |= (kana_led_status) ? 0x00000002 : 0;
+               _l |= (caps_led_status) ? 0x00000004 : 0;
+               return _l;
+       }
+       return 0;
 }
-#endif // FM77AV_VARIANTS
 
-void KEYBOARD::write_signal(int id, uint32 data, uint32 mask)
+
+void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
 {
        if(id == SIG_FM7KEY_SET_INSLED) {
-               write_signals(&ins_led, data & mask);
+               ins_led_status = ((data & mask) != 0);
+       } else if(id == SIG_FM7KEY_OVERRIDE_PRESS_BREAK) {
+               override_break_key = ((data & mask) != 0);
        }
 #if defined(_FM77AV_VARIANTS)  
         else if(id == SIG_FM7KEY_PUSH_TO_ENCODER) {
@@ -1305,7 +998,7 @@ void KEYBOARD::write_signal(int id, uint32 data, uint32 mask)
                 * Thanks to Ryu.Takegami and PI.
                 */
                int count;
-               if(key_ack->read_signal(0x00) == 0) return; // If (not(ACK)) noop.
+               if(!key_ack_status) return; // If (not(ACK)) noop.
 
                if(cmd_fifo->full()) {
                        cmd_fifo->clear();
@@ -1317,25 +1010,51 @@ void KEYBOARD::write_signal(int id, uint32 data, uint32 mask)
                cmd_fifo->write(data & 0xff);
                count = cmd_fifo->count();
                
-               key_ack->write_signal(0x00, 0x00, 0x01);
+               rxrdy_status = false;
+               key_ack_status = false;
+               write_signals(&key_ack, 0x00);
+               write_signals(&rxrdy, 0x00);
+           
                switch(cmd_phase) {
                        case 0: // Set mode
-                               if(count >= 2) set_mode();
+                               if(count >= 2) {
+                                       set_mode();
+                                       if(keymode == KEYMODE_SCAN) key_down_main(true);
+                                       cmd_phase = -1;
+                                       cmd_fifo->clear();
+                               }
                                break;
                        case 1: // Get mode
                                get_mode();
+                               cmd_fifo->clear();
+                               cmd_phase = -1;
                                break;
                        case 2: // Set LED Phase
-                               if(count >= 2) set_leds();
+                               if(count >= 2) {
+                                       set_leds();
+                                       if(keymode == KEYMODE_SCAN) key_down_main(true);
+                                       cmd_phase = -1;
+                                       cmd_fifo->clear();
+                               }
                                break;
                        case 3: // Get LED Phase
                                get_leds();
+                               cmd_phase = -1;
+                               cmd_fifo->clear();
                                break;
                        case 4:
-                               if(count >= 2) set_repeat_type();
+                               if(count >= 2) {
+                                       set_repeat_type();
+                                       cmd_phase = -1;
+                                       cmd_fifo->clear();
+                               }
                                break;
                        case 5:
-                               if(count >= 3) set_repeat_time();
+                               if(count >= 3) {
+                                       set_repeat_time();
+                                       cmd_phase = -1;
+                                       cmd_fifo->clear();
+                               }
                                break;
                        case 0x80: // Communicate to/from RTC.
                                if(count == 1) {
@@ -1344,48 +1063,75 @@ void KEYBOARD::write_signal(int id, uint32 data, uint32 mask)
                                if(count == 2) {
                                        if((data & 0xff) == 0) { // Get
                                                get_rtc();
+                                               cmd_phase = -1;
+                                               cmd_fifo->clear();
                                        } else if((data & 0xff) == 1) { // Set
                                                rtc_set_flag = true;
                                        } else { // Illegal
-                                               cmd_fifo->clear(); 
+                                               cmd_fifo->clear();
+                                               cmd_phase = -1;
                                        }
                                }
                                if(rtc_set_flag) {
                                        if(count >= 9) {
                                                set_rtc();
+                                               cmd_fifo->clear();
+                                               cmd_phase = -1;
                                        }
                                }
                                break;
                        case 0x81: // Digitize.
-                               if(count >= 2) do_digitize(); // WILL Implement?
+                               if(count >= 2) {
+                                       do_digitize(); // WILL Implement?
+                                       cmd_fifo->clear();
+                                       cmd_phase = -1;
+                               }
                                break;
                        case 0x82:
-                               if(count >= 2) set_screen_mode();
+                               if(count >= 2) {
+                                       set_screen_mode(); // WILL Implement?
+                                       cmd_fifo->clear();
+                                       cmd_phase = -1;
+                               }
                                break;
                        case 0x83:
-                               get_screen_mode();
+                               get_screen_mode(); // WILL Implement?
+                               cmd_fifo->clear();
+                               cmd_phase = -1;
                                break;
                        case 0x84:
-                               if(count >= 2) set_brightness();
+                               if(count >= 2) {
+                                       set_brightness(); // WILL Implement?
+                                       cmd_fifo->clear();
+                                       cmd_phase = -1;
+                               }
                                break;
                        default:
-                               //cmd_fifo->clear();
+                               cmd_fifo->clear();
+                               cmd_phase = -1;
                                break;
                }
                register_event(this, ID_KEYBOARD_ACK, 5, false, NULL); // Delay 5us until ACK is up.
+       } else if(id == SIG_FM7KEY_RXRDY) {
+               rxrdy_status = ((data & mask) != 0);
+               //write_signals(&rxrdy, (rxrdy_status) ? 0xffffffff : 0x00000000);
+       } else if(id == SIG_FM7KEY_ACK) {
+               key_ack_status = ((data & mask) != 0);
+               //write_signals(&key_ack, (key_ack_status) ? 0xffffffff : 0x00000000);
        }
+
 #endif
 }
 
-uint32 KEYBOARD::read_data8(uint32 addr)
+uint32_t KEYBOARD::read_data8(uint32_t addr)
 {
-       uint32 retval = 0xff;
+       uint32_t retval = 0xff;
        switch(addr) {
                case 0x00:
-                       retval = (keycode_7 >> 8) & 0x80;
+                       retval = get_keycode_high();
                        break;
                case 0x01:
-                       retval = keycode_7 & 0xff;
+                       retval = get_keycode_low();
                        break;
 #if defined(_FM77AV_VARIANTS)                  
                case 0x31:
@@ -1401,7 +1147,7 @@ uint32 KEYBOARD::read_data8(uint32 addr)
        return retval;
 }
 
-void KEYBOARD::write_data8(uint32 addr, uint32 data)
+void KEYBOARD::write_data8(uint32_t addr, uint32_t data)
 {
        switch(addr) {
 #if defined(_FM77AV_VARIANTS)                  
@@ -1412,13 +1158,12 @@ void KEYBOARD::write_data8(uint32 addr, uint32 data)
        }
 }
 
-KEYBOARD::KEYBOARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
+KEYBOARD::KEYBOARD(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
 {
-       int i;
-       p_vm = parent_vm;
-       p_emu = parent_emu;
-  
-       keycode_7 = 0;
+#if defined(_FM77AV_VARIANTS)
+       beep = NULL;
+#endif 
+       keycode_7 = 0xffffffff;
    
        ctrl_pressed = false; 
        lshift_pressed = false; 
@@ -1428,31 +1173,168 @@ KEYBOARD::KEYBOARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_em
        caps_pressed = false;
        kana_pressed = false;
        break_pressed = false;
-       
-       for(i = 0; i < 0x70; i++) {
-               event_ids[i] = 0;
-               key_pressed_flag[i] = false;
-       }
-   
+       event_keyrepeat = -1;
+       autokey_backup = 0x00;
+
+       keymode = KEYMODE_STANDARD;
+       override_break_key = false;
+#if defined(_FM77AV_VARIANTS)
        cmd_fifo = new FIFO(16);
        data_fifo = new FIFO(16);
-       keymode = KEYMODE_STANDARD;
+       rxrdy_status = true;
+       key_ack_status = false;
+       initialize_output_signals(&rxrdy);
+       initialize_output_signals(&key_ack);
        
-       init_output_signals(&rxrdy);
-       init_output_signals(&key_ack);
+       rtc_count24h = false;
+       rtc_dayofweek = 0;
+       rtc_ispm = false;
+       rtc_set = false;
+       rtc_set_flag = false;
+       rtc_yy = 0;
+       rtc_mm = 0;
+       rtc_dd = 0;
+       rtc_hour = 0;
+       rtc_minute = 0;
+       rtc_sec = 0;
+       event_key_rtc = -1;
+       event_hidden1_av = -1;
+       hidden1_ptr = 0;
+#endif
+       key_fifo = new FIFO(512);
+       event_int = -1;
        
-       init_output_signals(&break_line);
+       initialize_output_signals(&break_line);
+       initialize_output_signals(&int_line);
        
-       init_output_signals(&kana_led);
-       init_output_signals(&caps_led);
-       init_output_signals(&ins_led);
+       ins_led_status = false;
+       kana_led_status = false;
+       caps_led_status = false;
+       set_device_name(_T("KEYBOARD SUBSYSTEM"));
+}
 
-       
+void KEYBOARD::release(void)
+{
+#if defined(_FM77AV_VARIANTS)
+       cmd_fifo->release();
+       data_fifo->release();
+       delete cmd_fifo;
+       delete data_fifo;
+#endif   
+       key_fifo->release();
+       delete key_fifo;
 }
 
+
+
 KEYBOARD::~KEYBOARD()
 {
 }
 
-   
-   
+#define STATE_VERSION 9
+//#if defined(Q_OS_WIN)
+//DLL_PREFIX_I struct cur_time_s cur_time;
+//#endif
+
+bool KEYBOARD::decl_state(FILEIO *state_fio, bool loading)
+{
+       if(!state_fio->StateCheckUint32(STATE_VERSION)) {
+               return false;
+       }
+       if(!state_fio->StateCheckInt32(this_device_id)) {
+               return false;
+       }
+       
+       state_fio->StateUint32(keycode_7);
+       state_fio->StateInt32(keymode);
+       state_fio->StateBool(ctrl_pressed);
+       state_fio->StateBool(lshift_pressed);
+       state_fio->StateBool(rshift_pressed);
+       state_fio->StateBool(shift_pressed);
+       state_fio->StateBool(graph_pressed);
+       state_fio->StateBool(caps_pressed);
+       state_fio->StateBool(kana_pressed);
+       state_fio->StateBool(break_pressed);
+
+       state_fio->StateInt32(event_keyrepeat);
+          
+       state_fio->StateUint8(scancode); // After V.4, uint8_t
+       state_fio->StateUint8(datareg);
+       state_fio->StateUint32(older_vk);
+          
+       state_fio->StateBool(repeat_mode);
+       state_fio->StateInt32(repeat_time_short);
+       state_fio->StateInt32(repeat_time_long);
+       state_fio->StateUint8(repeat_keycode);
+          
+#if defined(_FM77AV_VARIANTS)
+       state_fio->StateInt32(event_key_rtc);
+       state_fio->StateUint8(rtc_yy);
+       state_fio->StateUint8(rtc_mm);
+       state_fio->StateUint8(rtc_dd);
+       state_fio->StateUint8(rtc_dayofweek);
+       state_fio->StateUint8(rtc_hour);
+       state_fio->StateUint8(rtc_minute);
+       state_fio->StateUint8(rtc_sec);
+
+       state_fio->StateBool(rtc_count24h);
+       state_fio->StateBool(rtc_ispm);
+
+       state_fio->StateBool(rtc_set);
+       state_fio->StateBool(rtc_set_flag);
+       state_fio->StateBool(rxrdy_status);
+       state_fio->StateBool(key_ack_status);
+               
+       state_fio->StateBool(did_hidden_message_av_1);
+       state_fio->StateInt32(event_hidden1_av);
+
+       state_fio->StateInt32(cmd_phase);
+       state_fio->StateUint16(hidden1_ptr);
+       state_fio->StateInt32(beep_phase);
+       
+       if(!cmd_fifo->process_state(state_fio, loading)) {
+               return false;
+       }
+       if(!data_fifo->process_state(state_fio, loading)) {
+               return false;
+       }
+       if(!cur_time.process_state(state_fio, loading)) {
+               return false;
+       }
+#endif
+       if(!key_fifo->process_state(state_fio, loading)) {
+               return false;
+       }
+       state_fio->StateInt32(event_int);
+       state_fio->StateUint8(autokey_backup);
+       // Version 5
+       state_fio->StateBool(ins_led_status);
+       state_fio->StateBool(kana_led_status);
+       state_fio->StateBool(caps_led_status);
+       // Version 6
+       state_fio->StateBool(override_break_key);
+
+       return true;
+}
+
+void KEYBOARD::save_state(FILEIO *state_fio)
+{
+       decl_state(state_fio, false);
+       //state_fio->FputUint32_BE(STATE_VERSION);
+       //state_fio->FputInt32_BE(this_device_id);
+       this->out_debug_log(_T("Save State: KEYBOARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
+}
+bool KEYBOARD::load_state(FILEIO *state_fio)
+{
+       uint32_t version;
+       
+       //version = state_fio->FgetUint32_BE();
+       //if(this_device_id != state_fio->FgetInt32_BE()) return false;
+       //this->out_debug_log(_T("Load State: KEYBOARD: id=%d ver=%d\n"), this_device_id, version);
+       bool mb = decl_state(state_fio, true);
+       if(!mb) return false;
+       return true;
+}
+
+}