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)
25 #include "./fm7_mainmem.h"
26 #include "./fm7_display.h"
27 #include "./fm7_keyboard.h"
28 #include "./kanjirom.h"
29 #include "./joystick.h"
30 #if defined(CAPABLE_JCOMMCARD)
31 #include "./jcommcard.h"
35 FM7_MAINIO::FM7_MAINIO(VM_TEMPLATE* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, parent_emu)
38 for(i = 0; i < 3; i++) {
41 for(i = 0; i < 3; i++) {
43 uart_enabled[i] = false;
45 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
46 rs232c_enabled = false;
49 rs232c_enabled = true;
52 # if !defined(_FM77AV_VARIANTS)
78 #if defined(CAPABLE_JCOMMCARD)
83 lpt_strobe = false; // bit6
84 lpt_slctin = false; // bit7
88 cmt_indat = true; // bit7
89 cmt_invert = false; // Invert signal
93 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
94 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
95 stat_kanjirom = true; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
96 #elif defined(_FM77_VARIANTS)
97 stat_fdmode_2hd = false; // R/W : bit6, '0' = 2HD, '1' = 2DD. FM-77 Only.
98 stat_kanjirom = true; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
100 firq_break_key = false; // bit1, ON = '0'.
101 firq_sub_attention = false; // bit0, ON = '0'.
102 intmode_fdc = false; // bit2, '0' = normal, '1' = SFD.
104 drqstat_fdc_2hd = false;
105 irqstat_fdc_2hd = false;
118 for(i = 0; i < 3; i++) {
119 opn_address[i] = 0x00;
122 opn_prescaler_type[i] = 1;
125 mouse_enable = false;
136 // FD20, FD21, FD22, FD23
137 connect_kanjiroml1 = false;
138 #if defined(_FM77AV_VARIANTS)
139 // FD2C, FD2D, FD2E, FD2F
140 connect_kanjiroml2 = false;
142 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
149 #if defined(_FM77_VARIANTS) || defined(_FM8)
150 bootmode = config.boot_mode & 7;
152 bootmode = config.boot_mode & 3;
154 memset(io_w_latch, 0xff, 0x100);
155 initialize_output_signals(&clock_status);
156 initialize_output_signals(&printer_reset_bus);
157 initialize_output_signals(&printer_strobe_bus);
158 initialize_output_signals(&printer_select_bus);
159 initialize_output_signals(&irq_bus);
160 initialize_output_signals(&firq_bus);
161 initialize_output_signals(&nmi_bus);
163 set_device_name(_T("MAIN I/O"));
166 FM7_MAINIO::~FM7_MAINIO()
171 void FM7_MAINIO::initialize()
174 event_beep_oneshot = -1;
176 event_fdc_motor = -1;
177 lpt_type = config.printer_type;
180 event_fdc_motor_2HD = -1;
182 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
184 # if defined(_FM77_VARIANTS)
185 stat_fdmode_2hd = false;
186 stat_kanjirom = true;
189 #if defined(_FM77AV_VARIANTS)
190 reg_fd12 = 0xbc; // 0b10111100
192 #if defined(_FM77_VARIANTS) || defined(_FM8)
193 bootmode = config.boot_mode & 7;
195 bootmode = config.boot_mode & 3;
204 void FM7_MAINIO::reset()
206 if(event_beep >= 0) cancel_event(this, event_beep);
208 if(event_beep_oneshot >= 0) cancel_event(this, event_beep_oneshot);
209 event_beep_oneshot = -1;
210 if(event_timerirq >= 0) cancel_event(this, event_timerirq);
213 register_event(this, EVENT_BEEP_CYCLE, (1000.0 * 1000.0) / (1200.0 * 2.0), true, &event_beep);
216 drqstat_fdc_2hd = false;
217 irqstat_fdc_2hd = false;
218 if(event_2hd_nmi >= 0) cancel_event(this, event_2hd_nmi);
221 #if defined(_FM77AV_VARIANTS)
225 #if defined(_FM77_VARIANTS)
227 #elif defined(_FM77AV_VARIANTS)
231 sub_cancel = false; // bit6 : '1' Cancel req.
232 sub_halt = false; // bit6 : '1' Cancel req.
233 sub_cancel_bak = sub_cancel; // bit6 : '1' Cancel req.
234 sub_halt_bak = sub_halt; // bit6 : '1' Cancel req.
235 req_z80run = false; // OK?
239 cmt_indat = true; // bit7
240 cmt_invert = false; // Invert signal
243 lpt_type = config.printer_type;
246 # if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
247 rs232c_enabled = false;
249 rs232c_enabled = true;
252 #if defined(_FM77AV_VARIANTS)
253 sub_monitor_type = 0x00;
255 if(config.cpu_type == 0) {
260 write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
263 irqmask_syndet = true;
264 irqmask_rxrdy = true;
265 irqmask_txrdy = true;
267 irqmask_timer = true;
268 irqmask_printer = true;
269 irqmask_keyboard = true;
273 intstat_syndet = false;
274 intstat_rxrdy = false;
275 intstat_txrdy = false;
276 irqstat_timer = false;
277 irqstat_printer = false;
278 irqstat_keyboard = false;
280 irqreq_syndet = false;
281 irqreq_rxrdy = false;
282 irqreq_txrdy = false;
283 irqreq_printer = false;
284 irqreq_keyboard = false;
286 modem_irqmask_rxrdy = modem_irqmask_txrdy = true;
287 modem_syndet = modem_rxrdy = modem_txrdy = false;
288 midi_uart_irqmask = midi_syndet = midi_rxrdy = midi_txrdy = false;
291 call_write_signal(drec, SIG_DATAREC_MIC, 0x00, 0x01);
292 call_write_signal(drec, SIG_DATAREC_REMOTE, 0x00, 0x02);
298 firq_break_key = (keyboard->read_signal(SIG_FM7KEY_BREAK_KEY) != 0x00000000); // bit1, ON = '0'.
300 set_sub_attention(false);
301 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
302 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
303 stat_kanjirom = true; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
304 #elif defined(_FM77_VARIANTS)
305 stat_fdmode_2hd = false; // R/W : bit6, '0' = 2HD, '1' = 2DD. FM-77 Only.
306 stat_kanjirom = true; // R/W : bit5, '0' = sub, '1' = main. FM-77 Only.
308 write_signals(&firq_bus, 0);
314 #if defined(_FM77AV_VARIANTS)
315 reg_fd12 = 0xbc; // 0b10111100
317 #if defined(WITH_Z80)
318 if(z80 != NULL) call_write_signal(z80, SIG_CPU_BUSREQ, 0xffffffff, 0xffffffff);
320 irqreg_fdc = 0xff; //0b11111111;
322 call_write_signal(maincpu, SIG_CPU_BUSREQ, 0, 0xffffffff);
323 call_write_signal(maincpu, SIG_CPU_HALTREQ, 0, 0xffffffff);
329 intstat_mouse = false;
334 register_event(this, EVENT_TIMERIRQ_ON, 10000.0 / 4.9152, true, &event_timerirq); // TIMER IRQ
336 #if defined(_FM77_VARIANTS) || defined(_FM8)
337 bootmode = config.boot_mode & 7;
339 bootmode = config.boot_mode & 3;
341 memset(io_w_latch, 0xff, 0x100);
344 void FM7_MAINIO::reset_printer()
350 write_signals(&printer_strobe_bus, 0);
351 write_signals(&printer_select_bus, 0xffffffff);
352 write_signals(&printer_reset_bus, 0xffffffff);
353 register_event(this, EVENT_PRINTER_RESET_COMPLETED, 5.0 * 1000.0, false, NULL);
355 printer->write_signal(SIG_PRINTER_STROBE, 0x00, 0xff);
358 lpt_error_inv = true;
359 lpt_ackng_inv = true;
364 void FM7_MAINIO::set_clockmode(uint8_t flags)
367 if((flags & FM7_MAINCLOCK_SLOW) != 0) {
372 if(f != clock_fast) {
373 write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
377 uint8_t FM7_MAINIO::get_clockmode(void)
379 if(!clock_fast) return FM7_MAINCLOCK_SLOW;
380 return FM7_MAINCLOCK_HIGH;
384 uint8_t FM7_MAINIO::get_port_fd00(void)
386 uint8_t ret = 0x7e; //0b01111110;
387 if(keyboard->read_data8(0x00) != 0) ret |= 0x80; // High bit.
388 if(clock_fast) ret |= 0x01; //0b00000001;
392 void FM7_MAINIO::set_port_fd00(uint8_t data)
395 call_write_signal(drec, SIG_DATAREC_MIC, data, 0x01);
396 call_write_signal(drec, SIG_DATAREC_REMOTE, data, 0x02);
398 lpt_slctin = ((data & 0x80) == 0);
399 lpt_strobe = ((data & 0x40) != 0);
400 write_signals(&printer_strobe_bus, lpt_strobe ? 0xffffffff : 0);
401 write_signals(&printer_select_bus, lpt_slctin ? 0xffffffff : 0);
402 if((lpt_type == 0) && (lpt_slctin)) {
403 printer->write_signal(SIG_PRINTER_STROBE, lpt_strobe ? 0xff : 0x00, 0xff);
407 uint8_t FM7_MAINIO::get_port_fd02(void)
410 bool ack_bak = lpt_ackng_inv;
412 ret = (cmt_indat) ? 0xff : 0x7f; // CMT
414 lpt_busy = (printer->read_signal(SIG_PRINTER_BUSY) != 0);
415 lpt_error_inv = true;
416 lpt_ackng_inv = (printer->read_signal(SIG_PRINTER_ACK) != 0);
418 } else if((lpt_type == 1) || (lpt_type == 2)) {
419 lpt_pe = (joystick->read_data8(lpt_type + 1) != 0); // check joy port;
421 lpt_error_inv = true;
422 lpt_ackng_inv = true;
425 lpt_error_inv = true;
426 lpt_ackng_inv = true;
429 ret &= (lpt_busy) ? 0xff : ~0x01;
430 ret &= (lpt_error_inv) ? 0xff : ~0x02;
431 ret &= (lpt_ackng_inv) ? 0xff : ~0x04;
432 ret &= (lpt_pe) ? 0xff : ~0x08;
433 ret &= (lpt_det1) ? 0xff : ~0x10;
434 ret &= (lpt_det2) ? 0xff : ~0x20;
435 if((lpt_ackng_inv == true) && (ack_bak == false)) set_irq_printer(true);
439 void FM7_MAINIO::set_port_fd02(uint8_t val)
443 bool syndetirq_bak = irqmask_syndet;
444 //bool rxrdyirq_bak = irqmask_rxrdy;
445 //bool txrdyirq_bak = irqmask_txrdy;
447 bool keyirq_bak = irqmask_keyboard;
448 //bool timerirq_bak = irqmask_timer;
449 //bool printerirq_bak = irqmask_printer;
450 //bool mfdirq_bak = irqmask_mfd;
452 // if((val & 0b00010000) != 0) {
453 if((val & 0x80) != 0) {
454 irqmask_syndet = false;
456 irqmask_syndet = true;
458 if(syndetirq_bak != irqmask_syndet) {
459 set_irq_txrdy(irqreq_syndet);
461 if((val & 0x40) != 0) {
462 irqmask_rxrdy = false;
464 irqmask_rxrdy = true;
466 // if(rxrdyirq_bak != irqmask_rxrdy) {
467 // set_irq_rxrdy(irqreq_rxrdy);
469 if((val & 0x20) != 0) {
470 irqmask_txrdy = false;
472 irqmask_txrdy = true;
474 // if(txrdyirq_bak != irqmask_txrdy) {
475 // set_irq_txrdy(irqreq_txrdy);
478 if((val & 0x10) != 0) {
484 if((val & 0x04) != 0) {
485 irqmask_timer = false;
487 irqmask_timer = true;
489 // if(timerirq_bak != irqmask_timer) {
490 // set_irq_timer(false);
493 if((val & 0x02) != 0) {
494 irqmask_printer = false;
496 irqmask_printer = true;
498 // if(printerirq_bak != irqmask_printer) {
499 // set_irq_printer(irqreq_printer);
502 if((val & 0x01) != 0) {
503 irqmask_keyboard = false;
505 irqmask_keyboard = true;
507 if(keyirq_bak != irqmask_keyboard) {
508 call_write_signal(display, SIG_FM7_SUB_KEY_MASK, irqmask_keyboard ? 1 : 0, 1);
509 set_irq_keyboard(irqreq_keyboard);
515 void FM7_MAINIO::set_irq_syndet(bool flag)
517 bool backup = intstat_syndet;
518 irqreq_syndet = flag;
519 if(flag && !(irqmask_syndet)) {
520 //irqstat_reg0 &= ~0x80; //~0x20;
521 intstat_syndet = true;
523 // irqstat_reg0 |= 0x80;
524 intstat_syndet = false;
526 if(backup != intstat_syndet) do_irq();
530 void FM7_MAINIO::set_irq_rxrdy(bool flag)
532 bool backup = intstat_rxrdy;
534 if(flag && !(irqmask_rxrdy)) {
535 //irqstat_reg0 &= ~0x40; //~0x20;
536 intstat_rxrdy = true;
538 //irqstat_reg0 |= 0x40;
539 intstat_rxrdy = false;
541 if(backup != intstat_rxrdy) do_irq();
546 void FM7_MAINIO::set_irq_txrdy(bool flag)
548 bool backup = intstat_txrdy;
550 if(flag && !(irqmask_txrdy)) {
551 //irqstat_reg0 &= ~0x20; //~0x20;
552 intstat_txrdy = true;
554 //irqstat_reg0 |= 0x20;
555 intstat_txrdy = false;
557 if(backup != intstat_txrdy) do_irq();
561 void FM7_MAINIO::set_irq_timer(bool flag)
564 irqstat_reg0 &= 0xfb; //~0x04;
565 irqstat_timer = true;
567 irqstat_reg0 |= 0x04;
568 irqstat_timer = false;
573 void FM7_MAINIO::set_irq_printer(bool flag)
575 irqreq_printer = flag;
576 if(flag && !(irqmask_printer)) {
577 irqstat_reg0 &= ~0x02;
578 irqstat_printer = true;
580 irqstat_reg0 |= 0x02;
581 irqstat_printer = false;
586 void FM7_MAINIO::set_irq_keyboard(bool flag)
588 //uint8_t backup = irqstat_reg0;
589 //printf("MAIN: KEYBOARD: IRQ=%d MASK=%d\n", flag ,irqmask_keyboard);
590 irqreq_keyboard = flag;
591 if(flag && !irqmask_keyboard) {
592 irqstat_reg0 &= 0xfe;
593 irqstat_keyboard = true;
595 irqstat_reg0 |= 0x01;
596 irqstat_keyboard = false;
602 void FM7_MAINIO::do_irq(void)
607 intstat = irqstat_timer | irqstat_keyboard | irqstat_printer;
608 intstat = intstat | intstat_opn | intstat_whg | intstat_thg;
609 intstat = intstat | intstat_txrdy | intstat_rxrdy | intstat_syndet;
610 intstat = intstat | intstat_mouse;
611 intstat = intstat | ((modem_irqmask_txrdy & modem_txrdy) | (modem_irqmask_rxrdy & modem_rxrdy) | modem_syndet);
612 intstat = intstat | ((!midi_uart_irqmask) & (midi_syndet | midi_txrdy | midi_rxrdy));
613 # if defined(HAS_DMA)
614 intstat = intstat | intstat_dma;
616 # if defined(HAS_2HD)
618 intstat = intstat | irqstat_fdc_2hd;
620 intstat = intstat | irqstat_fdc;
623 intstat = intstat | irqstat_fdc;
625 nval = (intstat) ? 0xffffffff : 0;
626 write_signals(&irq_bus, nval);
629 void FM7_MAINIO::do_firq(void)
633 firq_stat = firq_break_key | firq_sub_attention;
636 firq_stat = drqstat_fdc_2hd; // 20180226 BREAK KEY AND ATTENTION MUST BE MASK IF FIRQ USING FOR FDC's DRQ.Thanks to Haserin.
640 nval = (firq_stat) ? 0xffffffff : 0;
641 write_signals(&firq_bus, nval);
644 void FM7_MAINIO::do_nmi(bool flag)
646 write_signals(&nmi_bus, (flag) ? 0xffffffff : 0);
650 void FM7_MAINIO::set_break_key(bool pressed)
652 firq_break_key = pressed;
656 void FM7_MAINIO::set_sub_attention(bool flag)
658 firq_sub_attention = flag;
663 uint8_t FM7_MAINIO::get_fd04(void)
667 if(display->read_signal(SIG_DISPLAY_BUSY) != 0) val |= 0x80;
669 //f = keyboard->read_signal(SIG_FM7KEY_BREAK_KEY);
672 if(!firq_sub_attention) {
675 #if defined(_FM77_VARIANTS)
676 if(!stat_fdmode_2hd) val |= 0x40;
677 if(stat_kanjirom) val |= 0x20;
678 //if(intmode_fdc) val |= 0x04; // OK?
680 # if defined(_FM77L4)
681 val |= (display->read_signal(SIG_DISPLAY_EXTRA_MODE) & 0x18);
683 val |= 0x18; // For NON-77L4, these bit must be '1'.Thanks to Ryu Takegami.
687 // ToDo: MEMORY PARITY ERRO STATUS (if error, bit3 = '1').
688 #elif defined(_FM77AV_VARIANTS)
690 val |= 0x10; // ToDo: Hack for OS-9 for 77AV.Really need?
695 if(drqstat_fdc_2hd) {
696 drqstat_fdc_2hd = false;
697 if(!firq_sub_attention) do_firq();
700 if(firq_sub_attention) {
701 set_sub_attention(false);
702 //printf("Attention \n");
704 #if defined(_FM77AV_VARIANTS)
706 if(mainmem->read_signal(FM7_MAINIO_INITROM_ENABLED) == 0) {
707 set_break_key(false);
715 void FM7_MAINIO::set_fd04(uint8_t val)
718 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
719 call_write_signal(display, SIG_DISPLAY_EXTRA_MODE, val, 0xff);
720 stat_kanjirom = ((val & 0x20) != 0);
721 #elif defined(_FM77_VARIANTS)
722 call_write_signal(display, SIG_DISPLAY_EXTRA_MODE, val, 0xff);
723 stat_kanjirom = ((val & 0x20) != 0);
726 stat_fdmode_2hd = ((val & 0x40) == 0);
727 intmode_fdc = ((val & 0x04) == 0); // I/O port definition at Oh!FM 1985-5? is inverted status.
728 bool tmpf = intmode_fdc;
729 if(tmpf != intmode_fdc) {
736 uint8_t FM7_MAINIO::get_fd05(void)
739 if(display->read_signal(SIG_DISPLAY_BUSY) != 0) val |= 0x80;
740 if(!extdet_neg) val |= 0x01;
744 void FM7_MAINIO::set_fd05(uint8_t val)
746 sub_cancel = ((val & 0x40) != 0) ? true : false;
747 sub_halt = ((val & 0x80) != 0) ? true : false;
748 //if(sub_halt != sub_halt_bak) {
749 call_write_signal(display, SIG_DISPLAY_HALT, (sub_halt) ? 0xff : 0x00, 0xff);
751 sub_halt_bak = sub_halt;
753 //if(sub_cancel != sub_cancel_bak) {
754 call_write_signal(display, SIG_FM7_SUB_CANCEL, (sub_cancel) ? 0xff : 0x00, 0xff); // HACK
756 sub_cancel_bak = sub_cancel;
758 if((val & 0x01) != 0) {
759 call_write_signal(maincpu, SIG_CPU_HALTREQ, 1, 1);
763 if(z80 != NULL) call_write_signal(z80, SIG_CPU_BUSREQ, 1, 1);
768 void FM7_MAINIO::set_extdet(bool flag)
773 void FM7_MAINIO::write_fd0f(void)
775 call_write_signal(mainmem, FM7_MAINIO_PUSH_FD0F, 0, 0xffffffff);
778 uint8_t FM7_MAINIO::read_fd0f(void)
780 call_write_signal(mainmem, FM7_MAINIO_PUSH_FD0F, 0xffffffff, 0xffffffff);
784 bool FM7_MAINIO::get_rommode_fd0f(void)
786 return (mainmem->read_signal(FM7_MAINIO_PUSH_FD0F) == 0) ? false : true;
790 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
791 void FM7_MAINIO::write_kanjiaddr_hi(uint8_t addr)
793 #if defined(CAPABLE_JCOMMCARD) && !(defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS))
794 if(jcommcard != NULL) {
795 jcommcard->write_io8(0, (uint32_t)addr);
799 if(!connect_kanjiroml1) {
802 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
803 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
804 if(!stat_kanjirom) return;
806 kanjiclass1->write_data8(KANJIROM_ADDR_HI, addr);
810 void FM7_MAINIO::write_kanjiaddr_lo(uint8_t addr)
812 #if defined(CAPABLE_JCOMMCARD) && !(defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS))
813 if(jcommcard != NULL) {
814 jcommcard->write_io8(1, (uint32_t)addr);
818 if(!connect_kanjiroml1) {
821 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
822 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
823 if(!stat_kanjirom) return;
825 kanjiclass1->write_data8(KANJIROM_ADDR_LO, addr);
829 uint8_t FM7_MAINIO::read_kanjidata_left(void)
831 #if defined(CAPABLE_JCOMMCARD) && !(defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS))
832 if(jcommcard != NULL) {
833 return (uint8_t)(jcommcard->read_io8(2));
836 if(!connect_kanjiroml1) {
839 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
840 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
841 if(!stat_kanjirom) return 0xff;
843 //printf("KANJI MAIN CLASS1 ADDR: %05x\n", kaddress.w.l);
845 return kanjiclass1->read_data8(KANJIROM_DATA_HI);
851 uint8_t FM7_MAINIO::read_kanjidata_right(void)
853 #if defined(CAPABLE_JCOMMCARD) && !(defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS))
854 if(jcommcard != NULL) {
855 return (uint8_t)(jcommcard->read_io8(3));
858 if(!connect_kanjiroml1) {
861 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
862 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
863 if(!stat_kanjirom) return 0xff;
866 return kanjiclass1->read_data8(KANJIROM_DATA_LO);
872 #ifdef CAPABLE_KANJI_CLASS2
873 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
874 void FM7_MAINIO::write_kanjiaddr_hi_l2(uint8_t addr)
876 if(!connect_kanjiroml2) return;
877 if(!stat_kanjirom) return;
878 kanjiclass2->write_data8(KANJIROM_ADDR_HI, addr);
882 void FM7_MAINIO::write_kanjiaddr_lo_l2(uint8_t addr)
884 if(!connect_kanjiroml2) return;
885 if(!stat_kanjirom) return;
886 kanjiclass2->write_data8(KANJIROM_ADDR_LO, addr);
891 uint8_t FM7_MAINIO::read_kanjidata_left_l2(void)
893 if(!connect_kanjiroml2) return 0xff;
894 if(!stat_kanjirom) return 0xff;
897 return kanjiclass2->read_data8(KANJIROM_DATA_HI);
903 uint8_t FM7_MAINIO::read_kanjidata_right_l2(void)
905 if(!connect_kanjiroml2) return 0xff;
906 if(!stat_kanjirom) return 0xff;
909 return kanjiclass2->read_data8(KANJIROM_DATA_LO);
916 uint32_t FM7_MAINIO::read_signal(int id)
920 case FM7_MAINIO_KEYBOARDIRQ_MASK:
921 retval = (irqmask_keyboard) ? 0xffffffff : 0x00000000;
931 void FM7_MAINIO::write_signal(int id, uint32_t data, uint32_t mask)
934 val_b = ((data & mask) != 0);
937 case SIG_FM7_SUB_HALT:
938 mainmem->write_signal(SIG_FM7_SUB_HALT, data, mask);
940 case FM7_MAINIO_CLOCKMODE: // fd00
946 write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
948 case FM7_MAINIO_CMT_RECV: // FD02
949 cmt_indat = val_b ^ cmt_invert;
951 case FM7_MAINIO_CMT_INVERT: // FD02
954 case FM7_MAINIO_TIMERIRQ: //
955 set_irq_timer(val_b);
957 case FM7_MAINIO_LPTIRQ: //
958 set_irq_printer(val_b);
960 case FM7_MAINIO_LPT_BUSY:
963 case FM7_MAINIO_LPT_ERROR:
964 lpt_error_inv = val_b;
966 case FM7_MAINIO_LPT_ACK:
968 bool f = lpt_ackng_inv;
969 lpt_ackng_inv = val_b;
970 if((lpt_ackng_inv == true) && (f == false)) set_irq_printer(true);
973 case FM7_MAINIO_LPT_PAPER_EMPTY:
976 case FM7_MAINIO_LPT_DET1:
979 case FM7_MAINIO_LPT_DET2:
982 case FM7_MAINIO_KEYBOARDIRQ: //
983 set_irq_keyboard(val_b);
986 case FM7_MAINIO_PUSH_BREAK:
987 set_break_key(val_b);
989 #if defined(FM77AV_VARIANTS)
990 case FM7_MAINIO_HOT_RESET:
994 case FM7_MAINIO_SUB_ATTENTION:
995 if(val_b) set_sub_attention(true);
998 case FM7_MAINIO_EXTDET:
1001 case FM7_MAINIO_BEEP:
1004 case FM7_MAINIO_PSG_IRQ:
1006 #if defined(WITH_Z80)
1007 case FM7_MAINIO_RUN_Z80:
1008 if((req_z80run)/* && (val_b) */) {
1009 if(z80 != NULL) call_write_signal(z80, SIG_CPU_BUSREQ, 0, 1);
1011 //z80->reset(); // OK?
1014 case FM7_MAINIO_RUN_6809:
1015 if(!(req_z80run) /* && (val_b) */ && (z80_run)) {
1018 call_write_signal(maincpu, SIG_CPU_HALTREQ, 0, 1);
1022 case FM7_MAINIO_UART0_RXRDY:
1023 set_irq_rxrdy(val_b & rs232c_enabled);
1025 case FM7_MAINIO_UART0_TXRDY:
1026 set_irq_txrdy(val_b & rs232c_enabled);
1028 case FM7_MAINIO_UART0_SYNDET:
1029 set_irq_syndet(val_b & rs232c_enabled);
1031 case FM7_MAINIO_UART0_DCD:
1034 case FM7_MAINIO_MODEM_TXRDY:
1035 modem_txrdy = val_b;
1038 case FM7_MAINIO_MODEM_RXRDY:
1039 modem_rxrdy = val_b;
1042 case FM7_MAINIO_MODEM_SYNDET:
1043 modem_syndet = val_b;
1046 case FM7_MAINIO_MIDI_TXRDY:
1050 case FM7_MAINIO_MIDI_RXRDY:
1054 case FM7_MAINIO_MIDI_SYNDET:
1055 midi_syndet = val_b;
1059 //#if !defined(_FM8)
1060 case FM7_MAINIO_OPN_IRQ:
1061 if(!connect_opn) break;
1062 intstat_opn = val_b;
1065 case FM7_MAINIO_WHG_IRQ:
1066 if(!connect_whg) break;
1067 intstat_whg = val_b;
1070 case FM7_MAINIO_THG_IRQ:
1071 if(!connect_thg) break;
1072 intstat_thg = val_b;
1076 case FM7_MAINIO_FDC_DRQ:
1079 case FM7_MAINIO_FDC_IRQ:
1082 #if defined(HAS_2HD)
1083 case FM7_MAINIO_FDC_DRQ_2HD:
1084 set_drq_mfd_2HD(val_b);
1086 case FM7_MAINIO_FDC_IRQ_2HD:
1087 set_irq_mfd_2HD(val_b);
1090 #if defined(HAS_DMA)
1091 case FM7_MAINIO_DMA_INT:
1092 intstat_dma = val_b;
1096 #if defined(_FM77AV_VARIANTS)
1097 case SIG_DISPLAY_DISPLAY:
1104 case SIG_DISPLAY_VSYNC:
1111 case SIG_DISPLAY_MODE320:
1123 uint8_t FM7_MAINIO::get_irqstat_fd03(void)
1127 uint8_t backup = irqstat_reg0;
1129 extirq = intstat_opn | intstat_whg | intstat_thg;
1130 extirq = extirq | intstat_syndet | intstat_rxrdy | intstat_txrdy;
1131 # if defined(HAS_2HD)
1133 extirq = extirq | irqstat_fdc_2hd;
1135 extirq = extirq | irqstat_fdc;
1138 extirq = extirq | irqstat_fdc;
1140 # if defined(HAS_DMA)
1141 extirq = extirq | intstat_dma;
1144 irqstat_reg0 &= ~0x08;
1146 irqstat_reg0 |= 0x08;
1148 val = irqstat_reg0 | 0xf0;
1149 // Not call do_irq() twice. 20151221
1150 irqstat_timer = false;
1151 irqstat_printer = false;
1152 irqstat_reg0 |= 0x06;
1153 //if(backup != irqstat_reg0) do_irq();
1154 //this->out_debug_log(_T("IO: Check IRQ Status."));
1160 uint8_t FM7_MAINIO::get_extirq_fd17(void)
1163 if(intstat_opn && connect_opn) val &= ~0x08;
1164 if(intstat_mouse) val &= ~0x04;
1168 void FM7_MAINIO::set_ext_fd17(uint8_t data)
1170 if((data & 0x04) != 0) {
1171 mouse_enable = true;
1173 mouse_enable = false;
1177 #if defined(_FM77AV_VARIANTS)
1179 uint8_t FM7_MAINIO::subsystem_read_status(void)
1186 uint32_t FM7_MAINIO::read_io8(uint32_t addr)
1187 { // This is only for debug.
1188 addr = addr & 0xfff;
1190 return io_w_latch[addr];
1191 } else if(addr < 0x500) {
1192 uint32_t ofset = addr & 0xff;
1193 uint opnbank = (addr - 0x100) >> 8;
1194 return opn_regs[opnbank][ofset];
1195 } else if(addr < 0x600) {
1196 return mainmem->read_data8(addr - 0x500 + FM7_MAINIO_MMR_BANK);
1201 uint32_t FM7_MAINIO::read_dma_io8(uint32_t addr)
1203 return this->read_data8(addr & 0xff);
1206 uint32_t FM7_MAINIO::read_dma_data8(uint32_t addr)
1208 return this->read_data8(addr & 0xff);
1211 uint32_t FM7_MAINIO::read_data8(uint32_t addr)
1214 uint32_t mmr_segment;
1215 if(addr < FM7_MAINIO_IS_BASICROM) {
1218 #if defined(HAS_MMR)
1219 if((addr < 0x90) && (addr >= 0x80)) {
1220 mmr_segment = mainmem->read_data8(FM7_MAINIO_MMR_SEGMENT);
1221 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1222 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1223 mmr_segment &= 0x07;
1225 mmr_segment &= 0x03;
1227 return mainmem->read_data8(addr - 0x80 + FM7_MAINIO_MMR_BANK + mmr_segment * 16);
1230 // if((addr >= 0x0006) && !(addr == 0x1f) && !(addr == 0x0b)) printf("MAINIO: READ: %08x \n", addr);
1233 retval = (uint32_t) get_port_fd00();
1236 //#if !defined(_FM8)
1237 retval = keyboard->read_data8(0x01) & 0xff;
1241 retval = (uint32_t) get_port_fd02();
1244 //#if !defined(_FM8)
1245 retval = (uint32_t) get_irqstat_fd03();
1249 retval = (uint32_t) get_fd04();
1252 retval = (uint32_t) get_fd05();
1254 case 0x06: // RS-232C
1256 if(uart_enabled[0] && rs232c_enabled) {
1257 if(uart[0] != NULL) retval = uart[0]->read_io8(addr & 1);
1260 case 0x08: // Light pen
1264 #if defined(_FM77AV_VARIANTS)
1266 retval = ((config.boot_mode & 3) == 0) ? 0xfe : 0xff;
1267 #if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1268 retval &= (uint32_t)(~0x04);
1269 if(!rs232c_dcd) retval |= 0x04;
1273 case 0x0e: // PSG DATA
1274 retval = (uint32_t) get_psg();
1275 //printf("PSG DATA READ val=%02x\n", retval);
1281 #if defined(_FM77AV_VARIANTS)
1283 retval = subsystem_read_status();
1286 //printf("OPN CMD READ \n");
1288 case 0x16: // OPN DATA
1289 retval = (uint32_t) get_opn(0);
1292 retval = (uint32_t) get_extirq_fd17();
1295 #if defined(HAS_2HD)
1296 case 0x18: // FDC: STATUS
1297 if(stat_fdmode_2hd) {
1298 retval = (uint32_t) get_fdc_stat_2HD();
1300 retval = (uint32_t) get_fdc_stat();
1303 //printf("FDC: READ STATUS %02x PC=%04x\n", retval, maincpu->get_pc());
1305 case 0x19: // FDC: Track
1306 if(stat_fdmode_2hd) {
1307 retval = (uint32_t) get_fdc_track_2HD();
1309 retval = (uint32_t) get_fdc_track();
1311 //printf("FDC: READ TRACK REG %02x\n", retval);
1313 case 0x1a: // FDC: Sector
1314 if(stat_fdmode_2hd) {
1315 retval = (uint32_t) get_fdc_sector_2HD();
1317 retval = (uint32_t) get_fdc_sector();
1319 //printf("FDC: READ SECTOR REG %02x\n", retval);
1321 case 0x1b: // FDC: Data
1322 if(stat_fdmode_2hd) {
1323 retval = (uint32_t) get_fdc_data_2HD();
1325 retval = (uint32_t) get_fdc_data();
1329 if(stat_fdmode_2hd) {
1330 retval = (uint32_t) get_fdc_fd1c_2HD();
1332 retval = (uint32_t) get_fdc_fd1c();
1334 //printf("FDC: READ HEAD REG %02x\n", retval);
1337 if(stat_fdmode_2hd) {
1338 retval = (uint32_t) get_fdc_motor_2HD();
1340 retval = (uint32_t) get_fdc_motor();
1342 //printf("FDC: READ MOTOR REG %02x\n", retval);
1345 if(stat_fdmode_2hd) {
1346 retval = (uint32_t) get_fdc_fd1e_2HD();
1348 retval = (uint32_t) get_fdc_fd1e();
1350 //printf("FDC: READ MOTOR REG %02x\n", retval);
1353 if(stat_fdmode_2hd) {
1354 retval = (uint32_t) fdc_getdrqirq_2HD();
1356 retval = (uint32_t) fdc_getdrqirq();
1360 case 0x18: // FDC: STATUS
1361 retval = (uint32_t) get_fdc_stat();
1363 //printf("FDC: READ STATUS %02x PC=%04x\n", retval, maincpu->get_pc());
1365 case 0x19: // FDC: Track
1366 retval = (uint32_t) get_fdc_track();
1367 //printf("FDC: READ TRACK REG %02x\n", retval);
1369 case 0x1a: // FDC: Sector
1370 retval = (uint32_t) get_fdc_sector();
1371 //printf("FDC: READ SECTOR REG %02x\n", retval);
1373 case 0x1b: // FDC: Data
1374 retval = (uint32_t) get_fdc_data();
1377 retval = (uint32_t) get_fdc_fd1c();
1378 //printf("FDC: READ HEAD REG %02x\n", retval);
1381 retval = (uint32_t) get_fdc_motor();
1382 //printf("FDC: READ MOTOR REG %02x\n", retval);
1385 retval = (uint32_t) get_fdc_fd1e();
1386 //printf("FDC: READ MOTOR REG %02x\n", retval);
1389 retval = (uint32_t) fdc_getdrqirq();
1392 case 0x22: // Kanji ROM
1393 retval = (uint32_t) read_kanjidata_left();
1395 case 0x23: // Kanji ROM
1396 retval = (uint32_t) read_kanjidata_right();
1398 #if defined(CAPABLE_JCOMMCARD)
1401 # if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
1405 if(jcommcard != NULL) {
1406 retval = (uint32_t)(jcommcard->read_io8(addr));
1412 #if defined(CAPABLE_KANJI_CLASS2)
1413 case 0x2e: // Kanji ROM Level2
1414 retval = (uint32_t) read_kanjidata_left_l2();
1416 case 0x2f: // Kanji ROM Level2
1417 retval = (uint32_t) read_kanjidata_right_l2();
1420 //#if !defined(_FM8)
1421 case 0x37: // Multi page
1422 //retval = (uint32_t)display->read_data8(DISPLAY_ADDR_MULTIPAGE);
1426 if(uart_enabled[1]) {
1427 if(uart[1] != NULL) retval = uart[1]->read_io8(addr & 1);
1432 case 0x45: // WHG CMD
1434 case 0x46: // WHG DATA
1435 retval = (uint32_t) get_opn(1);
1438 retval = (uint32_t) get_extirq_whg();
1440 case 0x51: // THG CMD
1442 case 0x52: // THG DATA
1443 retval = (uint32_t) get_opn(2);
1446 retval = (uint32_t) get_extirq_thg();
1449 #if defined(HAS_MMR)
1453 if(mainmem->read_signal(FM7_MAINIO_BOOTRAM_RW) != 0) retval |= 0x01;
1454 if(mainmem->read_signal(FM7_MAINIO_WINDOW_ENABLED) != 0) retval |= 0x40;
1455 if(mainmem->read_signal(FM7_MAINIO_MMR_ENABLED) != 0) retval |= 0x80;
1458 #if defined(_FM77AV40SX) || defined(_FM77AV40EX)
1461 if(mainmem->read_signal(FM7_MAINIO_FASTMMR_ENABLED) != 0) retval |= 0x08;
1462 if(mainmem->read_signal(FM7_MAINIO_EXTROM) != 0) retval |= 0x80;
1465 #if defined(HAS_DMA)
1470 retval = dmac->read_data8(dma_addr);
1475 if(uart_enabled[2]) {
1476 if(uart[2] != NULL) retval = uart[2]->read_io8(addr & 1);
1482 //#if !defined(_FM8)
1483 if((addr < 0x40) && (addr >= 0x38)) {
1484 addr = (addr - 0x38) + FM7_SUBMEM_OFFSET_DPALETTE;
1485 return (uint32_t) display->read_data8(addr);
1490 } else if(addr == FM7_MAINIO_CLOCKMODE) {
1491 return (uint32_t)get_clockmode();
1493 #if defined(_FM77AV_VARIANTS)
1494 else if(addr == FM7_MAINIO_SUBMONITOR_ROM) {
1495 retval = sub_monitor_type & 0x03;
1497 } else if(addr == FM7_MAINIO_SUBMONITOR_RAM) {
1498 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1499 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1500 retval = ((sub_monitor_type & 0x04) != 0) ? 0xffffffff : 0x00000000;
1507 //if((addr >= 0x0006) && (addr != 0x1f)) printf("MAINIO: READ: %08x DATA=%08x\n", addr);
1511 void FM7_MAINIO::write_dma_io8(uint32_t addr, uint32_t data)
1513 this->write_data8(addr & 0xff, data);
1516 void FM7_MAINIO::write_dma_data8(uint32_t addr, uint32_t data)
1518 this->write_data8(addr & 0xff, data);
1522 void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
1525 uint32_t mmr_segment;
1526 if(addr < FM7_MAINIO_IS_BASICROM) {
1528 io_w_latch[addr] = data;
1529 #if defined(HAS_MMR)
1530 if((addr < 0x90) && (addr >= 0x80)) {
1531 mmr_segment = mainmem->read_data8(FM7_MAINIO_MMR_SEGMENT);
1532 # if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1533 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1534 mmr_segment &= 0x07;
1536 mmr_segment &= 0x03;
1538 mainmem->write_data8(FM7_MAINIO_MMR_BANK + mmr_segment * 16 + addr - 0x80, data);
1544 set_port_fd00((uint8_t)data);
1548 lpt_outdata = (uint8_t)data;
1550 case 0: // Write to file
1551 printer->write_signal(SIG_PRINTER_DATA, data, 0xff);
1555 joystick->write_data8(0x01, data);
1560 set_port_fd02((uint8_t)data);
1569 set_fd05((uint8_t)data);
1571 case 0x06: // RS-232C
1573 if(uart_enabled[0] && rs232c_enabled) {
1574 if(uart[0] != NULL) uart[0]->write_io8(addr & 1, data);
1577 case 0x08: // Light pen
1582 #if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
1583 if(rs232c_dtr != NULL) {
1584 if((data & 0x04) != 0) {
1585 rs232c_dtr->write_signal(SIG_AND_BIT_1, 0, 1);
1587 rs232c_dtr->write_signal(SIG_AND_BIT_1, 1, 1);
1590 rs232c_enabled = ((data & 0x01) != 0) ? true : false;
1594 //printf("PSG CMD WRITE val=%02x\n", data);
1598 //printf("PSG DATA WRITE val=%02x\n", data);
1604 #if defined(_FM77AV_VARIANTS)
1606 flag = ((data & 0x02) == 0) ? true : false;
1607 call_write_signal(mainmem, FM7_MAINIO_INITROM_ENABLED, (flag) ? 0xffffffff : 0 , 0xffffffff);
1610 call_write_signal(display, SIG_DISPLAY_MODE320, data, 0x40);
1612 reg_fd12 |= (data & 0x40);
1615 sub_monitor_type = data & 0x07;
1616 call_write_signal(display, SIG_FM7_SUB_BANK, sub_monitor_type, 0x07);
1619 case 0x15: // OPN CMD
1620 //printf("OPN CMD WRITE val=%02x\n", data);
1621 set_opn_cmd(0, data);
1623 case 0x16: // OPN DATA
1624 //printf("OPN DATA WRITE val=%02x\n", data);
1628 set_ext_fd17((uint8_t)data);
1630 #if defined(HAS_2HD)
1631 case 0x18: // FDC: COMMAND
1632 if(stat_fdmode_2hd) {
1633 set_fdc_cmd_2HD((uint8_t)data);
1635 set_fdc_cmd((uint8_t)data);
1637 //printf("FDC: WRITE CMD %02x\n", data);
1639 case 0x19: // FDC: Track
1640 if(stat_fdmode_2hd) {
1641 set_fdc_track_2HD((uint8_t)data);
1643 set_fdc_track((uint8_t)data);
1645 //printf("FDC: WRITE TRACK REG %02x\n", data);
1647 case 0x1a: // FDC: Sector
1648 if(stat_fdmode_2hd) {
1649 set_fdc_sector_2HD((uint8_t)data);
1651 set_fdc_sector((uint8_t)data);
1653 //printf("FDC: WRITE SECTOR REG %02x\n", data);
1655 case 0x1b: // FDC: Data
1656 if(stat_fdmode_2hd) {
1657 set_fdc_data_2HD((uint8_t)data);
1659 set_fdc_data((uint8_t)data);
1663 if(stat_fdmode_2hd) {
1664 set_fdc_fd1c_2HD((uint8_t)data);
1666 set_fdc_fd1c((uint8_t)data);
1668 //printf("FDC: WRITE HEAD REG %02x\n", data);
1671 if(stat_fdmode_2hd) {
1672 set_fdc_fd1d_2HD((uint8_t)data);
1674 set_fdc_fd1d((uint8_t)data);
1676 //printf("FDC: WRITE MOTOR REG %02x\n", data);
1679 if(stat_fdmode_2hd) {
1680 set_fdc_fd1e_2HD((uint8_t)data);
1682 set_fdc_fd1e((uint8_t)data);
1689 case 0x18: // FDC: COMMAND
1690 set_fdc_cmd((uint8_t)data);
1691 //printf("FDC: WRITE CMD %02x\n", data);
1693 case 0x19: // FDC: Track
1694 set_fdc_track((uint8_t)data);
1695 //printf("FDC: WRITE TRACK REG %02x\n", data);
1697 case 0x1a: // FDC: Sector
1698 set_fdc_sector((uint8_t)data);
1699 //printf("FDC: WRITE SECTOR REG %02x\n", data);
1701 case 0x1b: // FDC: Data
1702 set_fdc_data((uint8_t)data);
1705 set_fdc_fd1c((uint8_t)data);
1706 //printf("FDC: WRITE HEAD REG %02x\n", data);
1709 set_fdc_fd1d((uint8_t)data);
1710 //printf("FDC: WRITE MOTOR REG %02x\n", data);
1713 set_fdc_fd1e((uint8_t)data);
1719 case 0x20: // Kanji ROM
1720 write_kanjiaddr_hi((uint8_t)data);
1723 case 0x21: // Kanji ROM
1724 write_kanjiaddr_lo((uint8_t)data);
1726 #if defined(CAPABLE_JCOMMCARD)
1727 # if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
1733 if(jcommcard != NULL) jcommcard->write_io8(addr, data);
1736 case 0x2c: // Kanji ROM(DUP)
1737 #if defined(CAPABLE_KANJI_CLASS2)
1738 write_kanjiaddr_hi_l2((uint8_t)data);
1740 //write_kanjiaddr_hi((uint8_t)data);
1743 case 0x2d: // Kanji ROM(DUP)
1744 #if defined(CAPABLE_KANJI_CLASS2)
1745 write_kanjiaddr_lo_l2((uint8_t)data);
1747 //write_kanjiaddr_lo((uint8_t)data);
1750 #if defined(CAPABLE_DICTROM)
1752 call_write_signal(mainmem, FM7_MAINIO_EXTBANK, data, 0xff);
1755 #if defined(_FM77AV_VARIANTS)
1757 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_HI, data);
1760 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_LO, data);
1763 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_B, data);
1766 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_R, data);
1769 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_G, data);
1772 //#if !defined(_FM8)
1773 case 0x37: // Multi page
1774 call_write_signal(display, SIG_DISPLAY_MULTIPAGE, data, 0x00ff);
1778 if(uart_enabled[1]) {
1779 if(uart[1] != NULL) uart[1]->write_io8(addr & 1, data);
1783 modem_irqmask_txrdy = ((data & 0x20) != 0);
1784 modem_irqmask_rxrdy = ((data & 0x40) != 0);
1788 case 0x45: // WHG CMD
1789 set_opn_cmd(1, data);
1791 case 0x46: // WHG DATA
1796 case 0x51: // THG CMD
1797 set_opn_cmd(2, data);
1799 case 0x52: // THG DATA
1805 #if defined(HAS_MMR)
1807 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1808 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1809 mmr_segment = data & 7;
1811 // printf("MMR SEGMENT: %02x\n", data & 3);
1812 mmr_segment = data & 3;
1814 mainmem->write_data8(FM7_MAINIO_MMR_SEGMENT, (uint32_t)mmr_segment);
1817 mainmem->write_data8(FM7_MAINIO_WINDOW_OFFSET, (uint32_t)(data & 0x00ff));
1820 call_write_signal(mainmem, FM7_MAINIO_BOOTRAM_RW, data, 0x01);
1821 call_write_signal(mainmem, FM7_MAINIO_WINDOW_ENABLED, data , 0x40);
1822 //this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
1823 //mainmem->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
1824 call_write_signal(mainmem, FM7_MAINIO_MMR_ENABLED, data, 0x80);
1828 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || \
1829 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
1831 call_write_signal(mainmem, FM7_MAINIO_MMR_EXTENDED, data, 0x80);
1832 call_write_signal(mainmem, FM7_MAINIO_MEM_REFRESH_FAST, data, 0x04);
1833 call_write_signal(mainmem, FM7_MAINIO_WINDOW_FAST , data, 0x01);
1836 # if defined(_FM77AV40SX) || defined(_FM77AV40EX)
1838 call_write_signal(mainmem, FM7_MAINIO_FASTMMR_ENABLED, data, 0x08);
1839 call_write_signal(mainmem, FM7_MAINIO_EXTROM, data , 0x80);
1843 #if defined(HAS_DMA)
1845 dma_addr = data & 0x1f;
1848 dmac->write_data8(dma_addr, data);
1849 //this->out_debug_log(_T("IO: Wrote DMA %02x to reg %02x\n"), data, dma_addr);
1855 if(uart_enabled[2]) {
1856 if(uart[2] != NULL) uart[2]->write_io8(addr & 1, data);
1860 //printf("MAIN: Write I/O Addr=%08x DATA=%02x\n", addr, data);
1863 if((addr < 0x40) && (addr >= 0x38)) {
1864 addr = (addr - 0x38) | FM7_SUBMEM_OFFSET_DPALETTE;
1865 display->write_data8(addr, (uint8_t)data);
1869 } else if(addr == FM7_MAINIO_CLOCKMODE) {
1870 set_clockmode((uint8_t)data);
1873 //if((addr >= 0x0006) && !(addr == 0x1f)) printf("MAINIO: WRITE: %08x DATA=%08x\n", addr, data);
1876 void FM7_MAINIO::event_callback(int event_id, int err)
1878 // printf("MAIN EVENT id=%d\n", event_id);
1880 case EVENT_BEEP_OFF:
1883 case EVENT_BEEP_CYCLE:
1886 case EVENT_UP_BREAK:
1887 call_write_signal(keyboard, SIG_FM7KEY_OVERRIDE_PRESS_BREAK, 0, 0xffffffff);
1888 set_break_key(false);
1890 //#if !defined(_FM8)
1891 case EVENT_TIMERIRQ_ON:
1892 //if(!irqmask_timer) set_irq_timer(true);
1893 set_irq_timer(!irqmask_timer);
1896 case EVENT_FD_MOTOR_ON:
1897 set_fdc_motor(true);
1898 event_fdc_motor = -1;
1900 case EVENT_FD_MOTOR_OFF:
1901 set_fdc_motor(false);
1902 event_fdc_motor = -1;
1904 #if defined(HAS_2HD)
1905 case EVENT_FD_MOTOR_ON_2HD:
1906 set_fdc_motor_2HD(true);
1907 event_fdc_motor_2HD = -1;
1909 case EVENT_FD_MOTOR_OFF_2HD:
1910 set_fdc_motor_2HD(false);
1911 event_fdc_motor_2HD = -1;
1913 case EVENT_FD_NMI_2HD:
1918 case EVENT_PRINTER_RESET_COMPLETED:
1919 write_signals(&printer_reset_bus, 0x00);
1927 void FM7_MAINIO::update_config()
1929 switch(config.cpu_type){
1937 write_signals(&clock_status, clock_fast ? 0xffffffff : 0);
1940 void FM7_MAINIO::event_vline(int v, int clock)
1945 #define STATE_VERSION 17
1947 bool FM7_MAINIO::decl_state(FILEIO *state_fio, bool loading)
1949 if(!state_fio->StateCheckUint32(STATE_VERSION)) {
1952 if(!state_fio->StateCheckInt32(this_device_id)) {
1956 state_fio->StateBuffer(io_w_latch, sizeof(io_w_latch), 1);
1958 state_fio->StateBool(clock_fast);
1959 state_fio->StateBool(lpt_strobe);
1960 state_fio->StateBool(lpt_slctin);
1961 state_fio->StateBool(beep_flag);
1962 state_fio->StateBool(beep_snd);
1965 state_fio->StateUint8(lpt_outdata);
1967 state_fio->StateBool(cmt_indat);
1968 state_fio->StateBool(cmt_invert);
1969 state_fio->StateBool(lpt_det2);
1970 state_fio->StateBool(lpt_det1);
1971 state_fio->StateBool(lpt_pe);
1972 state_fio->StateBool(lpt_ackng_inv);
1973 state_fio->StateBool(lpt_error_inv);
1974 state_fio->StateUint8(irqmask_reg0);
1976 state_fio->StateBool(irqmask_syndet);
1977 state_fio->StateBool(irqmask_rxrdy);
1978 state_fio->StateBool(irqmask_txrdy);
1979 state_fio->StateBool(irqmask_mfd);
1980 state_fio->StateBool(irqmask_timer);
1981 state_fio->StateBool(irqmask_printer);
1982 state_fio->StateBool(irqmask_keyboard);
1984 state_fio->StateBool(irqreq_syndet);
1985 state_fio->StateBool(irqreq_rxrdy);
1986 state_fio->StateBool(irqreq_txrdy);
1987 state_fio->StateBool(irqreq_printer);
1988 state_fio->StateBool(irqreq_keyboard);
1989 state_fio->StateUint8(irqstat_reg0);
1991 state_fio->StateBool(irqstat_timer);
1992 state_fio->StateBool(irqstat_printer);
1993 state_fio->StateBool(irqstat_keyboard);
1996 #if defined(_FM77_VARIANTS)
1997 state_fio->StateBool(stat_fdmode_2hd);
1998 state_fio->StateBool(stat_kanjirom);
1999 #elif defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX) || \
2000 defined(_FM77AV20) || defined(_FM77AV20EX) || defined(_FM77AV20SX)
2001 state_fio->StateBool(stat_kanjirom);
2003 state_fio->StateBool(firq_break_key);
2004 state_fio->StateBool(firq_sub_attention);
2006 state_fio->StateBool(intmode_fdc);
2008 state_fio->StateBool(extdet_neg);
2009 state_fio->StateBool(sub_halt);
2010 state_fio->StateBool(sub_cancel);
2012 state_fio->StateBool(intstat_syndet);
2013 state_fio->StateBool(intstat_rxrdy);
2014 state_fio->StateBool(intstat_txrdy);
2017 state_fio->StateBool(intstat_opn);
2018 state_fio->StateBool(intstat_mouse);
2019 state_fio->StateBool(mouse_enable);
2021 state_fio->StateBool(intstat_whg);
2022 state_fio->StateBool(intstat_thg);
2025 state_fio->StateBool(connect_fdc);
2026 state_fio->StateUint8(fdc_statreg);
2027 state_fio->StateUint8(fdc_cmdreg);
2028 state_fio->StateUint8(fdc_trackreg);
2029 state_fio->StateUint8(fdc_sectreg);
2030 state_fio->StateUint8(fdc_datareg);
2031 state_fio->StateUint8(fdc_headreg);
2032 state_fio->StateUint8(fdc_drvsel);
2033 state_fio->StateUint8(irqreg_fdc);
2034 state_fio->StateBool(fdc_motor);
2035 state_fio->StateBool(irqstat_fdc);
2037 state_fio->StateBool(connect_kanjiroml1);
2038 #if defined(_FM77AV_VARIANTS)
2039 state_fio->StateBool(connect_kanjiroml2);
2040 state_fio->StateBool(boot_ram);
2041 state_fio->StateBool(hotreset);
2043 state_fio->StateUint8(sub_monitor_type);
2046 state_fio->StateInt32(event_beep);
2047 state_fio->StateInt32(event_beep_oneshot);
2048 state_fio->StateInt32(event_timerirq);
2051 state_fio->StateInt32(event_fdc_motor);
2052 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)|| \
2053 defined(_FM77AV20) || defined(_FM77AV20SX) || defined(_FM77AV20EX)
2054 state_fio->StateBuffer(fdc_drive_table, sizeof(fdc_drive_table), 1);
2055 state_fio->StateUint8(fdc_reg_fd1e);
2057 #if defined(HAS_DMA)
2058 state_fio->StateBool(intstat_dma);
2059 state_fio->StateUint8(dma_addr);
2061 #if defined(_FM77AV_VARIANTS)
2062 state_fio->StateUint8(reg_fd12);
2066 state_fio->StateBool(req_z80run);
2067 state_fio->StateBool(z80_run);
2070 state_fio->StateBool(rs232c_enabled);
2071 state_fio->StateBool(rs232c_dcd);
2072 state_fio->StateBuffer(uart_enabled, sizeof(uart_enabled), 1);
2074 state_fio->StateBool(modem_irqmask_rxrdy);
2075 state_fio->StateBool(modem_irqmask_txrdy);
2076 state_fio->StateBool(modem_syndet);
2077 state_fio->StateBool(modem_rxrdy);
2078 state_fio->StateBool(modem_txrdy);
2080 state_fio->StateBool(midi_uart_irqmask);
2081 state_fio->StateBool(midi_syndet);
2082 state_fio->StateBool(midi_rxrdy);
2083 state_fio->StateBool(midi_txrdy);
2084 #if defined(HAS_2HD)
2085 state_fio->StateInt32(event_fdc_motor_2HD);
2086 state_fio->StateBool(connect_fdc_2HD);
2087 state_fio->StateUint8(fdc_2HD_statreg);
2088 state_fio->StateUint8(fdc_2HD_cmdreg);
2089 state_fio->StateUint8(fdc_2HD_trackreg);
2090 state_fio->StateUint8(fdc_2HD_sectreg);
2091 state_fio->StateUint8(fdc_2HD_datareg);
2092 state_fio->StateUint8(fdc_2HD_headreg);
2093 state_fio->StateUint8(fdc_2HD_drvsel);
2094 state_fio->StateUint8(irqreg_fdc_2HD);
2095 state_fio->StateBool(fdc_2HD_motor);
2096 state_fio->StateInt32(event_2hd_nmi);
2097 state_fio->StateUint32(nmi_delay);
2098 state_fio->StateBool(irqstat_fdc_2hd);
2099 state_fio->StateBool(drqstat_fdc_2hd);
2102 if(!decl_state_opn(state_fio, loading)) {
2109 void FM7_MAINIO::save_state(FILEIO *state_fio)
2111 decl_state(state_fio, false);
2114 for(int i = 0; i < 3; i++) {
2115 out_debug_log("OPN#%d registers (to Save)", i);
2116 out_debug_log("ADDR: +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f");
2117 for(int ladr = 0; ladr < 0x100; ladr += 0x10) {
2118 out_debug_log("+%02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
2120 opn_regs[i][ladr + 0], opn_regs[i][ladr + 1], opn_regs[i][ladr + 2], opn_regs[i][ladr + 3],
2121 opn_regs[i][ladr + 4], opn_regs[i][ladr + 5], opn_regs[i][ladr + 6], opn_regs[i][ladr + 7],
2122 opn_regs[i][ladr + 8], opn_regs[i][ladr + 9], opn_regs[i][ladr + 10], opn_regs[i][ladr + 11],
2123 opn_regs[i][ladr + 12], opn_regs[i][ladr + 13], opn_regs[i][ladr + 14], opn_regs[i][ladr + 15]);
2129 bool FM7_MAINIO::load_state(FILEIO *state_fio)
2132 //bool stat = false;
2134 bool mb = decl_state(state_fio, true);
2136 #if defined(HAS_DMA)
2137 dma_addr = dma_addr & 0x1f;
2141 for(int i = 0; i < 3; i++) {
2142 out_debug_log("OPN#%d registers (Loaded)", i);
2143 out_debug_log("ADDR: +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +a +b +c +d +e +f");
2144 for(int ladr = 0; ladr < 0x100; ladr += 0x10) {
2145 out_debug_log("+%02x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x",
2147 opn_regs[i][ladr + 0], opn_regs[i][ladr + 1], opn_regs[i][ladr + 2], opn_regs[i][ladr + 3],
2148 opn_regs[i][ladr + 4], opn_regs[i][ladr + 5], opn_regs[i][ladr + 6], opn_regs[i][ladr + 7],
2149 opn_regs[i][ladr + 8], opn_regs[i][ladr + 9], opn_regs[i][ladr + 10], opn_regs[i][ladr + 11],
2150 opn_regs[i][ladr + 12], opn_regs[i][ladr + 13], opn_regs[i][ladr + 14], opn_regs[i][ladr + 15]);
2154 this->out_debug_log(_T("Load State: MAINIO: id=%d stat=%s\n"), this_device_id, (mb) ? _T("OK") : _T("NG"));