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"
13 #include "fm7_keyboard.h"
14 #include "keyboard_tables.h"
16 #if defined(_FM77AV_VARIANTS)
18 #include "fm77av_hidden_message_keyboard.h"
21 ID_KEYBOARD_RXRDY_OK = 1,
23 ID_KEYBOARD_RXRDY_BUSY,
24 ID_KEYBOARD_RTC_COUNTUP,
26 ID_KEYBOARD_AUTOREPEAT_FIRST,
27 ID_KEYBOARD_AUTOREPEAT,
28 ID_KEYBOARD_HIDDENMESSAGE_AV,
29 ID_KEYBOARD_HIDDEN_BEEP_ON,
30 ID_KEYBOARD_HIDDEN_BEEP_OFF,
31 ID_KEYBOARD_AUTO_8KEY_START,
32 ID_KEYBOARD_AUTO_8KEY_END,
33 ID_KEYBOARD_AUTO_5KEY_START,
34 ID_KEYBOARD_AUTO_5KEY_END,
35 ID_KEYBOARD_BREAK_ONESHOT,
42 // 0xd400(SUB) or 0xfd00(MAIN)
43 uint8_t KEYBOARD::get_keycode_high(void)
46 if((keycode_7 & 0x0100) != 0) data = 0x80;
50 // 0xd401(SUB) or 0xfd01(MAIN)
51 uint8_t KEYBOARD::get_keycode_low(void)
53 uint8_t data = keycode_7 & 0xff;
54 this->write_signals(&int_line, 0x00000000);
59 void KEYBOARD::turn_on_ins_led(void)
61 ins_led_status = true;
65 void KEYBOARD::turn_off_ins_led(void)
67 ins_led_status = false;
71 uint16_t KEYBOARD::vk2scancode(uint32_t vk)
75 if(vk == VK_PAUSE) vk = VK_KANJI; // Workaround some desktop environments for [ESC].
77 if(vk_matrix_106[i] == vk) return i;
79 } while(vk_matrix_106[i] != 0xffff);
83 bool KEYBOARD::isModifier(uint8_t sc)
85 if(((sc >= 0x52) && (sc <= 0x56)) || // CTRL LSHIFT RSHIFT CAPS GRPH
86 (sc == 0x5a) || (sc == 0x5c)) { // KANA BREAK
92 void KEYBOARD::set_modifiers(uint8_t sc, bool flag)
94 if(sc == 0x52) { // CTRL
96 } else if(sc == 0x53) { // LSHIFT
97 lshift_pressed = flag;
98 shift_pressed = lshift_pressed | rshift_pressed;
99 //printf("LSHIFT : %d\n", flag ? 1 : 0);
100 } else if(sc == 0x54) { // RSHIFT
101 rshift_pressed = flag;
102 shift_pressed = lshift_pressed | rshift_pressed;
103 //printf("RSHIFT : %d\n", flag ? 1 : 0);
104 } else if(sc == 0x56) { // GRPH
105 graph_pressed = flag;
106 } else if(sc == 0x55) { // CAPS
110 caps_pressed = false;
114 if(keymode == KEYMODE_STANDARD) caps_led_status = caps_pressed;
116 } else if(sc == 0x5a) { // KANA
120 kana_pressed = false;
124 if(keymode == KEYMODE_STANDARD) kana_led_status = kana_pressed;
126 } else if(sc == 0x5c) { // Break
127 if(!override_break_key) {
128 break_pressed = flag;
133 uint16_t KEYBOARD::scan2fmkeycode(uint8_t sc)
135 const struct key_tbl_t *keyptr = NULL;
140 if((sc == 0) || (sc >= 0x67)) return 0xffff;
141 // Set repeat flag(s)
142 if(shift_pressed && ctrl_pressed) {
156 if(keymode == KEYMODE_STANDARD) {
159 keyptr = ctrl_shift_key;
163 } else if(graph_pressed) {
165 keyptr = graph_shift_key;
169 } else if(kana_pressed) {
171 keyptr = kana_shift_key;
178 keyptr = standard_shift_key;
180 keyptr = standard_key;
184 #if defined(_FM77AV_VARIANTS)
185 else if(shift_pressed) {
186 // DO super-impose mode:
188 // F8 : IMPOSE (High brightness)
189 // F9 : IMPOSE (Low brightness)
192 if(keymode == KEYMODE_SCAN) {
193 retval = (uint16_t)sc;
195 } else if(keymode == KEYMODE_16BETA) { // Will Implement
198 keyptr = ctrl_shift_key_16beta;
200 keyptr = ctrl_key_16beta;
202 } else if(graph_pressed) {
204 keyptr = graph_shift_key_16beta;
206 keyptr = graph_key_16beta;
208 } else if(kana_pressed) {
210 keyptr = kana_shift_key_16beta;
212 keyptr = kana_key_16beta;
217 keyptr = standard_shift_key_16beta;
219 keyptr = standard_key_16beta;
223 #endif //_FM77AV_VARIANTS
226 if (keyptr == NULL) return 0xffff;
228 if(keyptr[i].phy == (uint16_t)sc) {
229 retval = keyptr[i].code;
233 } while(keyptr[i].phy != 0xffff);
234 if(keyptr[i].phy == 0xffff) return 0x00;
236 if((retval >= 'A') && (retval <= 'Z')) {
240 } else if((retval >= 'a') && (retval <= 'z')) {
249 void KEYBOARD::key_up_main(uint8_t bak_scancode)
251 bool stat_break = break_pressed;
253 if(bak_scancode == 0) return;
254 if((event_keyrepeat >= 0) && (repeat_keycode == bak_scancode)) { // Not Break
255 cancel_event(this, event_keyrepeat);
256 event_keyrepeat = -1;
259 if(keymode != KEYMODE_SCAN) {
260 if(this->isModifier(bak_scancode)) {
261 set_modifiers(bak_scancode, false);
262 if(break_pressed != stat_break) { // Break key UP.
263 this->write_signals(&break_line, 0x00);
266 if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
267 if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
268 switch(bak_scancode) {
275 ID_KEYBOARD_AUTO_8KEY_START,
276 10.0 * 1000.0, false, NULL);
279 if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
283 switch(bak_scancode) {
293 ID_KEYBOARD_AUTO_5KEY_START,
294 10.0 * 1000.0, false, NULL);
297 if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
304 if(bak_scancode != 0) { // Notify even key-up, when using SCAN mode.
305 uint8_t code = (bak_scancode & 0x7f) | 0x80;
306 if(this->isModifier(bak_scancode)) {
307 set_modifiers(bak_scancode, false);
309 #if defined(_FM77AV_VARIANTS)
310 if(bak_scancode != 0x5c) {
311 if(beep_phase == 1) {
312 if(break_pressed) this->write_signals(&break_line, 0x00);
313 break_pressed = false;
317 } else if(beep_phase == 2) {
320 ID_KEYBOARD_HIDDEN_BEEP_ON,
321 100.0, false, NULL); // 100.0 us is dummy.
325 } else { // 0x5c : BREAK is up.
327 if(stat_break) this->write_signals(&break_line, 0x00);
331 key_fifo->write(code);
332 scancode = bak_scancode;
338 void KEYBOARD::key_up(uint32_t vk)
340 uint8_t bak_scancode = (uint8_t)(vk2scancode(vk) & 0x00ff);
341 key_up_main(bak_scancode);
344 void KEYBOARD::key_down(uint32_t vk)
346 if(older_vk == vk) return;
349 scancode = (uint8_t)vk2scancode(vk);
350 #if defined(_FM77AV_VARIANTS)
351 // Below are FM-77AV's hidden message , see :
352 // https://twitter.com/maruan/status/499558392092831745
353 //if(caps_pressed && kana_pressed) {
354 // if(ctrl_pressed && lshift_pressed && rshift_pressed && graph_pressed) {
355 if(caps_pressed && kana_pressed && graph_pressed && shift_pressed && ctrl_pressed && !did_hidden_message_av_1) { // IT's deprecated key pressing
356 if(scancode == 0x15) { // "T"
357 if(event_hidden1_av < 0) {
359 did_hidden_message_av_1 = true;
361 ID_KEYBOARD_HIDDENMESSAGE_AV,
362 130.0 * 1000, true, &event_hidden1_av);
371 void KEYBOARD::key_down_main(bool repeat_auto_key)
373 bool stat_break = break_pressed;
375 if(scancode == 0) return;
376 if(keymode == KEYMODE_SCAN) {
377 code = scancode & 0x7f;
378 if(this->isModifier(scancode)) { // modifiers
379 set_modifiers(scancode, true);
381 #if defined(_FM77AV_VARIANTS)
385 // It's dirty hack for AMNORK ; Set dead zone for FIRQ to 0.25sec.
386 // I wish to replace this solution to more simple.
388 ID_KEYBOARD_BREAK_ONESHOT,
389 250.0 * 1000.0, false, NULL);
390 } else if(beep_phase == 1) {
392 if(break_pressed) this->write_signals(&break_line, 0x00);
393 break_pressed = false;
395 code = 0x7f; // Special
403 key_fifo->write(code);
404 // NOTE: With scan key code mode, auto repeat seems to be not effectable.
405 // See : http://hanabi.2ch.net/test/read.cgi/i4004/1430836648/607
409 if(this->isModifier(scancode)) { // modifiers
410 set_modifiers(scancode, true);
411 if(break_pressed != stat_break) { // Break key Down.
412 this->write_signals(&break_line, 0xff);
416 code = scan2fmkeycode(scancode);
417 if((code > 0x3ff) || (code == 0)) return;
418 if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
419 if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
426 autokey_backup = scancode;
439 autokey_backup = scancode;
444 autokey_backup = 0x00;
447 key_fifo->write(code);
448 if((scancode < 0x5c) && repeat_auto_key) {
449 double usec = (double)repeat_time_long * 1000.0;
450 if((repeat_keycode == 0) && repeat_mode) {
451 if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
452 event_keyrepeat = -1;
454 ID_KEYBOARD_AUTOREPEAT_FIRST,
455 usec, false, &event_keyrepeat);
457 repeat_keycode = scancode;
463 #if defined(_FM77AV_VARIANTS)
464 void KEYBOARD::adjust_rtc(void)
466 get_host_time(&cur_time);
467 rtc_yy = cur_time.year % 100;
468 rtc_mm = cur_time.month;
469 rtc_dd = cur_time.day;
471 rtc_dayofweek = cur_time.day_of_week;
473 rtc_ispm = (cur_time.hour >= 12) ? true : false;
474 rtc_hour = cur_time.hour % 12;
477 rtc_hour = cur_time.hour;
479 rtc_minute = cur_time.minute;
480 rtc_sec = cur_time.second;
481 if(event_key_rtc >= 0) {
482 cancel_event(this, event_key_rtc);
484 register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
488 void KEYBOARD::do_repeatkey(uint8_t sc)
491 if((sc == 0) || (sc >= 0x5c)) return; // scancode overrun.
493 if(event_keyrepeat >= 0) {
494 cancel_event(this, event_keyrepeat);
495 event_keyrepeat = -1;
499 if(keymode == KEYMODE_SCAN) {
500 code = (uint16_t)(sc & 0x7f);
501 key_fifo->write((uint32_t)code); // Make
502 //key_fifo->write((uint32_t)(code | 0x80)); // Break
504 code = scan2fmkeycode(sc);
506 key_fifo->write((uint32_t)code);
511 void KEYBOARD::event_callback(int event_id, int err)
513 #if defined(_FM77AV_VARIANTS)
514 if(event_id == ID_KEYBOARD_RXRDY_OK) {
516 write_signals(&rxrdy, 0xff);
517 } else if(event_id == ID_KEYBOARD_RXRDY_BUSY) {
518 rxrdy_status = false;
519 write_signals(&rxrdy, 0x00);
520 } else if(event_id == ID_KEYBOARD_ACK) {
521 key_ack_status = true;
522 write_signals(&key_ack, 0xff);
523 } else if(event_id == ID_KEYBOARD_RTC_COUNTUP) {
525 } else if(event_id == ID_KEYBOARD_HIDDENMESSAGE_AV) {
526 if(hidden_message_77av_1[hidden1_ptr] == 0x00) {
527 cancel_event(this, event_hidden1_av);
528 event_hidden1_av = -1;
531 key_fifo->write(hidden_message_77av_1[hidden1_ptr++]);
533 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
534 beep->write_signal(SIG_BEEP_ON, 1, 1);
536 ID_KEYBOARD_HIDDEN_BEEP_OFF,
537 25.0 * 1000.0, false, NULL);
538 } else if(event_id == ID_KEYBOARD_HIDDEN_BEEP_ON) {
539 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
540 beep->write_signal(SIG_BEEP_ON, 1, 1);
542 ID_KEYBOARD_HIDDEN_BEEP_OFF,
543 25.0 * 1000.0, false, NULL);
545 } else if(event_id == ID_KEYBOARD_HIDDEN_BEEP_OFF) {
546 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
547 beep->write_signal(SIG_BEEP_ON, 0, 1);
548 } else if(event_id == ID_KEYBOARD_BREAK_ONESHOT) {
549 if(break_pressed) this->write_signals(&break_line, 0xff);
552 if(event_id == ID_KEYBOARD_AUTOREPEAT_FIRST) {
553 double usec = (double)repeat_time_short * 1000.0;
555 do_repeatkey(repeat_keycode);
557 ID_KEYBOARD_AUTOREPEAT,
558 usec, true, &event_keyrepeat);
560 } else if(event_id == ID_KEYBOARD_AUTOREPEAT){
561 if(repeat_keycode != 0) {
562 do_repeatkey(repeat_keycode);
564 cancel_event(this, event_keyrepeat);
565 event_keyrepeat = -1;
567 } else if(event_id == ID_KEYBOARD_INT) {
568 if(!(key_fifo->empty())) {
569 keycode_7 = key_fifo->read();
570 this->write_signals(&int_line, 0xffffffff);
572 } else if(event_id == ID_KEYBOARD_AUTO_8KEY_START) {
573 if(keymode != KEYMODE_SCAN) {
574 scancode = 0x3b; // 8
575 autokey_backup = 0x00;
576 key_down_main(false);
578 ID_KEYBOARD_AUTO_8KEY_END,
579 50.0 * 1000.0, false, NULL);
581 } else if(event_id == ID_KEYBOARD_AUTO_8KEY_END) {
582 key_up_main(0x3b); // 8
583 } else if(event_id == ID_KEYBOARD_AUTO_5KEY_START) {
584 if(keymode != KEYMODE_SCAN) {
585 scancode = 0x3f; // 5
586 autokey_backup = 0x00;
587 key_down_main(false);
589 ID_KEYBOARD_AUTO_5KEY_END,
590 50.0 * 1000.0, false, NULL);
592 } else if(event_id == ID_KEYBOARD_AUTO_5KEY_END) {
593 key_up_main(0x3f); // 5
598 void KEYBOARD::reset_unchange_mode(void)
600 repeat_time_short = 70; // mS
601 repeat_time_long = 700; // mS
605 lshift_pressed = false;
606 rshift_pressed = false;
607 shift_pressed = false;
608 ctrl_pressed = false;
609 graph_pressed = false;
610 kana_pressed = false;
611 caps_pressed = false;
612 ins_led_status = false;
613 kana_led_status = false;
614 caps_led_status = false;
616 repeat_keycode = 0x00;
617 autokey_backup = 0x00;
619 if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
621 #if defined(_FM77AV_VARIANTS)
624 if(event_key_rtc >= 0) {
625 cancel_event(this, event_key_rtc);
627 register_event(this,ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
630 if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
631 event_keyrepeat = -1;
633 if(event_hidden1_av >= 0) cancel_event(this, event_hidden1_av);
634 event_hidden1_av = -1;
638 this->write_signals(&break_line, 0x00);
639 #if defined(_FM77AV_VARIANTS)
640 rxrdy_status = false;
641 key_ack_status = true;
642 this->write_signals(&rxrdy, 0x00);
643 this->write_signals(&key_ack, 0xff);
648 void KEYBOARD::reset(void)
650 keymode = KEYMODE_STANDARD;
653 keycode_7 = 0xffffffff;
655 reset_unchange_mode();
656 this->write_signals(&int_line, 0x00000000);
658 #if defined(_FM77AV_VARIANTS)
660 did_hidden_message_av_1 = false;
664 if(override_break_key) write_signals(&break_line, (break_pressed) ? 0xff : 0);
666 if(event_int >= 0) cancel_event(this, event_int);
669 20000.0, true, &event_int);
673 #if defined(_FM77AV_VARIANTS)
675 uint8_t KEYBOARD::read_data_reg(void)
677 if(!data_fifo->empty()) {
678 datareg = data_fifo->read() & 0xff;
680 if(!data_fifo->empty()) {
682 write_signals(&rxrdy, 0xff);
684 rxrdy_status = false;
685 write_signals(&rxrdy, 0x00);
691 uint8_t KEYBOARD::read_stat_reg(void)
697 if(!key_ack_status) {
700 // Digityze : bit0 = '0' when waiting,
704 void KEYBOARD::set_mode(void)
706 int count = cmd_fifo->count();
709 if(count < 2) return;
710 cmd = cmd_fifo->read();
711 mode = cmd_fifo->read();
712 if(mode <= KEYMODE_SCAN) {
714 //printf("Keymode : %d\n", keymode);
715 //reset_unchange_mode();
717 autokey_backup = 0x00;
718 this->write_signals(&break_line, 0x00);
719 if(scancode != 0) key_down_main(true);
722 data_fifo->clear(); // right?
723 rxrdy_status = false;
724 write_signals(&rxrdy, 0x00);
727 void KEYBOARD::get_mode(void)
731 cmd = cmd_fifo->read();
732 if(data_fifo->full()) {
733 dummy = data_fifo->read();
735 data_fifo->write(keymode);
737 write_signals(&rxrdy, 0xff);
740 void KEYBOARD::set_leds(void)
742 int count = cmd_fifo->count();
745 if(count < 2) return;
746 cmd = cmd_fifo->read();
747 ledvar = cmd_fifo->read();
749 if((ledvar & 0x02) != 0) {
751 kana_pressed = ((ledvar & 0x01) == 0);
752 kana_led_status = kana_pressed;
755 caps_pressed = ((ledvar & 0x01) == 0);
756 caps_led_status = caps_pressed;
760 data_fifo->clear(); // right?
761 rxrdy_status = false;
762 write_signals(&rxrdy, 0x00);
765 void KEYBOARD::get_leds(void)
767 uint8_t ledvar = 0x00;
769 ledvar |= caps_pressed ? 0x01 : 0x00;
770 ledvar |= kana_pressed ? 0x02 : 0x00;
771 data_fifo->write(ledvar);
774 write_signals(&rxrdy, 0xff);
777 void KEYBOARD::set_repeat_type(void)
782 cmd = cmd_fifo->read();
783 if(!cmd_fifo->empty()) {
784 modeval = cmd_fifo->read();
785 if((modeval < 2) && (modeval >= 0)) {
786 repeat_mode = (modeval == 0);
796 rxrdy_status = false;
797 write_signals(&rxrdy, 0x00);
800 void KEYBOARD::set_repeat_time(void)
803 uint32_t time_high = 0;
804 uint32_t time_low = 0;
805 cmd = cmd_fifo->read();
806 if(cmd_fifo->empty()) goto _end;
807 time_high = cmd_fifo->read();
808 if(cmd_fifo->empty()) goto _end;
809 time_low = cmd_fifo->read();
811 if((time_high == 0) || (time_low == 0)) {
812 repeat_time_long = 700;
813 repeat_time_short = 70;
815 repeat_time_long = (int)time_high * 10;
816 repeat_time_short = (int)time_low * 10;
820 rxrdy_status = false;
821 write_signals(&rxrdy, 0x00);
824 void KEYBOARD::set_rtc(void)
829 if(cmd_fifo->count() < 9) return;
830 cmd = cmd_fifo->read();
831 localcmd = cmd_fifo->read();
833 tmp = cmd_fifo->read();
834 rtc_yy = ((tmp >> 4) * 10) | (tmp & 0x0f);
836 tmp = cmd_fifo->read();
837 rtc_mm = ((tmp >> 4) * 10) | (tmp & 0x0f);
839 tmp = cmd_fifo->read();
840 rtc_dd = (((tmp & 0x30) >> 4) * 10) | (tmp & 0x0f);
842 tmp = cmd_fifo->read();
843 rtc_count24h = ((tmp & 0x08) != 0);
845 rtc_ispm = ((tmp & 0x04) != 0);
847 rtc_dayofweek = (tmp >> 4) % 0x07;
848 rtc_hour = ((tmp & 0x03) * 10);
850 tmp = cmd_fifo->read();
851 rtc_hour = rtc_hour | (tmp >> 4);
853 rtc_ispm = (rtc_hour >= 12);
855 rtc_minute = (tmp & 0x0f) * 10;
857 tmp = cmd_fifo->read();
858 rtc_minute = rtc_minute | (tmp >> 4);
859 rtc_sec = (tmp & 0x0f) * 10;
861 tmp = cmd_fifo->read();
862 rtc_sec = rtc_sec | (tmp >> 4);
866 if(event_key_rtc >= 0) {
867 cancel_event(this, event_key_rtc);
869 register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
870 rxrdy_status = false;
871 write_signals(&rxrdy, 0x00);
874 void KEYBOARD::get_rtc(void)
879 tmp = ((rtc_yy / 10) << 4) | (rtc_yy % 10);
880 data_fifo->write(tmp);
882 tmp = ((rtc_mm / 10) << 4) | (rtc_mm % 10);
883 data_fifo->write(tmp);
885 tmp = ((rtc_dd / 10) << 4) | (rtc_dd % 10);
886 tmp = tmp | (0 << 6); // leap
887 data_fifo->write(tmp);
889 tmp = rtc_dayofweek << 4;
890 tmp = tmp | (rtc_hour / 10);
898 data_fifo->write(tmp);
900 tmp = (rtc_hour % 10) << 4;
901 tmp = tmp | (rtc_minute / 10);
902 data_fifo->write(tmp);
904 tmp = (rtc_minute % 10) << 4;
905 tmp = tmp | (rtc_sec / 10);
906 data_fifo->write(tmp);
908 tmp = (rtc_sec % 10) << 4;
909 data_fifo->write(tmp);
913 write_signals(&rxrdy, 0xff);
916 const int rtc_month_days[12] = {
917 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
920 void KEYBOARD::rtc_count(void)
927 if(rtc_minute >= 60) {
931 rtc_ispm = (rtc_hour >= 12);
932 if(rtc_hour < 24) return;
935 if(rtc_hour < 12) return;
937 if(rtc_hour < 12) return;
947 if(rtc_dayofweek >= 7) rtc_dayofweek = 0;
948 if(rtc_dd > rtc_month_days[rtc_mm]){
949 if((rtc_mm ==1) && (rtc_dd == 29)) {
950 if((rtc_yy % 4) == 0) return;
957 if(rtc_yy >= 100) rtc_yy = 0;
963 #endif // FM77AV_VARIANTS
965 uint32_t KEYBOARD::read_signal(int id)
967 if(id == SIG_FM7KEY_BREAK_KEY) {
968 return break_pressed ? 0xfffffff : 0x00000000;
969 } else if(id == SIG_FM7KEY_LED_STATUS) {
971 _l = (ins_led_status) ? 0x00000001 : 0;
972 _l |= (kana_led_status) ? 0x00000002 : 0;
973 _l |= (caps_led_status) ? 0x00000004 : 0;
980 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
982 if(id == SIG_FM7KEY_SET_INSLED) {
983 ins_led_status = ((data & mask) != 0);
984 } else if(id == SIG_FM7KEY_OVERRIDE_PRESS_BREAK) {
985 override_break_key = ((data & mask) != 0);
987 #if defined(_FM77AV_VARIANTS)
988 else if(id == SIG_FM7KEY_PUSH_TO_ENCODER) {
990 * I refered XM7's sourcecode : VM/keyboard.c act of key-encoder.
991 * Thanks to Ryu.Takegami and PI.
994 if(!key_ack_status) return; // If (not(ACK)) noop.
996 if(cmd_fifo->full()) {
999 if(cmd_fifo->empty()) {
1000 cmd_phase = data & 0xff;
1003 cmd_fifo->write(data & 0xff);
1004 count = cmd_fifo->count();
1006 rxrdy_status = false;
1007 key_ack_status = false;
1008 write_signals(&key_ack, 0x00);
1009 write_signals(&rxrdy, 0x00);
1015 if(keymode == KEYMODE_SCAN) key_down_main(true);
1025 case 2: // Set LED Phase
1028 if(keymode == KEYMODE_SCAN) key_down_main(true);
1033 case 3: // Get LED Phase
1052 case 0x80: // Communicate to/from RTC.
1057 if((data & 0xff) == 0) { // Get
1061 } else if((data & 0xff) == 1) { // Set
1062 rtc_set_flag = true;
1076 case 0x81: // Digitize.
1078 do_digitize(); // WILL Implement?
1085 set_screen_mode(); // WILL Implement?
1091 get_screen_mode(); // WILL Implement?
1097 set_brightness(); // WILL Implement?
1107 register_event(this, ID_KEYBOARD_ACK, 5, false, NULL); // Delay 5us until ACK is up.
1108 } else if(id == SIG_FM7KEY_RXRDY) {
1109 rxrdy_status = ((data & mask) != 0);
1110 //write_signals(&rxrdy, (rxrdy_status) ? 0xffffffff : 0x00000000);
1111 } else if(id == SIG_FM7KEY_ACK) {
1112 key_ack_status = ((data & mask) != 0);
1113 //write_signals(&key_ack, (key_ack_status) ? 0xffffffff : 0x00000000);
1119 uint32_t KEYBOARD::read_data8(uint32_t addr)
1121 uint32_t retval = 0xff;
1124 retval = get_keycode_high();
1127 retval = get_keycode_low();
1129 #if defined(_FM77AV_VARIANTS)
1131 retval = read_data_reg();
1134 retval = read_stat_reg();
1143 void KEYBOARD::write_data8(uint32_t addr, uint32_t data)
1146 #if defined(_FM77AV_VARIANTS)
1148 this->write_signal(SIG_FM7KEY_PUSH_TO_ENCODER, data, 0x000000ff);
1154 KEYBOARD::KEYBOARD(VM_TEMPLATE* parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
1156 #if defined(_FM77AV_VARIANTS)
1159 keycode_7 = 0xffffffff;
1161 ctrl_pressed = false;
1162 lshift_pressed = false;
1163 rshift_pressed = false;
1164 shift_pressed = false;
1165 graph_pressed = false;
1166 caps_pressed = false;
1167 kana_pressed = false;
1168 break_pressed = false;
1169 event_keyrepeat = -1;
1170 autokey_backup = 0x00;
1172 keymode = KEYMODE_STANDARD;
1173 override_break_key = false;
1174 #if defined(_FM77AV_VARIANTS)
1175 cmd_fifo = new FIFO(16);
1176 data_fifo = new FIFO(16);
1177 rxrdy_status = true;
1178 key_ack_status = false;
1179 initialize_output_signals(&rxrdy);
1180 initialize_output_signals(&key_ack);
1182 rtc_count24h = false;
1186 rtc_set_flag = false;
1194 event_hidden1_av = -1;
1197 key_fifo = new FIFO(512);
1200 initialize_output_signals(&break_line);
1201 initialize_output_signals(&int_line);
1203 ins_led_status = false;
1204 kana_led_status = false;
1205 caps_led_status = false;
1206 set_device_name(_T("KEYBOARD SUBSYSTEM"));
1209 void KEYBOARD::release(void)
1211 #if defined(_FM77AV_VARIANTS)
1212 cmd_fifo->release();
1213 data_fifo->release();
1217 key_fifo->release();
1223 KEYBOARD::~KEYBOARD()
1227 #define STATE_VERSION 8
1228 //#if defined(Q_OS_WIN)
1229 //DLL_PREFIX_I struct cur_time_s cur_time;
1232 #include "../../statesub.h"
1234 void KEYBOARD::decl_state()
1236 #if defined(_FM77AV_VARIANTS)
1237 enter_decl_state(STATE_VERSION, _T("KEYBOARD_AND_RTC"));
1239 enter_decl_state(STATE_VERSION, _T("KEYBOARD"));
1242 DECL_STATE_ENTRY_UINT32(keycode_7);
1243 DECL_STATE_ENTRY_INT32(keymode);
1245 DECL_STATE_ENTRY_BOOL(ctrl_pressed);
1246 DECL_STATE_ENTRY_BOOL(lshift_pressed);
1247 DECL_STATE_ENTRY_BOOL(rshift_pressed);
1248 DECL_STATE_ENTRY_BOOL(shift_pressed);
1249 DECL_STATE_ENTRY_BOOL(graph_pressed);
1250 DECL_STATE_ENTRY_BOOL(caps_pressed);
1251 DECL_STATE_ENTRY_BOOL(kana_pressed);
1252 DECL_STATE_ENTRY_BOOL(break_pressed);
1254 DECL_STATE_ENTRY_INT32(event_keyrepeat);
1256 DECL_STATE_ENTRY_UINT8(scancode); // After V.4, uint8_t
1257 DECL_STATE_ENTRY_UINT8(datareg);
1258 DECL_STATE_ENTRY_UINT32(older_vk);
1260 DECL_STATE_ENTRY_BOOL(repeat_mode);
1261 DECL_STATE_ENTRY_INT32(repeat_time_short);
1262 DECL_STATE_ENTRY_INT32(repeat_time_long);
1263 DECL_STATE_ENTRY_UINT8(repeat_keycode);
1265 #if defined(_FM77AV_VARIANTS)
1266 DECL_STATE_ENTRY_INT32(event_key_rtc);
1268 DECL_STATE_ENTRY_UINT8(rtc_yy);
1269 DECL_STATE_ENTRY_UINT8(rtc_mm);
1270 DECL_STATE_ENTRY_UINT8(rtc_dd);
1271 DECL_STATE_ENTRY_UINT8(rtc_dayofweek);
1272 DECL_STATE_ENTRY_UINT8(rtc_hour);
1273 DECL_STATE_ENTRY_UINT8(rtc_minute);
1274 DECL_STATE_ENTRY_UINT8(rtc_sec);
1276 DECL_STATE_ENTRY_BOOL(rtc_count24h);
1277 DECL_STATE_ENTRY_BOOL(rtc_ispm);
1279 DECL_STATE_ENTRY_BOOL(rtc_set);
1280 DECL_STATE_ENTRY_BOOL(rtc_set_flag);
1281 DECL_STATE_ENTRY_BOOL(rxrdy_status);
1282 DECL_STATE_ENTRY_BOOL(key_ack_status);
1284 DECL_STATE_ENTRY_BOOL(did_hidden_message_av_1);
1285 DECL_STATE_ENTRY_INT32(event_hidden1_av);
1287 DECL_STATE_ENTRY_INT32(cmd_phase);
1288 DECL_STATE_ENTRY_UINT16(hidden1_ptr);
1289 DECL_STATE_ENTRY_INT32(beep_phase);
1290 //cmd_fifo->save_state((void *)state_fio);
1291 //data_fifo->save_state((void *)state_fio);
1292 //cur_time.save_state((void *)state_fio);
1294 #if defined(_FM77AV_VARIANTS)
1295 DECL_STATE_ENTRY_FIFO(cmd_fifo);
1296 DECL_STATE_ENTRY_FIFO(data_fifo);
1297 DECL_STATE_ENTRY_CUR_TIME_T(cur_time);
1299 DECL_STATE_ENTRY_FIFO(key_fifo);
1300 DECL_STATE_ENTRY_INT32(event_int);
1301 //key_fifo->save_state((void *)state_fio);
1302 DECL_STATE_ENTRY_UINT8(autokey_backup);
1304 DECL_STATE_ENTRY_BOOL(ins_led_status);
1305 DECL_STATE_ENTRY_BOOL(kana_led_status);
1306 DECL_STATE_ENTRY_BOOL(caps_led_status);
1308 DECL_STATE_ENTRY_BOOL(override_break_key);
1313 void KEYBOARD::save_state(FILEIO *state_fio)
1315 if(state_entry != NULL) {
1316 state_entry->save_state(state_fio);
1318 //state_fio->FputUint32_BE(STATE_VERSION);
1319 //state_fio->FputInt32_BE(this_device_id);
1320 this->out_debug_log(_T("Save State: KEYBOARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
1323 bool KEYBOARD::load_state(FILEIO *state_fio)
1327 //version = state_fio->FgetUint32_BE();
1328 //if(this_device_id != state_fio->FgetInt32_BE()) return false;
1329 //this->out_debug_log(_T("Load State: KEYBOARD: id=%d ver=%d\n"), this_device_id, version);
1331 if(state_entry != NULL) {
1332 mb = state_entry->load_state(state_fio);
1334 if(!mb) return false;