2 FUJITSU FMR-50 Emulator 'eFMR-50'
3 FUJITSU FMR-60 Emulator 'eFMR-60'
5 Author : Takeda.Toshiya
13 #include "../../fifo.h"
15 #define EVENT_KEY_CODE 1
16 #define EVENT_DELAY_PUSH 2
19 void KEYBOARD::initialize()
22 key_buf = new FIFO(64);
23 cmd_buf = new FIFO(16);
26 memset(table, 0, sizeof(table));
27 memset(boot_code, 0x00, sizeof(boot_code));
31 repeat_start_ms = 400;
34 special_boot_num = -1;
37 void KEYBOARD::release()
45 void KEYBOARD::reset()
51 void KEYBOARD::reset_device()
53 out_debug_log("RESET\n");
54 special_boot_num = -1;
57 memset(table, 0, sizeof(table));
61 kbstat = kbdata = kbint = kbmsk = 0;
63 enable_double_pressed_cursor = true;
65 reserved_key_num = -1;
66 if(event_keycode > -1) {
67 cancel_event(this, event_keycode);
70 if(event_key_reset > -1) {
71 cancel_event(this, event_key_reset);
74 write_signals(&output_intr_line, 0);
75 write_signals(&output_nmi_line, 0);
78 void KEYBOARD::enqueue_key(uint8_t code)
84 void KEYBOARD::enqueue_key2(uint8_t code)
90 void KEYBOARD::special_reset(int num)
92 out_debug_log("SPECIAL RESET %d\n", num);
93 memset(boot_code, 0x00, sizeof(boot_code));
96 special_boot_num = num;
113 // register_event(this, EVENT_DELAY_PUSH, 1.0, false, NULL);
114 event_callback(EVENT_DELAY_PUSH, 0);
121 register_key_interrupt(true); // NEXT BYTE
124 void KEYBOARD::register_key_interrupt(bool first)
126 double usec = (first) ? 1000.0 : 50.0;
127 if(event_keycode > -1) {
128 cancel_event(this, event_keycode);
131 register_event(this, EVENT_KEY_CODE, usec, false, &event_keycode);
134 void KEYBOARD::do_common_command(uint8_t cmd)
136 static const int type_start_ms[] = {400, 500, 300};
137 static const int type_repeat_ms[] = {50, 30, 20};
138 out_debug_log(_T("CMD %02X"), cmd);
141 this->reset_device(); // RESET
143 // key_buf->write(0xa0);
144 // key_buf->write(0x7f);
145 // memset(boot_code, 0x00, sizeof(boot_code));
148 // boot_code_ptr = false;
151 if(last_cmd != 0xa0) {
152 this->reset_device(); // RESET
153 memset(boot_code, 0x00, sizeof(boot_code));
156 boot_code_ptr = false;
160 // Check double press (for OYAYUBI-Shift)
163 // Don't check double press (for OYAYUBI-Shift)
168 repeat_start_ms = type_start_ms[cmd - 0xa9];
173 repeat_tick_ms = type_repeat_ms[cmd - 0xac];
176 enable_double_pressed_cursor = true;
179 enable_double_pressed_cursor = false;
182 write_signals(&output_nmi_line, 0);
192 void KEYBOARD::write_io8(uint32_t addr, uint32_t data)
194 // out_debug_log(_T("WRITE I/O ADDR=%04X VAL=%02X"), addr, data);
203 if((data & 0x80) == 0x00) {
205 if((device_order) && (cmd_buf->count() > 0)) {
206 cmd_buf->write(data & 0x7f);
210 device_order = false;
213 } else if(data & 0xe0 == 0xc0) {
215 if((cmd_buf->count() > 0) && (device_order)){
219 cmd_buf->write(data & 0xff);
220 device_order = false;
222 } else if(data & 0xe0 == 0xa0) {
224 if((cmd_buf->count() > 0) && (device_order)){
227 device_order = false;
229 do_common_command(data);
238 uint32_t KEYBOARD::read_io8(uint32_t addr)
246 write_signals(&output_intr_line, 0);
247 if(key_buf->empty()) {
250 register_key_interrupt(false); // NEXT BYTE
252 out_debug_log(_T("READ I/O ADDR=%04X VAL=%02X"), addr, kbdata);
255 // out_debug_log(_T("READ I/O ADDR=%04X VAL=%02X"), addr, kbstat);
258 // out_debug_log(_T("READ I/O ADDR=%04X VAL=%02X"), addr, kbint);
259 return (((kbint & 1) != 0) ? 1 : 0) | ((nmi_status) ? 2 : 0);
265 void KEYBOARD::event_callback(int event_id, int err)
269 kbdata = key_buf->read();
273 write_signals(&output_intr_line, 0xffffffff);
277 case EVENT_DELAY_PUSH:
279 int num = special_boot_num;
280 switch(special_boot_num) {
301 enqueue_key(0x01 + (num - 1));
303 enqueue_key(0x01 + (num - 1));
305 enqueue_key2(0x01 + (num - 1));
320 enqueue_key(0x01 + (num - 5));
322 enqueue_key(0x01 + (num - 5));
324 enqueue_key2(0x01 + (num - 5));
339 special_boot_num = -1;
340 memset(boot_code, 0x00, sizeof(boot_code));
346 void KEYBOARD::key_down(int code)
348 // if(!table[code]) {
350 if(code = key_table[code]) {
351 // $11:CTRL, $10:SHIFT
352 if((code >= 0x70) && (code < 0x7a)) {
353 // If PFkey, press with /*SHIFT or */RALT, PF += 10.
354 if((table[0xa5]) /*|| (table[0x10])*/) { // RALT /*or SHIFT*/
355 static const int pf1xtbl[] = { 0x69, 0x5b, 0x74, 0x75, 0x76,
356 0x77, 0x78, 0x79, 0x7a, 0x7b};
357 code = pf1xtbl[code - 0x70];
359 } else if((code == 0x7d)) { // Print Screen + RALT -> Kanji Jisho
360 if(table[0xa5]) { // RALT
363 } else if((code == 0x7c)) { // Pause Break + RALT -> Tango Touroku
364 if(table[0xa5]) { // RALT
367 } else if((code == 0x6c)) { // Scroll Lock + RALT -> Tango Massyou.
368 if(table[0xa5]) { // RALT
372 key_buf->write(0xc0 | (table[0x11] ? 8 : 0) | (table[0x10] ? 4 : 0));
373 key_buf->write(code & 0x7f);
374 register_key_interrupt(true);
379 void KEYBOARD::key_up(int code)
383 if(code = key_table[code]) {
384 if((code >= 0x70) && (code < 0x7a)) {
385 // If PFkey, press with /*SHIFT or */RALT, PF += 10.
386 if((table[0xa5]) /*|| (table[0x10])*/) { // RALT /*or SHIFT*/
387 static const int pf1xtbl[] = { 0x69, 0x5b, 0x74, 0x75, 0x76,
388 0x77, 0x78, 0x79, 0x7a, 0x7b};
389 code = pf1xtbl[code - 0x70];
391 } else if((code == 0x7d)) { // Print Screen + RALT -> Kanji Jisho
392 if(table[0xa5]) { // RALT
395 } else if((code == 0x7c)) { // Pause Break + RALT -> Tango Touroku
396 if(table[0xa5]) { // RALT
399 } else if((code == 0x6c)) { // Scroll Lock + RALT -> Tango Massyou.
400 if(table[0xa5]) { // RALT
404 key_buf->write(0xd0 | (table[0x11] ? 8 : 0) | (table[0x10] ? 4 : 0));
405 key_buf->write(code & 0x7f);
406 register_key_interrupt(true);
411 void KEYBOARD::write_signal(int id, uint32_t data, uint32_t mask)
414 case SIG_KEYBOARD_BOOTSEQ_END:
415 // out_debug_log(_T("SIG_KEYBOARD_BOOTSEQ_END"));
420 #define STATE_VERSION 2
422 bool KEYBOARD::process_state(FILEIO* state_fio, bool loading)
424 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
427 if(!state_fio->StateCheckInt32(this_device_id)) {
430 if(!(key_buf->process_state((void *)state_fio, loading))) {
433 if(!(cmd_buf->process_state((void *)state_fio, loading))) {
437 state_fio->StateValue(last_cmd);
438 state_fio->StateValue(kbstat);
439 state_fio->StateValue(kbdata);
440 state_fio->StateValue(kbint);
441 state_fio->StateValue(kbmsk);
443 state_fio->StateValue(nmi_status);
444 state_fio->StateValue(repeat_start_ms);
445 state_fio->StateValue(repeat_tick_ms);
446 state_fio->StateValue(enable_double_pressed_cursor);
447 state_fio->StateValue(device_order);
449 state_fio->StateArray(table, sizeof(table), 1);
450 state_fio->StateValue(reserved_key_num);
451 state_fio->StateValue(key_count_phase);
452 state_fio->StateValue(special_boot_num);
454 state_fio->StateArray(boot_code, sizeof(boot_code), 1);
455 state_fio->StateValue(boot_ptr);
456 state_fio->StateValue(boot_seq);
457 state_fio->StateValue(boot_code_ptr);
459 state_fio->StateValue(event_keycode);
460 state_fio->StateValue(event_key_reset);