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"
11 #include "fm7_keyboard.h"
13 #include "keyboard_tables.h"
14 #if defined(_FM77AV_VARIANTS)
16 #include "fm77av_hidden_message_keyboard.h"
19 ID_KEYBOARD_RXRDY_OK = 1,
21 ID_KEYBOARD_RXRDY_BUSY,
22 ID_KEYBOARD_RTC_COUNTUP,
24 ID_KEYBOARD_AUTOREPEAT_FIRST,
25 ID_KEYBOARD_AUTOREPEAT,
26 ID_KEYBOARD_HIDDENMESSAGE_AV,
27 ID_KEYBOARD_HIDDEN_BEEP_ON,
28 ID_KEYBOARD_HIDDEN_BEEP_OFF,
29 ID_KEYBOARD_AUTO_8KEY_START,
30 ID_KEYBOARD_AUTO_8KEY_END,
31 ID_KEYBOARD_AUTO_5KEY_START,
32 ID_KEYBOARD_AUTO_5KEY_END,
33 ID_KEYBOARD_BREAK_ONESHOT,
40 // 0xd400(SUB) or 0xfd00(MAIN)
41 uint8_t KEYBOARD::get_keycode_high(void)
44 if((keycode_7 & 0x0100) != 0) data = 0x80;
48 // 0xd401(SUB) or 0xfd01(MAIN)
49 uint8_t KEYBOARD::get_keycode_low(void)
51 uint8_t data = keycode_7 & 0xff;
52 this->write_signals(&int_line, 0x00000000);
57 void KEYBOARD::turn_on_ins_led(void)
59 this->write_signals(&ins_led, 0xff);
63 void KEYBOARD::turn_off_ins_led(void)
65 this->write_signals(&ins_led, 0x00);
69 uint16_t KEYBOARD::vk2scancode(uint32_t vk)
73 if(vk == VK_PAUSE) vk = VK_KANJI; // Workaround some desktop environments for [ESC].
75 if(vk_matrix_106[i] == vk) return i;
77 } while(vk_matrix_106[i] != 0xffff);
81 bool KEYBOARD::isModifier(uint8_t sc)
83 if(((sc >= 0x52) && (sc <= 0x56)) || // CTRL LSHIFT RSHIFT CAPS GRPH
84 (sc == 0x5a) || (sc == 0x5c)) { // KANA BREAK
90 void KEYBOARD::set_modifiers(uint8_t sc, bool flag)
92 if(sc == 0x52) { // CTRL
94 } else if(sc == 0x53) { // LSHIFT
95 lshift_pressed = flag;
96 shift_pressed = lshift_pressed | rshift_pressed;
97 //printf("LSHIFT : %d\n", flag ? 1 : 0);
98 } else if(sc == 0x54) { // RSHIFT
99 rshift_pressed = flag;
100 shift_pressed = lshift_pressed | rshift_pressed;
101 //printf("RSHIFT : %d\n", flag ? 1 : 0);
102 } else if(sc == 0x56) { // GRPH
103 graph_pressed = flag;
104 } else if(sc == 0x55) { // CAPS
108 caps_pressed = false;
112 if(keymode == KEYMODE_STANDARD) this->write_signals(&caps_led, caps_pressed ? 0xff : 0x00);
114 } else if(sc == 0x5a) { // KANA
118 kana_pressed = false;
122 if(keymode == KEYMODE_STANDARD) this->write_signals(&kana_led, kana_pressed ? 0xff : 0x00);
124 } else if(sc == 0x5c) { // Break
125 break_pressed = flag;
129 uint16_t KEYBOARD::scan2fmkeycode(uint8_t sc)
131 const struct key_tbl_t *keyptr = NULL;
136 if((sc == 0) || (sc >= 0x67)) return 0xffff;
137 // Set repeat flag(s)
138 if(shift_pressed && ctrl_pressed) {
152 if(keymode == KEYMODE_STANDARD) {
155 keyptr = ctrl_shift_key;
159 } else if(graph_pressed) {
161 keyptr = graph_shift_key;
165 } else if(kana_pressed) {
167 keyptr = kana_shift_key;
174 keyptr = standard_shift_key;
176 keyptr = standard_key;
180 #if defined(_FM77AV_VARIANTS)
181 else if(shift_pressed) {
182 // DO super-impose mode:
184 // F8 : IMPOSE (High brightness)
185 // F9 : IMPOSE (Low brightness)
188 if(keymode == KEYMODE_SCAN) {
189 retval = (uint16_t)sc;
191 } else if(keymode == KEYMODE_16BETA) { // Will Implement
194 keyptr = ctrl_shift_key_16beta;
196 keyptr = ctrl_key_16beta;
198 } else if(graph_pressed) {
200 keyptr = graph_shift_key_16beta;
202 keyptr = graph_key_16beta;
204 } else if(kana_pressed) {
206 keyptr = kana_shift_key_16beta;
208 keyptr = kana_key_16beta;
213 keyptr = standard_shift_key_16beta;
215 keyptr = standard_key_16beta;
219 #endif //_FM77AV_VARIANTS
222 if (keyptr == NULL) return 0xffff;
224 if(keyptr[i].phy == (uint16_t)sc) {
225 retval = keyptr[i].code;
229 } while(keyptr[i].phy != 0xffff);
230 if(keyptr[i].phy == 0xffff) return 0x00;
232 if((retval >= 'A') && (retval <= 'Z')) {
236 } else if((retval >= 'a') && (retval <= 'z')) {
245 void KEYBOARD::key_up_main(uint8_t bak_scancode)
247 bool stat_break = break_pressed;
249 if(bak_scancode == 0) return;
250 if((event_keyrepeat >= 0) && (repeat_keycode == bak_scancode)) { // Not Break
251 cancel_event(this, event_keyrepeat);
252 event_keyrepeat = -1;
255 if(keymode != KEYMODE_SCAN) {
256 if(this->isModifier(bak_scancode)) {
257 set_modifiers(bak_scancode, false);
258 if(break_pressed != stat_break) { // Break key UP.
259 this->write_signals(&break_line, 0x00);
262 if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
263 if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
264 switch(bak_scancode) {
271 ID_KEYBOARD_AUTO_8KEY_START,
272 10.0 * 1000.0, false, NULL);
275 if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
279 switch(bak_scancode) {
289 ID_KEYBOARD_AUTO_5KEY_START,
290 10.0 * 1000.0, false, NULL);
293 if(autokey_backup != 0) key_fifo->write(scan2fmkeycode(autokey_backup));
300 if(bak_scancode != 0) { // Notify even key-up, when using SCAN mode.
301 uint8_t code = (bak_scancode & 0x7f) | 0x80;
302 if(this->isModifier(bak_scancode)) {
303 set_modifiers(bak_scancode, false);
305 #if defined(_FM77AV_VARIANTS)
306 if(bak_scancode != 0x5c) {
307 if(beep_phase == 1) {
308 if(break_pressed) this->write_signals(&break_line, 0x00);
309 break_pressed = false;
313 } else if(beep_phase == 2) {
316 ID_KEYBOARD_HIDDEN_BEEP_ON,
317 100.0, false, NULL); // 100.0 us is dummy.
321 } else { // 0x5c : BREAK is up.
323 if(stat_break) this->write_signals(&break_line, 0x00);
327 key_fifo->write(code);
328 scancode = bak_scancode;
334 void KEYBOARD::key_up(uint32_t vk)
336 uint8_t bak_scancode = (uint8_t)(vk2scancode(vk) & 0x00ff);
337 key_up_main(bak_scancode);
340 void KEYBOARD::key_down(uint32_t vk)
342 if(older_vk == vk) return;
345 scancode = (uint8_t)vk2scancode(vk);
346 #if defined(_FM77AV_VARIANTS)
347 // Below are FM-77AV's hidden message , see :
348 // https://twitter.com/maruan/status/499558392092831745
349 //if(caps_pressed && kana_pressed) {
350 // if(ctrl_pressed && lshift_pressed && rshift_pressed && graph_pressed) {
351 if(caps_pressed && kana_pressed && graph_pressed && shift_pressed && ctrl_pressed && !did_hidden_message_av_1) { // IT's deprecated key pressing
352 if(scancode == 0x15) { // "T"
353 if(event_hidden1_av < 0) {
355 did_hidden_message_av_1 = true;
357 ID_KEYBOARD_HIDDENMESSAGE_AV,
358 130.0 * 1000, true, &event_hidden1_av);
367 void KEYBOARD::key_down_main(bool repeat_auto_key)
369 bool stat_break = break_pressed;
371 if(scancode == 0) return;
372 if(keymode == KEYMODE_SCAN) {
373 code = scancode & 0x7f;
374 if(this->isModifier(scancode)) { // modifiers
375 set_modifiers(scancode, true);
377 #if defined(_FM77AV_VARIANTS)
381 // It's dirty hack for AMNORK ; Set dead zone for FIRQ to 0.25sec.
382 // I wish to replace this solution to more simple.
384 ID_KEYBOARD_BREAK_ONESHOT,
385 250.0 * 1000.0, false, NULL);
386 } else if(beep_phase == 1) {
388 if(break_pressed) this->write_signals(&break_line, 0x00);
389 break_pressed = false;
391 code = 0x7f; // Special
399 key_fifo->write(code);
400 // NOTE: With scan key code mode, auto repeat seems to be not effectable.
401 // See : http://hanabi.2ch.net/test/read.cgi/i4004/1430836648/607
405 if(this->isModifier(scancode)) { // modifiers
406 set_modifiers(scancode, true);
407 if(break_pressed != stat_break) { // Break key Down.
408 this->write_signals(&break_line, 0xff);
412 code = scan2fmkeycode(scancode);
413 if((code > 0x3ff) || (code == 0)) return;
414 if((config.dipswitch & FM7_DIPSW_AUTO_5_OR_8KEY) != 0) {
415 if((config.dipswitch & FM7_DIPSW_SELECT_5_OR_8KEY) == 0) { // Auto 8
422 autokey_backup = scancode;
435 autokey_backup = scancode;
440 autokey_backup = 0x00;
443 key_fifo->write(code);
444 if((scancode < 0x5c) && repeat_auto_key) {
445 double usec = (double)repeat_time_long * 1000.0;
446 if((repeat_keycode == 0) && repeat_mode) {
447 if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
448 event_keyrepeat = -1;
450 ID_KEYBOARD_AUTOREPEAT_FIRST,
451 usec, false, &event_keyrepeat);
453 repeat_keycode = scancode;
459 #if defined(_FM77AV_VARIANTS)
460 void KEYBOARD::adjust_rtc(void)
462 get_host_time(&cur_time);
463 rtc_yy = cur_time.year % 100;
464 rtc_mm = cur_time.month;
465 rtc_dd = cur_time.day;
467 rtc_dayofweek = cur_time.day_of_week;
469 rtc_ispm = (cur_time.hour >= 12) ? true : false;
470 rtc_hour = cur_time.hour % 12;
473 rtc_hour = cur_time.hour;
475 rtc_minute = cur_time.minute;
476 rtc_sec = cur_time.second;
477 if(event_key_rtc >= 0) {
478 cancel_event(this, event_key_rtc);
480 register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
484 void KEYBOARD::do_repeatkey(uint8_t sc)
487 if((sc == 0) || (sc >= 0x5c)) return; // scancode overrun.
489 if(event_keyrepeat >= 0) {
490 cancel_event(this, event_keyrepeat);
491 event_keyrepeat = -1;
495 if(keymode == KEYMODE_SCAN) {
496 code = (uint16_t)(sc & 0x7f);
497 key_fifo->write((uint32_t)code); // Make
498 //key_fifo->write((uint32_t)(code | 0x80)); // Break
500 code = scan2fmkeycode(sc);
502 key_fifo->write((uint32_t)code);
507 void KEYBOARD::event_callback(int event_id, int err)
509 #if defined(_FM77AV_VARIANTS)
510 if(event_id == ID_KEYBOARD_RXRDY_OK) {
512 write_signals(&rxrdy, 0xff);
513 } else if(event_id == ID_KEYBOARD_RXRDY_BUSY) {
514 rxrdy_status = false;
515 write_signals(&rxrdy, 0x00);
516 } else if(event_id == ID_KEYBOARD_ACK) {
517 key_ack_status = true;
518 write_signals(&key_ack, 0xff);
519 } else if(event_id == ID_KEYBOARD_RTC_COUNTUP) {
521 } else if(event_id == ID_KEYBOARD_HIDDENMESSAGE_AV) {
522 if(hidden_message_77av_1[hidden1_ptr] == 0x00) {
523 cancel_event(this, event_hidden1_av);
524 event_hidden1_av = -1;
527 key_fifo->write(hidden_message_77av_1[hidden1_ptr++]);
529 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
530 beep->write_signal(SIG_BEEP_ON, 1, 1);
532 ID_KEYBOARD_HIDDEN_BEEP_OFF,
533 25.0 * 1000.0, false, NULL);
534 } else if(event_id == ID_KEYBOARD_HIDDEN_BEEP_ON) {
535 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
536 beep->write_signal(SIG_BEEP_ON, 1, 1);
538 ID_KEYBOARD_HIDDEN_BEEP_OFF,
539 25.0 * 1000.0, false, NULL);
541 } else if(event_id == ID_KEYBOARD_HIDDEN_BEEP_OFF) {
542 beep->write_signal(SIG_BEEP_MUTE, 0, 1);
543 beep->write_signal(SIG_BEEP_ON, 0, 1);
544 } else if(event_id == ID_KEYBOARD_BREAK_ONESHOT) {
545 if(break_pressed) this->write_signals(&break_line, 0xff);
548 if(event_id == ID_KEYBOARD_AUTOREPEAT_FIRST) {
549 double usec = (double)repeat_time_short * 1000.0;
551 do_repeatkey(repeat_keycode);
553 ID_KEYBOARD_AUTOREPEAT,
554 usec, true, &event_keyrepeat);
556 } else if(event_id == ID_KEYBOARD_AUTOREPEAT){
557 if(repeat_keycode != 0) {
558 do_repeatkey(repeat_keycode);
560 cancel_event(this, event_keyrepeat);
561 event_keyrepeat = -1;
563 } else if(event_id == ID_KEYBOARD_INT) {
564 if(!(key_fifo->empty())) {
565 keycode_7 = key_fifo->read();
566 this->write_signals(&int_line, 0xffffffff);
568 } else if(event_id == ID_KEYBOARD_AUTO_8KEY_START) {
569 if(keymode != KEYMODE_SCAN) {
570 scancode = 0x3b; // 8
571 autokey_backup = 0x00;
572 key_down_main(false);
574 ID_KEYBOARD_AUTO_8KEY_END,
575 50.0 * 1000.0, false, NULL);
577 } else if(event_id == ID_KEYBOARD_AUTO_8KEY_END) {
578 key_up_main(0x3b); // 8
579 } else if(event_id == ID_KEYBOARD_AUTO_5KEY_START) {
580 if(keymode != KEYMODE_SCAN) {
581 scancode = 0x3f; // 5
582 autokey_backup = 0x00;
583 key_down_main(false);
585 ID_KEYBOARD_AUTO_5KEY_END,
586 50.0 * 1000.0, false, NULL);
588 } else if(event_id == ID_KEYBOARD_AUTO_5KEY_END) {
589 key_up_main(0x3f); // 5
594 void KEYBOARD::reset_unchange_mode(void)
596 repeat_time_short = 70; // mS
597 repeat_time_long = 700; // mS
601 lshift_pressed = false;
602 rshift_pressed = false;
603 shift_pressed = false;
604 ctrl_pressed = false;
605 graph_pressed = false;
606 kana_pressed = false;
607 caps_pressed = false;
608 // ins_pressed = false;
610 repeat_keycode = 0x00;
611 autokey_backup = 0x00;
613 #if defined(_FM77AV_VARIANTS)
616 if(event_key_rtc >= 0) {
617 cancel_event(this, event_key_rtc);
619 register_event(this,ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
622 if(event_keyrepeat >= 0) cancel_event(this, event_keyrepeat);
623 event_keyrepeat = -1;
625 if(event_hidden1_av >= 0) cancel_event(this, event_hidden1_av);
626 event_hidden1_av = -1;
630 this->write_signals(&break_line, 0x00);
631 #if defined(_FM77AV_VARIANTS)
632 rxrdy_status = false;
633 key_ack_status = true;
634 this->write_signals(&rxrdy, 0x00);
635 this->write_signals(&key_ack, 0xff);
637 this->write_signals(&kana_led, 0x00);
638 this->write_signals(&caps_led, 0x00);
639 this->write_signals(&ins_led, 0x00);
643 void KEYBOARD::reset(void)
645 keymode = KEYMODE_STANDARD;
648 keycode_7 = 0xffffffff;
649 reset_unchange_mode();
650 this->write_signals(&int_line, 0x00000000);
652 #if defined(_FM77AV_VARIANTS)
654 did_hidden_message_av_1 = false;
658 if(event_int >= 0) cancel_event(this, event_int);
661 20000.0, true, &event_int);
665 #if defined(_FM77AV_VARIANTS)
667 uint8_t KEYBOARD::read_data_reg(void)
669 if(!data_fifo->empty()) {
670 datareg = data_fifo->read() & 0xff;
672 if(!data_fifo->empty()) {
674 write_signals(&rxrdy, 0xff);
676 rxrdy_status = false;
677 write_signals(&rxrdy, 0x00);
683 uint8_t KEYBOARD::read_stat_reg(void)
689 if(!key_ack_status) {
692 // Digityze : bit0 = '0' when waiting,
696 void KEYBOARD::set_mode(void)
698 int count = cmd_fifo->count();
701 if(count < 2) return;
702 cmd = cmd_fifo->read();
703 mode = cmd_fifo->read();
704 if(mode <= KEYMODE_SCAN) {
706 //printf("Keymode : %d\n", keymode);
707 //reset_unchange_mode();
709 autokey_backup = 0x00;
710 this->write_signals(&break_line, 0x00);
711 if(scancode != 0) key_down_main(true);
714 data_fifo->clear(); // right?
715 rxrdy_status = false;
716 write_signals(&rxrdy, 0x00);
719 void KEYBOARD::get_mode(void)
723 cmd = cmd_fifo->read();
724 if(data_fifo->full()) {
725 dummy = data_fifo->read();
727 data_fifo->write(keymode);
729 write_signals(&rxrdy, 0xff);
732 void KEYBOARD::set_leds(void)
734 int count = cmd_fifo->count();
737 if(count < 2) return;
738 cmd = cmd_fifo->read();
739 ledvar = cmd_fifo->read();
741 if((ledvar & 0x02) != 0) {
743 kana_pressed = ((ledvar & 0x01) == 0);
744 write_signals(&kana_led, kana_pressed);
747 caps_pressed = ((ledvar & 0x01) == 0);
748 write_signals(&caps_led, caps_pressed);
752 data_fifo->clear(); // right?
753 rxrdy_status = false;
754 write_signals(&rxrdy, 0x00);
757 void KEYBOARD::get_leds(void)
759 uint8_t ledvar = 0x00;
761 ledvar |= caps_pressed ? 0x01 : 0x00;
762 ledvar |= kana_pressed ? 0x02 : 0x00;
763 data_fifo->write(ledvar);
766 write_signals(&rxrdy, 0xff);
769 void KEYBOARD::set_repeat_type(void)
774 cmd = cmd_fifo->read();
775 if(!cmd_fifo->empty()) {
776 modeval = cmd_fifo->read();
777 if((modeval < 2) && (modeval >= 0)) {
778 repeat_mode = (modeval == 0);
788 rxrdy_status = false;
789 write_signals(&rxrdy, 0x00);
792 void KEYBOARD::set_repeat_time(void)
795 uint32_t time_high = 0;
796 uint32_t time_low = 0;
797 cmd = cmd_fifo->read();
798 if(cmd_fifo->empty()) goto _end;
799 time_high = cmd_fifo->read();
800 if(cmd_fifo->empty()) goto _end;
801 time_low = cmd_fifo->read();
803 if((time_high == 0) || (time_low == 0)) {
804 repeat_time_long = 700;
805 repeat_time_short = 70;
807 repeat_time_long = (int)time_high * 10;
808 repeat_time_short = (int)time_low * 10;
812 rxrdy_status = false;
813 write_signals(&rxrdy, 0x00);
816 void KEYBOARD::set_rtc(void)
821 if(cmd_fifo->count() < 9) return;
822 cmd = cmd_fifo->read();
823 localcmd = cmd_fifo->read();
825 tmp = cmd_fifo->read();
826 rtc_yy = ((tmp >> 4) * 10) | (tmp & 0x0f);
828 tmp = cmd_fifo->read();
829 rtc_mm = ((tmp >> 4) * 10) | (tmp & 0x0f);
831 tmp = cmd_fifo->read();
832 rtc_dd = (((tmp & 0x30) >> 4) * 10) | (tmp & 0x0f);
834 tmp = cmd_fifo->read();
835 rtc_count24h = ((tmp & 0x08) != 0);
837 rtc_ispm = ((tmp & 0x04) != 0);
839 rtc_dayofweek = (tmp >> 4) % 0x07;
840 rtc_hour = ((tmp & 0x03) * 10);
842 tmp = cmd_fifo->read();
843 rtc_hour = rtc_hour | (tmp >> 4);
845 rtc_ispm = (rtc_hour >= 12);
847 rtc_minute = (tmp & 0x0f) * 10;
849 tmp = cmd_fifo->read();
850 rtc_minute = rtc_minute | (tmp >> 4);
851 rtc_sec = (tmp & 0x0f) * 10;
853 tmp = cmd_fifo->read();
854 rtc_sec = rtc_sec | (tmp >> 4);
858 if(event_key_rtc >= 0) {
859 cancel_event(this, event_key_rtc);
861 register_event(this, ID_KEYBOARD_RTC_COUNTUP, 1000.0 * 1000.0, true, &event_key_rtc);
862 rxrdy_status = false;
863 write_signals(&rxrdy, 0x00);
866 void KEYBOARD::get_rtc(void)
871 tmp = ((rtc_yy / 10) << 4) | (rtc_yy % 10);
872 data_fifo->write(tmp);
874 tmp = ((rtc_mm / 10) << 4) | (rtc_mm % 10);
875 data_fifo->write(tmp);
877 tmp = ((rtc_dd / 10) << 4) | (rtc_dd % 10);
878 tmp = tmp | (0 << 6); // leap
879 data_fifo->write(tmp);
881 tmp = rtc_dayofweek << 4;
882 tmp = tmp | (rtc_hour / 10);
890 data_fifo->write(tmp);
892 tmp = (rtc_hour % 10) << 4;
893 tmp = tmp | (rtc_minute / 10);
894 data_fifo->write(tmp);
896 tmp = (rtc_minute % 10) << 4;
897 tmp = tmp | (rtc_sec / 10);
898 data_fifo->write(tmp);
900 tmp = (rtc_sec % 10) << 4;
901 data_fifo->write(tmp);
905 write_signals(&rxrdy, 0xff);
908 const int rtc_month_days[12] = {
909 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
912 void KEYBOARD::rtc_count(void)
919 if(rtc_minute >= 60) {
923 rtc_ispm = (rtc_hour >= 12);
924 if(rtc_hour < 24) return;
927 if(rtc_hour < 12) return;
929 if(rtc_hour < 12) return;
939 if(rtc_dayofweek >= 7) rtc_dayofweek = 0;
940 if(rtc_dd > rtc_month_days[rtc_mm]){
941 if((rtc_mm ==1) && (rtc_dd == 29)) {
942 if((rtc_yy % 4) == 0) return;
949 if(rtc_yy >= 100) rtc_yy = 0;
955 #endif // FM77AV_VARIANTS
957 uint32_t KEYBOARD::read_signal(int id)
959 if(id == SIG_FM7KEY_BREAK_KEY) {
960 return break_pressed ? 0xfffffff : 0x00000000;
966 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
968 if(id == SIG_FM7KEY_SET_INSLED) {
969 write_signals(&ins_led, data & mask);
971 #if defined(_FM77AV_VARIANTS)
972 else if(id == SIG_FM7KEY_PUSH_TO_ENCODER) {
974 * I refered XM7's sourcecode : VM/keyboard.c act of key-encoder.
975 * Thanks to Ryu.Takegami and PI.
978 if(!key_ack_status) return; // If (not(ACK)) noop.
980 if(cmd_fifo->full()) {
983 if(cmd_fifo->empty()) {
984 cmd_phase = data & 0xff;
987 cmd_fifo->write(data & 0xff);
988 count = cmd_fifo->count();
990 rxrdy_status = false;
991 key_ack_status = false;
992 write_signals(&key_ack, 0x00);
993 write_signals(&rxrdy, 0x00);
999 if(keymode == KEYMODE_SCAN) key_down_main(true);
1009 case 2: // Set LED Phase
1012 if(keymode == KEYMODE_SCAN) key_down_main(true);
1017 case 3: // Get LED Phase
1036 case 0x80: // Communicate to/from RTC.
1041 if((data & 0xff) == 0) { // Get
1045 } else if((data & 0xff) == 1) { // Set
1046 rtc_set_flag = true;
1060 case 0x81: // Digitize.
1062 do_digitize(); // WILL Implement?
1069 set_screen_mode(); // WILL Implement?
1075 get_screen_mode(); // WILL Implement?
1081 set_brightness(); // WILL Implement?
1091 register_event(this, ID_KEYBOARD_ACK, 5, false, NULL); // Delay 5us until ACK is up.
1092 } else if(id == SIG_FM7KEY_RXRDY) {
1093 rxrdy_status = ((data & mask) != 0);
1094 //write_signals(&rxrdy, (rxrdy_status) ? 0xffffffff : 0x00000000);
1095 } else if(id == SIG_FM7KEY_ACK) {
1096 key_ack_status = ((data & mask) != 0);
1097 //write_signals(&key_ack, (key_ack_status) ? 0xffffffff : 0x00000000);
1103 uint32_t KEYBOARD::read_data8(uint32_t addr)
1105 uint32_t retval = 0xff;
1108 retval = get_keycode_high();
1111 retval = get_keycode_low();
1113 #if defined(_FM77AV_VARIANTS)
1115 retval = read_data_reg();
1118 retval = read_stat_reg();
1127 void KEYBOARD::write_data8(uint32_t addr, uint32_t data)
1130 #if defined(_FM77AV_VARIANTS)
1132 this->write_signal(SIG_FM7KEY_PUSH_TO_ENCODER, data, 0x000000ff);
1138 KEYBOARD::KEYBOARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
1143 #if defined(_FM77AV_VARIANTS)
1146 keycode_7 = 0xffffffff;
1148 ctrl_pressed = false;
1149 lshift_pressed = false;
1150 rshift_pressed = false;
1151 shift_pressed = false;
1152 graph_pressed = false;
1153 caps_pressed = false;
1154 kana_pressed = false;
1155 break_pressed = false;
1156 event_keyrepeat = -1;
1157 autokey_backup = 0x00;
1159 keymode = KEYMODE_STANDARD;
1160 #if defined(_FM77AV_VARIANTS)
1161 cmd_fifo = new FIFO(16);
1162 data_fifo = new FIFO(16);
1163 rxrdy_status = true;
1164 key_ack_status = false;
1165 initialize_output_signals(&rxrdy);
1166 initialize_output_signals(&key_ack);
1168 rtc_count24h = false;
1172 rtc_set_flag = false;
1180 event_hidden1_av = -1;
1183 key_fifo = new FIFO(512);
1186 initialize_output_signals(&break_line);
1187 initialize_output_signals(&int_line);
1189 initialize_output_signals(&kana_led);
1190 initialize_output_signals(&caps_led);
1191 initialize_output_signals(&ins_led);
1192 set_device_name(_T("KEYBOARD SUBSYSTEM"));
1195 void KEYBOARD::release(void)
1197 #if defined(_FM77AV_VARIANTS)
1198 cmd_fifo->release();
1199 data_fifo->release();
1203 key_fifo->release();
1209 KEYBOARD::~KEYBOARD()
1213 #define STATE_VERSION 4
1214 void KEYBOARD::save_state(FILEIO *state_fio)
1216 state_fio->FputUint32_BE(STATE_VERSION);
1217 state_fio->FputInt32_BE(this_device_id);
1218 this->out_debug_log("Save State: KEYBOARD: id=%d ver=%d\n", this_device_id, STATE_VERSION);
1222 state_fio->FputUint32_BE(keycode_7);
1223 state_fio->FputInt32_BE(keymode);
1225 state_fio->FputBool(ctrl_pressed);
1226 state_fio->FputBool(lshift_pressed);
1227 state_fio->FputBool(rshift_pressed);
1228 state_fio->FputBool(shift_pressed);
1229 state_fio->FputBool(graph_pressed);
1230 state_fio->FputBool(caps_pressed);
1231 state_fio->FputBool(kana_pressed);
1232 state_fio->FputBool(break_pressed);
1234 state_fio->FputInt32_BE(event_keyrepeat);
1236 state_fio->FputUint8(scancode); // After V.4, uint8_t
1237 state_fio->FputUint8(datareg);
1238 state_fio->FputUint32(older_vk);
1240 state_fio->FputBool(repeat_mode);
1241 state_fio->FputInt32_BE(repeat_time_short);
1242 state_fio->FputInt32_BE(repeat_time_long);
1243 state_fio->FputUint8(repeat_keycode);
1245 #if defined(_FM77AV_VARIANTS)
1246 state_fio->FputInt32_BE(event_key_rtc);
1248 state_fio->FputUint8(rtc_yy);
1249 state_fio->FputUint8(rtc_mm);
1250 state_fio->FputUint8(rtc_dd);
1251 state_fio->FputUint8(rtc_dayofweek);
1252 state_fio->FputUint8(rtc_hour);
1253 state_fio->FputUint8(rtc_minute);
1254 state_fio->FputUint8(rtc_sec);
1256 state_fio->FputBool(rtc_count24h);
1257 state_fio->FputBool(rtc_ispm);
1259 state_fio->FputBool(rtc_set);
1260 state_fio->FputBool(rtc_set_flag);
1261 state_fio->FputBool(rxrdy_status);
1262 state_fio->FputBool(key_ack_status);
1263 state_fio->FputInt32_BE(cmd_phase);
1265 state_fio->FputInt32_BE(event_hidden1_av);
1266 state_fio->FputUint16_BE(hidden1_ptr);
1268 cmd_fifo->save_state((void *)state_fio);
1269 data_fifo->save_state((void *)state_fio);
1270 cur_time.save_state((void *)state_fio);
1272 state_fio->FputInt32_BE(event_int);
1273 key_fifo->save_state((void *)state_fio);
1277 #if defined(_FM77AV_VARIANTS)
1278 state_fio->FputBool(did_hidden_message_av_1);
1283 #if defined(_FM77AV_VARIANTS)
1284 state_fio->FputInt32_BE(beep_phase);
1288 state_fio->FputUint8(autokey_backup);
1291 bool KEYBOARD::load_state(FILEIO *state_fio)
1295 version = state_fio->FgetUint32_BE();
1296 if(this_device_id != state_fio->FgetInt32_BE()) return false;
1297 this->out_debug_log("Load State: KEYBOARD: id=%d ver=%d\n", this_device_id, version);
1300 keycode_7 = state_fio->FgetUint32_BE();
1301 keymode = state_fio->FgetInt32_BE();
1303 ctrl_pressed = state_fio->FgetBool();
1304 lshift_pressed = state_fio->FgetBool();
1305 rshift_pressed = state_fio->FgetBool();
1306 shift_pressed = state_fio->FgetBool();
1307 graph_pressed = state_fio->FgetBool();
1308 caps_pressed = state_fio->FgetBool();
1309 kana_pressed = state_fio->FgetBool();
1310 break_pressed = state_fio->FgetBool();
1312 event_keyrepeat = state_fio->FgetInt32_BE();
1314 scancode = state_fio->FgetUint8();
1315 datareg = state_fio->FgetUint8();
1316 older_vk = state_fio->FgetUint32();
1318 repeat_mode = state_fio->FgetBool();
1319 repeat_time_short = state_fio->FgetInt32_BE();
1320 repeat_time_long = state_fio->FgetInt32_BE();
1321 repeat_keycode = state_fio->FgetUint8();
1323 #if defined(_FM77AV_VARIANTS)
1324 event_key_rtc = state_fio->FgetInt32_BE();
1325 rtc_yy = state_fio->FgetUint8();
1326 rtc_mm = state_fio->FgetUint8();
1327 rtc_dd = state_fio->FgetUint8();
1328 rtc_dayofweek = state_fio->FgetUint8();
1329 rtc_hour = state_fio->FgetUint8();
1330 rtc_minute = state_fio->FgetUint8();
1331 rtc_sec = state_fio->FgetUint8();
1333 rtc_count24h = state_fio->FgetBool();
1334 rtc_ispm = state_fio->FgetBool();
1336 rtc_set = state_fio->FgetBool();
1337 rtc_set_flag = state_fio->FgetBool();
1338 rxrdy_status = state_fio->FgetBool();
1339 key_ack_status = state_fio->FgetBool();
1340 cmd_phase = state_fio->FgetInt32_BE();
1342 event_hidden1_av = state_fio->FgetInt32_BE();
1343 hidden1_ptr = state_fio->FgetUint16_BE();
1345 cmd_fifo->load_state((void *)state_fio);
1346 data_fifo->load_state((void *)state_fio);
1347 cur_time.load_state((void *)state_fio);
1349 event_int = state_fio->FgetInt32_BE();
1350 key_fifo->load_state((void *)state_fio);
1351 if(version == 1) return true;
1355 #if defined(_FM77AV_VARIANTS)
1356 did_hidden_message_av_1 = state_fio->FgetBool();
1361 #if defined(_FM77AV_VARIANTS)
1362 beep_phase = state_fio->FgetInt32_BE();
1366 autokey_backup = state_fio->FgetUint8();
1367 if(version == STATE_VERSION) {