2 * Common Source code Project -> VM -> FM-7/77AV -> Keyboard
3 * (C) 2015 K.Ohta <whatisthis.sowhat _at_ gmail.com>
6 * Feb 12, 2015 : Initial
9 #include "../../fifo.h"
10 #include "../device.h"
14 SIG_FM7KEY_KEY_UP = 0x800,
16 SIG_FM7KEY_READ, // D400 = high , D401 = low
17 SIG_FM7KEY_LED_ONOFF, // D40D: Write = OFF / Read = ON
19 SIG_FM7KEY_PUSH_TO_ENCODER,
23 uint16 vk_matrix[0x68] = { // VK
24 // +0, +1, +2, +3, +4, +5, +6, +7
25 /* 0x00, ESC, 1 , 2, 3, 4, 5, 6 */
26 0x00, VK_KANJI, '1', '2', '3', '4', '5', '6', // +0x00
27 /* 7, 8, 9, 0, - , ^, \|, BS */
28 '7', '8', '9', '0', 0xbd, 0xde, 0xdc, VK_BACK, // +0x08
29 /* TAB, Q, W, E, R, T, Y, U */
30 VK_TAB, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', // +0x10
31 /* I, O, P, @, [, [RET], A, S */
32 'I', 'O', 'P', 0xc0, 0xdb, VK_RETURN, 'A', 'S', //+0x18
33 /* D, F, G, H, J, K, L, ; */
34 'D', 'F', 'G', 'H', 'J', 'K', 'L', 0xbb, // +0x20
35 /* :, ], Z, X, C, V, B, N */
36 0xba, 0xdd, 'Z', 'X', 'C', 'V', 'B', 'N', // +0x28
37 /* M, , , ., / , \, RSPACE=RWIN , * , / */
38 'M', 0xbc, 0xbe, 0xbf, 0xe2, VK_RWIN, VK_MULTIPLY, VK_DIVIDE, // +0x30
39 /* + , - , 7, 8, 9, = , 4, 5 */
40 VK_ADD, VK_SUBTRACT, VK_NUMPAD7, VK_NUMPAD8, VK_NUMPAD9, 0x00, VK_NUMPAD4, VK_NUMPAD5, // +0x38
41 /* 6, NUMPADCOMMA=RMENU , 1, 2, 3, NUMPADENTER=RETURN,0, . */
42 VK_NUMPAD6, VK_RMENU, VK_NUMPAD1, VK_NUMPAD2, VK_NUMPAD3, VK_RETURN, VK_NUMPAD0, VK_DECIMAL, // +0x40
43 /* INS, HOME, PRIOR, DEL, END, ↑, ↓,← */
44 VK_INSERT, VK_HOME, VK_PRIOR, VK_DELETE, VK_END, VK_UP, VK_NEXT, VK_LEFT, // +0x48
45 /* PAgeDown, →, LCTRL, LSHIFT, RSHIFT, CAPS, Graph=Muhenkan, Lspace=LALT */
46 VK_DOWN, VK_RIGHT, VK_LCONTROL, VK_LSHIFT, VK_RSHIFT, VK_CAPITAL, 0x1d, 0xf3, // +0x50
47 /* Cspace=Space, *Unknown*, KANA, *Unknown* , ESC(Break), F1, F2, F3 */
48 VK_SPACE, 0x00, 0xf2, 0x00, VK_ESCAPE, VK_F1, VK_F2, VK_F3, // +0x58
49 /* F4, F5, F6, F7, F8, F9, F10 , *END* */
50 VK_F4, VK_F5, VK_F6, VK_F7, VK_F8, VK_F9, VK_F10, 0xffff // +0x60
58 // Key tables value from XM7.
59 const key_tbl_t standard_key[] = {
164 const key_tbl_t standard_shift_key[] = {
257 const struct key_tbl_t ctrl_key[] = {
297 const struct key_tbl_t ctrl_shift_key[] = {
337 const struct key_tbl_t graph_key[] = {
425 /* Belows is none when shift */
438 const struct key_tbl_t graph_shift_key[] = {
530 const struct key_tbl_t kana_key[] = {
637 const struct key_tbl_t kana_shift_key[] = {
704 uint8 KEYBOARD::read_data_reg(void)
706 if(rxrdy->read_signal(0) != 0) {
707 if(!data_fifo->empty()) {
708 datareg = data_fifo->read() & 0xff;
711 if(data_fifo->empty()) {
712 rxrdy->write_signal(0x00, 0x00, 0x01);
714 rxrdy->write_signal(0x00, 0x01, 0x01);
720 uint8 KEYBOARD::read_stat_reg(void)
724 if(!data_fifo->empty()) {
725 rxrdy->write_signal(0x00, 0x01, 0x01);
728 if(key_ack->read_signal(0) == 0x00) {
731 // Digityze : bit0 = '0' when waiting,
735 // 0xd400(SUB) or 0xfd00(MAIN)
736 uint8 KEYBOARD::get_keycode_high(void)
739 if((keycode_7 & 0x0100) != 0) data |= 0x01;
743 // 0xd401(SUB) or 0xfd01(MAIN)
744 uint8 KEYBOARD::get_keycode_low(void)
746 uint8 data = keycode_7 & 0xff;
747 maincpu->write_signal(SIG_CPU_IRQ, 0, 1);
748 subcpu->write_signal(SIG_CPU_FIRQ, 0, 1);
753 void KEYBOARD::turn_on_ins_led(void)
755 ins_led->write_signal(0x00, 0x01, 0x01);
759 void KEYBOARD::turn_off_ins_led(void)
761 ins_led->write_signal(0x00, 0x00, 0x01);
767 uint16 KEYBOARD::vk2scancode(uint32 vk)
773 if(vk_matrix[i] == vk) return i;
775 } while(vk_matrix[i] != 0xffff);
779 bool KEYBOARD::isModifier(uint16 scancode)
781 if(((scancode >= 0x52) && (scancode <= 0x56)) || // CTRL LSHIFT RSHIFT CAPS GRPH
782 (scancode == 0x5a) || (scancode == 0x5c)) { // KANA BREAK
788 void KEYBOARD::set_modifiers(uint16 scancode, bool flag)
790 if(scancode == 0x52) { // CTRL
792 } else if(scancode == 0x53) { // LSHIFT
793 lshift_pressed = flag;
795 shift_pressed = true;
797 shift_pressed = flag;
799 } else if(scancode == 0x54) { // RSHIFT
800 rshift_pressed = flag;
802 shift_pressed = true;
804 shift_pressed = flag;
806 } else if(scancode == 0x56) { // GRPH
807 graph_pressed = flag;
808 } else if(scancode == 0x55) { // CAPS
812 caps_pressed = false;
816 if(keymode == KEYMODE_STANDARD) caps_led->write_signal(0x00, caps_pressed ? 0x01 : 0x00, 0x01);
818 } else if(scancode == 0x5a) { // KANA
822 kana_pressed = false;
826 if(keymode == KEYMODE_STANDARD) kana_led->write_signal(0x00, kana_pressed ? 0x01 : 0x00, 0x01);
828 } else if(scancode == 0x5c) { // Break
829 break_pressed = flag;
833 uint16 KEYBOARD::scan2fmkeycode(uint16 scancode)
835 struct key_tbl_t *keyptr;
841 if((scancode == 0) || (scancode >= 0x67)) return 0xffff;
842 // Set repeat flag(s)
843 if(shift_pressed && ctrl_pressed) {
858 // DO super-impose mode:
860 // F8 : IMPOSE (High brightness)
861 // F9 : IMPOSE (Low brightness)
864 if(keymode == KEYMODE_SCAN) {
867 } else if(keymode == KEYMODE_STANDARD) {
870 keyptr = ctrl_shift_key;
874 } else if(graphkey_pressed) {
876 keyptr = graph_shift_key;
880 } else if(kanakey_pressed) {
882 keyptr = kana_shift_key;
889 keyptr = standard_shift_key;
891 keyptr = standard_key;
894 if(keyptr == NULL) return 0xffff;
895 } else if(keymode == KEYMODE_16BETA) {
902 if(keyptr[i].phy == scancode) {
903 retval = keyptr[i].code;
907 } while(keyptr[i].phy != 0xffff);
910 if((retval >= 'A') && (retval <= 'Z')) {
914 } else if((retval >= 'a') && (retval <= 'z')) {
923 void KEYBOARD::key_up(uint32 vk)
925 uint16 scancode = vk2scancode(vk);
926 bool stat_break = break_pressed;
927 if(event_ids[scancode] >= 0){
928 cancel_event(this, event_ids[scancode]);
929 event_ids[scancode] = -1;
931 if(this->isModifiers(scancode)) {
932 set_modifiers(scancode, false);
933 if(break_pressed != stat_break) { // Break key UP.
934 break_line->write_signal(0x00, 0, 1);
935 maincpu->write_signal(SIG_CPU_FIRQ, 0, 1);
938 key_pressed_flag[scancode] = false;
941 void KEYBOARD::key_down(uint32 vk)
943 double usec = (double)repeat_time_long * 1000.0;
945 uint16 scancode = vk2scancode(vk);
946 bool stat_break = break_pressed;
947 key_pressed_flag[scancode] = true;
949 code_7 = scan2fmkeycode(scancode);
952 maincpu->write_signal(SIG_CPU_IRQ, 1, 1);
953 subcpu->write_signal(SIG_CPU_FIRQ, 1, 1);
955 if(this->isModifiers(scancode)) { // modifiers
956 if(break_pressed != stat_break) { // Break key Down.
957 break_line->write_signal(0x00, 1, 1);
958 maincpu->write_signal(SIG_CPU_FIRQ, 1, 1);
961 // If repeat && !(PF) && !(BREAK)
962 if((repeat_mode) && (scancode < 0x5c) && (scancode != 0)) {
964 ID_KEYBOARD_AUTOREPEAT_FIRST + scancode,
965 usec, false, &event_ids[scancode]);
967 event_ids[scancode] = -1;
969 key_pressed_flag[scancode] = true;
973 void KEYBOARD::do_repeatkey(uint16 scancode)
976 if((scancode == 0) || (scancode >= 0x67)) return; // scancode overrun.
978 if(event_ids[scancode] >= 0) {
979 cancel_event(this, event_ids[scancode]);
980 event_ids[scancode] = -1;
984 key_pressed_flag[scancode] = true;
985 code_7 = scan2fmkeycode(scancode);
988 maincpu->write_signal(SIG_CPU_IRQ, 1, 1);
989 subcpu->write_signal(SIG_CPU_FIRQ, 1, 1);
991 //if(this->isModifiers(scancode)) { // modifiers
992 //if(break_pressed != stat_break) { // Break key Down.
993 // break_line->write_signal(0x00, 1, 1);
994 // maincpu->write_signal(SIG_CPU_FIRQ, 1, 1);
999 void KEYBOARD::event_callback(int event_id, int err)
1001 if(event_id == ID_KEYBOARD_RXRDY_OK) {
1002 rxrdy->write_signal(0x00, 0x01, 0x01);
1003 } else if(event_id == ID_KEYBOARD_RXRDY_BUSY) {
1004 rxrdy->write_signal(0x00, 0x00, 0x01);
1005 } else if(event_id == ID_KEYBOARD_ACK) {
1006 key_ack->write_signal(0x00, 0x01, 0x01);
1007 } else if((event_id >= ID_KEYBOARD_AUTOREPEAT_FIRST) && (event_id <= (ID_KEYBOARD_AUTOREPEAT_FIRST + 0x1ff))) {
1008 uint32 scancode = event_id - ID_KEYBOARD_AUTOREPEAT_FIRST;
1009 double usec = (double)repeat_time_short * 1000.0;
1011 if((scancode >= 0x67) || (scancode == 0)) return;
1012 do_repeatkey((uint16)scancode);
1013 register_event(this,
1014 ID_KEYBOARD_AUTOREPEAT + scancode,
1015 usec, true, &event_ids[scancode]);
1017 } else if((event_id >= ID_KEYBOARD_AUTOREPEAT) && (event_id <= (ID_KEYBOARD_AUTOREPEAT + 0x1ff))){
1018 uint32 scancode = event_id - ID_KEYBOARD_AUTOREPEAT;
1019 do_repeatkey((uint16)scancode);
1024 void KEYBOARD::reset_keyboard(void)
1026 repeat_time_short = 70; // mS
1027 repeat_time_long = 700; // mS
1031 lshift_pressed = false;
1032 rshift_pressed = false;
1033 ctrl_pressed = false;
1034 graph_pressed = false;
1035 // ins_pressed = false;
1040 rxrdy->write_signal(0x00, 0x00, 0x01);
1041 key_ack->write_signal(0x00, 0x01, 0x01);
1042 break_line->write_signal(0x00, 0, 1);
1044 ins_led->write_signal(0x01, 0x00, 0x01);
1045 caps_led->write_signal(0x01, 0x00, 0x01);
1046 kana_led->write_signal(0x01, 0x00, 0x01);
1049 void KEYBOARD::set_mode(void)
1051 int count = cmd_fifo->count();
1053 if(count < 2) return;
1054 cmd = cmd_fifo->read();
1055 key_format = cmd_fifo->read();
1059 void KEYBOARD::get_mode(void)
1063 cmd = cmd_fifo->read();
1064 if(data_fifo->full()) {
1065 dummy = data_fifo->read();
1067 data_fifo->write(key_format);
1068 rxrdy->write_signal(0x01, 0x01, 0x01);
1072 void KEYBOARD::write_signal(int id, uint32 data, uint32 mask)
1075 if(id == SIG_FM7KEY_PUSH_TO_ENCODER) {
1077 * I refered XM7's sourcecode : VM/keyboard.c act of key-encoder.
1078 * Thanks to Ryu.Takegami and PI.
1081 if(key_ack->read_signal(0x00) == 0) return; // If (not(ACK)) noop.
1083 if(cmd_fifo->full()) {
1086 if(cmd_fifo->empty()) {
1087 cmd_phase = data & 0xff;
1090 cmd_fifo->write(data & 0xff);
1091 count = cmd_fifo->count();
1093 key_ack->write_signal(0x00, 0x00, 0x01);
1096 if(count >= 2) set_mode();
1101 case 2: // Set LED Phase
1102 if(count >= 2) set_leds();
1104 case 3: // Get LED Phase
1108 if(count >= 2) set_repeat_type();
1111 if(count >= 3) set_repeat_time();
1113 case 0x80: // Communicate to/from RTC.
1118 if((data & 0xff) == 0) { // Get
1120 } else if((data & 0xff) == 1) { // Set
1121 rtc_set_flag = true;
1132 case 0x81: // Digitize.
1133 if(count >= 2) do_digitize(); // WILL Implement?
1136 if(count >= 2) set_screen_mode();
1142 if(count >= 2) set_brightness();
1145 //cmd_fifo->clear();
1148 register_event(this, ID_KEYBOARD_ACK, 5, false, NULL); // Delay 5us until ACK is up.