OSDN Git Service

[VM][FM7] Fix state save/load.
[csp-qt/common_source_project-fm7.git] / source / src / vm / fm7 / keyboard.cpp
index 48bd5e5..f020953 100644 (file)
 #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_PAUSE,      '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,           VK_ESCAPE,      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}
-};
-
-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}
-};
-
-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}
-};
-
-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},
-
-       {0xffff, 0xffff}
+#include "keyboard_tables.h"
+#if defined(_FM77AV_VARIANTS)
+#include "../beep.h"
+#include "fm77av_hidden_message_keyboard.h"
+#endif
+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,
 };
 
+//
 /*
  * 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;
+       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;
 }
 
@@ -721,10 +61,11 @@ void KEYBOARD::turn_off_ins_led(void)
 }
 
 // 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,7 +73,7 @@ uint16 KEYBOARD::vk2scancode(uint32 vk)
        return 0x0000;
 }
 
-bool KEYBOARD::isModifier(uint16 sc)
+bool KEYBOARD::isModifier(uint16_t sc)
 {
        if(((sc >= 0x52) && (sc <= 0x56)) || // CTRL LSHIFT RSHIFT CAPS GRPH
                (sc == 0x5a) || (sc == 0x5c)) { // KANA BREAK
@@ -741,24 +82,18 @@ bool KEYBOARD::isModifier(uint16 sc)
        return false;
 }
 
-void KEYBOARD::set_modifiers(uint16 sc, bool flag)
+void KEYBOARD::set_modifiers(uint16_t sc, bool flag)
 {
        if(sc == 0x52) { // CTRL
                ctrl_pressed = flag; 
        } else if(sc == 0x53) { // LSHIFT
                lshift_pressed = flag;
-               if(rshift_pressed) {
-                       shift_pressed = true;
-               } else {
-                       shift_pressed = flag;
-               }
+               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;
-               }
+               shift_pressed = lshift_pressed | rshift_pressed;
+               //printf("RSHIFT : %d\n", flag ? 1 : 0);
        } else if(sc == 0x56) { // GRPH
                graph_pressed = flag;
        } else if(sc == 0x55) { // CAPS
@@ -770,6 +105,7 @@ void KEYBOARD::set_modifiers(uint16 sc, bool flag)
                                caps_pressed = true;
                        }
                        if(keymode == KEYMODE_STANDARD) this->write_signals(&caps_led, caps_pressed ? 0xff : 0x00);
+                       //this->write_signals(&caps_led, caps_pressed ? 0xff : 0x00);
                }
        } else if(sc == 0x5a) { // KANA
                // Toggle on press.
@@ -786,12 +122,12 @@ void KEYBOARD::set_modifiers(uint16 sc, bool flag)
        }
 }
 
-uint16 KEYBOARD::scan2fmkeycode(uint16 sc)
+uint16_t KEYBOARD::scan2fmkeycode(uint16_t sc)
 {
        const struct key_tbl_t *keyptr = NULL;
        bool stdkey = false;
        int i;
-       uint16 retval;
+       uint16_t retval;
        
        if((sc == 0) || (sc >= 0x67)) return 0xffff;
        // Set repeat flag(s)
@@ -810,7 +146,6 @@ uint16 KEYBOARD::scan2fmkeycode(uint16 sc)
                }
        }
        if(keymode == KEYMODE_STANDARD) {
-               bool dmy = isModifier(sc);
                if(ctrl_pressed) {
                        if(shift_pressed) {
                                keyptr = ctrl_shift_key;
@@ -850,7 +185,32 @@ uint16 KEYBOARD::scan2fmkeycode(uint16 sc)
                retval = 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;
@@ -863,7 +223,7 @@ uint16 KEYBOARD::scan2fmkeycode(uint16 sc)
                }
                i++;
        } while(keyptr[i].phy != 0xffff);
-
+       if(keyptr[i].phy == 0xffff) return 0x00;
        if(stdkey) {
                if((retval >= 'A') && (retval <= 'Z')) {
                        if(caps_pressed) {
@@ -878,89 +238,105 @@ uint16 KEYBOARD::scan2fmkeycode(uint16 sc)
        return retval;
 }
 
-void KEYBOARD::key_up(uint32 vk)
+void KEYBOARD::key_up(uint32_t vk)
 {
-       scancode = vk2scancode(vk);
+       uint16_t bak_scancode = vk2scancode(vk);
        bool stat_break = break_pressed;
-       uint32 code_7;
        older_vk = 0;
-       if(scancode == 0) return;
-       if(event_ids[scancode] >= 0){
-               cancel_event(this, event_ids[scancode]);
-               event_ids[scancode] = -1;
+       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.
-                       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(key_pressed_flag[scancode] == false) return; 
-       key_pressed_flag[scancode] = false; 
-       if(keymode == KEYMODE_SCAN) { // Notify even key-up, when using SCAN mode.
-               //printf("UP SCAN=%04x break=%d\n", scancode, stat_break);
-               if(scancode !=  0) {   
-                       code_7 = scancode | 0x80;
-                       keycode_7 = code_7 | 0x8000;
-                       mainio->write_signal(FM7_MAINIO_KEYBOARDIRQ, keycode_7, 0x8000);
-                       display->write_signal(SIG_FM7_SUB_KEY_FIRQ, keycode_7, 0x8000);
+       } else {
+               //scancode = 0;
+               if((keymode == KEYMODE_SCAN) && (bak_scancode != 0)) { // Notify even key-up, when using SCAN mode.
+                       uint32_t code = (bak_scancode & 0x7f) | 0x80;
+                       key_fifo->write(code);
+                       scancode = bak_scancode;
                }
        }
 }
 
-void KEYBOARD::key_down(uint32 vk)
+void KEYBOARD::key_down(uint32_t vk)
 {
        if(older_vk == vk) return;
        older_vk = vk;
        
        scancode = 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;
+               }
+       }
+#endif 
        key_down_main();
 }
 
 void KEYBOARD::key_down_main(void)
 {
-       double usec = (double)repeat_time_long * 1000.0;
-       uint32 code_7;
        bool stat_break = break_pressed;
-
+       uint32_t code;
        if(scancode == 0) return;
-       if(this->isModifier(scancode)) {  // modifiers
-               set_modifiers(scancode, true);
-               if(break_pressed != stat_break) { // Break key Down.
-                       this->write_signals(&break_line, 0xff);
-               }
-       }
-       code_7 = scan2fmkeycode(scancode);
        if(keymode == KEYMODE_SCAN) {
-               code_7 = scancode & 0x7f;
-       }
-       //printf("DOWN SCAN=%04x 7CODE=%03x break=%d\n", scancode, code_7, stat_break);
-       if(key_pressed_flag[scancode] != false) return;
-       if(code_7 < 0x200) {
-               keycode_7 = code_7 | 0x8000;
-               //mainio->write_signal(FM7_MAINIO_PUSH_KEYBOARD, code_7, 0x1ff);
-               mainio->write_signal(FM7_MAINIO_KEYBOARDIRQ, keycode_7, 0x8000);
-               display->write_signal(SIG_FM7_SUB_KEY_FIRQ, keycode_7, 0x8000);
-               key_pressed_flag[scancode] = true;
-       }
-   
-       // If repeat && !(PF) && !(BREAK) 
-       if((repeat_mode) && (scancode < 0x5c) && (code_7 != 0xffff)) {
-               register_event(this,
-                              ID_KEYBOARD_AUTOREPEAT_FIRST + scancode,
-                              usec, false, &event_ids[scancode]);
+               code = scancode & 0x7f;
+               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 {
-               if(event_ids[scancode] >= 0) cancel_event(this, event_ids[scancode]);
-               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(code != 0) {
+                       key_fifo->write(code);
+                       if(scancode < 0x5c) {
+                               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 = (uint8_t)scancode;
+                       }
+               }
        }
-       key_pressed_flag[scancode] = true;
-
 }
 
 #if defined(_FM77AV_VARIANTS)
 void KEYBOARD::adjust_rtc(void)
 {
-       p_emu->get_host_time(&cur_time);
+       get_host_time(&cur_time);
        rtc_yy = cur_time.year % 100;
        rtc_mm = cur_time.month;
        rtc_dd = cur_time.day;
@@ -982,26 +358,26 @@ void KEYBOARD::adjust_rtc(void)
 }
 #endif
 
-void KEYBOARD::do_repeatkey(uint16 sc)
+void KEYBOARD::do_repeatkey(uint16_t sc)
 {
-       uint16 code_7;
-       if((sc == 0) || (sc >= 0x67)) return; // scancode overrun.
+       uint16_t code;
+       if((sc == 0) || (sc >= 0x5c)) return; // scancode overrun.
        if(!repeat_mode) {
-               if(event_ids[sc] >= 0) {
-                       cancel_event(this, event_ids[sc]);
-                       event_ids[sc] = -1;
+               if(event_keyrepeat >= 0) {
+                       cancel_event(this, event_keyrepeat);
+                       event_keyrepeat = -1;
                }
                return;
        }
-       key_pressed_flag[sc] = true;
-       code_7 = scan2fmkeycode(sc);
        if(keymode == KEYMODE_SCAN) {
-               code_7 = sc;
-       }
-       if(code_7 < 0x200) {
-               keycode_7 = code_7 | 0x8000;
-               mainio->write_signal(FM7_MAINIO_KEYBOARDIRQ, keycode_7, 0x8000);
-               display->write_signal(SIG_FM7_SUB_KEY_FIRQ, keycode_7, 0x8000);
+               code = 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);
+               }
        }
 }
 
@@ -1009,62 +385,99 @@ void KEYBOARD::event_callback(int event_id, int err)
 {
 #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;
+               key_ack_status = true;
                write_signals(&key_ack, 0xff);
        } 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,
+                      20.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,
+                      20.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
 #endif
-       if((event_id >= ID_KEYBOARD_AUTOREPEAT_FIRST) && (event_id <= (ID_KEYBOARD_AUTOREPEAT_FIRST + 0x1ff))) {
-               uint32 sc = event_id - ID_KEYBOARD_AUTOREPEAT_FIRST;
+       if(event_id == ID_KEYBOARD_AUTOREPEAT_FIRST) {
+               uint32_t sc = (uint32_t)repeat_keycode;
                double usec = (double)repeat_time_short * 1000.0;
 
-               if((sc >= 0x67) || (sc == 0)) return;
-               do_repeatkey((uint16)sc);
+               do_repeatkey((uint16_t)sc);
                register_event(this,
-                              ID_KEYBOARD_AUTOREPEAT + sc,
-                              usec, true, &event_ids[sc]);
+                              ID_KEYBOARD_AUTOREPEAT,
+                              usec, true, &event_keyrepeat);
                // Key repeat.
-       } else if((event_id >= ID_KEYBOARD_AUTOREPEAT) && (event_id <= (ID_KEYBOARD_AUTOREPEAT + 0x1ff))){
-               uint32 sc = event_id - ID_KEYBOARD_AUTOREPEAT;
-               do_repeatkey((uint16)sc);
+       } else if(event_id == ID_KEYBOARD_AUTOREPEAT){
+               if(repeat_keycode != 0) {
+                       do_repeatkey((uint16_t)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);
+               }
        }
 }
 
 // Commands
 void KEYBOARD::reset_unchange_mode(void)
 {
-       int i;
        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;
+       kana_pressed = false;
+       caps_pressed = false;
        //      ins_pressed = false;
-       cmd_fifo->clear();
-       data_fifo->clear();
        datareg = 0x00;
+       repeat_keycode = 0x00;
+
 #if defined(_FM77AV_VARIANTS)
+       cmd_fifo->clear();
+       data_fifo->clear();
        if(event_key_rtc >= 0) {
-          cancel_event(this, event_key_rtc);
+               cancel_event(this, event_key_rtc);
        }
        register_event(this,ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
 
        cmd_phase = 0;
-       for(i = 0; i < 0x70; i++) {
-               if(event_ids[i] >= 0) cancel_event(this,event_ids[i]);
-               event_ids[i] = -1;
-               key_pressed_flag[i] = false;
-       }
+       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);
@@ -1073,14 +486,10 @@ void KEYBOARD::reset_unchange_mode(void)
        key_ack_status = true;
        this->write_signals(&rxrdy, 0x00);                
        this->write_signals(&key_ack, 0xff);              
+#endif
        this->write_signals(&kana_led, 0x00);             
        this->write_signals(&caps_led, 0x00);             
-       this->write_signals(&ins_led, 0x00);              
-#else
-       this->write_signals(&kana_led, 0x00);             
-       this->write_signals(&caps_led, 0x00);             
-       this->write_signals(&ins_led, 0x00);              
-#endif    
+       this->write_signals(&ins_led, 0x00);
 }
 
 
@@ -1088,33 +497,46 @@ void KEYBOARD::reset(void)
 {
        keymode = KEYMODE_STANDARD;
        scancode = 0x00;
-       keycode_7 = 0x00; 
+
+       keycode_7 = 0xffffffff; 
        reset_unchange_mode();
+       this->write_signals(&int_line, 0x00000000);
+       key_fifo->clear();
 #if defined(_FM77AV_VARIANTS)  
        adjust_rtc();
+       did_hidden_message_av_1 = false;
 #endif
+       if(event_int >= 0) cancel_event(this, event_int);
+       register_event(this,
+                      ID_KEYBOARD_INT,
+                      20000.0, true, &event_int);
+//     register_event(this,
+//                    ID_KEYBOARD_INT,
+//                    5000.0, true, &event_int);
 }
 
 
 #if defined(_FM77AV_VARIANTS)  
 // 0xd431 : Read
-uint8 KEYBOARD::read_data_reg(void)
+uint8_t KEYBOARD::read_data_reg(void)
 {
        if(!data_fifo->empty()) {
                datareg = data_fifo->read() & 0xff;
        }
-       if(data_fifo->empty()) {
-               write_signals(&rxrdy, 0x00);
-       } else {
+       if(!data_fifo->empty()) {
+               rxrdy_status = true;
                write_signals(&rxrdy, 0xff);
+       } else {
+               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;
+       uint8_t data = 0xff;
        if(rxrdy_status) {
                data &= 0x7f;
        }
@@ -1135,10 +557,13 @@ void KEYBOARD::set_mode(void)
        mode = cmd_fifo->read();
        if(mode <= KEYMODE_SCAN) {
                keymode = mode;
-               reset_unchange_mode();
+               //printf("Keymode : %d\n", keymode);
+               //reset_unchange_mode();
+               if(scancode != 0) key_down_main(); 
        }
        cmd_fifo->clear();
        data_fifo->clear(); // right?
+       rxrdy_status = false;
        write_signals(&rxrdy, 0x00);
 }
 
@@ -1151,6 +576,7 @@ void KEYBOARD::get_mode(void)
                dummy = data_fifo->read();
        }
        data_fifo->write(keymode);
+       rxrdy_status = true;
        write_signals(&rxrdy, 0xff);
 }
 
@@ -1175,17 +601,19 @@ void KEYBOARD::set_leds(void)
        }
        cmd_fifo->clear();
        data_fifo->clear(); // right?
+       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_status = true;
        write_signals(&rxrdy, 0xff);
 }
 
@@ -1200,37 +628,39 @@ void KEYBOARD::set_repeat_type(void)
                if((modeval < 2) && (modeval >= 0)) {
                        repeat_mode = (modeval == 0);
                        if(repeat_mode) {
-                               keycode_7 = 0x00;
-                               scancode = 0x00;
+                               //scancode = 0x00;
+                               //keycode_7 = 0x00;
+                               key_fifo->clear();
                        }
                }
        }
        data_fifo->clear();
        cmd_fifo->clear();
+       rxrdy_status = false;
        write_signals(&rxrdy, 0x00);
 }
 
 void KEYBOARD::set_repeat_time(void)
 {
        int cmd;
-       int time_high = 0;
-       int time_low = 0;
+       uint32_t time_high = 0;
+       uint32_t time_low = 0;
        cmd = cmd_fifo->read();
        if(cmd_fifo->empty()) goto _end;
        time_high = cmd_fifo->read();
        if(cmd_fifo->empty()) goto _end;
        time_low = cmd_fifo->read();
-//     if(cmd_fifo->empty()) goto _end;
 _end:
        if((time_high == 0) || (time_low == 0)) {
                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_status = false;
        write_signals(&rxrdy, 0x00);
 }
 
@@ -1280,6 +710,7 @@ void KEYBOARD::set_rtc(void)
                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);
 }
 
@@ -1321,6 +752,7 @@ void KEYBOARD::get_rtc(void)
        data_fifo->write(tmp);
        
        cmd_fifo->clear();
+       rxrdy_status = true;
        write_signals(&rxrdy, 0xff);
 }
 
@@ -1373,7 +805,7 @@ void KEYBOARD::rtc_count(void)
 }
 #endif // FM77AV_VARIANTS
 
-uint32 KEYBOARD::read_signal(int id)
+uint32_t KEYBOARD::read_signal(int id)
 {
        if(id == SIG_FM7KEY_BREAK_KEY) {
                return break_pressed ? 0xfffffff : 0x00000000;
@@ -1382,7 +814,7 @@ uint32 KEYBOARD::read_signal(int id)
 }
 
 
-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);
@@ -1406,32 +838,51 @@ void KEYBOARD::write_signal(int id, uint32 data, uint32 mask)
                cmd_fifo->write(data & 0xff);
                count = cmd_fifo->count();
                
-               write_signals(&key_ack, 0x00);
+               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(keymode == KEYMODE_SCAN) key_down_main();
+                                       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(keymode == KEYMODE_SCAN) key_down_main();
+                                       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) {
@@ -1440,32 +891,52 @@ 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.
@@ -1480,9 +951,9 @@ void KEYBOARD::write_signal(int id, uint32 data, uint32 mask)
 #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 = get_keycode_high();
@@ -1504,7 +975,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)                  
@@ -1517,11 +988,13 @@ void KEYBOARD::write_data8(uint32 addr, uint32 data)
 
 KEYBOARD::KEYBOARD(VM *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; 
@@ -1531,21 +1004,17 @@ 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] = -1;
-               key_pressed_flag[i] = false;
-       }
+       event_keyrepeat = -1;
    
-       cmd_fifo = new FIFO(16);
-       data_fifo = new FIFO(16);
        keymode = KEYMODE_STANDARD;
 #if defined(_FM77AV_VARIANTS)
-       rxrdy_status = false;
+       cmd_fifo = new FIFO(16);
+       data_fifo = new FIFO(16);
+       rxrdy_status = true;
        key_ack_status = false;
-       init_output_signals(&rxrdy);
-       init_output_signals(&key_ack);
-
+       initialize_output_signals(&rxrdy);
+       initialize_output_signals(&key_ack);
+       
        rtc_count24h = false;
        rtc_dayofweek = 0;
        rtc_ispm = false;
@@ -1558,26 +1027,180 @@ KEYBOARD::KEYBOARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_em
        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);
+       initialize_output_signals(&kana_led);
+       initialize_output_signals(&caps_led);
+       initialize_output_signals(&ins_led);
 }
 
 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 2
+void KEYBOARD::save_state(FILEIO *state_fio)
+{
+       state_fio->FputUint32_BE(STATE_VERSION);
+       state_fio->FputInt32_BE(this_device_id);
+       p_emu->out_debug_log("Save State: KEYBOARD: id=%d ver=%d\n", this_device_id, STATE_VERSION);
+
+       // Version 1
+       {
+               state_fio->FputUint32_BE(keycode_7);
+               state_fio->FputInt32_BE(keymode);
+          
+               state_fio->FputBool(ctrl_pressed);
+               state_fio->FputBool(lshift_pressed);
+               state_fio->FputBool(rshift_pressed);
+               state_fio->FputBool(shift_pressed);
+               state_fio->FputBool(graph_pressed);
+               state_fio->FputBool(caps_pressed);
+               state_fio->FputBool(kana_pressed);
+               state_fio->FputBool(break_pressed);
+
+               state_fio->FputInt32_BE(event_keyrepeat);
+          
+               state_fio->FputUint32(scancode);
+               state_fio->FputUint8(datareg);
+               state_fio->FputUint32(older_vk);
+          
+               state_fio->FputBool(repeat_mode);
+               state_fio->FputInt32_BE(repeat_time_short);
+               state_fio->FputInt32_BE(repeat_time_long);
+               state_fio->FputUint8(repeat_keycode);
+          
+#if defined(_FM77AV_VARIANTS)
+               state_fio->FputInt32_BE(event_key_rtc);
+  
+               state_fio->FputUint8(rtc_yy);
+               state_fio->FputUint8(rtc_mm);
+               state_fio->FputUint8(rtc_dd);
+               state_fio->FputUint8(rtc_dayofweek);
+               state_fio->FputUint8(rtc_hour);
+               state_fio->FputUint8(rtc_minute);
+               state_fio->FputUint8(rtc_sec);
+
+               state_fio->FputBool(rtc_count24h);
+               state_fio->FputBool(rtc_ispm);
+
+               state_fio->FputBool(rtc_set);
+               state_fio->FputBool(rtc_set_flag);
+               state_fio->FputBool(rxrdy_status);
+               state_fio->FputBool(key_ack_status);
+               state_fio->FputInt32_BE(cmd_phase);
+
+               state_fio->FputInt32_BE(event_hidden1_av);
+               state_fio->FputUint16_BE(hidden1_ptr);
+
+               cmd_fifo->save_state((void *)state_fio);
+               data_fifo->save_state((void *)state_fio);
+               cur_time.save_state((void *)state_fio);
+#endif
+               state_fio->FputInt32_BE(event_int);
+               key_fifo->save_state((void *)state_fio);
+       }
+       // Version 2
+       {
+#if defined(_FM77AV_VARIANTS)
+               state_fio->FputBool(did_hidden_message_av_1);
+#endif
+       }
+}
+
+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;
+       p_emu->out_debug_log("Load State: KEYBOARD: id=%d ver=%d\n", this_device_id, version);
+
+       if(version >= 1) {
+               keycode_7 = state_fio->FgetUint32_BE();
+               keymode = state_fio->FgetInt32_BE();
+          
+               ctrl_pressed = state_fio->FgetBool();
+               lshift_pressed = state_fio->FgetBool();
+               rshift_pressed = state_fio->FgetBool();
+               shift_pressed = state_fio->FgetBool();
+               graph_pressed = state_fio->FgetBool();
+               caps_pressed = state_fio->FgetBool();
+               kana_pressed = state_fio->FgetBool();
+               break_pressed = state_fio->FgetBool();
+
+               event_keyrepeat = state_fio->FgetInt32_BE();
+          
+               scancode = state_fio->FgetUint32();
+               datareg = state_fio->FgetUint8();
+               older_vk = state_fio->FgetUint32();
+          
+               repeat_mode = state_fio->FgetBool();
+               repeat_time_short = state_fio->FgetInt32_BE();
+               repeat_time_long = state_fio->FgetInt32_BE();
+               repeat_keycode = state_fio->FgetUint8();
+          
+#if defined(_FM77AV_VARIANTS)
+               event_key_rtc = state_fio->FgetInt32_BE();
+               rtc_yy = state_fio->FgetUint8();
+               rtc_mm = state_fio->FgetUint8();
+               rtc_dd = state_fio->FgetUint8();
+               rtc_dayofweek = state_fio->FgetUint8();
+               rtc_hour = state_fio->FgetUint8();
+               rtc_minute = state_fio->FgetUint8();
+               rtc_sec = state_fio->FgetUint8();
+
+               rtc_count24h = state_fio->FgetBool();
+               rtc_ispm = state_fio->FgetBool();
+
+               rtc_set = state_fio->FgetBool();
+               rtc_set_flag = state_fio->FgetBool();
+               rxrdy_status = state_fio->FgetBool();
+               key_ack_status = state_fio->FgetBool();
+               cmd_phase = state_fio->FgetInt32_BE();
+
+               event_hidden1_av = state_fio->FgetInt32_BE();
+               hidden1_ptr = state_fio->FgetUint16_BE();
+
+               cmd_fifo->load_state((void *)state_fio);
+               data_fifo->load_state((void *)state_fio);
+               cur_time.load_state((void *)state_fio);
+#endif
+               event_int = state_fio->FgetInt32_BE();
+               key_fifo->load_state((void *)state_fio);
+               if(version == 1) return true;
+       }
+       // Version 2
+       {
+#if defined(_FM77AV_VARIANTS)
+               did_hidden_message_av_1 = state_fio->FgetBool();
+#endif
+       }
+       if(version == STATE_VERSION) {
+               return true;
+       }
+       return false;
+}
+