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
11 #include "../../fifo.h"
12 #include "../device.h"
14 #include "fm7_keyboard.h"
15 #include "keyboard_tables.h"
17 #if defined(_FM77AV_VARIANTS)
21 #include "fm77av_hidden_message_keyboard.h"
28 ID_KEYBOARD_RXRDY_OK = 1,
30 ID_KEYBOARD_RXRDY_BUSY,
31 ID_KEYBOARD_RTC_COUNTUP,
33 ID_KEYBOARD_AUTOREPEAT_FIRST,
34 ID_KEYBOARD_AUTOREPEAT,
35 ID_KEYBOARD_HIDDENMESSAGE_AV,
36 ID_KEYBOARD_HIDDEN_BEEP_ON,
37 ID_KEYBOARD_HIDDEN_BEEP_OFF,
38 ID_KEYBOARD_AUTO_8KEY_START,
39 ID_KEYBOARD_AUTO_8KEY_END,
40 ID_KEYBOARD_AUTO_5KEY_START,
41 ID_KEYBOARD_AUTO_5KEY_END,
42 ID_KEYBOARD_BREAK_ONESHOT,
49 // 0xd400(SUB) or 0xfd00(MAIN)
50 uint8_t KEYBOARD::get_keycode_high(void)
53 if((keycode_7 & 0x0100) != 0) data = 0x80;
57 // 0xd401(SUB) or 0xfd01(MAIN)
58 uint8_t KEYBOARD::get_keycode_low(void)
60 uint8_t data = keycode_7 & 0xff;
61 this->write_signals(&int_line, 0x00000000);
66 void KEYBOARD::turn_on_ins_led(void)
68 ins_led_status = true;
72 void KEYBOARD::turn_off_ins_led(void)
74 ins_led_status = false;
78 uint16_t KEYBOARD::vk2scancode(uint32_t vk)
82 if(vk == VK_PAUSE) vk = VK_KANJI; // Workaround some desktop environments for [ESC].
84 if(vk_matrix_106[i] == vk) return i;
86 } while(vk_matrix_106[i] != 0xffff);
90 bool KEYBOARD::isModifier(uint8_t sc)
92 if(((sc >= 0x52) && (sc <= 0x56)) || // CTRL LSHIFT RSHIFT CAPS GRPH
93 (sc == 0x5a) || (sc == 0x5c)) { // KANA BREAK
99 void KEYBOARD::set_modifiers(uint8_t sc, bool flag)
101 if(sc == 0x52) { // CTRL
103 } else if(sc == 0x53) { // LSHIFT
104 lshift_pressed = flag;
105 shift_pressed = lshift_pressed | rshift_pressed;
106 //printf("LSHIFT : %d\n", flag ? 1 : 0);
107 } else if(sc == 0x54) { // RSHIFT
108 rshift_pressed = flag;
109 shift_pressed = lshift_pressed | rshift_pressed;
110 //printf("RSHIFT : %d\n", flag ? 1 : 0);
111 } else if(sc == 0x56) { // GRPH
112 graph_pressed = flag;
113 } else if(sc == 0x55) { // CAPS
117 caps_pressed = false;
121 if(keymode == KEYMODE_STANDARD) caps_led_status = caps_pressed;
123 } else if(sc == 0x5a) { // KANA
127 kana_pressed = false;
131 if(keymode == KEYMODE_STANDARD) kana_led_status = kana_pressed;
133 } else if(sc == 0x5c) { // Break
134 if(!override_break_key) {
135 break_pressed = flag;
140 uint16_t KEYBOARD::scan2fmkeycode(uint8_t sc)
142 const struct key_tbl_t *keyptr = NULL;
147 if((sc == 0) || (sc >= 0x67)) return 0xffff;
148 // Set repeat flag(s)
149 if(shift_pressed && ctrl_pressed) {
163 if(keymode == KEYMODE_STANDARD) {
166 keyptr = ctrl_shift_key;
170 } else if(graph_pressed) {
172 keyptr = graph_shift_key;
176 } else if(kana_pressed) {
178 keyptr = kana_shift_key;
185 keyptr = standard_shift_key;
187 keyptr = standard_key;
191 #if defined(_FM77AV_VARIANTS)
192 else if(shift_pressed) {
193 // DO super-impose mode:
195 // F8 : IMPOSE (High brightness)
196 // F9 : IMPOSE (Low brightness)
199 if(keymode == KEYMODE_SCAN) {
200 retval = (uint16_t)sc;
202 } else if(keymode == KEYMODE_16BETA) { // Will Implement
205 keyptr = ctrl_shift_key_16beta;
207 keyptr = ctrl_key_16beta;
209 } else if(graph_pressed) {
211 keyptr = graph_shift_key_16beta;
213 keyptr = graph_key_16beta;
215 } else if(kana_pressed) {
217 keyptr = kana_shift_key_16beta;
219 keyptr = kana_key_16beta;
224 keyptr = standard_shift_key_16beta;
226 keyptr = standard_key_16beta;
230 #endif //_FM77AV_VARIANTS
233 if (keyptr == NULL) return 0xffff;
235 if(keyptr[i].phy == (uint16_t)sc) {
236 retval = keyptr[i].code;
240 } while(keyptr[i].phy != 0xffff);
241 if(keyptr[i].phy == 0xffff) return 0x00;
243 if((retval >= 'A') && (retval <= 'Z')) {
247 } else if((retval >= 'a') && (retval <= 'z')) {
256 void KEYBOARD::key_up_main(uint8_t bak_scancode)
258 bool stat_break = break_pressed;
260 if(bak_scancode == 0) return;
261 if((event_keyrepeat >= 0) && (repeat_keycode == bak_scancode)) { // Not Break
262 cancel_event(this, event_keyrepeat);
263 event_keyrepeat = -1;
266 if(keymode != KEYMODE_SCAN) {
267 if(this->isModifier(bak_scancode)) {
268 set_modifiers(bak_scancode, false);
269 if(break_pressed != stat_break) { // Break key UP.
270 this->write_signals(&break_line, 0x00);
273 if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
274 if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
275 switch(bak_scancode) {
282 ID_KEYBOARD_AUTO_8KEY_START,
283 10.0 * 1000.0, false, NULL);
286 if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
290 switch(bak_scancode) {
300 ID_KEYBOARD_AUTO_5KEY_START,
301 10.0 * 1000.0, false, NULL);
304 if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
311 if(bak_scancode != 0) { // Notify even key-up, when using SCAN mode.
312 uint8_t code = (bak_scancode & 0x7f) | 0x80;
313 if(this->isModifier(bak_scancode)) {
314 set_modifiers(bak_scancode, false);
316 #if defined(_FM77AV_VARIANTS)
317 if(bak_scancode != 0x5c) {
318 if(beep_phase == 1) {
319 if(break_pressed) this->write_signals(&break_line, 0x00);
320 break_pressed = false;
324 } else if(beep_phase == 2) {
327 ID_KEYBOARD_HIDDEN_BEEP_ON,
328 100.0, false, NULL); // 100.0 us is dummy.
332 } else { // 0x5c : BREAK is up.
334 if(stat_break) this->write_signals(&break_line, 0x00);
338 key_fifo->write(code);
339 scancode = bak_scancode;
345 void KEYBOARD::key_up(uint32_t vk)
347 uint8_t bak_scancode = (uint8_t)(vk2scancode(vk) & 0x00ff);
348 key_up_main(bak_scancode);
351 void KEYBOARD::key_down(uint32_t vk)
353 if(older_vk == vk) return;
356 scancode = (uint8_t)vk2scancode(vk);
357 #if defined(_FM77AV_VARIANTS)
358 // Below are FM-77AV's hidden message , see :
359 // https://twitter.com/maruan/status/499558392092831745
360 //if(caps_pressed && kana_pressed) {
361 // if(ctrl_pressed && lshift_pressed && rshift_pressed && graph_pressed) {
362 if(caps_pressed && kana_pressed && graph_pressed && shift_pressed && ctrl_pressed && !did_hidden_message_av_1) { // IT's deprecated key pressing
363 if(scancode == 0x15) { // "T"
364 if(event_hidden1_av < 0) {
366 did_hidden_message_av_1 = true;
368 ID_KEYBOARD_HIDDENMESSAGE_AV,
369 130.0 * 1000, true, &event_hidden1_av);
378 void KEYBOARD::key_down_main(bool repeat_auto_key)
380 bool stat_break = break_pressed;
382 if(scancode == 0) return;
383 if(keymode == KEYMODE_SCAN) {
384 code = scancode & 0x7f;
385 if(this->isModifier(scancode)) { // modifiers
386 set_modifiers(scancode, true);
388 #if defined(_FM77AV_VARIANTS)
392 // It's dirty hack for AMNORK ; Set dead zone for FIRQ to 0.25sec.
393 // I wish to replace this solution to more simple.
395 ID_KEYBOARD_BREAK_ONESHOT,
396 250.0 * 1000.0, false, NULL);
397 } else if(beep_phase == 1) {
399 if(break_pressed) this->write_signals(&break_line, 0x00);
400 break_pressed = false;
402 code = 0x7f; // Special
410 key_fifo->write(code);
411 // NOTE: With scan key code mode, auto repeat seems to be not effectable.
412 // See : http://hanabi.2ch.net/test/read.cgi/i4004/1430836648/607
416 if(this->isModifier(scancode)) { // modifiers
417 set_modifiers(scancode, true);
418 if(break_pressed != stat_break) { // Break key Down.
419 this->write_signals(&break_line, 0xff);
423 code = scan2fmkeycode(scancode);
424 if((code > 0x3ff) || (code == 0)) return;
425 if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
426 if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
433 autokey_backup = scancode;
446 autokey_backup = scancode;
451 autokey_backup = 0x00;
454 key_fifo->write(code);
455 if((scancode < 0x5c) && repeat_auto_key) {
456 double usec = (double)repeat_time_long * 1000.0;
457 if((repeat_keycode == 0) && repeat_mode) {
458 if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
459 event_keyrepeat = -1;
461 ID_KEYBOARD_AUTOREPEAT_FIRST,
462 usec, false, &event_keyrepeat);
464 repeat_keycode = scancode;
470 #if defined(_FM77AV_VARIANTS)
471 void KEYBOARD::adjust_rtc(void)
473 get_host_time(&cur_time);
474 rtc_yy = cur_time.year % 100;
475 rtc_mm = cur_time.month;
476 rtc_dd = cur_time.day;
478 rtc_dayofweek = cur_time.day_of_week;
480 rtc_ispm = (cur_time.hour >= 12) ? true : false;
481 rtc_hour = cur_time.hour % 12;
484 rtc_hour = cur_time.hour;
486 rtc_minute = cur_time.minute;
487 rtc_sec = cur_time.second;
488 if(event_key_rtc >= 0) {
489 cancel_event(this, event_key_rtc);
491 register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
495 void KEYBOARD::do_repeatkey(uint8_t sc)
498 if((sc == 0) || (sc >= 0x5c)) return; // scancode overrun.
500 if(event_keyrepeat >= 0) {
501 cancel_event(this, event_keyrepeat);
502 event_keyrepeat = -1;
506 if(keymode == KEYMODE_SCAN) {
507 code = (uint16_t)(sc & 0x7f);
508 key_fifo->write((uint32_t)code); // Make
509 //key_fifo->write((uint32_t)(code | 0x80)); // Break
511 code = scan2fmkeycode(sc);
513 key_fifo->write((uint32_t)code);
518 void KEYBOARD::event_callback(int event_id, int err)
520 #if defined(_FM77AV_VARIANTS)
521 if(event_id == ID_KEYBOARD_RXRDY_OK) {
523 write_signals(&rxrdy, 0xff);
524 } else if(event_id == ID_KEYBOARD_RXRDY_BUSY) {
525 rxrdy_status = false;
526 write_signals(&rxrdy, 0x00);
527 } else if(event_id == ID_KEYBOARD_ACK) {
528 key_ack_status = true;
529 write_signals(&key_ack, 0xff);
530 } else if(event_id == ID_KEYBOARD_RTC_COUNTUP) {
532 } else if(event_id == ID_KEYBOARD_HIDDENMESSAGE_AV) {
533 if(hidden_message_77av_1[hidden1_ptr] == 0x00) {
534 cancel_event(this, event_hidden1_av);
535 event_hidden1_av = -1;
538 key_fifo->write(hidden_message_77av_1[hidden1_ptr++]);
540 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
541 beep->write_signal(SIG_BEEP_ON, 1, 1);
543 ID_KEYBOARD_HIDDEN_BEEP_OFF,
544 25.0 * 1000.0, false, NULL);
545 } else if(event_id == ID_KEYBOARD_HIDDEN_BEEP_ON) {
546 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
547 beep->write_signal(SIG_BEEP_ON, 1, 1);
549 ID_KEYBOARD_HIDDEN_BEEP_OFF,
550 25.0 * 1000.0, false, NULL);
552 } else if(event_id == ID_KEYBOARD_HIDDEN_BEEP_OFF) {
553 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
554 beep->write_signal(SIG_BEEP_ON, 0, 1);
555 } else if(event_id == ID_KEYBOARD_BREAK_ONESHOT) {
556 if(break_pressed) this->write_signals(&break_line, 0xff);
559 if(event_id == ID_KEYBOARD_AUTOREPEAT_FIRST) {
560 double usec = (double)repeat_time_short * 1000.0;
562 do_repeatkey(repeat_keycode);
564 ID_KEYBOARD_AUTOREPEAT,
565 usec, true, &event_keyrepeat);
567 } else if(event_id == ID_KEYBOARD_AUTOREPEAT){
568 if(repeat_keycode != 0) {
569 do_repeatkey(repeat_keycode);
571 cancel_event(this, event_keyrepeat);
572 event_keyrepeat = -1;
574 } else if(event_id == ID_KEYBOARD_INT) {
575 if(!(key_fifo->empty())) {
576 keycode_7 = key_fifo->read();
577 this->write_signals(&int_line, 0xffffffff);
579 } else if(event_id == ID_KEYBOARD_AUTO_8KEY_START) {
580 if(keymode != KEYMODE_SCAN) {
581 scancode = 0x3b; // 8
582 autokey_backup = 0x00;
583 key_down_main(false);
585 ID_KEYBOARD_AUTO_8KEY_END,
586 50.0 * 1000.0, false, NULL);
588 } else if(event_id == ID_KEYBOARD_AUTO_8KEY_END) {
589 key_up_main(0x3b); // 8
590 } else if(event_id == ID_KEYBOARD_AUTO_5KEY_START) {
591 if(keymode != KEYMODE_SCAN) {
592 scancode = 0x3f; // 5
593 autokey_backup = 0x00;
594 key_down_main(false);
596 ID_KEYBOARD_AUTO_5KEY_END,
597 50.0 * 1000.0, false, NULL);
599 } else if(event_id == ID_KEYBOARD_AUTO_5KEY_END) {
600 key_up_main(0x3f); // 5
605 void KEYBOARD::reset_unchange_mode(void)
607 repeat_time_short = 70; // mS
608 repeat_time_long = 700; // mS
612 lshift_pressed = false;
613 rshift_pressed = false;
614 shift_pressed = false;
615 ctrl_pressed = false;
616 graph_pressed = false;
617 kana_pressed = false;
618 caps_pressed = false;
619 ins_led_status = false;
620 kana_led_status = false;
621 caps_led_status = false;
623 repeat_keycode = 0x00;
624 autokey_backup = 0x00;
626 if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
628 #if defined(_FM77AV_VARIANTS)
631 if(event_key_rtc >= 0) {
632 cancel_event(this, event_key_rtc);
634 register_event(this,ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
637 if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
638 event_keyrepeat = -1;
640 if(event_hidden1_av >= 0) cancel_event(this, event_hidden1_av);
641 event_hidden1_av = -1;
645 this->write_signals(&break_line, 0x00);
646 #if defined(_FM77AV_VARIANTS)
647 rxrdy_status = false;
648 key_ack_status = true;
649 this->write_signals(&rxrdy, 0x00);
650 this->write_signals(&key_ack, 0xff);
655 void KEYBOARD::reset(void)
657 keymode = KEYMODE_STANDARD;
660 keycode_7 = 0xffffffff;
662 reset_unchange_mode();
663 this->write_signals(&int_line, 0x00000000);
665 #if defined(_FM77AV_VARIANTS)
667 did_hidden_message_av_1 = false;
671 if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
673 if(event_int >= 0) cancel_event(this, event_int);
676 20000.0, true, &event_int);
680 #if defined(_FM77AV_VARIANTS)
682 uint8_t KEYBOARD::read_data_reg(void)
684 if(!data_fifo->empty()) {
685 datareg = data_fifo->read() & 0xff;
687 if(!data_fifo->empty()) {
689 write_signals(&rxrdy, 0xff);
691 rxrdy_status = false;
692 write_signals(&rxrdy, 0x00);
698 uint8_t KEYBOARD::read_stat_reg(void)
704 if(!key_ack_status) {
707 // Digityze : bit0 = '0' when waiting,
711 void KEYBOARD::set_mode(void)
713 int count = cmd_fifo->count();
716 if(count < 2) return;
717 cmd = cmd_fifo->read();
718 mode = cmd_fifo->read();
719 if(mode <= KEYMODE_SCAN) {
721 //printf("Keymode : %d\n", keymode);
722 //reset_unchange_mode();
724 autokey_backup = 0x00;
725 this->write_signals(&break_line, 0x00);
726 if(scancode != 0) key_down_main(true);
729 data_fifo->clear(); // right?
730 rxrdy_status = false;
731 write_signals(&rxrdy, 0x00);
734 void KEYBOARD::get_mode(void)
738 cmd = cmd_fifo->read();
739 if(data_fifo->full()) {
740 dummy = data_fifo->read();
742 data_fifo->write(keymode);
744 write_signals(&rxrdy, 0xff);
747 void KEYBOARD::set_leds(void)
749 int count = cmd_fifo->count();
752 if(count < 2) return;
753 cmd = cmd_fifo->read();
754 ledvar = cmd_fifo->read();
756 if((ledvar & 0x02) != 0) {
758 kana_pressed = ((ledvar & 0x01) == 0);
759 kana_led_status = kana_pressed;
762 caps_pressed = ((ledvar & 0x01) == 0);
763 caps_led_status = caps_pressed;
767 data_fifo->clear(); // right?
768 rxrdy_status = false;
769 write_signals(&rxrdy, 0x00);
772 void KEYBOARD::get_leds(void)
774 uint8_t ledvar = 0x00;
776 ledvar |= caps_pressed ? 0x01 : 0x00;
777 ledvar |= kana_pressed ? 0x02 : 0x00;
778 data_fifo->write(ledvar);
781 write_signals(&rxrdy, 0xff);
784 void KEYBOARD::set_repeat_type(void)
789 cmd = cmd_fifo->read();
790 if(!cmd_fifo->empty()) {
791 modeval = cmd_fifo->read();
792 if((modeval < 2) && (modeval >= 0)) {
793 repeat_mode = (modeval == 0);
803 rxrdy_status = false;
804 write_signals(&rxrdy, 0x00);
807 void KEYBOARD::set_repeat_time(void)
810 uint32_t time_high = 0;
811 uint32_t time_low = 0;
812 cmd = cmd_fifo->read();
813 if(cmd_fifo->empty()) goto _end;
814 time_high = cmd_fifo->read();
815 if(cmd_fifo->empty()) goto _end;
816 time_low = cmd_fifo->read();
818 if((time_high == 0) || (time_low == 0)) {
819 repeat_time_long = 700;
820 repeat_time_short = 70;
822 repeat_time_long = (int)time_high * 10;
823 repeat_time_short = (int)time_low * 10;
827 rxrdy_status = false;
828 write_signals(&rxrdy, 0x00);
831 void KEYBOARD::set_rtc(void)
836 if(cmd_fifo->count() < 9) return;
837 cmd = cmd_fifo->read();
838 localcmd = cmd_fifo->read();
840 tmp = cmd_fifo->read();
841 rtc_yy = ((tmp >> 4) * 10) | (tmp & 0x0f);
843 tmp = cmd_fifo->read();
844 rtc_mm = ((tmp >> 4) * 10) | (tmp & 0x0f);
846 tmp = cmd_fifo->read();
847 rtc_dd = (((tmp & 0x30) >> 4) * 10) | (tmp & 0x0f);
849 tmp = cmd_fifo->read();
850 rtc_count24h = ((tmp & 0x08) != 0);
852 rtc_ispm = ((tmp & 0x04) != 0);
854 rtc_dayofweek = (tmp >> 4) % 0x07;
855 rtc_hour = ((tmp & 0x03) * 10);
857 tmp = cmd_fifo->read();
858 rtc_hour = rtc_hour | (tmp >> 4);
860 rtc_ispm = (rtc_hour >= 12);
862 rtc_minute = (tmp & 0x0f) * 10;
864 tmp = cmd_fifo->read();
865 rtc_minute = rtc_minute | (tmp >> 4);
866 rtc_sec = (tmp & 0x0f) * 10;
868 tmp = cmd_fifo->read();
869 rtc_sec = rtc_sec | (tmp >> 4);
873 if(event_key_rtc >= 0) {
874 cancel_event(this, event_key_rtc);
876 register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
877 rxrdy_status = false;
878 write_signals(&rxrdy, 0x00);
881 void KEYBOARD::get_rtc(void)
886 tmp = ((rtc_yy / 10) << 4) | (rtc_yy % 10);
887 data_fifo->write(tmp);
889 tmp = ((rtc_mm / 10) << 4) | (rtc_mm % 10);
890 data_fifo->write(tmp);
892 tmp = ((rtc_dd / 10) << 4) | (rtc_dd % 10);
893 tmp = tmp | (0 << 6); // leap
894 data_fifo->write(tmp);
896 tmp = rtc_dayofweek << 4;
897 tmp = tmp | (rtc_hour / 10);
905 data_fifo->write(tmp);
907 tmp = (rtc_hour % 10) << 4;
908 tmp = tmp | (rtc_minute / 10);
909 data_fifo->write(tmp);
911 tmp = (rtc_minute % 10) << 4;
912 tmp = tmp | (rtc_sec / 10);
913 data_fifo->write(tmp);
915 tmp = (rtc_sec % 10) << 4;
916 data_fifo->write(tmp);
920 write_signals(&rxrdy, 0xff);
923 const int rtc_month_days[12] = {
924 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
927 void KEYBOARD::rtc_count(void)
934 if(rtc_minute >= 60) {
938 rtc_ispm = (rtc_hour >= 12);
939 if(rtc_hour < 24) return;
942 if(rtc_hour < 12) return;
944 if(rtc_hour < 12) return;
954 if(rtc_dayofweek >= 7) rtc_dayofweek = 0;
955 if(rtc_dd > rtc_month_days[rtc_mm]){
956 if((rtc_mm ==1) && (rtc_dd == 29)) {
957 if((rtc_yy % 4) == 0) return;
964 if(rtc_yy >= 100) rtc_yy = 0;
970 #endif // FM77AV_VARIANTS
972 uint32_t KEYBOARD::read_signal(int id)
974 if(id == SIG_FM7KEY_BREAK_KEY) {
975 return break_pressed ? 0xfffffff : 0x00000000;
976 } else if(id == SIG_FM7KEY_LED_STATUS) {
978 _l = (ins_led_status) ? 0x00000001 : 0;
979 _l |= (kana_led_status) ? 0x00000002 : 0;
980 _l |= (caps_led_status) ? 0x00000004 : 0;
987 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
989 if(id == SIG_FM7KEY_SET_INSLED) {
990 ins_led_status = ((data & mask) != 0);
991 } else if(id == SIG_FM7KEY_OVERRIDE_PRESS_BREAK) {
992 override_break_key = ((data & mask) != 0);
994 #if defined(_FM77AV_VARIANTS)
995 else if(id == SIG_FM7KEY_PUSH_TO_ENCODER) {
997 * I refered XM7's sourcecode : VM/keyboard.c act of key-encoder.
998 * Thanks to Ryu.Takegami and PI.
1001 if(!key_ack_status) return; // If (not(ACK)) noop.
1003 if(cmd_fifo->full()) {
1006 if(cmd_fifo->empty()) {
1007 cmd_phase = data & 0xff;
1010 cmd_fifo->write(data & 0xff);
1011 count = cmd_fifo->count();
1013 rxrdy_status = false;
1014 key_ack_status = false;
1015 write_signals(&key_ack, 0x00);
1016 write_signals(&rxrdy, 0x00);
1022 if(keymode == KEYMODE_SCAN) key_down_main(true);
1032 case 2: // Set LED Phase
1035 if(keymode == KEYMODE_SCAN) key_down_main(true);
1040 case 3: // Get LED Phase
1059 case 0x80: // Communicate to/from RTC.
1064 if((data & 0xff) == 0) { // Get
1068 } else if((data & 0xff) == 1) { // Set
1069 rtc_set_flag = true;
1083 case 0x81: // Digitize.
1085 do_digitize(); // WILL Implement?
1092 set_screen_mode(); // WILL Implement?
1098 get_screen_mode(); // WILL Implement?
1104 set_brightness(); // WILL Implement?
1114 register_event(this, ID_KEYBOARD_ACK, 5, false, NULL); // Delay 5us until ACK is up.
1115 } else if(id == SIG_FM7KEY_RXRDY) {
1116 rxrdy_status = ((data & mask) != 0);
1117 //write_signals(&rxrdy, (rxrdy_status) ? 0xffffffff : 0x00000000);
1118 } else if(id == SIG_FM7KEY_ACK) {
1119 key_ack_status = ((data & mask) != 0);
1120 //write_signals(&key_ack, (key_ack_status) ? 0xffffffff : 0x00000000);
1126 uint32_t KEYBOARD::read_data8(uint32_t addr)
1128 uint32_t retval = 0xff;
1131 retval = get_keycode_high();
1134 retval = get_keycode_low();
1136 #if defined(_FM77AV_VARIANTS)
1138 retval = read_data_reg();
1141 retval = read_stat_reg();
1150 void KEYBOARD::write_data8(uint32_t addr, uint32_t data)
1153 #if defined(_FM77AV_VARIANTS)
1155 this->write_signal(SIG_FM7KEY_PUSH_TO_ENCODER, data, 0x000000ff);
1161 KEYBOARD::KEYBOARD(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
1163 #if defined(_FM77AV_VARIANTS)
1166 keycode_7 = 0xffffffff;
1168 ctrl_pressed = false;
1169 lshift_pressed = false;
1170 rshift_pressed = false;
1171 shift_pressed = false;
1172 graph_pressed = false;
1173 caps_pressed = false;
1174 kana_pressed = false;
1175 break_pressed = false;
1176 event_keyrepeat = -1;
1177 autokey_backup = 0x00;
1179 keymode = KEYMODE_STANDARD;
1180 override_break_key = false;
1181 #if defined(_FM77AV_VARIANTS)
1182 cmd_fifo = new FIFO(16);
1183 data_fifo = new FIFO(16);
1184 rxrdy_status = true;
1185 key_ack_status = false;
1186 initialize_output_signals(&rxrdy);
1187 initialize_output_signals(&key_ack);
1189 rtc_count24h = false;
1193 rtc_set_flag = false;
1201 event_hidden1_av = -1;
1204 key_fifo = new FIFO(512);
1207 initialize_output_signals(&break_line);
1208 initialize_output_signals(&int_line);
1210 ins_led_status = false;
1211 kana_led_status = false;
1212 caps_led_status = false;
1213 set_device_name(_T("KEYBOARD SUBSYSTEM"));
1216 void KEYBOARD::release(void)
1218 #if defined(_FM77AV_VARIANTS)
1219 cmd_fifo->release();
1220 data_fifo->release();
1224 key_fifo->release();
1230 KEYBOARD::~KEYBOARD()
1234 #define STATE_VERSION 9
1235 //#if defined(Q_OS_WIN)
1236 //DLL_PREFIX_I struct cur_time_s cur_time;
1239 bool KEYBOARD::decl_state(FILEIO *state_fio, bool loading)
1241 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1244 if(!state_fio->StateCheckInt32(this_device_id)) {
1248 state_fio->StateUint32(keycode_7);
1249 state_fio->StateInt32(keymode);
1250 state_fio->StateBool(ctrl_pressed);
1251 state_fio->StateBool(lshift_pressed);
1252 state_fio->StateBool(rshift_pressed);
1253 state_fio->StateBool(shift_pressed);
1254 state_fio->StateBool(graph_pressed);
1255 state_fio->StateBool(caps_pressed);
1256 state_fio->StateBool(kana_pressed);
1257 state_fio->StateBool(break_pressed);
1259 state_fio->StateInt32(event_keyrepeat);
1261 state_fio->StateUint8(scancode); // After V.4, uint8_t
1262 state_fio->StateUint8(datareg);
1263 state_fio->StateUint32(older_vk);
1265 state_fio->StateBool(repeat_mode);
1266 state_fio->StateInt32(repeat_time_short);
1267 state_fio->StateInt32(repeat_time_long);
1268 state_fio->StateUint8(repeat_keycode);
1270 #if defined(_FM77AV_VARIANTS)
1271 state_fio->StateInt32(event_key_rtc);
1272 state_fio->StateUint8(rtc_yy);
1273 state_fio->StateUint8(rtc_mm);
1274 state_fio->StateUint8(rtc_dd);
1275 state_fio->StateUint8(rtc_dayofweek);
1276 state_fio->StateUint8(rtc_hour);
1277 state_fio->StateUint8(rtc_minute);
1278 state_fio->StateUint8(rtc_sec);
1280 state_fio->StateBool(rtc_count24h);
1281 state_fio->StateBool(rtc_ispm);
1283 state_fio->StateBool(rtc_set);
1284 state_fio->StateBool(rtc_set_flag);
1285 state_fio->StateBool(rxrdy_status);
1286 state_fio->StateBool(key_ack_status);
1288 state_fio->StateBool(did_hidden_message_av_1);
1289 state_fio->StateInt32(event_hidden1_av);
1291 state_fio->StateInt32(cmd_phase);
1292 state_fio->StateUint16(hidden1_ptr);
1293 state_fio->StateInt32(beep_phase);
1295 if(!cmd_fifo->process_state(state_fio, loading)) {
1298 if(!data_fifo->process_state(state_fio, loading)) {
1301 if(!cur_time.process_state(state_fio, loading)) {
1305 if(!key_fifo->process_state(state_fio, loading)) {
1308 state_fio->StateInt32(event_int);
1309 state_fio->StateUint8(autokey_backup);
1311 state_fio->StateBool(ins_led_status);
1312 state_fio->StateBool(kana_led_status);
1313 state_fio->StateBool(caps_led_status);
1315 state_fio->StateBool(override_break_key);
1320 void KEYBOARD::save_state(FILEIO *state_fio)
1322 decl_state(state_fio, false);
1323 //state_fio->FputUint32_BE(STATE_VERSION);
1324 //state_fio->FputInt32_BE(this_device_id);
1325 this->out_debug_log(_T("Save State: KEYBOARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
1328 bool KEYBOARD::load_state(FILEIO *state_fio)
1332 //version = state_fio->FgetUint32_BE();
1333 //if(this_device_id != state_fio->FgetInt32_BE()) return false;
1334 //this->out_debug_log(_T("Load State: KEYBOARD: id=%d ver=%d\n"), this_device_id, version);
1335 bool mb = decl_state(state_fio, true);
1336 if(!mb) return false;