#include "../datarec.h"
// TEST
-//#include <SDL2/SDL.h>
+#include <SDL2/SDL.h>
-void FM7_MAINIO::initialize(void)
+void FM7_MAINIO::initialize()
{
+ int i;
event_beep = -1;
+ event_beep_oneshot = -1;
event_timerirq = -1;
bootmode = config.boot_mode & 3;
#if defined(_FM77AV_VARIANTS)
opn_psg_77av = true;
#else
+ //opn_psg_77av = true;
opn_psg_77av = false;
#endif
+#if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
+ boot_ram = false;
+#endif
+#if defined(_FM77AV_VARIANTS)
+ enable_initiator = true;
+#endif
+#ifdef HAS_MMR
+ mmr_enabled = false;
+ mmr_fast = false;
+ window_enabled = false;
+ mmr_segment = 0x00;
+ for(i = 0x00; i < 0x80; i++) mmr_table[i] = 0;
+ // for(i = 0x00; i < 0x10; i++) mmr_table[i] = 0x30 + i;
+#endif
+ switch(config.cpu_type){
+ case 0:
+ clock_fast = true;
+ break;
+ case 1:
+ clock_fast = false;
+ break;
+ }
+ this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
+ sub_busy = false;
}
-void FM7_MAINIO::reset(void)
+void FM7_MAINIO::reset()
{
int i, j;
uint8 data;
- //if(event_beep >= 0) cancel_event(this, event_beep);
- if(event_timerirq >= 0) cancel_event(this, event_timerirq);
+ if(event_beep >= 0) cancel_event(this, event_beep);
event_beep = -1;
+ if(event_beep_oneshot >= 0) cancel_event(this, event_beep_oneshot);
+ event_beep_oneshot = -1;
+ if(event_timerirq >= 0) cancel_event(this, event_timerirq);
beep_snd = true;
beep_flag = false;
+ if(event_beep < 0) register_event(this, EVENT_BEEP_CYCLE, (1000.0 * 1000.0) / (1200.0 * 2.0), true, &event_beep);
+
extdet_neg = false;
stat_romrammode = true;
} else { // ELSE RAM
stat_romrammode = false;
}
-
+#if defined(_FM77_VARIANTS) || defined(_FM77AV_VARIANTS)
+ boot_ram = false;
+ kaddress.d = 0;
+#endif
+#if defined(_FM77AV_VARIANTS)
+ mode320 = false;
+ sub_monitor_type = 0x00;
+ sub_monitor_bak = sub_monitor_type;
+ display->write_signal(SIG_FM7_SUB_BANK, sub_monitor_type, 0x07);
+#endif
+
+#ifdef HAS_MMR
+ mmr_enabled = false;
+ mmr_fast = false;
+ window_enabled = false;
+#endif
clock_fast = false;
if(config.cpu_type == 0) clock_fast = true;
reset_sound();
+ key_irq_req = false;
+ key_irq_bak = key_irq_req;
irqmask_reg0 = 0x00;
irqstat_bak = false;
// FD04
//firq_break_key = false; // bit1, ON = '0'.
firq_sub_attention = false; // bit0, ON = '0'.
+ firq_sub_attention_bak = false; // bit0, ON = '0'.
// FD05
- sub_busy = false;
extdet_neg = false;
sub_cancel = false; // bit6 : '1' Cancel req.
-
+ sub_halt = false; // bit6 : '1' Cancel req.
+ sub_cancel_bak = !sub_cancel; // bit6 : '1' Cancel req.
+ sub_halt_bak = !sub_halt; // bit6 : '1' Cancel req.
nmi_count = 0;
reset_fdc();
register_event(this, EVENT_TIMERIRQ_ON, 10000.0 / 4.9152, true, &event_timerirq); // TIMER IRQ
-
- maincpu->reset();
+ mainmem->reset();
+ memset(io_w_latch, 0x00, 0x100);
+ sub_busy = (read_signal(SIG_DISPLAY_BUSY) == 0) ? false : true;
+ keycode_7 = 0x00;
+ keycode = 0x00;
+ //register_event_by_clock(this, EVENT_FM7SUB_PROC, 16, true, NULL); // 2uS / 8MHz
+ //maincpu->reset();
}
void FM7_MAINIO::set_clockmode(uint8 flags)
{
- if(flags == FM7_MAINCLOCK_SLOW) {
+ uint f = clock_fast;
+ if((flags & FM7_MAINCLOCK_SLOW) != 0) {
clock_fast = false;
} else {
clock_fast = true;
}
+ if(f != clock_fast) {
+ this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
+ }
}
uint8 FM7_MAINIO::get_clockmode(void)
uint8 FM7_MAINIO::get_port_fd00(void)
{
- uint8 ret = 0b01111110;
- if(kbd_bit8) ret |= 0b10000000;
- if(clock_fast) ret |= 0b00000001;
+ uint8 ret = 0x7e; //0b01111110;
+ if((keycode & 0x100) != 0) ret |= 0x80; // High bit.
+ if(clock_fast) ret |= 0x01; //0b00000001;
return ret;
}
bool printerirq_bak = irqmask_printer;
bool mfdirq_bak = irqmask_mfd;
bool flag;
- if((val & 0b00010000) != 0) {
- irqmask_mfd = false;
+ // if((val & 0b00010000) != 0) {
+ if((val & 0x10) != 0) {
+ irqmask_mfd = false;
} else {
irqmask_mfd = true;
}
flag = irqstat_fdc;
set_irq_mfd(flag);
}
- if((val & 0b00000100) != 0) {
+ //if((val & 0b00000100) != 0) {
+ if((val & 0x04) != 0) {
irqmask_timer = false;
} else {
irqmask_timer = true;
flag = irqstat_timer;
set_irq_timer(flag);
}
- if((val & 0b00000010) != 0) {
+ //if((val & 0b00000010) != 0) {
+ if((val & 0x02) != 0) {
irqmask_printer = false;
} else {
irqmask_printer = true;
set_irq_printer(flag);
}
- if((val & 0b00000001) != 0) {
+ //if((val & 0b00000001) != 0) {
+ if((val & 0x01) != 0) {
irqmask_keyboard = false;
} else {
irqmask_keyboard = true;
if(keyirq_bak != irqmask_keyboard) {
flag = irqstat_keyboard;
flag = flag & !irqmask_keyboard;
- display->write_signal(SIG_FM7_SUB_KEY_FIRQ, flag ? 1 : 0, 1);
+ display->write_signal(SIG_FM7_SUB_KEY_MASK, flag ? 1 : 0, 1);
+ display->write_signal(SIG_FM7_SUB_KEY_FIRQ, flag ? keycode : 0, 0xffffffff);
//printf("KEYBOARD: Interrupted %d\n", flag);
irqmask_keyboard = flag;
- do_irq(flag);
+ do_irq();
}
return;
}
-
-uint32 FM7_MAINIO::get_keyboard(void)
-{
- uint32 kbd_data = (uint32) kbd_bit7_0;
- kbd_data &= 0x0ff;
- if(kbd_bit8) kbd_data |= 0x0100;
- return kbd_data;
-}
-
-
-
void FM7_MAINIO::set_irq_timer(bool flag)
{
uint8 backup = irqstat_reg0;
if(flag && !(irqmask_timer)) {
- //irqstat_reg0 |= 0b00000100;
- irqstat_reg0 &= 0b11111011;
+ irqstat_reg0 &= 0xfb; //~0x04;
irqstat_timer = true;
- if(backup != irqstat_reg0) do_irq(true);
+ if(backup != irqstat_reg0) do_irq();
} else {
- irqstat_reg0 |= 0b00000100;
- //irqstat_reg0 &= 0b11111011;
+ irqstat_reg0 |= 0x04;
irqstat_timer = false;
- if(backup != irqstat_reg0) do_irq(false);
+ if(backup != irqstat_reg0) do_irq();
}
//printf("IRQ TIMER: %02x MASK=%d\n", irqstat_reg0, irqmask_timer);
}
{
uint8 backup = irqstat_reg0;
if(flag && !(irqmask_printer)) {
- irqstat_reg0 &= 0b111111101;
+ irqstat_reg0 &= ~0x02;
irqstat_printer = true;
- if(backup != irqstat_reg0) do_irq(true);
+ if(backup != irqstat_reg0) do_irq();
} else {
- irqstat_reg0 |= 0b000000010;
+ irqstat_reg0 |= 0x02;
irqstat_printer = false;
- if(backup != irqstat_reg0) do_irq(false);
+ if(backup != irqstat_reg0) do_irq();
}
-// if(!irqmask_printer || !flag) do_irq(flag);
+// if(!irqmask_printer || !flag) do_irq();
}
void FM7_MAINIO::set_irq_keyboard(bool flag)
{
uint8 backup = irqstat_reg0;
+ //printf("MAIN: KEYBOARD: IRQ=%d MASK=%d\n", flag ,irqmask_keyboard);
if(irqmask_keyboard) return;
if(flag) {
- irqstat_reg0 &= 0b11111110;
+ irqstat_reg0 &= 0xfe;
irqstat_keyboard = true;
- if(backup != irqstat_reg0) do_irq(true);
+ // if(backup != irqstat_reg0) do_irq();
} else {
- //irqstat_reg0 &= 0b11111110;
- irqstat_reg0 |= 0b00000001;
+ irqstat_reg0 |= 0x01;
irqstat_keyboard = false;
- if(backup != irqstat_reg0) do_irq(false);
+ // if(backup != irqstat_reg0) do_irq();
}
- //printf("MAIN: KEYBOARD: IRQ=%d\n", flag && !(irqmask_keyboard));
-}
-
-void FM7_MAINIO::set_keyboard(uint32 data)
-{
- if((data & 0x100) != 0){
- kbd_bit8 = true;
- } else {
- kbd_bit8 = false;
- }
- kbd_bit7_0 = (data & 0xff);
+ do_irq();
}
-void FM7_MAINIO::do_irq(bool flag)
+void FM7_MAINIO::do_irq(void)
{
bool intstat;
intstat = irqstat_timer | irqstat_keyboard | irqstat_printer;
intstat = intstat | intstat_opn | intstat_whg | intstat_thg;
intstat = intstat | intstat_mouse;
- if(irqstat_bak == intstat) return;
+ //if(irqstat_bak == intstat) return;
//printf("%08d : IRQ: REG0=%02x FDC=%02x, stat=%d\n", SDL_GetTicks(), irqstat_reg0, irqstat_fdc, intstat);
if(intstat) {
maincpu->write_signal(SIG_CPU_IRQ, 1, 1);
irqstat_bak = intstat;
}
-void FM7_MAINIO::do_firq(bool flag)
+void FM7_MAINIO::do_firq(void)
{
bool firq_stat;
- firq_stat = firq_break_key || firq_sub_attention;
+ firq_stat = firq_break_key | firq_sub_attention;
//printf("%08d : FIRQ: break=%d attn=%d stat = %d\n", SDL_GetTicks(), firq_break_key, firq_sub_attention, firq_stat);
- //if(firqstat_bak == firq_stat) return;
+ if(firqstat_bak == firq_stat) return;
if(firq_stat) {
maincpu->write_signal(SIG_CPU_FIRQ, 1, 1);
} else {
void FM7_MAINIO::set_break_key(bool pressed)
{
firq_break_key = pressed;
- do_firq(pressed);
+ do_firq();
}
void FM7_MAINIO::set_sub_attention(bool flag)
{
firq_sub_attention = flag;
- do_firq(flag);
+ //register_event_by_clock(this, EVENT_FM7SUB_PROC, 8, false, NULL); // 1uS / 8MHz
+// do_firq();
+ do_sync_main_sub();
}
uint8 FM7_MAINIO::get_fd04(void)
{
- uint8 val = 0b11111100;
- //if(!sub_busy) val &= 0b01111111;
- if(!firq_break_key) val |= 0b00000010;
- if(!firq_sub_attention) val |= 0b00000001;
- //if(firq_sub_attention) {
- //firq_sub_attention = false;
- //printf("MAINIO : ATTENTION OFF\n");
+ uint8 val = 0x7c;
+ if(sub_busy) val |= 0x80;
+ if(!firq_break_key) val |= 0x02;
+ if(!firq_sub_attention) {
+ val |= 0x01;
+ }
set_sub_attention(false);
- //}
return val;
}
void FM7_MAINIO::set_fd04(uint8 val)
{
// NOOP?
+#if defined(_FM77AV40) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+ display->write_signal(SIG_DISPLAY_EXTRA_MODE, val, 0xff);
+#endif
}
// FD05
uint8 FM7_MAINIO::get_fd05(void)
{
- uint8 val = 0b01111110;
- if(sub_busy) val |= 0b10000000;
- if(!extdet_neg) val |= 0b00000001;
+ uint8 val;
+ val = (sub_busy) ? 0xfe : 0x7e;
+ if(!extdet_neg) val |= 0x01;
+ //printf("FD05: READ: %d VAL=%02x\n", SDL_GetTicks(), val);
return val;
}
void FM7_MAINIO::set_fd05(uint8 val)
{
-// subcpu->write_signal(SIG_CPU_BUSREQ, val, 0b10000000);
- display->write_signal(SIG_FM7_SUB_CANCEL, val, 0b01000000); // HACK
- display->write_signal(SIG_DISPLAY_HALT, val, 0b10000000);
+ sub_cancel = ((val & 0x40) != 0) ? true : false;
+ sub_halt = ((val & 0x80) != 0) ? true : false;
+ //register_event_by_clock(this, EVENT_FM7SUB_PROC, 8, false, NULL); // 1uS / 8MHz
+ do_sync_main_sub();
+
+ if(sub_cancel != sub_cancel_bak) {
+ display->write_signal(SIG_FM7_SUB_CANCEL, (sub_cancel) ? 0xff : 0x00, 0xff); // HACK
+ }
+ sub_cancel_bak = sub_cancel;
#ifdef WITH_Z80
- if((val & 0b00000001) != 0) {
+ if((val & 0x01) != 0) {
//maincpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
//z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
} else {
void FM7_MAINIO::write_kanjiaddr_hi(uint8 addr)
{
if(!connect_kanjiroml1) return;
- kaddress_hi = addr;
+ kaddress.b.h = addr;
return;
}
void FM7_MAINIO::write_kanjiaddr_lo(uint8 addr)
{
if(!connect_kanjiroml1) return;
- kaddress_lo = addr;
+ kaddress.b.l = addr;
return;
}
uint32 addr;
if(!connect_kanjiroml1) return 0xff;
- addr = ((uint32)kaddress_hi << 8) | (uint32)kaddress_lo;
+ addr = kaddress.w.l;
addr = addr << 1;
+ //printf("KANJI MAIN CLASS1 ADDR: %05x\n", kaddress.w.l);
if(kanjiclass1) {
return kanjiclass1->read_data8(addr);
} else {
uint32 addr;
if(!connect_kanjiroml1) return 0xff;
- addr = ((uint32)kaddress_hi << 8) | (uint32)kaddress_lo;
- addr = (addr << 1) | 1;
+ addr = kaddress.w.l;
+ addr = (addr << 1) + 1;
if(kanjiclass1) {
return kanjiclass1->read_data8(addr);
} else {
}
}
-#ifdef _FM77AV_VARIANTS
+#ifdef CAPABLE_KANJICLASS2
// Kanji ROM, FD20 AND FD21 (or SUBSYSTEM)
void FM7_MAINIO::write_kanjiaddr_hi_l2(uint8 addr)
{
if(!connect_kanjiroml2) return;
- kaddress_hi_l2 = addr;
+ kaddress_l2.b.h = addr;
return;
}
void FM7_MAINIO::write_kanjiaddr_lo_l2(uint8 addr)
{
if(!connect_kanjiroml2) return;
- kaddress_lo_l2 = addr;
+ kaddress_l2.b.l = addr;
return;
}
uint32 addr;
if(!connect_kanjiroml2) return 0xff;
- addr = ((uint32)kaddress_hi_l2 << 8) | (uint32)kaddress_lo_l2;
+ addr = kaddress.w.l;
addr = addr << 1;
if(kanjiclass2) {
return kanjiclass2->read_data8(addr);
uint32 addr;
if(!connect_kanjiroml2) return 0xff;
- addr = ((uint32)kaddress_hi_l2 << 8) | (uint32)kaddress_lo_l2;
- addr = (addr << 1) | 0x01;
+ addr = kaddress_l2.w.l;
+ addr = (addr << 1) + 0x01;
if(kanjiclass2) {
return kanjiclass2->read_data8(addr);
} else {
val_b = ((data & mask) != 0);
switch(id) {
+ case FM7_MAINIO_SUB_BUSY:
+ sub_busy = val_b;
+ break;
case FM7_MAINIO_CLOCKMODE: // fd00
if(val_b) {
clock_fast = true;
clocks = 1095000; // Hz
}
#endif
- if(clock_fast) {
- subclocks = 2000000; // Hz
- } else {
- subclocks = 999000; // Hz
- }
p_vm->set_cpu_clock(this->maincpu, clocks);
- p_vm->set_cpu_clock(this->subcpu, subclocks);
+ display->write_signal(SIG_DISPLAY_CLOCK, clock_fast ? 1 : 0, 1);
}
break;
case FM7_MAINIO_CMT_RECV: // FD02
set_irq_printer(val_b);
break;
case FM7_MAINIO_KEYBOARDIRQ: //
- set_irq_keyboard(val_b);
- break;
- case FM7_MAINIO_PUSH_KEYBOARD:
- set_keyboard(data & 0x1ff);
+ key_irq_req = val_b;
+ if(val_b) keycode_7 = data & 0x3ff;
+ set_irq_keyboard(key_irq_req);
+ keycode = keycode_7;
break;
// FD04
case FM7_MAINIO_PUSH_BREAK:
set_break_key(val_b);
break;
case FM7_MAINIO_SUB_ATTENTION:
- set_sub_attention(val_b);
+ if(val_b) set_sub_attention(true);
break;
// FD05
- case FM7_MAINIO_SUB_BUSY:
- sub_busy = val_b;
- break;
case FM7_MAINIO_EXTDET:
extdet_neg = !val_b;
break;
case FM7_MAINIO_OPN_IRQ:
if(!connect_opn) break;
intstat_opn = val_b;
- do_irq(val_b);
+ do_irq();
break;
case FM7_MAINIO_WHG_IRQ:
if(!connect_whg) break;
intstat_whg = val_b;
- do_irq(val_b);
+ do_irq();
break;
case FM7_MAINIO_THG_IRQ:
if(!connect_thg) break;
intstat_thg = val_b;
- do_irq(val_b);
+ do_irq();
break;
case FM7_MAINIO_FDC_DRQ:
set_drq_mfd(val_b);
case FM7_MAINIO_FDC_IRQ:
set_irq_mfd(val_b);
break;
+ case FM7_MAINIO_KANJI1_ADDR_HIGH:
+ kaddress.b.h = data;
+ break;
+ case FM7_MAINIO_KANJI1_ADDR_LOW:
+ kaddress.b.l = data;
+ break;
+#if defined(CAPABLE_KANJI_CLASS2)
+ case FM7_MAINIO_KANJI2_ADDR_HIGH:
+ kaddress_l2.b.h = data;
+ break;
+ case FM7_MAINIO_KANJI2_ADDR_LOW:
+ kaddress_l2.b.l = data;
+ break;
+#endif
}
}
//extirq = extirq | intstat_syndet | intstat_rxrdy | intstat_txrdy;
if(extirq) {
- irqstat_reg0 &= 0b11110111;
- //irqstat_reg0 |= 0b00001000;
+ irqstat_reg0 &= ~0x08;
} else {
- irqstat_reg0 |= 0b00001000;
- //irqstat_reg0 &= 0b11110111;
+ irqstat_reg0 |= 0x08;
}
- val = irqstat_reg0;
+ val = irqstat_reg0 | 0xf0;
set_irq_timer(false);
set_irq_printer(false);
return val;
uint8 FM7_MAINIO::get_extirq_fd17(void)
{
uint8 val = 0xff;
- if(intstat_opn) val &= 0b11110111;
- if(intstat_mouse) val &= 0b11111011;
+ if(intstat_opn) val &= ~0x08;
+ if(intstat_mouse) val &= ~0x04;
//if(!intstat_opn && !intstat_mouse) do_irq(false);
return val;
}
void FM7_MAINIO::set_ext_fd17(uint8 data)
{
- if((data & 0b00000100) != 0) {
+ if((data & 0x04) != 0) {
mouse_enable = true;
} else {
mouse_enable = false;
}
}
+#if defined(_FM77AV_VARIANTS)
+// FD12
+uint8 FM7_MAINIO::subsystem_read_status(void)
+{
+ uint8 retval;
+ //retval = (display->read_signal(SIG_DISPLAY_MODE320) != 0) ? 0x40 : 0;
+ retval = (mode320) ? 0x40 : 0;
+ retval |= display->read_signal(SIG_DISPLAY_VSYNC);
+ retval |= display->read_signal(SIG_DISPLAY_DISPLAY);
+ retval |= ~0x43;
+ return retval;
+}
+#endif
-
uint32 FM7_MAINIO::read_signal(uint32 addr)
{
uint32 retval = 0xffffffff;
uint32 FM7_MAINIO::read_data8(uint32 addr)
{
uint32 retval;
-
if(addr == FM7_MAINIO_IS_BASICROM) {
retval = 0;
if(stat_bootsw_basic) retval = 0xffffffff;
} else if(addr == FM7_MAINIO_BOOTMODE) {
retval = bootmode & 0x03;
#if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4) || defined(_FM77AV_VARIANTS)
- if(bootram) retval = 4;
+ if(boot_ram) retval = 4;
#endif
return retval;
} else if(addr == FM7_MAINIO_READ_FD0F) {
} else if(addr == FM7_MAINIO_WINDOW_ENABLED) {
retval = (window_enabled) ? 0xffffffff:0x00000000;
return retval;
+ } else if(addr == FM7_MAINIO_WINDOW_OFFSET) {
+ retval = (uint32)window_offset;
+ return retval;
} else if(addr == FM7_MAINIO_MMR_SEGMENT) {
retval = (uint32) mmr_segment;
return retval;
- } else if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 64))) {
- retval = (uint32)mmr_table[addr - FM7_MAINIO_MMR_BANK];
+ } else if((addr >= FM7_MAINIO_MMR_BANK) && (addr < (FM7_MAINIO_MMR_BANK + 16))) {
+#if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
+ retval = (uint32)mmr_table[(addr - FM7_MAINIO_MMR_BANK) | (mmr_segment & 7) * 16];
+#else
+ retval = (uint32)mmr_table[(addr - FM7_MAINIO_MMR_BANK) | (mmr_segment & 3) * 16] & 0x3f;
+#endif
return retval;
}
#endif
#if defined(_FM77AV_VARIANTS)
else if(addr == FM7_MAINIO_INITROM_ENABLED) {
+ retval = (enable_initiator) ? 0xffffffff : 0x00000000;
+ return retval;
+ } else if(addr == FM7_MAINIO_MODE320) {
+ retval = (mode320) ? 0xffffffff : 0x00000000;
+ return retval;
+ } else if(addr == FM7_MAINIO_SUBMONITOR_ROM) {
+ retval = sub_monitor_type & 0x03;
+ return retval;
+ } else if(addr == FM7_MAINIO_SUBMONITOR_RAM) {
+#if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
+ retval = ((sub_monitor_type & 0x04) != 0) ? 0xffffffff : 0x00000000;
+#else
+ retval = 0;
+#endif
+ return retval;
}
#endif
#if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
} else if(addr == FM7_MAINIO_EXTROM) {
}
#endif
+ //if((addr >= 0x0006) && (addr != 0x1f)) printf("MAINIO: READ: %08x DATA=%08x\n", addr);
addr = addr & 0xff;
retval = 0xff;
+#if defined(HAS_MMR)
+ if((addr < 0x90) && (addr >= 0x80)) {
+#if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
+ return mmr_table[addr - 0x80 + mmr_segment * 16];
+#else
+ return mmr_table[addr - 0x80 + (mmr_segment & 0x03) * 16];
+#endif
+ }
+#endif
+ // if((addr >= 0x0006) && !(addr == 0x1f) && !(addr == 0x0b)) printf("MAINIO: READ: %08x \n", addr);
switch(addr) {
case 0x00: // FD00
retval = (uint32) get_port_fd00();
break;
case 0x01: // FD01
+ retval = keycode & 0xff;
+ key_irq_req = false;
display->write_signal(SIG_FM7_SUB_KEY_FIRQ, 0, 1);
- set_irq_keyboard(false);
- retval = (uint32) kbd_bit7_0;
+ set_irq_keyboard(key_irq_req);
break;
case 0x02: // FD02
retval = (uint32) get_port_fd02();
case 0x09:
case 0x0a:
break;
+#if defined(_FM77AV_VARIANTS)
+ case 0x0b:
+ retval = (bootmode == 0) ? 0xfe : 0xff;
+ break;
+#endif
case 0x0e: // PSG DATA
retval = (uint32) get_psg();
+ //printf("PSG DATA READ val=%02x\n", retval);
break;
case 0x0f: // FD0F
read_fd0f();
+ retval = 0xff;
+ break;
+#if defined(_FM77AV_VARIANTS)
+ case 0x12:
+ retval = subsystem_read_status();
break;
+#endif
case 0x15: // OPN CMD
+ //printf("OPN CMD READ \n");
break;
case 0x16: // OPN DATA
retval = (uint32) get_opn(0);
+ //printf("OPN DATA READ val=%02x\n", retval);
break;
case 0x17:
retval = (uint32) get_extirq_fd17();
break;
case 0x18: // FDC: STATUS
retval = (uint32) get_fdc_stat();
+ //printf("FDC: READ STATUS %02x PC=%04x\n", retval, maincpu->get_pc());
break;
case 0x19: // FDC: Track
retval = (uint32) get_fdc_track();
+ //printf("FDC: READ TRACK REG %02x\n", retval);
break;
case 0x1a: // FDC: Sector
retval = (uint32) get_fdc_sector();
+ //printf("FDC: READ SECTOR REG %02x\n", retval);
break;
case 0x1b: // FDC: Data
retval = (uint32) get_fdc_data();
break;
case 0x1c:
retval = (uint32) get_fdc_fd1c();
+ //printf("FDC: READ HEAD REG %02x\n", retval);
break;
case 0x1d:
retval = (uint32) get_fdc_motor();
+ //printf("FDC: READ MOTOR REG %02x\n", retval);
break;
case 0x1f:
retval = (uint32) fdc_getdrqirq();
case 0x23: // Kanji ROM
retval = (uint32) read_kanjidata_right();
break;
-#if defined(_FM77AV_VARIANTS)
+#if defined(CAPABLE_KANJI_CLASS2)
case 0x2e: // Kanji ROM Level2
retval = (uint32) read_kanjidata_left_l2();
break;
case 0x53:
retval = (uint32) get_extirq_thg();
break;
+#if defined(HAS_MMR)
+ case 0x93:
+ retval = 0x3e;
+ if(boot_ram) retval |= 0x01;
+ if(window_enabled) retval |= 0x40;
+ if(mmr_enabled) retval |= 0x80;
+ break;
+#endif
default:
//printf("MAIN: Read another I/O Addr=%08x\n", addr);
break;
void FM7_MAINIO::write_data8(uint32 addr, uint32 data)
{
+ bool flag;
if(addr == FM7_MAINIO_BOOTMODE) {
bootmode = data & 0x03;
return;
set_clockmode((uint8)data);
return;
}
+ //if((addr >= 0x0006) && !(addr == 0x1f)) printf("MAINIO: WRITE: %08x DATA=%08x\n", addr, data);
data = data & 0xff;
addr = addr & 0xff;
+ io_w_latch[addr] = data;
+#if defined(HAS_MMR)
+ if((addr < 0x90) && (addr >= 0x80)) {
+#if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
+ mmr_table[addr - 0x80 + mmr_segment * 16] = data;
+#else
+ mmr_table[addr - 0x80 + (mmr_segment & 0x03) * 16] = data & 0x3f;
+#endif
+ //printf("MMR: Write access segment=%02x addr=%02x page=%02x\n", mmr_segment, addr - 0x80, data);
+ return;
+ }
+#endif
switch(addr) {
case 0x00: // FD00
set_port_fd00((uint8)data);
case 0x0a:
break;
case 0x0d:
+ //printf("PSG CMD WRITE val=%02x\n", data);
set_psg_cmd(data);
break;
case 0x0e:
+ //printf("PSG DATA WRITE val=%02x\n", data);
set_psg(data);
break;
case 0x0f: // FD0F
write_fd0f();
break;
+#if defined(_FM77AV_VARIANTS)
+ case 0x10:
+ flag = enable_initiator;
+ //printf("INITIATOR ENABLE = %02x\n", data);
+ enable_initiator = ((data & 0x02) == 0) ? true : false;
+ if(flag != enable_initiator) {
+ mainmem->reset();
+ //this->reset();
+ }
+ break;
+ case 0x12:
+ mode320 = ((data & 0x40) != 0);
+ display->write_signal(SIG_DISPLAY_MODE320, data, 0x40);
+ break;
+ case 0x13:
+ sub_monitor_type = data & 0x07;
+ //register_event_by_clock(this, EVENT_FM7SUB_PROC, 8, false, NULL); // 1uS / 8MHz
+ do_sync_main_sub();
+ break;
+#endif
case 0x15: // OPN CMD
+ //printf("OPN CMD WRITE val=%02x\n", data);
set_opn_cmd(0, data);
break;
case 0x16: // OPN DATA
+ //printf("OPN DATA WRITE val=%02x\n", data);
set_opn(0, data);
break;
case 0x17:
break;
case 0x18: // FDC: COMMAND
set_fdc_cmd((uint8)data);
+ //printf("FDC: WRITE CMD %02x\n", data);
break;
case 0x19: // FDC: Track
set_fdc_track((uint8)data);
+ //printf("FDC: WRITE TRACK REG %02x\n", data);
break;
case 0x1a: // FDC: Sector
set_fdc_sector((uint8)data);
+ //printf("FDC: WRITE SECTOR REG %02x\n", data);
break;
case 0x1b: // FDC: Data
set_fdc_data((uint8)data);
break;
case 0x1c:
set_fdc_fd1c((uint8)data);
+ //printf("FDC: WRITE HEAD REG %02x\n", data);
break;
case 0x1d:
set_fdc_fd1d((uint8)data);
+ //printf("FDC: WRITE MOTOR REG %02x\n", data);
break;
case 0x1f: // ??
return;
break;
case 0x20: // Kanji ROM
+ case 0x2c: // Kanji ROM(DUP)
write_kanjiaddr_hi((uint8)data);
+#if defined(CAPABLE_KANJI_CLASS2)
+ write_kanjiaddr_hi_l2((uint8)data);
+#endif
break;
case 0x21: // Kanji ROM
+ case 0x2d: // Kanji ROM(DUP)
write_kanjiaddr_lo((uint8)data);
+#if defined(CAPABLE_KANJI_CLASS2)
+ write_kanjiaddr_lo_l2((uint8)data);
+#endif
break;
#if defined(_FM77AV_VARIANTS)
- case 0x2c: // Kanji ROM
- write_kanjiaddr_hi_l2((uint8)data);
+ case 0x30:
+ display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_HI, data);
break;
- case 0x2d: // Kanji ROM
- write_kanjiaddr_lo_l2((uint8)data);
+ case 0x31:
+ display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_LO, data);
+ break;
+ case 0x32:
+ display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_B, data);
+ break;
+ case 0x33:
+ display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_R, data);
+ break;
+ case 0x34:
+ display->write_data8(FM7_SUBMEM_OFFSET_APALETTE_G, data);
break;
#endif
case 0x37: // Multi page
- display->write_signal(SIG_FM7_SUB_MULTIPAGE, data, 0x00ff);
+ display->write_signal(SIG_DISPLAY_MULTIPAGE, data, 0x00ff);
break;
case 0x45: // WHG CMD
set_opn_cmd(1, data);
break;
case 0x53:
break;
-#if defined(_FM77) || defined(_FM77L2) || defined(_FM77L4) || defined(_FM77AV_VARIANTS)
+#if defined(HAS_MMR)
+ case 0x90:
+#if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX)
+ mmr_segment = data & 7;
+#else
+ // printf("MMR SEGMENT: %02x\n", data & 3);
+ mmr_segment = data & 3;
+#endif
+ break;
+ case 0x92:
+ window_offset = data & 0x00ff;
+ break;
case 0x93:
if((data & 0x01) == 0) {
boot_ram = false;
window_enabled = false;
} else {
window_enabled = true;
- }
+ }
+ flag = mmr_enabled;
if((data & 0x80) == 0) {
mmr_enabled = false;
} else {
mmr_enabled = true;
}
+ if(flag != mmr_enabled) {
+ this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
+ }
break;
#endif
default:
break;
case EVENT_TIMERIRQ_ON:
if(!irqmask_timer) set_irq_timer(true);
- register_event(this, EVENT_TIMERIRQ_OFF, 10000.0 / (4.9152 * 2.0) , false, NULL); // TIMER IRQ
+ //register_event(this, EVENT_TIMERIRQ_OFF, 10000.0 / (4.9152 * 2.0) , false, NULL); // TIMER IRQ
break;
case EVENT_TIMERIRQ_OFF:
if(!irqmask_timer) set_irq_timer(false);
case EVENT_FD_MOTOR_OFF:
set_fdc_motor(false);
break;
+ case EVENT_FM7SUB_PROC:
+ proc_sync_to_sub();
+ break;
default:
break;
}
}
+void FM7_MAINIO::update_config()
+{
+ switch(config.cpu_type){
+ case 0:
+ clock_fast = true;
+ break;
+ case 1:
+ clock_fast = false;
+ break;
+ }
+ // this->write_signal(FM7_MAINIO_CLOCKMODE, clock_fast ? 1 : 0, 1);
+}
+
+void FM7_MAINIO::event_vline(int v, int clock)
+{
+}
+
+void FM7_MAINIO::do_sync_main_sub(void)
+{
+ register_event_by_clock(this, EVENT_FM7SUB_PROC, 8, false, NULL); // 1uS
+ register_event_by_clock(display, EVENT_FM7SUB_PROC, 8, false, NULL); // 1uS
+}
+
+
+void FM7_MAINIO::proc_sync_to_sub(void)
+{
+ if(sub_halt != sub_halt_bak) {
+ display->write_signal(SIG_DISPLAY_HALT, (sub_halt) ? 0xff : 0x00, 0xff);
+ }
+ sub_halt_bak = sub_halt;
+ if(firq_sub_attention != firq_sub_attention_bak){
+ do_firq();
+ }
+ firq_sub_attention_bak = firq_sub_attention;
+ //sub_cancel_bak = sub_cancel;
+ //if(key_irq_req != key_irq_bak) {
+ // set_irq_keyboard(key_irq_req);
+ //}
+ //key_irq_bak = key_irq_req;
+ //keycode = keycode_7;
+#if defined(_FM77AV_VARIANTS)
+ if(sub_monitor_type != sub_monitor_bak) {
+ display->write_signal(SIG_FM7_SUB_BANK, sub_monitor_type, 0x07);
+ }
+ sub_monitor_bak = sub_monitor_type;
+#endif
+}
+
+