2 * FM-7 Main I/O [fm7_mainio.h]
4 * Author: K.Ohta <whatisthis.sowhat _at_ gmail.com>
7 * Jan 03, 2015 : Initial
11 #include "fm7_mainio.h"
13 #include "../mc6809.h"
16 #include "../datarec.h"
19 #if !defined(_MSC_VER)
23 void FM7_MAINIO::initialize()
27 event_beep_oneshot = -1;
30 bootmode = config.boot_mode & 3;
31 #if defined(_FM77AV_VARIANTS)
34 //opn_psg_77av = true;
37 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
40 #if defined(_FM77AV_VARIANTS)
41 enable_initiator = true;
46 window_enabled = false;
48 for(i = 0x00; i < 0x80; i++) mmr_table[i] = 0;
49 // for(i = 0x00; i < 0x10; i++) mmr_table[i] = 0x30 + i;
51 switch(config.cpu_type){
59 this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
63 void FM7_MAINIO::reset()
67 if(event_beep >= 0) cancel_event(this, event_beep);
69 if(event_beep_oneshot >= 0) cancel_event(this, event_beep_oneshot);
70 event_beep_oneshot = -1;
71 if(event_timerirq >= 0) cancel_event(this, event_timerirq);
72 if(event_sync >= 0) cancel_event(this, event_sync);
75 if(event_beep < 0) register_event(this, EVENT_BEEP_CYCLE, (1000.0 * 1000.0) / (1200.0 * 2.0), true, &event_beep);
79 stat_romrammode = true;
80 bootmode = config.boot_mode & 3;
81 if(bootmode == 0) { // IF BASIC BOOT THEN ROM
82 stat_romrammode = true;
84 stat_romrammode = false;
86 #if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
90 #if defined(_FM77AV_VARIANTS)
92 sub_monitor_type = 0x00;
93 sub_monitor_bak = sub_monitor_type;
94 display->write_signal(SIG_FM7_SUB_BANK, sub_monitor_type, 0x07);
100 window_enabled = false;
103 if(config.cpu_type == 0) clock_fast = true;
107 //key_irq_bak = key_irq_req;
111 firqstat_bak = false;
114 irqmask_timer = true;
115 irqmask_printer = true;
116 irqmask_keyboard = true;
118 irqstat_timer = false;
119 irqstat_printer = false;
120 irqstat_keyboard = false;
123 //firq_break_key = false; // bit1, ON = '0'.
124 firq_sub_attention = false; // bit0, ON = '0'.
125 firq_sub_attention_bak = false; // bit0, ON = '0'.
128 sub_cancel = false; // bit6 : '1' Cancel req.
129 sub_halt = false; // bit6 : '1' Cancel req.
130 sub_cancel_bak = !sub_cancel; // bit6 : '1' Cancel req.
131 sub_halt_bak = !sub_halt; // bit6 : '1' Cancel req.
135 register_event(this, EVENT_TIMERIRQ_ON, 10000.0 / 4.9152, true, &event_timerirq); // TIMER IRQ
137 memset(io_w_latch, 0x00, 0x100);
138 sub_busy = (read_signal(SIG_DISPLAY_BUSY) == 0) ? false : true;
139 register_event(this, EVENT_FM7SUB_PROC, 50.0, true, &event_sync); // 2uS / 8MHz
144 void FM7_MAINIO::set_clockmode(uint8 flags)
147 if((flags & FM7_MAINCLOCK_SLOW) != 0) {
152 if(f != clock_fast) {
153 this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
157 uint8 FM7_MAINIO::get_clockmode(void)
159 if(!clock_fast) return FM7_MAINCLOCK_SLOW;
160 return FM7_MAINCLOCK_HIGH;
164 uint8 FM7_MAINIO::get_port_fd00(void)
166 uint8 ret = 0x7e; //0b01111110;
167 if(keyboard->read_data8(0x00) != 0) ret |= 0x80; // High bit.
168 if(clock_fast) ret |= 0x01; //0b00000001;
172 void FM7_MAINIO::set_port_fd00(uint8 data)
174 drec->write_signal(SIG_DATAREC_OUT, data, 0x01);
175 drec->write_signal(SIG_DATAREC_REMOTE, data, 0x02);
178 uint8 FM7_MAINIO::get_port_fd02(void)
181 // Still unimplemented printer.
182 ret = (cmt_indat) ? 0xff : 0x7f; // CMT
186 void FM7_MAINIO::set_port_fd02(uint8 val)
189 bool keyirq_bak = irqmask_keyboard;
190 bool timerirq_bak = irqmask_timer;
191 bool printerirq_bak = irqmask_printer;
192 bool mfdirq_bak = irqmask_mfd;
194 // if((val & 0b00010000) != 0) {
195 if((val & 0x10) != 0) {
200 if(mfdirq_bak != irqmask_mfd) {
204 //if((val & 0b00000100) != 0) {
205 if((val & 0x04) != 0) {
206 irqmask_timer = false;
208 irqmask_timer = true;
210 if(timerirq_bak != irqmask_timer) {
211 flag = irqstat_timer;
214 //if((val & 0b00000010) != 0) {
215 if((val & 0x02) != 0) {
216 irqmask_printer = false;
218 irqmask_printer = true;
220 if(printerirq_bak != irqmask_printer) {
221 flag = irqstat_printer;
222 set_irq_printer(flag);
225 //if((val & 0b00000001) != 0) {
226 if((val & 0x01) != 0) {
227 irqmask_keyboard = false;
229 irqmask_keyboard = true;
231 if(keyirq_bak != irqmask_keyboard) {
232 flag = irqstat_keyboard;
233 flag = flag & !irqmask_keyboard;
234 display->write_signal(SIG_FM7_SUB_KEY_MASK, flag ? 1 : 0, 1);
235 display->write_signal(SIG_FM7_SUB_KEY_FIRQ, flag ? 1 : 0, 0xffffffff);
236 //printf("KEYBOARD: Interrupted %d\n", flag);
237 irqmask_keyboard = flag;
244 void FM7_MAINIO::set_irq_timer(bool flag)
246 uint8 backup = irqstat_reg0;
247 if(flag && !(irqmask_timer)) {
248 irqstat_reg0 &= 0xfb; //~0x04;
249 irqstat_timer = true;
250 if(backup != irqstat_reg0) do_irq();
252 irqstat_reg0 |= 0x04;
253 irqstat_timer = false;
254 if(backup != irqstat_reg0) do_irq();
256 //printf("IRQ TIMER: %02x MASK=%d\n", irqstat_reg0, irqmask_timer);
259 void FM7_MAINIO::set_irq_printer(bool flag)
261 uint8 backup = irqstat_reg0;
262 if(flag && !(irqmask_printer)) {
263 irqstat_reg0 &= ~0x02;
264 irqstat_printer = true;
265 if(backup != irqstat_reg0) do_irq();
267 irqstat_reg0 |= 0x02;
268 irqstat_printer = false;
269 if(backup != irqstat_reg0) do_irq();
271 // if(!irqmask_printer || !flag) do_irq();
274 void FM7_MAINIO::set_irq_keyboard(bool flag)
276 uint8 backup = irqstat_reg0;
277 //printf("MAIN: KEYBOARD: IRQ=%d MASK=%d\n", flag ,irqmask_keyboard);
278 flag = flag & !irqmask_keyboard;
280 irqstat_reg0 &= 0xfe;
281 irqstat_keyboard = true;
282 // if(backup != irqstat_reg0) do_irq();
284 irqstat_reg0 |= 0x01;
285 irqstat_keyboard = false;
286 // if(backup != irqstat_reg0) do_irq();
288 if(irqstat_reg0 != backup) do_irq();
292 void FM7_MAINIO::do_irq(void)
295 intstat = irqstat_timer | irqstat_keyboard | irqstat_printer;
296 intstat = intstat | irqstat_fdc;
297 intstat = intstat | intstat_opn | intstat_whg | intstat_thg;
298 intstat = intstat | intstat_mouse;
300 //if(irqstat_bak == intstat) return;
301 //printf("%08d : IRQ: REG0=%02x FDC=%02x, stat=%d\n", SDL_GetTicks(), irqstat_reg0, irqstat_fdc, intstat);
303 maincpu->write_signal(SIG_CPU_IRQ, 1, 1);
305 maincpu->write_signal(SIG_CPU_IRQ, 0, 1);
307 irqstat_bak = intstat;
310 void FM7_MAINIO::do_firq(void)
313 firq_stat = firq_break_key | firq_sub_attention;
314 //printf("%08d : FIRQ: break=%d attn=%d stat = %d\n", SDL_GetTicks(), firq_break_key, firq_sub_attention, firq_stat);
315 if(firqstat_bak == firq_stat) return;
317 maincpu->write_signal(SIG_CPU_FIRQ, 1, 1);
319 maincpu->write_signal(SIG_CPU_FIRQ, 0, 1);
321 firqstat_bak = firq_stat;
324 void FM7_MAINIO::do_nmi(bool flag)
327 if(nmi_count >= 0x7ff0) {
332 if(nmi_count <= 1) maincpu->write_signal(SIG_CPU_NMI, 1, 1);
339 if(nmi_count == 0) maincpu->write_signal(SIG_CPU_NMI, 0, 1);
344 void FM7_MAINIO::set_break_key(bool pressed)
346 firq_break_key = pressed;
350 void FM7_MAINIO::set_sub_attention(bool flag)
352 firq_sub_attention = flag;
353 //register_event_by_clock(this, EVENT_FM7SUB_PROC, 8, false, NULL); // 1uS / 8MHz
359 uint8 FM7_MAINIO::get_fd04(void)
362 if(sub_busy) val |= 0x80;
363 if(!firq_break_key) val |= 0x02;
364 if(!firq_sub_attention) {
367 set_sub_attention(false);
371 void FM7_MAINIO::set_fd04(uint8 val)
374 #if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
375 display->write_signal(SIG_DISPLAY_EXTRA_MODE, val, 0xff);
380 uint8 FM7_MAINIO::get_fd05(void)
383 val = (sub_busy) ? 0xfe : 0x7e;
384 if(!extdet_neg) val |= 0x01;
385 //printf("FD05: READ: %d VAL=%02x\n", SDL_GetTicks(), val);
389 void FM7_MAINIO::set_fd05(uint8 val)
391 sub_cancel = ((val & 0x40) != 0) ? true : false;
392 sub_halt = ((val & 0x80) != 0) ? true : false;
393 //register_event_by_clock(this, EVENT_FM7SUB_PROC, 8, false, NULL); // 1uS / 8MHz
396 if(sub_cancel != sub_cancel_bak) {
397 display->write_signal(SIG_FM7_SUB_CANCEL, (sub_cancel) ? 0xff : 0x00, 0xff); // HACK
399 sub_cancel_bak = sub_cancel;
401 if((val & 0x01) != 0) {
402 //maincpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
403 //z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
405 //maincpu->write_signal(SIG_CPU_BUSREQ, 0, 1);
406 //z80->write_signal(SIG_CPU_BUSREQ, 1, 1);
411 void FM7_MAINIO::set_extdet(bool flag)
416 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
417 void FM7_MAINIO::write_kanjiaddr_hi(uint8 addr)
419 if(!connect_kanjiroml1) return;
424 void FM7_MAINIO::write_kanjiaddr_lo(uint8 addr)
426 if(!connect_kanjiroml1) return;
431 uint8 FM7_MAINIO::read_kanjidata_left(void)
435 if(!connect_kanjiroml1) return 0xff;
438 //printf("KANJI MAIN CLASS1 ADDR: %05x\n", kaddress.w.l);
440 return kanjiclass1->read_data8(addr);
446 uint8 FM7_MAINIO::read_kanjidata_right(void)
450 if(!connect_kanjiroml1) return 0xff;
452 addr = (addr << 1) + 1;
454 return kanjiclass1->read_data8(addr);
460 #ifdef CAPABLE_KANJICLASS2
461 // Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
462 void FM7_MAINIO::write_kanjiaddr_hi_l2(uint8 addr)
464 if(!connect_kanjiroml2) return;
465 kaddress_l2.b.h = addr;
469 void FM7_MAINIO::write_kanjiaddr_lo_l2(uint8 addr)
471 if(!connect_kanjiroml2) return;
472 kaddress_l2.b.l = addr;
476 uint8 FM7_MAINIO::read_kanjidata_left_l2(void)
480 if(!connect_kanjiroml2) return 0xff;
484 return kanjiclass2->read_data8(addr);
490 uint8 FM7_MAINIO::read_kanjidata_right_l2(void)
494 if(!connect_kanjiroml2) return 0xff;
495 addr = kaddress_l2.w.l;
496 addr = (addr << 1) + 0x01;
498 return kanjiclass2->read_data8(addr);
507 void FM7_MAINIO::write_signal(int id, uint32 data, uint32 mask)
510 val_b = ((data & mask) != 0);
513 case FM7_MAINIO_SUB_BUSY:
516 case FM7_MAINIO_CLOCKMODE: // fd00
525 #if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
529 clocks = 2016000; // Hz
531 clocks = 1230502; // (2016 * 1095 / 1794)[KHz]
535 clocks = 1565000; // Hz
537 clocks = 955226; // (1565 * 1095 / 1794)[KHz]
542 clocks = 1794000; // Hz
544 clocks = 1095000; // Hz
549 clocks = 1794000; // Hz
551 clocks = 1095000; // Hz
554 p_vm->set_cpu_clock(this->maincpu, clocks);
555 display->write_signal(SIG_DISPLAY_CLOCK, clock_fast ? 1 : 0, 1);
558 case FM7_MAINIO_CMT_RECV: // FD02
559 cmt_indat = val_b ^ cmt_invert;
561 case FM7_MAINIO_CMT_INVERT: // FD02
564 case FM7_MAINIO_TIMERIRQ: //
565 set_irq_timer(val_b);
567 case FM7_MAINIO_LPTIRQ: //
568 set_irq_printer(val_b);
570 case FM7_MAINIO_KEYBOARDIRQ: //
571 set_irq_keyboard(val_b);
574 case FM7_MAINIO_PUSH_BREAK:
575 set_break_key(val_b);
577 case FM7_MAINIO_SUB_ATTENTION:
578 if(val_b) set_sub_attention(true);
581 case FM7_MAINIO_EXTDET:
584 case FM7_MAINIO_BEEP:
587 case FM7_MAINIO_JOYPORTA_CHANGED:
588 joyport_a = data & mask;
590 case FM7_MAINIO_JOYPORTB_CHANGED:
591 joyport_b = data & mask;
593 case FM7_MAINIO_PSG_IRQ:
595 case FM7_MAINIO_OPN_IRQ:
596 if(!connect_opn) break;
600 case FM7_MAINIO_WHG_IRQ:
601 if(!connect_whg) break;
605 case FM7_MAINIO_THG_IRQ:
606 if(!connect_thg) break;
610 case FM7_MAINIO_FDC_DRQ:
613 case FM7_MAINIO_FDC_IRQ:
616 case FM7_MAINIO_KANJI1_ADDR_HIGH:
619 case FM7_MAINIO_KANJI1_ADDR_LOW:
622 #if defined(CAPABLE_KANJI_CLASS2)
623 case FM7_MAINIO_KANJI2_ADDR_HIGH:
624 kaddress_l2.b.h = data;
626 case FM7_MAINIO_KANJI2_ADDR_LOW:
627 kaddress_l2.b.l = data;
635 uint8 FM7_MAINIO::get_irqstat_fd03(void)
640 extirq = irqstat_fdc | intstat_opn | intstat_whg | intstat_thg;
642 //extirq = extirq | intstat_syndet | intstat_rxrdy | intstat_txrdy;
644 irqstat_reg0 &= ~0x08;
646 irqstat_reg0 |= 0x08;
648 val = irqstat_reg0 | 0xf0;
649 set_irq_timer(false);
650 set_irq_printer(false);
654 uint8 FM7_MAINIO::get_extirq_fd17(void)
657 if(intstat_opn) val &= ~0x08;
658 if(intstat_mouse) val &= ~0x04;
659 //if(!intstat_opn && !intstat_mouse) do_irq(false);
663 void FM7_MAINIO::set_ext_fd17(uint8 data)
665 if((data & 0x04) != 0) {
668 mouse_enable = false;
672 #if defined(_FM77AV_VARIANTS)
674 uint8 FM7_MAINIO::subsystem_read_status(void)
677 //retval = (display->read_signal(SIG_DISPLAY_MODE320) != 0) ? 0x40 : 0;
678 retval = (mode320) ? 0x40 : 0;
679 retval |= display->read_signal(SIG_DISPLAY_VSYNC);
680 retval |= display->read_signal(SIG_DISPLAY_DISPLAY);
686 uint32 FM7_MAINIO::read_signal(uint32 addr)
688 uint32 retval = 0xffffffff;
694 uint32 FM7_MAINIO::read_data8(uint32 addr)
697 if(addr == FM7_MAINIO_IS_BASICROM) {
699 if(stat_bootsw_basic) retval = 0xffffffff;
701 } else if(addr == FM7_MAINIO_BOOTMODE) {
702 retval = bootmode & 0x03;
703 #if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4) || defined(_FM77AV_VARIANTS)
704 if(boot_ram) retval = 4;
707 } else if(addr == FM7_MAINIO_READ_FD0F) {
708 if(stat_romrammode) return 0xffffffff;
710 } else if(addr == FM7_MAINIO_CLOCKMODE) {
711 return (uint32)get_clockmode();
714 else if(addr == FM7_MAINIO_MMR_ENABLED) {
715 retval = (mmr_enabled) ? 0xffffffff:0x00000000;
717 } else if(addr == FM7_MAINIO_WINDOW_ENABLED) {
718 retval = (window_enabled) ? 0xffffffff:0x00000000;
720 } else if(addr == FM7_MAINIO_WINDOW_OFFSET) {
721 retval = (uint32)window_offset;
723 } else if(addr == FM7_MAINIO_MMR_SEGMENT) {
724 retval = (uint32) mmr_segment;
726 } else if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 16))) {
727 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
728 retval = (uint32)mmr_table[(addr - FM7_MAINIO_MMR_BANK) | (mmr_segment & 7) * 16];
730 retval = (uint32)mmr_table[(addr - FM7_MAINIO_MMR_BANK) | (mmr_segment & 3) * 16] & 0x3f;
735 #if defined(_FM77AV_VARIANTS)
736 else if(addr == FM7_MAINIO_INITROM_ENABLED) {
737 retval = (enable_initiator) ? 0xffffffff : 0x00000000;
739 } else if(addr == FM7_MAINIO_MODE320) {
740 retval = (mode320) ? 0xffffffff : 0x00000000;
742 } else if(addr == FM7_MAINIO_SUBMONITOR_ROM) {
743 retval = sub_monitor_type & 0x03;
745 } else if(addr == FM7_MAINIO_SUBMONITOR_RAM) {
746 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
747 retval = ((sub_monitor_type & 0x04) != 0) ? 0xffffffff : 0x00000000;
754 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
755 else if(addr == FM7_MAINIO_EXTBANK) {
756 } else if(addr == FM7_MAINIO_EXTROM) {
759 //if((addr >= 0x0006) && (addr != 0x1f)) printf("MAINIO: READ: %08x DATA=%08x\n", addr);
763 if((addr < 0x90) && (addr >= 0x80)) {
764 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
765 return mmr_table[addr - 0x80 + mmr_segment * 16];
767 return mmr_table[addr - 0x80 + (mmr_segment & 0x03) * 16];
771 // if((addr >= 0x0006) && !(addr == 0x1f) && !(addr == 0x0b)) printf("MAINIO: READ: %08x \n", addr);
774 retval = (uint32) get_port_fd00();
777 retval = keyboard->read_data8(0x01) & 0xff;
779 //set_irq_keyboard(key_irq_req);
782 retval = (uint32) get_port_fd02();
785 retval = (uint32) get_irqstat_fd03();
788 retval = (uint32) get_fd04();
791 retval = (uint32) get_fd05();
793 case 0x06: // RS-232C
796 case 0x08: // Light pen
800 #if defined(_FM77AV_VARIANTS)
802 retval = (bootmode == 0) ? 0xfe : 0xff;
805 case 0x0e: // PSG DATA
806 retval = (uint32) get_psg();
807 //printf("PSG DATA READ val=%02x\n", retval);
813 #if defined(_FM77AV_VARIANTS)
815 retval = subsystem_read_status();
818 case 0x15: // OPN CMD
819 //printf("OPN CMD READ \n");
821 case 0x16: // OPN DATA
822 retval = (uint32) get_opn(0);
823 //printf("OPN DATA READ val=%02x\n", retval);
826 retval = (uint32) get_extirq_fd17();
828 case 0x18: // FDC: STATUS
829 retval = (uint32) get_fdc_stat();
830 //printf("FDC: READ STATUS %02x PC=%04x\n", retval, maincpu->get_pc());
832 case 0x19: // FDC: Track
833 retval = (uint32) get_fdc_track();
834 //printf("FDC: READ TRACK REG %02x\n", retval);
836 case 0x1a: // FDC: Sector
837 retval = (uint32) get_fdc_sector();
838 //printf("FDC: READ SECTOR REG %02x\n", retval);
840 case 0x1b: // FDC: Data
841 retval = (uint32) get_fdc_data();
844 retval = (uint32) get_fdc_fd1c();
845 //printf("FDC: READ HEAD REG %02x\n", retval);
848 retval = (uint32) get_fdc_motor();
849 //printf("FDC: READ MOTOR REG %02x\n", retval);
852 retval = (uint32) fdc_getdrqirq();
854 case 0x22: // Kanji ROM
855 retval = (uint32) read_kanjidata_left();
857 case 0x23: // Kanji ROM
858 retval = (uint32) read_kanjidata_right();
860 #if defined(CAPABLE_KANJI_CLASS2)
861 case 0x2e: // Kanji ROM Level2
862 retval = (uint32) read_kanjidata_left_l2();
864 case 0x2f: // Kanji ROM Level2
865 retval = (uint32) read_kanjidata_right_l2();
868 case 0x37: // Multi page
869 //retval = (uint32)display->read_data8(DISPLAY_ADDR_MULTIPAGE);
871 case 0x45: // WHG CMD
873 case 0x46: // WHG DATA
874 retval = (uint32) get_opn(1);
877 retval = (uint32) get_extirq_whg();
879 case 0x51: // THG CMD
881 case 0x52: // THG DATA
882 retval = (uint32) get_opn(2);
885 retval = (uint32) get_extirq_thg();
890 if(boot_ram) retval |= 0x01;
891 if(window_enabled) retval |= 0x40;
892 if(mmr_enabled) retval |= 0x80;
896 //printf("MAIN: Read another I/O Addr=%08x\n", addr);
899 if((addr < 0x40) && (addr >= 0x38)) {
900 addr = (addr - 0x38) + FM7_SUBMEM_OFFSET_DPALETTE;
901 return (uint32) display->read_data8(addr);
907 void FM7_MAINIO::write_data8(uint32 addr, uint32 data)
910 if(addr == FM7_MAINIO_BOOTMODE) {
911 bootmode = data & 0x03;
913 } else if(addr == FM7_MAINIO_CLOCKMODE) {
914 set_clockmode((uint8)data);
917 //if((addr >= 0x0006) && !(addr == 0x1f)) printf("MAINIO: WRITE: %08x DATA=%08x\n", addr, data);
921 io_w_latch[addr] = data;
923 if((addr < 0x90) && (addr >= 0x80)) {
924 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
925 mmr_table[addr - 0x80 + mmr_segment * 16] = data;
927 mmr_table[addr - 0x80 + (mmr_segment & 0x03) * 16] = data & 0x3f;
929 //printf("MMR: Write access segment=%02x addr=%02x page=%02x\n", mmr_segment, addr - 0x80, data);
935 set_port_fd00((uint8)data);
939 // set_lptdata_fd01((uint8)data);
942 set_port_fd02((uint8)data);
948 // set_flags_fd04(data);
951 set_fd05((uint8)data);
953 case 0x06: // RS-232C
956 case 0x08: // Light pen
961 //printf("PSG CMD WRITE val=%02x\n", data);
965 //printf("PSG DATA WRITE val=%02x\n", data);
971 #if defined(_FM77AV_VARIANTS)
973 flag = enable_initiator;
974 //printf("INITIATOR ENABLE = %02x\n", data);
975 enable_initiator = ((data & 0x02) == 0) ? true : false;
976 if(flag != enable_initiator) {
982 mode320 = ((data & 0x40) != 0);
983 display->write_signal(SIG_DISPLAY_MODE320, data, 0x40);
986 sub_monitor_type = data & 0x07;
987 //register_event_by_clock(this, EVENT_FM7SUB_PROC, 8, false, NULL); // 1uS / 8MHz
988 //do_sync_main_sub();
991 case 0x15: // OPN CMD
992 //printf("OPN CMD WRITE val=%02x\n", data);
993 set_opn_cmd(0, data);
995 case 0x16: // OPN DATA
996 //printf("OPN DATA WRITE val=%02x\n", data);
1000 set_ext_fd17((uint8)data);
1002 case 0x18: // FDC: COMMAND
1003 set_fdc_cmd((uint8)data);
1004 //printf("FDC: WRITE CMD %02x\n", data);
1006 case 0x19: // FDC: Track
1007 set_fdc_track((uint8)data);
1008 //printf("FDC: WRITE TRACK REG %02x\n", data);
1010 case 0x1a: // FDC: Sector
1011 set_fdc_sector((uint8)data);
1012 //printf("FDC: WRITE SECTOR REG %02x\n", data);
1014 case 0x1b: // FDC: Data
1015 set_fdc_data((uint8)data);
1018 set_fdc_fd1c((uint8)data);
1019 //printf("FDC: WRITE HEAD REG %02x\n", data);
1022 set_fdc_fd1d((uint8)data);
1023 //printf("FDC: WRITE MOTOR REG %02x\n", data);
1028 case 0x20: // Kanji ROM
1029 case 0x2c: // Kanji ROM(DUP)
1030 write_kanjiaddr_hi((uint8)data);
1031 #if defined(CAPABLE_KANJI_CLASS2)
1032 write_kanjiaddr_hi_l2((uint8)data);
1035 case 0x21: // Kanji ROM
1036 case 0x2d: // Kanji ROM(DUP)
1037 write_kanjiaddr_lo((uint8)data);
1038 #if defined(CAPABLE_KANJI_CLASS2)
1039 write_kanjiaddr_lo_l2((uint8)data);
1042 #if defined(_FM77AV_VARIANTS)
1044 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_HI, data);
1047 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_LO, data);
1050 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_B, data);
1053 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_R, data);
1056 display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_G, data);
1059 case 0x37: // Multi page
1060 display->write_signal(SIG_DISPLAY_MULTIPAGE, data, 0x00ff);
1062 case 0x45: // WHG CMD
1063 set_opn_cmd(1, data);
1065 case 0x46: // WHG DATA
1070 case 0x51: // THG CMD
1071 set_opn_cmd(2, data);
1073 case 0x52: // THG DATA
1078 #if defined(HAS_MMR)
1080 #if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
1081 mmr_segment = data & 7;
1083 // printf("MMR SEGMENT: %02x\n", data & 3);
1084 mmr_segment = data & 3;
1088 window_offset = data & 0x00ff;
1091 if((data & 0x01) == 0) {
1096 if((data & 0x40) == 0) {
1097 window_enabled = false;
1099 window_enabled = true;
1102 if((data & 0x80) == 0) {
1103 mmr_enabled = false;
1107 if(flag != mmr_enabled) {
1108 this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
1113 //printf("MAIN: Write I/O Addr=%08x DATA=%02x\n", addr, data);
1116 if((addr < 0x40) && (addr >= 0x38)) {
1117 addr = (addr - 0x38) | FM7_SUBMEM_OFFSET_DPALETTE;
1118 display->write_data8(addr, (uint8)data);
1124 void FM7_MAINIO::event_callback(int event_id, int err)
1126 // printf("MAIN EVENT id=%d\n", event_id);
1128 case EVENT_BEEP_OFF:
1131 case EVENT_BEEP_CYCLE:
1134 case EVENT_UP_BREAK:
1135 set_break_key(false);
1137 case EVENT_TIMERIRQ_ON:
1138 if(!irqmask_timer) set_irq_timer(true);
1139 //register_event(this, EVENT_TIMERIRQ_OFF, 10000.0 / (4.9152 * 2.0) , false, NULL); // TIMER IRQ
1141 case EVENT_TIMERIRQ_OFF:
1142 if(!irqmask_timer) set_irq_timer(false);
1143 //register_event(this, EVENT_TIMERIRQ_ON, 2035, false, NULL); // TIMER ON
1145 case EVENT_FD_MOTOR_ON:
1146 set_fdc_motor(true);
1148 case EVENT_FD_MOTOR_OFF:
1149 set_fdc_motor(false);
1151 case EVENT_FM7SUB_PROC:
1160 void FM7_MAINIO::update_config()
1162 switch(config.cpu_type){
1170 // this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
1173 void FM7_MAINIO::event_vline(int v, int clock)
1177 void FM7_MAINIO::do_sync_main_sub(void)
1179 register_event(this, EVENT_FM7SUB_PROC, 1.0, false, NULL); // 1uS
1180 register_event(display, EVENT_FM7SUB_PROC, 1.0, false, NULL); // 1uS
1184 void FM7_MAINIO::proc_sync_to_sub(void)
1186 if(sub_halt != sub_halt_bak) {
1187 display->write_signal(SIG_DISPLAY_HALT, (sub_halt) ? 0xff : 0x00, 0xff);
1189 sub_halt_bak = sub_halt;
1190 if(firq_sub_attention != firq_sub_attention_bak){
1193 firq_sub_attention_bak = firq_sub_attention;
1194 #if defined(_FM77AV_VARIANTS)
1195 if(sub_monitor_type != sub_monitor_bak) {
1196 display->write_signal(SIG_FM7_SUB_BANK, sub_monitor_type, 0x07);
1198 sub_monitor_bak = sub_monitor_type;