2 * FM-7 Main I/O [fm7_mainio.h]
4 * Author: K.Ohta <whatisthis.sowhat _at_ gmail.com>
7 * Jan 03, 2015 : Initial
12 #include "fm7_mainio.h"
14 #include "../mc6809.h"
17 #include "../datarec.h"
22 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
27 FM7_MAINIO::FM7_MAINIO(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
32 for(i = 0; i < 3; i++) {
35 for(i = 0; i < 3; i++) {
37 uart_enabled[i] = false;
39 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
40 rs232c_enabled = false;
43 rs232c_enabled = true;
46 # if !defined(_FM77AV_VARIANTS)
72 #if defined(CAPABLE_JCOMMCARD)
77 lpt_strobe = false; // bit6
78 lpt_slctin = false; // bit7
82 cmt_indat = true; // bit7
83 cmt_invert = false; // Invert signal
87 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
88 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
89 stat_kanjirom = true; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
90 #elif defined(_FM77_VARIANTS)
91 stat_fdmode_2hd = false; // R/W : bit6, '0' = 2HD, '1' = 2DD. FM-77 Only.
92 stat_kanjirom = true; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
94 firq_break_key = false; // bit1, ON = '0'.
95 firq_sub_attention = false; // bit0, ON = '0'.
96 intmode_fdc = false; // bit2, '0' = normal, '1' = SFD.
98 drqstat_fdc_2hd = false;
99 irqstat_fdc_2hd = false;
106 intstat_syndet = false;
107 intstat_rxrdy = false;
108 intstat_txrdy = false;
109 irqstat_timer = false;
110 irqstat_printer = false;
111 irqstat_keyboard = false;
120 for(i = 0; i < 3; i++) {
121 opn_address[i] = 0x00;
129 intstat_mouse = false;
130 mouse_enable = false;
142 irqreg_fdc = 0xff; //0b11111111;
143 irqmask_syndet = true;
144 irqmask_rxrdy = true;
145 irqmask_txrdy = true;
147 irqmask_timer = true;
148 irqmask_printer = true;
149 irqmask_keyboard = true;
153 irqreq_syndet = false;
154 irqreq_rxrdy = false;
155 irqreq_txrdy = false;
156 irqreq_printer = false;
157 irqreq_keyboard = false;
159 // FD20, FD21, FD22, FD23
160 connect_kanjiroml1 = false;
161 #if defined(_FM77AV_VARIANTS)
162 // FD2C, FD2D, FD2E, FD2F
163 connect_kanjiroml2 = false;
165 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
172 #if defined(_FM77_VARIANTS) || defined(_FM8)
173 bootmode = config.boot_mode & 7;
175 bootmode = config.boot_mode & 3;
177 memset(io_w_latch, 0xff, 0x100);
178 initialize_output_signals(&clock_status);
179 initialize_output_signals(&printer_reset_bus);
180 initialize_output_signals(&printer_strobe_bus);
181 initialize_output_signals(&printer_select_bus);
182 initialize_output_signals(&irq_bus);
183 initialize_output_signals(&firq_bus);
184 initialize_output_signals(&nmi_bus);
185 set_device_name(_T("MAIN I/O"));
188 FM7_MAINIO::~FM7_MAINIO()
193 void FM7_MAINIO::initialize()
196 event_beep_oneshot = -1;
198 event_fdc_motor = -1;
199 lpt_type = config.printer_type;
202 event_fdc_motor_2HD = -1;
204 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
206 # if defined(_FM77_VARIANTS)
207 stat_fdmode_2hd = false;
208 stat_kanjirom = true;
211 #if defined(_FM77AV_VARIANTS)
212 reg_fd12 = 0xbc; // 0b10111100
214 #if defined(_FM77_VARIANTS) || defined(_FM8)
215 bootmode = config.boot_mode & 7;
217 bootmode = config.boot_mode & 3;
226 void FM7_MAINIO::reset()
228 if(event_beep >= 0) cancel_event(this, event_beep);
230 if(event_beep_oneshot >= 0) cancel_event(this, event_beep_oneshot);
231 event_beep_oneshot = -1;
232 if(event_timerirq >= 0) cancel_event(this, event_timerirq);
235 register_event(this, EVENT_BEEP_CYCLE, (1000.0 * 1000.0) / (1200.0 * 2.0), true, &event_beep);
238 drqstat_fdc_2hd = false;
239 irqstat_fdc_2hd = false;
240 if(event_2hd_nmi >= 0) cancel_event(this, event_2hd_nmi);
243 #if defined(_FM77AV_VARIANTS)
247 #if defined(_FM77_VARIANTS)
249 #elif defined(_FM77AV_VARIANTS)
253 sub_cancel = false; // bit6 : '1' Cancel req.
254 sub_halt = false; // bit6 : '1' Cancel req.
255 sub_cancel_bak = sub_cancel; // bit6 : '1' Cancel req.
256 sub_halt_bak = sub_halt; // bit6 : '1' Cancel req.
257 req_z80run = false; // OK?
261 cmt_indat = true; // bit7
262 cmt_invert = false; // Invert signal
265 lpt_type = config.printer_type;
268 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
269 rs232c_enabled = false;
271 rs232c_enabled = true;
274 #if defined(_FM77AV_VARIANTS)
275 sub_monitor_type = 0x00;
277 if(config.cpu_type == 0) {
282 this->write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
285 irqmask_syndet = true;
286 irqmask_rxrdy = true;
287 irqmask_txrdy = true;
289 irqmask_timer = true;
290 irqmask_printer = true;
291 irqmask_keyboard = true;
294 intstat_syndet = false;
295 intstat_rxrdy = false;
296 intstat_txrdy = false;
297 irqstat_timer = false;
298 irqstat_printer = false;
299 irqstat_keyboard = false;
301 irqreq_syndet = false;
302 irqreq_rxrdy = false;
303 irqreq_txrdy = false;
304 irqreq_printer = false;
305 irqreq_keyboard = false;
307 modem_irqmask_rxrdy = modem_irqmask_txrdy = true;
308 modem_syndet = modem_rxrdy = modem_txrdy = false;
309 midi_uart_irqmask = midi_syndet = midi_rxrdy = midi_txrdy = false;
312 drec->write_signal(SIG_DATAREC_MIC, 0x00, 0x01);
313 drec->write_signal(SIG_DATAREC_REMOTE, 0x00, 0x02);
319 firq_break_key = (keyboard->read_signal(SIG_FM7KEY_BREAK_KEY) != 0x00000000); // bit1, ON = '0'.
321 set_sub_attention(false);
322 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
323 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
324 stat_kanjirom = true; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
325 #elif defined(_FM77_VARIANTS)
326 stat_fdmode_2hd = false; // R/W : bit6, '0' = 2HD, '1' = 2DD. FM-77 Only.
327 stat_kanjirom = true; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
329 write_signals(&firq_bus, 0);
335 #if defined(_FM77AV_VARIANTS)
336 reg_fd12 = 0xbc; // 0b10111100
338 #if defined(WITH_Z80)
339 if(z80 != NULL) z80->write_signal(SIG_CPU_BUSREQ, 0xffffffff, 0xffffffff);
341 maincpu->write_signal(SIG_CPU_BUSREQ, 0, 0xffffffff);
342 maincpu->write_signal(SIG_CPU_HALTREQ, 0, 0xffffffff);
346 register_event(this, EVENT_TIMERIRQ_ON, 10000.0 / 4.9152, true, &event_timerirq); // TIMER IRQ
348 #if defined(_FM77_VARIANTS) || defined(_FM8)
349 bootmode = config.boot_mode & 7;
351 bootmode = config.boot_mode & 3;
353 memset(io_w_latch, 0xff, 0x100);
356 void FM7_MAINIO::reset_printer()
362 this->write_signals(&printer_strobe_bus, 0);
363 this->write_signals(&printer_select_bus, 0xffffffff);
364 this->write_signals(&printer_reset_bus, 0xffffffff);
365 register_event(this, EVENT_PRINTER_RESET_COMPLETED, 5.0 * 1000.0, false, NULL);
367 printer->write_signal(SIG_PRINTER_STROBE, 0x00, 0xff);
370 lpt_error_inv = true;
371 lpt_ackng_inv = true;
376 void FM7_MAINIO::set_clockmode(uint8_t flags)
379 if((flags & FM7_MAINCLOCK_SLOW) != 0) {
384 if(f != clock_fast) {
385 this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
389 uint8_t FM7_MAINIO::get_clockmode(void)
391 if(!clock_fast) return FM7_MAINCLOCK_SLOW;
392 return FM7_MAINCLOCK_HIGH;
396 uint8_t FM7_MAINIO::get_port_fd00(void)
398 uint8_t ret = 0x7e; //0b01111110;
399 if(keyboard->read_data8(0x00) != 0) ret |= 0x80; // High bit.
400 if(clock_fast) ret |= 0x01; //0b00000001;
404 void FM7_MAINIO::set_port_fd00(uint8_t data)
407 drec->write_signal(SIG_DATAREC_MIC, data, 0x01);
408 drec->write_signal(SIG_DATAREC_REMOTE, data, 0x02);
410 lpt_slctin = ((data & 0x80) == 0);
411 lpt_strobe = ((data & 0x40) != 0);
412 this->write_signals(&printer_strobe_bus, lpt_strobe ? 0xffffffff : 0);
413 this->write_signals(&printer_select_bus, lpt_slctin ? 0xffffffff : 0);
414 if((lpt_type == 0) && (lpt_slctin)) {
415 printer->write_signal(SIG_PRINTER_STROBE, lpt_strobe ? 0xff : 0x00, 0xff);
419 uint8_t FM7_MAINIO::get_port_fd02(void)
422 bool ack_bak = lpt_ackng_inv;
424 ret = (cmt_indat) ? 0xff : 0x7f; // CMT
426 lpt_busy = (printer->read_signal(SIG_PRINTER_BUSY) != 0);
427 lpt_error_inv = true;
428 lpt_ackng_inv = (printer->read_signal(SIG_PRINTER_ACK) != 0);
430 } else if((lpt_type == 1) || (lpt_type == 2)) {
431 lpt_pe = (joystick->read_data8(lpt_type + 1) != 0); // check joy port;
433 lpt_error_inv = true;
434 lpt_ackng_inv = true;
437 lpt_error_inv = true;
438 lpt_ackng_inv = true;
441 ret &= (lpt_busy) ? 0xff : ~0x01;
442 ret &= (lpt_error_inv) ? 0xff : ~0x02;
443 ret &= (lpt_ackng_inv) ? 0xff : ~0x04;
444 ret &= (lpt_pe) ? 0xff : ~0x08;
445 ret &= (lpt_det1) ? 0xff : ~0x10;
446 ret &= (lpt_det2) ? 0xff : ~0x20;
447 if((lpt_ackng_inv == true) && (ack_bak == false)) set_irq_printer(true);
451 void FM7_MAINIO::set_port_fd02(uint8_t val)
455 bool syndetirq_bak = irqmask_syndet;
456 //bool rxrdyirq_bak = irqmask_rxrdy;
457 //bool txrdyirq_bak = irqmask_txrdy;
459 bool keyirq_bak = irqmask_keyboard;
460 //bool timerirq_bak = irqmask_timer;
461 //bool printerirq_bak = irqmask_printer;
462 //bool mfdirq_bak = irqmask_mfd;
464 // if((val & 0b00010000) != 0) {
465 if((val & 0x80) != 0) {
466 irqmask_syndet = false;
468 irqmask_syndet = true;
470 if(syndetirq_bak != irqmask_syndet) {
471 set_irq_txrdy(irqreq_syndet);
473 if((val & 0x40) != 0) {
474 irqmask_rxrdy = false;
476 irqmask_rxrdy = true;
478 // if(rxrdyirq_bak != irqmask_rxrdy) {
479 // set_irq_rxrdy(irqreq_rxrdy);
481 if((val & 0x20) != 0) {
482 irqmask_txrdy = false;
484 irqmask_txrdy = true;
486 // if(txrdyirq_bak != irqmask_txrdy) {
487 // set_irq_txrdy(irqreq_txrdy);
490 if((val & 0x10) != 0) {
496 if((val & 0x04) != 0) {
497 irqmask_timer = false;
499 irqmask_timer = true;
501 // if(timerirq_bak != irqmask_timer) {
502 // set_irq_timer(false);
505 if((val & 0x02) != 0) {
506 irqmask_printer = false;
508 irqmask_printer = true;
510 // if(printerirq_bak != irqmask_printer) {
511 // set_irq_printer(irqreq_printer);
514 if((val & 0x01) != 0) {
515 irqmask_keyboard = false;
517 irqmask_keyboard = true;
519 if(keyirq_bak != irqmask_keyboard) {
520 display->write_signal(SIG_FM7_SUB_KEY_MASK, irqmask_keyboard ? 1 : 0, 1);
521 set_irq_keyboard(irqreq_keyboard);
527 void FM7_MAINIO::set_irq_syndet(bool flag)
529 bool backup = intstat_syndet;
530 irqreq_syndet = flag;
531 if(flag && !(irqmask_syndet)) {
532 //irqstat_reg0 &= ~0x80; //~0x20;
533 intstat_syndet = true;
535 // irqstat_reg0 |= 0x80;
536 intstat_syndet = false;
538 if(backup != intstat_syndet) do_irq();
542 void FM7_MAINIO::set_irq_rxrdy(bool flag)
544 bool backup = intstat_rxrdy;
546 if(flag && !(irqmask_rxrdy)) {
547 //irqstat_reg0 &= ~0x40; //~0x20;
548 intstat_rxrdy = true;
550 //irqstat_reg0 |= 0x40;
551 intstat_rxrdy = false;
553 if(backup != intstat_rxrdy) do_irq();
558 void FM7_MAINIO::set_irq_txrdy(bool flag)
560 bool backup = intstat_txrdy;
562 if(flag && !(irqmask_txrdy)) {
563 //irqstat_reg0 &= ~0x20; //~0x20;
564 intstat_txrdy = true;
566 //irqstat_reg0 |= 0x20;
567 intstat_txrdy = false;
569 if(backup != intstat_txrdy) do_irq();
573 void FM7_MAINIO::set_irq_timer(bool flag)
576 irqstat_reg0 &= 0xfb; //~0x04;
577 irqstat_timer = true;
579 irqstat_reg0 |= 0x04;
580 irqstat_timer = false;
585 void FM7_MAINIO::set_irq_printer(bool flag)
587 irqreq_printer = flag;
588 if(flag && !(irqmask_printer)) {
589 irqstat_reg0 &= ~0x02;
590 irqstat_printer = true;
592 irqstat_reg0 |= 0x02;
593 irqstat_printer = false;
598 void FM7_MAINIO::set_irq_keyboard(bool flag)
600 //uint8_t backup = irqstat_reg0;
601 //printf("MAIN: KEYBOARD: IRQ=%d MASK=%d\n", flag ,irqmask_keyboard);
602 irqreq_keyboard = flag;
603 if(flag && !irqmask_keyboard) {
604 irqstat_reg0 &= 0xfe;
605 irqstat_keyboard = true;
607 irqstat_reg0 |= 0x01;
608 irqstat_keyboard = false;
614 void FM7_MAINIO::do_irq(void)
619 intstat = irqstat_timer | irqstat_keyboard | irqstat_printer;
620 intstat = intstat | intstat_opn | intstat_whg | intstat_thg;
621 intstat = intstat | intstat_txrdy | intstat_rxrdy | intstat_syndet;
622 intstat = intstat | intstat_mouse;
623 intstat = intstat | ((modem_irqmask_txrdy & modem_txrdy) | (modem_irqmask_rxrdy & modem_rxrdy) | modem_syndet);
624 intstat = intstat | ((!midi_uart_irqmask) & (midi_syndet | midi_txrdy | midi_rxrdy));
625 # if defined(HAS_DMA)
626 intstat = intstat | intstat_dma;
628 # if defined(HAS_2HD)
630 intstat = intstat | irqstat_fdc_2hd;
632 intstat = intstat | irqstat_fdc;
635 intstat = intstat | irqstat_fdc;
637 nval = (intstat) ? 0xffffffff : 0;
638 write_signals(&irq_bus, nval);
641 void FM7_MAINIO::do_firq(void)
645 firq_stat = firq_break_key | firq_sub_attention;
648 //if((connect_fdc_2HD) && (fdc_2HD != NULL) && ((irqreg_fdc_2HD & 0x40) != 0)) {
649 firq_stat |= drqstat_fdc_2hd;
653 nval = (firq_stat) ? 0xffffffff : 0;
654 write_signals(&firq_bus, nval);
657 void FM7_MAINIO::do_nmi(bool flag)
659 write_signals(&nmi_bus, (flag) ? 0xffffffff : 0);
663 void FM7_MAINIO::set_break_key(bool pressed)
665 firq_break_key = pressed;
669 void FM7_MAINIO::set_sub_attention(bool flag)
671 firq_sub_attention = flag;
676 uint8_t FM7_MAINIO::get_fd04(void)
680 if(display->read_signal(SIG_DISPLAY_BUSY) != 0) val |= 0x80;
682 //f = keyboard->read_signal(SIG_FM7KEY_BREAK_KEY);
685 if(!firq_sub_attention) {
688 #if defined(_FM77_VARIANTS)
689 if(!stat_fdmode_2hd) val |= 0x40;
690 if(stat_kanjirom) val |= 0x20;
691 //if(intmode_fdc) val |= 0x04; // OK?
693 # if defined(_FM77L4)
694 val |= (display->read_signal(SIG_DISPLAY_EXTRA_MODE) & 0x18);
696 val |= 0x18; // For NON-77L4, these bit must be '1'.Thanks to Ryu Takegami.
700 // ToDo: MEMORY PARITY ERRO STATUS (if error, bit3 = '1').
701 #elif defined(_FM77AV_VARIANTS)
703 val |= 0x10; // ToDo: Hack for OS-9 for 77AV.Really need?
708 if(drqstat_fdc_2hd) {
709 drqstat_fdc_2hd = false;
710 if(!firq_sub_attention) do_firq();
713 if(firq_sub_attention) {
714 set_sub_attention(false);
715 //printf("Attention \n");
717 #if defined(_FM77AV_VARIANTS)
719 if(mainmem->read_signal(FM7_MAINIO_INITROM_ENABLED) == 0) {
720 set_break_key(false);
728 void FM7_MAINIO::set_fd04(uint8_t val)
731 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
732 display->write_signal(SIG_DISPLAY_EXTRA_MODE, val, 0xff);
733 stat_kanjirom = ((val & 0x20) != 0);
734 #elif defined(_FM77_VARIANTS)
735 display->write_signal(SIG_DISPLAY_EXTRA_MODE, val, 0xff);
736 stat_kanjirom = ((val & 0x20) != 0);
739 stat_fdmode_2hd = ((val & 0x40) == 0);
740 intmode_fdc = ((val & 0x04) == 0); // I/O port definition at Oh!FM 1985-5? is inverted status.
741 bool tmpf = intmode_fdc;
742 if(tmpf != intmode_fdc) {
749 uint8_t FM7_MAINIO::get_fd05(void)
752 if(display->read_signal(SIG_DISPLAY_BUSY) != 0) val |= 0x80;
753 if(!extdet_neg) val |= 0x01;
757 void FM7_MAINIO::set_fd05(uint8_t val)
759 sub_cancel = ((val & 0x40) != 0) ? true : false;
760 sub_halt = ((val & 0x80) != 0) ? true : false;
761 //if(sub_halt != sub_halt_bak) {
762 display->write_signal(SIG_DISPLAY_HALT, (sub_halt) ? 0xff : 0x00, 0xff);
764 sub_halt_bak = sub_halt;
766 //if(sub_cancel != sub_cancel_bak) {
767 display->write_signal(SIG_FM7_SUB_CANCEL, (sub_cancel) ? 0xff : 0x00, 0xff); // HACK
769 sub_cancel_bak = sub_cancel;
771 if((val & 0x01) != 0) {
772 maincpu->write_signal(SIG_CPU_HALTREQ, 1, 1);
776 if(z80 != NULL) z80->write_signal(SIG_CPU_BUSREQ, 1, 1);
781 void FM7_MAINIO::set_extdet(bool flag)
786 void FM7_MAINIO::write_fd0f(void)
788 mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, 0, 0xffffffff);
791 uint8_t FM7_MAINIO::read_fd0f(void)
793 mainmem->write_signal(FM7_MAINIO_PUSH_FD0F, 0xffffffff, 0xffffffff);
797 bool FM7_MAINIO::get_rommode_fd0f(void)
799 return (mainmem->read_signal(FM7_MAINIO_PUSH_FD0F) == 0) ? false : true;
803 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
804 void FM7_MAINIO::write_kanjiaddr_hi(uint8_t addr)
806 #if defined(CAPABLE_JCOMMCARD) && !(defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS))
807 if(jcommcard != NULL) {
808 jcommcard->write_io8(0, (uint32_t)addr);
812 if(!connect_kanjiroml1) {
815 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
816 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
817 if(!stat_kanjirom) return;
819 kanjiclass1->write_data8(KANJIROM_ADDR_HI, addr);
823 void FM7_MAINIO::write_kanjiaddr_lo(uint8_t addr)
825 #if defined(CAPABLE_JCOMMCARD) && !(defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS))
826 if(jcommcard != NULL) {
827 jcommcard->write_io8(1, (uint32_t)addr);
831 if(!connect_kanjiroml1) {
834 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
835 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
836 if(!stat_kanjirom) return;
838 kanjiclass1->write_data8(KANJIROM_ADDR_LO, addr);
842 uint8_t FM7_MAINIO::read_kanjidata_left(void)
844 #if defined(CAPABLE_JCOMMCARD) && !(defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS))
845 if(jcommcard != NULL) {
846 return (uint8_t)(jcommcard->read_io8(2));
849 if(!connect_kanjiroml1) {
852 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
853 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
854 if(!stat_kanjirom) return 0xff;
856 //printf("KANJI MAIN CLASS1 ADDR: %05x\n", kaddress.w.l);
858 return kanjiclass1->read_data8(KANJIROM_DATA_HI);
864 uint8_t FM7_MAINIO::read_kanjidata_right(void)
866 #if defined(CAPABLE_JCOMMCARD) && !(defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS))
867 if(jcommcard != NULL) {
868 return (uint8_t)(jcommcard->read_io8(3));
871 if(!connect_kanjiroml1) {
874 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
875 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
876 if(!stat_kanjirom) return 0xff;
879 return kanjiclass1->read_data8(KANJIROM_DATA_LO);
885 #ifdef CAPABLE_KANJI_CLASS2
886 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
887 void FM7_MAINIO::write_kanjiaddr_hi_l2(uint8_t addr)
889 if(!connect_kanjiroml2) return;
890 if(!stat_kanjirom) return;
891 kanjiclass2->write_data8(KANJIROM_ADDR_HI, addr);
895 void FM7_MAINIO::write_kanjiaddr_lo_l2(uint8_t addr)
897 if(!connect_kanjiroml2) return;
898 if(!stat_kanjirom) return;
899 kanjiclass2->write_data8(KANJIROM_ADDR_LO, addr);
904 uint8_t FM7_MAINIO::read_kanjidata_left_l2(void)
906 if(!connect_kanjiroml2) return 0xff;
907 if(!stat_kanjirom) return 0xff;
910 return kanjiclass2->read_data8(KANJIROM_DATA_HI);
916 uint8_t FM7_MAINIO::read_kanjidata_right_l2(void)
918 if(!connect_kanjiroml2) return 0xff;
919 if(!stat_kanjirom) return 0xff;
922 return kanjiclass2->read_data8(KANJIROM_DATA_LO);
929 uint32_t FM7_MAINIO::read_signal(int id)
933 case FM7_MAINIO_KEYBOARDIRQ_MASK:
934 retval = (irqmask_keyboard) ? 0xffffffff : 0x00000000;
944 void FM7_MAINIO::write_signal(int id, uint32_t data, uint32_t mask)
947 val_b = ((data & mask) != 0);
950 //case SIG_FM7_SUB_HALT:
951 // mainmem->write_signal(SIG_FM7_SUB_HALT, data, mask);
953 case FM7_MAINIO_CLOCKMODE: // fd00
959 this->write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
961 case FM7_MAINIO_CMT_RECV: // FD02
962 cmt_indat = val_b ^ cmt_invert;
964 case FM7_MAINIO_CMT_INVERT: // FD02
967 case FM7_MAINIO_TIMERIRQ: //
968 set_irq_timer(val_b);
970 case FM7_MAINIO_LPTIRQ: //
971 set_irq_printer(val_b);
973 case FM7_MAINIO_LPT_BUSY:
976 case FM7_MAINIO_LPT_ERROR:
977 lpt_error_inv = val_b;
979 case FM7_MAINIO_LPT_ACK:
981 bool f = lpt_ackng_inv;
982 lpt_ackng_inv = val_b;
983 if((lpt_ackng_inv == true) && (f == false)) set_irq_printer(true);
986 case FM7_MAINIO_LPT_PAPER_EMPTY:
989 case FM7_MAINIO_LPT_DET1:
992 case FM7_MAINIO_LPT_DET2:
995 case FM7_MAINIO_KEYBOARDIRQ: //
996 set_irq_keyboard(val_b);
999 case FM7_MAINIO_PUSH_BREAK:
1000 set_break_key(val_b);
1002 #if defined(FM77AV_VARIANTS)
1003 case FM7_MAINIO_HOT_RESET:
1007 case FM7_MAINIO_SUB_ATTENTION:
1008 if(val_b) set_sub_attention(true);
1011 case FM7_MAINIO_EXTDET:
1012 extdet_neg = !val_b;
1014 case FM7_MAINIO_BEEP:
1017 case FM7_MAINIO_PSG_IRQ:
1019 #if defined(WITH_Z80)
1020 case FM7_MAINIO_RUN_Z80:
1021 if((req_z80run)/* && (val_b) */) {
1022 if(z80 != NULL) z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
1024 //z80->reset(); // OK?
1027 case FM7_MAINIO_RUN_6809:
1028 if(!(req_z80run) /* && (val_b) */ && (z80_run)) {
1031 maincpu->write_signal(SIG_CPU_HALTREQ, 0, 1);
1035 case FM7_MAINIO_UART0_RXRDY:
1036 set_irq_rxrdy(val_b & rs232c_enabled);
1038 case FM7_MAINIO_UART0_TXRDY:
1039 set_irq_txrdy(val_b & rs232c_enabled);
1041 case FM7_MAINIO_UART0_SYNDET:
1042 set_irq_syndet(val_b & rs232c_enabled);
1044 case FM7_MAINIO_UART0_DCD:
1047 case FM7_MAINIO_MODEM_TXRDY:
1048 modem_txrdy = val_b;
1051 case FM7_MAINIO_MODEM_RXRDY:
1052 modem_rxrdy = val_b;
1055 case FM7_MAINIO_MODEM_SYNDET:
1056 modem_syndet = val_b;
1059 case FM7_MAINIO_MIDI_TXRDY:
1063 case FM7_MAINIO_MIDI_RXRDY:
1067 case FM7_MAINIO_MIDI_SYNDET:
1068 midi_syndet = val_b;
1072 //#if !defined(_FM8)
1073 case FM7_MAINIO_OPN_IRQ:
1074 if(!connect_opn) break;
1075 intstat_opn = val_b;
1078 case FM7_MAINIO_WHG_IRQ:
1079 if(!connect_whg) break;
1080 intstat_whg = val_b;
1083 case FM7_MAINIO_THG_IRQ:
1084 if(!connect_thg) break;
1085 intstat_thg = val_b;
1089 case FM7_MAINIO_FDC_DRQ:
1092 case FM7_MAINIO_FDC_IRQ:
1095 #if defined(HAS_2HD)
1096 case FM7_MAINIO_FDC_DRQ_2HD:
1097 set_drq_mfd_2HD(val_b);
1099 case FM7_MAINIO_FDC_IRQ_2HD:
1100 set_irq_mfd_2HD(val_b);
1103 #if defined(HAS_DMA)
1104 case FM7_MAINIO_DMA_INT:
1105 intstat_dma = val_b;
1109 #if defined(_FM77AV_VARIANTS)
1110 case SIG_DISPLAY_DISPLAY:
1117 case SIG_DISPLAY_VSYNC:
1124 case SIG_DISPLAY_MODE320:
1136 uint8_t FM7_MAINIO::get_irqstat_fd03(void)
1140 uint8_t backup = irqstat_reg0;
1142 extirq = intstat_opn | intstat_whg | intstat_thg;
1143 extirq = extirq | intstat_syndet | intstat_rxrdy | intstat_txrdy;
1144 # if defined(HAS_2HD)
1146 extirq = extirq | irqstat_fdc_2hd;
1148 extirq = extirq | irqstat_fdc;
1151 extirq = extirq | irqstat_fdc;
1153 # if defined(HAS_DMA)
1154 extirq = extirq | intstat_dma;
1157 irqstat_reg0 &= ~0x08;
1159 irqstat_reg0 |= 0x08;
1161 val = irqstat_reg0 | 0xf0;
1162 // Not call do_irq() twice. 20151221
1163 irqstat_timer = false;
1164 irqstat_printer = false;
1165 irqstat_reg0 |= 0x06;
1166 //if(backup != irqstat_reg0) do_irq();
1167 //this->out_debug_log(_T("IO: Check IRQ Status."));
1173 uint8_t FM7_MAINIO::get_extirq_fd17(void)
1176 if(intstat_opn && connect_opn) val &= ~0x08;
1177 if(intstat_mouse) val &= ~0x04;
1181 void FM7_MAINIO::set_ext_fd17(uint8_t data)
1183 if((data & 0x04) != 0) {
1184 mouse_enable = true;
1186 mouse_enable = false;
1190 #if defined(_FM77AV_VARIANTS)
1192 uint8_t FM7_MAINIO::subsystem_read_status(void)
1199 uint32_t FM7_MAINIO::read_io8(uint32_t addr)
1200 { // This is only for debug.
1201 addr = addr & 0xfff;
1203 return io_w_latch[addr];
1204 } else if(addr < 0x500) {
1205 uint32_t ofset = addr & 0xff;
1206 uint opnbank = (addr - 0x100) >> 8;
1207 return opn_regs[opnbank][ofset];
1208 } else if(addr < 0x600) {
1209 return mainmem->read_data8(addr - 0x500 + FM7_MAINIO_MMR_BANK);
1214 uint32_t FM7_MAINIO::read_dma_io8(uint32_t addr)
1216 return this->read_data8(addr & 0xff);
1219 uint32_t FM7_MAINIO::read_dma_data8(uint32_t addr)
1221 return this->read_data8(addr & 0xff);
1224 uint32_t FM7_MAINIO::read_data8(uint32_t addr)
1227 uint32_t mmr_segment;
1228 if(addr < FM7_MAINIO_IS_BASICROM) {
1231 #if defined(HAS_MMR)
1232 if((addr < 0x90) && (addr >= 0x80)) {
1233 mmr_segment = mainmem->read_data8(FM7_MAINIO_MMR_SEGMENT);
1234 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1235 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1236 mmr_segment &= 0x07;
1238 mmr_segment &= 0x03;
1240 return mainmem->read_data8(addr - 0x80 + FM7_MAINIO_MMR_BANK + mmr_segment * 16);
1243 // if((addr >= 0x0006) && !(addr == 0x1f) && !(addr == 0x0b)) printf("MAINIO: READ: %08x \n", addr);
1246 retval = (uint32_t) get_port_fd00();
1249 //#if !defined(_FM8)
1250 retval = keyboard->read_data8(0x01) & 0xff;
1254 retval = (uint32_t) get_port_fd02();
1257 //#if !defined(_FM8)
1258 retval = (uint32_t) get_irqstat_fd03();
1262 retval = (uint32_t) get_fd04();
1265 retval = (uint32_t) get_fd05();
1267 case 0x06: // RS-232C
1269 if(uart_enabled[0] && rs232c_enabled) {
1270 if(uart[0] != NULL) retval = uart[0]->read_io8(addr & 1);
1273 case 0x08: // Light pen
1277 #if defined(_FM77AV_VARIANTS)
1279 retval = ((config.boot_mode & 3) == 0) ? 0xfe : 0xff;
1280 #if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1281 retval &= (uint32_t)(~0x04);
1282 if(!rs232c_dcd) retval |= 0x04;
1286 case 0x0e: // PSG DATA
1287 retval = (uint32_t) get_psg();
1288 //printf("PSG DATA READ val=%02x\n", retval);
1294 #if defined(_FM77AV_VARIANTS)
1296 retval = subsystem_read_status();
1299 //printf("OPN CMD READ \n");
1301 case 0x16: // OPN DATA
1302 retval = (uint32_t) get_opn(0);
1305 retval = (uint32_t) get_extirq_fd17();
1308 #if defined(HAS_2HD)
1309 case 0x18: // FDC: STATUS
1310 if(stat_fdmode_2hd) {
1311 retval = (uint32_t) get_fdc_stat_2HD();
1313 retval = (uint32_t) get_fdc_stat();
1316 //printf("FDC: READ STATUS %02x PC=%04x\n", retval, maincpu->get_pc());
1318 case 0x19: // FDC: Track
1319 if(stat_fdmode_2hd) {
1320 retval = (uint32_t) get_fdc_track_2HD();
1322 retval = (uint32_t) get_fdc_track();
1324 //printf("FDC: READ TRACK REG %02x\n", retval);
1326 case 0x1a: // FDC: Sector
1327 if(stat_fdmode_2hd) {
1328 retval = (uint32_t) get_fdc_sector_2HD();
1330 retval = (uint32_t) get_fdc_sector();
1332 //printf("FDC: READ SECTOR REG %02x\n", retval);
1334 case 0x1b: // FDC: Data
1335 if(stat_fdmode_2hd) {
1336 retval = (uint32_t) get_fdc_data_2HD();
1338 retval = (uint32_t) get_fdc_data();
1342 if(stat_fdmode_2hd) {
1343 retval = (uint32_t) get_fdc_fd1c_2HD();
1345 retval = (uint32_t) get_fdc_fd1c();
1347 //printf("FDC: READ HEAD REG %02x\n", retval);
1350 if(stat_fdmode_2hd) {
1351 retval = (uint32_t) get_fdc_motor_2HD();
1353 retval = (uint32_t) get_fdc_motor();
1355 //printf("FDC: READ MOTOR REG %02x\n", retval);
1358 if(stat_fdmode_2hd) {
1359 retval = (uint32_t) get_fdc_fd1e_2HD();
1361 retval = (uint32_t) get_fdc_fd1e();
1363 //printf("FDC: READ MOTOR REG %02x\n", retval);
1366 if(stat_fdmode_2hd) {
1367 retval = (uint32_t) fdc_getdrqirq_2HD();
1369 retval = (uint32_t) fdc_getdrqirq();
1373 case 0x18: // FDC: STATUS
1374 retval = (uint32_t) get_fdc_stat();
1376 //printf("FDC: READ STATUS %02x PC=%04x\n", retval, maincpu->get_pc());
1378 case 0x19: // FDC: Track
1379 retval = (uint32_t) get_fdc_track();
1380 //printf("FDC: READ TRACK REG %02x\n", retval);
1382 case 0x1a: // FDC: Sector
1383 retval = (uint32_t) get_fdc_sector();
1384 //printf("FDC: READ SECTOR REG %02x\n", retval);
1386 case 0x1b: // FDC: Data
1387 retval = (uint32_t) get_fdc_data();
1390 retval = (uint32_t) get_fdc_fd1c();
1391 //printf("FDC: READ HEAD REG %02x\n", retval);
1394 retval = (uint32_t) get_fdc_motor();
1395 //printf("FDC: READ MOTOR REG %02x\n", retval);
1398 retval = (uint32_t) get_fdc_fd1e();
1399 //printf("FDC: READ MOTOR REG %02x\n", retval);
1402 retval = (uint32_t) fdc_getdrqirq();
1405 case 0x22: // Kanji ROM
1406 retval = (uint32_t) read_kanjidata_left();
1408 case 0x23: // Kanji ROM
1409 retval = (uint32_t) read_kanjidata_right();
1411 #if defined(CAPABLE_JCOMMCARD)
1414 # if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
1418 if(jcommcard != NULL) {
1419 retval = (uint32_t)(jcommcard->read_io8(addr));
1425 #if defined(CAPABLE_KANJI_CLASS2)
1426 case 0x2e: // Kanji ROM Level2
1427 retval = (uint32_t) read_kanjidata_left_l2();
1429 case 0x2f: // Kanji ROM Level2
1430 retval = (uint32_t) read_kanjidata_right_l2();
1433 //#if !defined(_FM8)
1434 case 0x37: // Multi page
1435 //retval = (uint32_t)display->read_data8(DISPLAY_ADDR_MULTIPAGE);
1439 if(uart_enabled[1]) {
1440 if(uart[1] != NULL) retval = uart[1]->read_io8(addr & 1);
1445 case 0x45: // WHG CMD
1447 case 0x46: // WHG DATA
1448 retval = (uint32_t) get_opn(1);
1451 retval = (uint32_t) get_extirq_whg();
1453 case 0x51: // THG CMD
1455 case 0x52: // THG DATA
1456 retval = (uint32_t) get_opn(2);
1459 retval = (uint32_t) get_extirq_thg();
1462 #if defined(HAS_MMR)
1466 if(mainmem->read_signal(FM7_MAINIO_BOOTRAM_RW) != 0) retval |= 0x01;
1467 if(mainmem->read_signal(FM7_MAINIO_WINDOW_ENABLED) != 0) retval |= 0x40;
1468 if(mainmem->read_signal(FM7_MAINIO_MMR_ENABLED) != 0) retval |= 0x80;
1471 #if defined(_FM77AV40SX) || defined(_FM77AV40EX)
1474 if(mainmem->read_signal(FM7_MAINIO_FASTMMR_ENABLED) != 0) retval |= 0x08;
1475 if(mainmem->read_signal(FM7_MAINIO_EXTROM) != 0) retval |= 0x80;
1478 #if defined(HAS_DMA)
1483 retval = dmac->read_data8(dma_addr);
1488 if(uart_enabled[2]) {
1489 if(uart[2] != NULL) retval = uart[2]->read_io8(addr & 1);
1495 //#if !defined(_FM8)
1496 if((addr < 0x40) && (addr >= 0x38)) {
1497 addr = (addr - 0x38) + FM7_SUBMEM_OFFSET_DPALETTE;
1498 return (uint32_t) display->read_data8(addr);
1503 } else if(addr == FM7_MAINIO_CLOCKMODE) {
1504 return (uint32_t)get_clockmode();
1506 #if defined(_FM77AV_VARIANTS)
1507 else if(addr == FM7_MAINIO_SUBMONITOR_ROM) {
1508 retval = sub_monitor_type & 0x03;
1510 } else if(addr == FM7_MAINIO_SUBMONITOR_RAM) {
1511 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1512 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1513 retval = ((sub_monitor_type & 0x04) != 0) ? 0xffffffff : 0x00000000;
1520 //if((addr >= 0x0006) && (addr != 0x1f)) printf("MAINIO: READ: %08x DATA=%08x\n", addr);
1524 void FM7_MAINIO::write_dma_io8(uint32_t addr, uint32_t data)
1526 this->write_data8(addr & 0xff, data);
1529 void FM7_MAINIO::write_dma_data8(uint32_t addr, uint32_t data)
1531 this->write_data8(addr & 0xff, data);
1535 void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
1538 uint32_t mmr_segment;
1539 if(addr < FM7_MAINIO_IS_BASICROM) {
1541 io_w_latch[addr] = data;
1542 #if defined(HAS_MMR)
1543 if((addr < 0x90) && (addr >= 0x80)) {
1544 mmr_segment = mainmem->read_data8(FM7_MAINIO_MMR_SEGMENT);
1545 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1546 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1547 mmr_segment &= 0x07;
1549 mmr_segment &= 0x03;
1551 mainmem->write_data8(FM7_MAINIO_MMR_BANK + mmr_segment * 16 + addr - 0x80, data);
1557 set_port_fd00((uint8_t)data);
1561 lpt_outdata = (uint8_t)data;
1563 case 0: // Write to file
1564 printer->write_signal(SIG_PRINTER_DATA, data, 0xff);
1568 joystick->write_data8(0x01, data);
1573 set_port_fd02((uint8_t)data);
1582 set_fd05((uint8_t)data);
1584 case 0x06: // RS-232C
1586 if(uart_enabled[0] && rs232c_enabled) {
1587 if(uart[0] != NULL) uart[0]->write_io8(addr & 1, data);
1590 case 0x08: // Light pen
1595 #if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1596 if(rs232c_dtr != NULL) {
1597 if((data & 0x04) != 0) {
1598 rs232c_dtr->write_signal(SIG_AND_BIT_1, 0, 1);
1600 rs232c_dtr->write_signal(SIG_AND_BIT_1, 1, 1);
1603 rs232c_enabled = ((data & 0x01) != 0) ? true : false;
1607 //printf("PSG CMD WRITE val=%02x\n", data);
1611 //printf("PSG DATA WRITE val=%02x\n", data);
1617 #if defined(_FM77AV_VARIANTS)
1619 flag = ((data & 0x02) == 0) ? true : false;
1620 mainmem->write_signal(FM7_MAINIO_INITROM_ENABLED, (flag) ? 0xffffffff : 0 , 0xffffffff);
1623 display->write_signal(SIG_DISPLAY_MODE320, data, 0x40);
1625 reg_fd12 |= (data & 0x40);
1628 sub_monitor_type = data & 0x07;
1629 display->write_signal(SIG_FM7_SUB_BANK, sub_monitor_type, 0x07);
1632 case 0x15: // OPN CMD
1633 //printf("OPN CMD WRITE val=%02x\n", data);
1634 set_opn_cmd(0, data);
1636 case 0x16: // OPN DATA
1637 //printf("OPN DATA WRITE val=%02x\n", data);
1641 set_ext_fd17((uint8_t)data);
1643 #if defined(HAS_2HD)
1644 case 0x18: // FDC: COMMAND
1645 if(stat_fdmode_2hd) {
1646 set_fdc_cmd_2HD((uint8_t)data);
1648 set_fdc_cmd((uint8_t)data);
1650 //printf("FDC: WRITE CMD %02x\n", data);
1652 case 0x19: // FDC: Track
1653 if(stat_fdmode_2hd) {
1654 set_fdc_track_2HD((uint8_t)data);
1656 set_fdc_track((uint8_t)data);
1658 //printf("FDC: WRITE TRACK REG %02x\n", data);
1660 case 0x1a: // FDC: Sector
1661 if(stat_fdmode_2hd) {
1662 set_fdc_sector_2HD((uint8_t)data);
1664 set_fdc_sector((uint8_t)data);
1666 //printf("FDC: WRITE SECTOR REG %02x\n", data);
1668 case 0x1b: // FDC: Data
1669 if(stat_fdmode_2hd) {
1670 set_fdc_data_2HD((uint8_t)data);
1672 set_fdc_data((uint8_t)data);
1676 if(stat_fdmode_2hd) {
1677 set_fdc_fd1c_2HD((uint8_t)data);
1679 set_fdc_fd1c((uint8_t)data);
1681 //printf("FDC: WRITE HEAD REG %02x\n", data);
1684 if(stat_fdmode_2hd) {
1685 set_fdc_fd1d_2HD((uint8_t)data);
1687 set_fdc_fd1d((uint8_t)data);
1689 //printf("FDC: WRITE MOTOR REG %02x\n", data);
1692 if(stat_fdmode_2hd) {
1693 set_fdc_fd1e_2HD((uint8_t)data);
1695 set_fdc_fd1e((uint8_t)data);
1702 case 0x18: // FDC: COMMAND
1703 set_fdc_cmd((uint8_t)data);
1704 //printf("FDC: WRITE CMD %02x\n", data);
1706 case 0x19: // FDC: Track
1707 set_fdc_track((uint8_t)data);
1708 //printf("FDC: WRITE TRACK REG %02x\n", data);
1710 case 0x1a: // FDC: Sector
1711 set_fdc_sector((uint8_t)data);
1712 //printf("FDC: WRITE SECTOR REG %02x\n", data);
1714 case 0x1b: // FDC: Data
1715 set_fdc_data((uint8_t)data);
1718 set_fdc_fd1c((uint8_t)data);
1719 //printf("FDC: WRITE HEAD REG %02x\n", data);
1722 set_fdc_fd1d((uint8_t)data);
1723 //printf("FDC: WRITE MOTOR REG %02x\n", data);
1726 set_fdc_fd1e((uint8_t)data);
1732 case 0x20: // Kanji ROM
1733 write_kanjiaddr_hi((uint8_t)data);
1736 case 0x21: // Kanji ROM
1737 write_kanjiaddr_lo((uint8_t)data);
1739 #if defined(CAPABLE_JCOMMCARD)
1740 # if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
1746 if(jcommcard != NULL) jcommcard->write_io8(addr, data);
1749 case 0x2c: // Kanji ROM(DUP)
1750 #if defined(CAPABLE_KANJI_CLASS2)
1751 write_kanjiaddr_hi_l2((uint8_t)data);
1753 //write_kanjiaddr_hi((uint8_t)data);
1756 case 0x2d: // Kanji ROM(DUP)
1757 #if defined(CAPABLE_KANJI_CLASS2)
1758 write_kanjiaddr_lo_l2((uint8_t)data);
1760 //write_kanjiaddr_lo((uint8_t)data);
1763 #if defined(CAPABLE_DICTROM)
1765 mainmem->write_signal(FM7_MAINIO_EXTBANK, data, 0xff);
1768 #if defined(_FM77AV_VARIANTS)
1770 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_HI, data);
1773 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_LO, data);
1776 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_B, data);
1779 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_R, data);
1782 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_G, data);
1785 //#if !defined(_FM8)
1786 case 0x37: // Multi page
1787 display->write_signal(SIG_DISPLAY_MULTIPAGE, data, 0x00ff);
1791 if(uart_enabled[1]) {
1792 if(uart[1] != NULL) uart[1]->write_io8(addr & 1, data);
1796 modem_irqmask_txrdy = ((data & 0x20) != 0);
1797 modem_irqmask_rxrdy = ((data & 0x40) != 0);
1801 case 0x45: // WHG CMD
1802 set_opn_cmd(1, data);
1804 case 0x46: // WHG DATA
1809 case 0x51: // THG CMD
1810 set_opn_cmd(2, data);
1812 case 0x52: // THG DATA
1818 #if defined(HAS_MMR)
1820 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1821 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1822 mmr_segment = data & 7;
1824 // printf("MMR SEGMENT: %02x\n", data & 3);
1825 mmr_segment = data & 3;
1827 mainmem->write_data8(FM7_MAINIO_MMR_SEGMENT, (uint32_t)mmr_segment);
1830 mainmem->write_data8(FM7_MAINIO_WINDOW_OFFSET, (uint32_t)(data & 0x00ff));
1833 mainmem->write_signal(FM7_MAINIO_BOOTRAM_RW, data, 0x01);
1834 mainmem->write_signal(FM7_MAINIO_WINDOW_ENABLED, data , 0x40);
1835 //this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
1836 //mainmem->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
1837 mainmem->write_signal(FM7_MAINIO_MMR_ENABLED, data, 0x80);
1841 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1842 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1844 mainmem->write_signal(FM7_MAINIO_MMR_EXTENDED, data, 0x80);
1845 mainmem->write_signal(FM7_MAINIO_MEM_REFRESH_FAST, data, 0x04);
1846 mainmem->write_signal(FM7_MAINIO_WINDOW_FAST , data, 0x01);
1849 # if defined(_FM77AV40SX) || defined(_FM77AV40EX)
1851 mainmem->write_signal(FM7_MAINIO_FASTMMR_ENABLED, data, 0x08);
1852 mainmem->write_signal(FM7_MAINIO_EXTROM, data , 0x80);
1856 #if defined(HAS_DMA)
1858 dma_addr = data & 0x1f;
1861 dmac->write_data8(dma_addr, data);
1862 //this->out_debug_log(_T("IO: Wrote DMA %02x to reg %02x\n"), data, dma_addr);
1868 if(uart_enabled[2]) {
1869 if(uart[2] != NULL) uart[2]->write_io8(addr & 1, data);
1873 //printf("MAIN: Write I/O Addr=%08x DATA=%02x\n", addr, data);
1876 if((addr < 0x40) && (addr >= 0x38)) {
1877 addr = (addr - 0x38) | FM7_SUBMEM_OFFSET_DPALETTE;
1878 display->write_data8(addr, (uint8_t)data);
1882 } else if(addr == FM7_MAINIO_CLOCKMODE) {
1883 set_clockmode((uint8_t)data);
1886 //if((addr >= 0x0006) && !(addr == 0x1f)) printf("MAINIO: WRITE: %08x DATA=%08x\n", addr, data);
1889 void FM7_MAINIO::event_callback(int event_id, int err)
1891 // printf("MAIN EVENT id=%d\n", event_id);
1893 case EVENT_BEEP_OFF:
1896 case EVENT_BEEP_CYCLE:
1899 case EVENT_UP_BREAK:
1900 keyboard->write_signal(SIG_FM7KEY_OVERRIDE_PRESS_BREAK, 0, 0xffffffff);
1901 set_break_key(false);
1903 //#if !defined(_FM8)
1904 case EVENT_TIMERIRQ_ON:
1905 //if(!irqmask_timer) set_irq_timer(true);
1906 set_irq_timer(!irqmask_timer);
1909 case EVENT_FD_MOTOR_ON:
1910 set_fdc_motor(true);
1911 event_fdc_motor = -1;
1913 case EVENT_FD_MOTOR_OFF:
1914 set_fdc_motor(false);
1915 event_fdc_motor = -1;
1917 #if defined(HAS_2HD)
1918 case EVENT_FD_MOTOR_ON_2HD:
1919 set_fdc_motor_2HD(true);
1920 event_fdc_motor_2HD = -1;
1922 case EVENT_FD_MOTOR_OFF_2HD:
1923 set_fdc_motor_2HD(false);
1924 event_fdc_motor_2HD = -1;
1926 case EVENT_FD_NMI_2HD:
1931 case EVENT_PRINTER_RESET_COMPLETED:
1932 this->write_signals(&printer_reset_bus, 0x00);
1940 void FM7_MAINIO::update_config()
1942 switch(config.cpu_type){
1950 this->write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
1953 void FM7_MAINIO::event_vline(int v, int clock)
1957 #define STATE_VERSION 13
1958 void FM7_MAINIO::save_state_main(FILEIO *state_fio)
1963 for(addr = 0; addr < 0x100; addr++) state_fio->FputUint8(io_w_latch[addr]);
1965 state_fio->FputBool(clock_fast);
1966 state_fio->FputBool(lpt_strobe);
1967 state_fio->FputBool(lpt_slctin);
1968 state_fio->FputBool(beep_flag);
1969 state_fio->FputBool(beep_snd);
1972 state_fio->FputUint8(lpt_outdata);
1974 state_fio->FputBool(cmt_indat);
1975 state_fio->FputBool(cmt_invert);
1976 state_fio->FputBool(lpt_det2);
1977 state_fio->FputBool(lpt_det1);
1978 state_fio->FputBool(lpt_pe);
1979 state_fio->FputBool(lpt_ackng_inv);
1980 state_fio->FputBool(lpt_error_inv);
1981 state_fio->FputUint8(irqmask_reg0);
1983 state_fio->FputBool(irqmask_syndet);
1984 state_fio->FputBool(irqmask_rxrdy);
1985 state_fio->FputBool(irqmask_txrdy);
1986 state_fio->FputBool(irqmask_mfd);
1987 state_fio->FputBool(irqmask_timer);
1988 state_fio->FputBool(irqmask_printer);
1989 state_fio->FputBool(irqmask_keyboard);
1991 state_fio->FputBool(irqreq_syndet);
1992 state_fio->FputBool(irqreq_rxrdy);
1993 state_fio->FputBool(irqreq_txrdy);
1994 state_fio->FputBool(irqreq_printer);
1995 state_fio->FputBool(irqreq_keyboard);
1997 state_fio->FputUint8(irqstat_reg0);
1999 state_fio->FputBool(irqstat_timer);
2000 state_fio->FputBool(irqstat_printer);
2001 state_fio->FputBool(irqstat_keyboard);
2004 #if defined(_FM77_VARIANTS)
2005 state_fio->FputBool(stat_fdmode_2hd);
2006 state_fio->FputBool(stat_kanjirom);
2007 #elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2008 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2009 state_fio->FputBool(stat_kanjirom);
2011 state_fio->FputBool(firq_break_key);
2012 state_fio->FputBool(firq_sub_attention);
2014 state_fio->FputBool(intmode_fdc);
2016 state_fio->FputBool(extdet_neg);
2017 state_fio->FputBool(sub_halt);
2018 state_fio->FputBool(sub_cancel);
2020 state_fio->FputBool(intstat_syndet);
2021 state_fio->FputBool(intstat_rxrdy);
2022 state_fio->FputBool(intstat_txrdy);
2025 state_fio->FputBool(intstat_opn);
2026 state_fio->FputBool(intstat_mouse);
2027 state_fio->FputBool(mouse_enable);
2029 state_fio->FputBool(intstat_whg);
2030 state_fio->FputBool(intstat_thg);
2033 state_fio->FputBool(connect_fdc);
2034 state_fio->FputUint8(fdc_statreg);
2035 state_fio->FputUint8(fdc_cmdreg);
2036 state_fio->FputUint8(fdc_trackreg);
2037 state_fio->FputUint8(fdc_sectreg);
2038 state_fio->FputUint8(fdc_datareg);
2039 state_fio->FputUint8(fdc_headreg);
2040 state_fio->FputUint8(fdc_drvsel);
2041 state_fio->FputUint8(irqreg_fdc);
2042 state_fio->FputBool(fdc_motor);
2043 state_fio->FputBool(irqstat_fdc);
2045 state_fio->FputBool(connect_kanjiroml1);
2046 #if defined(_FM77AV_VARIANTS)
2047 state_fio->FputBool(connect_kanjiroml2);
2049 state_fio->FputBool(boot_ram);
2050 state_fio->FputBool(hotreset);
2052 state_fio->FputUint8(sub_monitor_type);
2058 state_fio->FputInt32_BE(event_beep);
2059 state_fio->FputInt32_BE(event_beep_oneshot);
2060 state_fio->FputInt32_BE(event_timerirq);
2063 state_fio->FputInt32_BE(event_fdc_motor);
2064 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)|| \
2065 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
2066 for(int ch = 0; ch < 4; ch++) state_fio->FputUint8(fdc_drive_table[ch]);
2067 state_fio->FputUint8(fdc_reg_fd1e);
2069 #if defined(HAS_DMA)
2070 state_fio->FputBool(intstat_dma);
2071 state_fio->FputUint8(dma_addr & 0x1f);
2073 #if defined(_FM77AV_VARIANTS)
2074 state_fio->FputUint8(reg_fd12);
2078 state_fio->FputBool(req_z80run);
2079 state_fio->FputBool(z80_run);
2082 state_fio->FputBool(rs232c_enabled);
2083 state_fio->FputBool(rs232c_dcd);
2084 for(int i = 0; i < 3; i++) state_fio->FputBool(uart_enabled[i]);
2085 state_fio->FputBool(modem_irqmask_rxrdy);
2086 state_fio->FputBool(modem_irqmask_txrdy);
2087 state_fio->FputBool(modem_syndet);
2088 state_fio->FputBool(modem_rxrdy);
2089 state_fio->FputBool(modem_txrdy);
2091 state_fio->FputBool(midi_uart_irqmask);
2092 state_fio->FputBool(midi_syndet);
2093 state_fio->FputBool(midi_rxrdy);
2094 state_fio->FputBool(midi_txrdy);
2095 #if defined(HAS_2HD)
2096 state_fio->FputInt32_BE(event_fdc_motor_2HD);
2097 state_fio->FputBool(connect_fdc_2HD);
2098 state_fio->FputUint8(fdc_2HD_statreg);
2099 state_fio->FputUint8(fdc_2HD_cmdreg);
2100 state_fio->FputUint8(fdc_2HD_trackreg);
2101 state_fio->FputUint8(fdc_2HD_sectreg);
2102 state_fio->FputUint8(fdc_2HD_datareg);
2103 state_fio->FputUint8(fdc_2HD_headreg);
2104 state_fio->FputUint8(fdc_2HD_drvsel);
2105 state_fio->FputBool(irqreg_fdc_2HD);
2106 state_fio->FputBool(fdc_2HD_motor);
2107 //state_fio->FputBool(irqstat_fdc);
2111 void FM7_MAINIO::save_state(FILEIO *state_fio)
2115 state_fio->FputUint32_BE(STATE_VERSION);
2116 state_fio->FputInt32_BE(this_device_id);
2117 this->out_debug_log(_T("Save State: MAINIO: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
2119 save_state_main(state_fio);
2122 state_fio->FputBool(connect_opn);
2123 state_fio->FputBool(connect_whg);
2124 state_fio->FputBool(connect_thg);
2126 state_fio->FputBool(opn_psg_77av);
2127 for(ch = 0; ch < 4; ch++) {
2128 state_fio->FputUint32_BE(opn_address[ch]);
2129 state_fio->FputUint32_BE(opn_data[ch]);
2130 state_fio->FputUint32_BE(opn_stat[ch]);
2131 state_fio->FputUint32_BE(opn_cmdreg[ch]);
2132 state_fio->FputUint32_BE(opn_ch3mode[ch]);
2134 #if defined(HAS_2HD)
2135 state_fio->FputInt32_BE(event_2hd_nmi);
2136 state_fio->FputUint32_BE(nmi_delay);
2137 state_fio->FputBool(irqstat_fdc_2hd);
2138 state_fio->FputBool(drqstat_fdc_2hd);
2142 bool FM7_MAINIO::load_state_main(FILEIO *state_fio, uint32_t version)
2147 for(addr = 0; addr < 0x100; addr++) io_w_latch[addr] = state_fio->FgetUint8();
2149 clock_fast = state_fio->FgetBool();
2150 lpt_strobe = state_fio->FgetBool();
2151 lpt_slctin = state_fio->FgetBool();
2152 beep_flag = state_fio->FgetBool();
2153 beep_snd = state_fio->FgetBool();
2156 lpt_outdata = state_fio->FgetUint8();
2158 cmt_indat = state_fio->FgetBool();
2159 cmt_invert = state_fio->FgetBool();
2160 lpt_det2 = state_fio->FgetBool();
2161 lpt_det1 = state_fio->FgetBool();
2162 lpt_pe = state_fio->FgetBool();
2163 lpt_ackng_inv = state_fio->FgetBool();
2164 lpt_error_inv = state_fio->FgetBool();
2165 irqmask_reg0 = state_fio->FgetUint8();
2167 irqmask_syndet = state_fio->FgetBool();
2168 irqmask_rxrdy = state_fio->FgetBool();
2169 irqmask_txrdy = state_fio->FgetBool();
2170 irqmask_mfd = state_fio->FgetBool();
2171 irqmask_timer = state_fio->FgetBool();
2172 irqmask_printer = state_fio->FgetBool();
2173 irqmask_keyboard = state_fio->FgetBool();
2175 irqreq_syndet = state_fio->FgetBool();
2176 irqreq_rxrdy = state_fio->FgetBool();
2177 irqreq_txrdy = state_fio->FgetBool();
2178 irqreq_printer = state_fio->FgetBool();
2179 irqreq_keyboard = state_fio->FgetBool();
2181 irqstat_reg0 = state_fio->FgetUint8();
2183 irqstat_timer = state_fio->FgetBool();
2184 irqstat_printer = state_fio->FgetBool();
2185 irqstat_keyboard = state_fio->FgetBool();
2188 #if defined(_FM77_VARIANTS)
2189 stat_fdmode_2hd = state_fio->FgetBool();
2190 stat_kanjirom = state_fio->FgetBool();
2191 #elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2192 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2193 stat_kanjirom = state_fio->FgetBool();
2195 firq_break_key = state_fio->FgetBool();
2196 firq_sub_attention = state_fio->FgetBool();
2198 intmode_fdc = state_fio->FgetBool();
2200 extdet_neg = state_fio->FgetBool();
2201 sub_halt = state_fio->FgetBool();
2202 sub_cancel = state_fio->FgetBool();
2204 intstat_syndet = state_fio->FgetBool();
2205 intstat_rxrdy = state_fio->FgetBool();
2206 intstat_txrdy = state_fio->FgetBool();
2208 intstat_opn = state_fio->FgetBool();
2209 intstat_mouse = state_fio->FgetBool();
2210 mouse_enable = state_fio->FgetBool();
2212 intstat_whg = state_fio->FgetBool();
2213 intstat_thg = state_fio->FgetBool();
2216 connect_fdc = state_fio->FgetBool();
2217 fdc_statreg = state_fio->FgetUint8();
2218 fdc_cmdreg = state_fio->FgetUint8();
2219 fdc_trackreg = state_fio->FgetUint8();
2220 fdc_sectreg = state_fio->FgetUint8();
2221 fdc_datareg = state_fio->FgetUint8();
2222 fdc_headreg = state_fio->FgetUint8();
2223 fdc_drvsel = state_fio->FgetUint8();
2224 irqreg_fdc = state_fio->FgetUint8();
2225 fdc_motor = state_fio->FgetBool();
2226 irqstat_fdc = state_fio->FgetBool();
2229 connect_kanjiroml1 = state_fio->FgetBool();
2230 #if defined(_FM77AV_VARIANTS)
2231 connect_kanjiroml2 = state_fio->FgetBool();
2232 boot_ram = state_fio->FgetBool();
2233 hotreset = state_fio->FgetBool();
2235 sub_monitor_type = state_fio->FgetUint8();
2239 event_beep = state_fio->FgetInt32_BE();
2240 event_beep_oneshot = state_fio->FgetInt32_BE();
2241 event_timerirq = state_fio->FgetInt32_BE();
2244 if(version >= 3) { // V3
2245 event_fdc_motor = state_fio->FgetInt32_BE();
2246 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)|| \
2247 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
2248 for(ch = 0; ch < 4; ch++) fdc_drive_table[ch] = state_fio->FgetUint8();
2249 fdc_reg_fd1e = state_fio->FgetUint8();
2251 #if defined(HAS_DMA)
2252 intstat_dma = state_fio->FgetBool();
2253 dma_addr = (uint32_t)(state_fio->FgetUint8() & 0x1f);
2255 #if defined(_FM77AV_VARIANTS)
2256 reg_fd12 = state_fio->FgetUint8();
2260 req_z80run = state_fio->FgetBool();
2261 z80_run = state_fio->FgetBool();
2264 rs232c_enabled = state_fio->FgetBool();
2265 rs232c_dcd = state_fio->FgetBool();
2266 for(int i = 0; i < 3; i++) uart_enabled[i] = state_fio->FgetBool();
2267 modem_irqmask_rxrdy = state_fio->FgetBool();
2268 modem_irqmask_txrdy = state_fio->FgetBool();
2269 modem_syndet = state_fio->FgetBool();
2270 modem_rxrdy = state_fio->FgetBool();
2271 modem_txrdy = state_fio->FgetBool();
2273 midi_uart_irqmask = state_fio->FgetBool();
2274 midi_syndet = state_fio->FgetBool();
2275 midi_rxrdy = state_fio->FgetBool();
2276 midi_txrdy = state_fio->FgetBool();
2277 #if defined(HAS_2HD)
2278 event_fdc_motor_2HD = state_fio->FgetInt32_BE();
2279 connect_fdc_2HD = state_fio->FgetBool();
2280 fdc_2HD_statreg = state_fio->FgetUint8();
2281 fdc_2HD_cmdreg = state_fio->FgetUint8();
2282 fdc_2HD_trackreg = state_fio->FgetUint8();
2283 fdc_2HD_sectreg = state_fio->FgetUint8();
2284 fdc_2HD_datareg =state_fio->FgetUint8();
2285 fdc_2HD_headreg = state_fio->FgetUint8();
2286 fdc_2HD_drvsel = state_fio->FgetUint8();
2287 irqreg_fdc_2HD = state_fio->FgetBool();
2288 fdc_2HD_motor = state_fio->FgetBool();
2289 //state_fio->FputBool(irqstat_fdc);
2294 bool FM7_MAINIO::load_state(FILEIO *state_fio)
2298 //bool stat = false;
2301 version = state_fio->FgetUint32_BE();
2302 if(this_device_id != state_fio->FgetInt32_BE()) return false;
2303 this->out_debug_log(_T("Load State: MAINIO: id=%d ver=%d\n"), this_device_id, version);
2305 if(!load_state_main(state_fio, version)) return false;
2308 connect_opn = state_fio->FgetBool();
2309 connect_whg = state_fio->FgetBool();
2310 connect_thg = state_fio->FgetBool();
2312 opn_psg_77av = state_fio->FgetBool();
2313 for(ch = 0; ch < 4; ch++) {
2314 opn_address[ch] = state_fio->FgetUint32_BE();
2315 opn_data[ch] = state_fio->FgetUint32_BE();
2316 opn_stat[ch] = state_fio->FgetUint32_BE();
2317 opn_cmdreg[ch] = state_fio->FgetUint32_BE();
2318 opn_ch3mode[ch] = state_fio->FgetUint32_BE();
2320 #if defined(HAS_2HD)
2321 event_2hd_nmi = state_fio->FgetInt32_BE();
2322 nmi_delay = state_fio->FgetUint32_BE();
2323 irqstat_fdc_2hd = state_fio->FgetBool();
2324 drqstat_fdc_2hd = state_fio->FgetBool();
2326 if(version != STATE_VERSION) return false;