[VM][FM7] Add turning ON/OFF Z80 extra board.
"eFM7" "eFMNEW7" "eFM77" "eFM77L2" - Fujitsu FM-7/FM-NEW7/FM-77/FM-77L2
- 2/26/2016
+ 1/12/2018
--- Internal ROM image
Please select one of two:
KANJI1.ROM JIS class 1 Kanji ROM $20000 bytes
KANJI.ROM JIS class 1 Kanji ROM $20000 bytes
-
+ JSUBSYS.ROM Firmware of Japanese communication board (FM-7/77/AV). $4000 bytes.
+ JSUBDICT.ROM Dictionary of Japanese communication board (FM-7/77/AV). $40000 bytes.
+ JSUBKANJI.ROM Kanji data of Japanese communication board (FM-7/77/AV). $20000 bytes.
+ If you don't have, KANJI.ROM/KANJI1.ROM is used for fallback.
+
+--- Saves file(s)
+ JCOMMCARD.bin RAM data of Japanese communication board. $2000 bytes.
+
--- Key maps
Virtual PC
"eFM77AV" "eFM77AV20" "eFM77AV20EX" "eFM77AV40"
"eFM77AV40EX" "eFM77AV40SX"
- Fujitsu FM-77AV/20/20EX/40/40EX/40SX
- 2/26/2016
+ 1/12/2018
--- Internal ROM image
EXTSUB.ROM FM77AV40EX/SX's extra subsystem ROM.
Display Sub System:
- SUBSYS_C.ROM $D800 - $FFFF Subsystem monitor and font.
+ SUBSYS_A.ROM $E000 - $FFFF Subsystem monitor type A.
+ SUBSYS_B.ROM $E000 - $FFFF Subsystem monitor type B.
+ SUBSYS_C.ROM $D800 - $FFFF Subsystem monitor (type C) and font.
+ SUBSYSCG.ROM $E000 - $FFFF ANK Fonts data.
External dictionary card (with FM77AV40/EX/SX, must have these):
DICROM.ROM Dictionary ROM
KANJI2.ROM JIS class 2 Kanji ROM $20000 bytes.
-
+
+ Optional (for eFM77AV only):
+ JSUBSYS.ROM Firmware of Japanese communication board (FM-7/77/AV). $4000 bytes.
+ JSUBDICT.ROM Dictionary of Japanese communication board (FM-7/77/AV). $40000 bytes.
+ JSUBKANJI.ROM Kanji data of Japanese communication board (FM-7/77/AV). $20000 bytes.
+ If you don't have, KANJI.ROM/KANJI1.ROM is used for fallback.
+
In addition, will save on exit:
+ JCOMMCARD.bin RAM data of Japanese communication board. $2000 bytes.
USERDIC.DAT Learning data of Kana Kanji conversion.
- to battery backuped CMOS RAM.
+ to battery backuped CMOS RAM.
--- Key maps
void Ui_MainWindow::OnOpenDebugger(int no)
{
- if((no < 0) || (no > 3)) return;
+ if((no < 0) || (no > 7)) return;
//emu->open_debugger(no);
VM *vm = emu->get_vm();
}
#if defined(WITH_Z80)
+void Object_Menu_Control_7::do_set_z80card_on(bool flag)
+{
+ if(flag) {
+ config.dipswitch = config.dipswitch | FM7_DIPSW_Z80CARD_ON;
+ } else {
+ config.dipswitch = config.dipswitch & ~FM7_DIPSW_Z80CARD_ON;
+ }
+}
+
void Object_Menu_Control_7::do_set_z80_irq(bool flag)
{
if(flag) {
emit sig_emu_update_config();
}
#endif
+#if defined(CAPABLE_JCOMMCARD)
+void Object_Menu_Control_7::do_set_jcommcard(bool flag)
+{
+ if(flag) {
+ config.dipswitch = config.dipswitch | FM7_DIPSW_JSUBCARD_ON;
+ } else {
+ config.dipswitch = config.dipswitch & ~FM7_DIPSW_JSUBCARD_ON;
+ }
+}
+#endif
#if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
void Object_Menu_Control_7::do_set_kanji_rom(bool flag)
}
#endif
+#if defined(_FM8) || defined(_FM7) || defined(_FMNEW7) || defined(_FM77_VARIANTS)
+void Object_Menu_Control_7::do_set_jis78_emulation(bool flag)
+{
+ if(flag) {
+ config.dipswitch = config.dipswitch | FM7_DIPSW_JIS78EMU_ON;
+ } else {
+ config.dipswitch = config.dipswitch & ~FM7_DIPSW_JIS78EMU_ON;
+ }
+}
+#endif
+
#if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
void Object_Menu_Control_7::do_set_320kFloppy(bool flag)
{
void META_MainWindow::retranslateUi(void)
{
+
+ int z80num, jcommnum;
+ z80num = -1;
+ jcommnum = -1;
retranslateControlMenu("Hot Start (BREAK+RESET)", true);
retranslateFloppyMenu(0, 0);
actionPrintDevice[2]->setText(QApplication::translate("Machine", "Dempa Joystick with #2", 0));
actionPrintDevice[2]->setToolTip(QApplication::translate("Machine", "Use joystick #2 as DEMPA's joystick.", 0));
#endif
+
#ifdef USE_DEBUGGER
actionDebugger[0]->setText(QApplication::translate("Machine", "Main CPU", 0));
actionDebugger[1]->setText(QApplication::translate("Machine", "Sub CPU", 0));
actionDebugger[0]->setVisible(true);
actionDebugger[1]->setVisible(true);
-#ifdef WITH_Z80
- actionDebugger[2]->setText(QApplication::translate("Machine", "Z80 CPU Board", 0));
- actionDebugger[2]->setVisible(true);
-#else
+# ifdef WITH_Z80
+ if((config.dipswitch & FM7_DIPSW_Z80CARD_ON) != 0) z80num = 2;
+# ifdef CAPABLE_JCOMMCARD
+ if((config.dipswitch & FM7_DIPSW_JSUBCARD_ON) != 0) {
+ if(z80num < 0) {
+ jcommnum = 2;
+ } else {
+ jcommnum = 3;
+ }
+ }
+# endif
+# else
+# ifdef CAPABLE_JCOMMCARD
+ if((config.dipswitch & FM7_DIPSW_JSUBCARD_ON) != 0) {
+ jcommnum = 2;
+ }
+# endif
+# endif
+
actionDebugger[2]->setVisible(false);
-#endif
actionDebugger[3]->setVisible(false);
+ if(z80num > 0) {
+ actionDebugger[z80num]->setText(QApplication::translate("Machine", "Z80 CPU Board", 0));
+ actionDebugger[z80num]->setVisible(true);
+ }
+ if(jcommnum > 0) {
+ actionDebugger[jcommnum]->setText(QApplication::translate("Machine", "Japanese Communication Board", 0));
+ actionDebugger[jcommnum]->setVisible(true);
+ }
#endif
// actionStart_Record_Movie->setText(QApplication::translate("Machine", "Start Record Movie", 0));
// actionStop_Record_Movie->setText(QApplication::translate("Machine", "Stop Record Movie", 0));
#if defined(_FM8) || defined(_FM7) || defined(_FMNEW7) || defined(_FM77_VARIANTS)
action_1MFloppy->setText(QApplication::translate("Machine", "Connect 1MB FDD(Need Restart)", 0));
action_1MFloppy->setToolTip(QApplication::translate("Machine", "**Note: This option still not implemented**\nConnect 2HD (or 8inch) floppy drive.\nNeed to restart emulator if changed.\n", 0));
+
+ actionJIS78EMULATION->setText(QApplication::translate("Machine", "KANJI:JIS78 emulation.", 0));
+ actionJIS78EMULATION->setToolTip(QApplication::translate("Machine", "Emulate JIS78 kanji ROM.", 0));
#endif
menuAuto5_8Key->setTitle(QApplication::translate("Machine", "Auto Stop Ten Key (hack)", 0));
action_Neither_5_or_8key->setText(QApplication::translate("Machine", "None used.", 0));
// Set Labels
menuMachine->setToolTipsVisible(true);
menuAuto5_8Key->setToolTipsVisible(true);
+
#if !defined(_FM8)
# if defined(USE_MOUSE_TYPE)
menuMouseType->setToolTipsVisible(true);
# endif
#endif
#if defined(WITH_Z80)
+ actionZ80CARD_ON->setText(QApplication::translate("Machine", "Connect Z80 CARD", 0));
+ actionZ80CARD_ON->setToolTip(QApplication::translate("Machine", "Turn ON Z80 extra card.\nNeed to restart this emulator to change connection", 0));
+
actionZ80_IRQ->setText(QApplication::translate("Machine", "Z80:IRQ ON", 0));
actionZ80_IRQ->setToolTip(QApplication::translate("Machine", "Turn ON IRQ to Z80 extra card.", 0));
actionZ80_NMI->setText(QApplication::translate("Machine", "Z80:NMI ON", 0));
actionZ80_NMI->setToolTip(QApplication::translate("Machine", "Turn ON NMI to Z80 extra card.", 0));
#endif
+#if defined(CAPABLE_JCOMMCARD)
+ actionJCOMMCARD->setText(QApplication::translate("Machine", "Connect Japanese Communication Card.", 0));
+ actionJCOMMCARD->setToolTip(QApplication::translate("Machine", "Connect Japanese communication card.\nNeed to restart this emulator if you change.", 0));
+#endif
+
menuCpuType->setToolTipsVisible(true);
menuBootMode->setToolTipsVisible(true);
} // retranslateUi
connect(actionKanjiRom, SIGNAL(toggled(bool)),
actionKanjiRom->fm7_binds, SLOT(do_set_kanji_rom(bool)));
#endif
+#if defined(_FM8) || defined(_FM7) || defined(_FMNEW7) || defined(_FM77_VARIANTS)
+ actionJIS78EMULATION = new Action_Control_7(this, using_flags);
+ menuMachine->addAction(actionJIS78EMULATION);
+ actionJIS78EMULATION->setCheckable(true);
+ actionJIS78EMULATION->setVisible(true);
+ if((config.dipswitch & FM7_DIPSW_JIS78EMU_ON) != 0) actionJIS78EMULATION->setChecked(true);
+ connect(actionJIS78EMULATION, SIGNAL(toggled(bool)), actionJIS78EMULATION->fm7_binds, SLOT(do_set_jis78_emulation(bool)));
+#endif
#if defined(WITH_Z80)
+ menuMachine->addSeparator();
+ actionZ80CARD_ON = new Action_Control_7(this, using_flags);
+ menuMachine->addAction(actionZ80CARD_ON);
+ actionZ80CARD_ON->setCheckable(true);
+ actionZ80CARD_ON->setVisible(true);
+ if((config.dipswitch & FM7_DIPSW_Z80CARD_ON) != 0) actionZ80CARD_ON->setChecked(true);
+ connect(actionZ80CARD_ON, SIGNAL(toggled(bool)), actionZ80CARD_ON->fm7_binds, SLOT(do_set_z80card_on(bool)));
+
actionZ80_IRQ = new Action_Control_7(this, using_flags);
menuMachine->addAction(actionZ80_IRQ);
actionZ80_IRQ->setCheckable(true);
if((config.dipswitch & FM7_DIPSW_Z80_NMI_ON) != 0) actionZ80_NMI->setChecked(true);
connect(actionZ80_NMI, SIGNAL(toggled(bool)), actionZ80_NMI->fm7_binds, SLOT(do_set_z80_nmi(bool)));
connect(actionZ80_NMI->fm7_binds, SIGNAL(sig_emu_update_config()), this, SLOT(do_emu_update_config()));
+ if((config.dipswitch & FM7_DIPSW_Z80CARD_ON) == 0) {
+ actionZ80_IRQ->setVisible(false);
+ actionZ80_FIRQ->setVisible(false);
+ actionZ80_NMI->setVisible(false);
+ }
#endif
+#if defined(CAPABLE_JCOMMCARD)
+ actionJCOMMCARD = new Action_Control_7(this, using_flags);
+ menuMachine->addAction(actionJCOMMCARD);
+ actionJCOMMCARD->setCheckable(true);
+ actionJCOMMCARD->setVisible(true);
+ if((config.dipswitch & FM7_DIPSW_JSUBCARD_ON) != 0) actionJCOMMCARD->setChecked(true);
+ connect(actionJCOMMCARD, SIGNAL(toggled(bool)), actionJCOMMCARD->fm7_binds, SLOT(do_set_jcommcard(bool)));
+#endif
+
#if defined(_FM8)
actionRamProtect = new Action_Control_7(this, using_flags);
menuMachine->addAction(actionRamProtect);
<name>Machine</name>
<message>
<source>Frame skip</source>
- <translation>フレームスキップ</translation>
+ <translation> フレームスキップ</translation>
</message>
<message>
<source>None</source>
<translation>OPN</translation>
</message>
<message>
- <source>OPN+WHG</source>
- <translation></translation>
- </message>
- <message>
- <source>OPN+THG</source>
- <translation></translation>
- </message>
- <message>
- <source>OPN+WHG+THG</source>
- <translation></translation>
- </message>
- <message>
<source>Using only default FM synthesizer board.</source>
<translation>本体のFM音源のみ使います。</translation>
</message>
THG(3枚目のFM音源)を使います。</translation>
</message>
<message>
- <source>PSG</source>
- <translation></translation>
- </message>
- <message>
- <source>PSG+OPN</source>
- <translation></translation>
- </message>
- <message>
- <source>PSG+WHG</source>
- <translation></translation>
- </message>
- <message>
- <source>PSG+OPN+WHG</source>
- <translation></translation>
- </message>
- <message>
- <source>PSG+THG</source>
- <translation></translation>
- </message>
- <message>
- <source>PSG+OPN+THG</source>
- <translation></translation>
- </message>
- <message>
- <source>PSG+WHG+THG</source>
- <translation></translation>
- </message>
- <message>
- <source>PSG+OPN+WHG+THG</source>
- <translation></translation>
- </message>
- <message>
<source>Using only default PSG.</source>
<translation>本体のPSGのみ使います。</translation>
</message>
<translation>起動モード</translation>
</message>
<message>
- <source>BASIC</source>
- <translation></translation>
- </message>
- <message>
- <source>DOS</source>
- <translation></translation>
- </message>
- <message>
<source>Using default PSG
and THG third FM synthesizer board.</source>
<translation>本体のPSGと
<source>Sub CPU</source>
<translation>サブCPU</translation>
</message>
+ <message>
+ <source>Z80 CPU Board</source>
+ <translation>Z80 CPUカード</translation>
+ </message>
+ <message>
+ <source>Japanese Communication Board</source>
+ <translation>日本語通信カード</translation>
+ </message>
+ <message>
+ <source>BASIC</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>DOS</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>OPN+WHG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>OPN+THG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>OPN+WHG+THG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>PSG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>PSG+OPN</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>PSG+WHG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>PSG+OPN+WHG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>PSG+THG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>PSG+OPN+THG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>PSG+WHG+THG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>PSG+OPN+WHG+THG</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>KANJI:JIS78 emulation.</source>
+ <translation>JIS78漢字ROMエミュレーション</translation>
+ </message>
+ <message>
+ <source>Emulate JIS78 kanji ROM.</source>
+ <translation>JIS78タイプの漢字ROMの動作をエミュレートします。</translation>
+ </message>
+ <message>
+ <source>Connect Z80 CARD</source>
+ <translation>Z80カードを接続する</translation>
+ </message>
+ <message>
+ <source>Turn ON Z80 extra card.
+Need to restart this emulator to change connection</source>
+ <translation>Z80カードを有効にします。エミュレータの再起動が必要です。</translation>
+ </message>
+ <message>
+ <source>Z80:IRQ ON</source>
+ <translation>Z80:IRQ ON</translation>
+ </message>
+ <message>
+ <source>Turn ON IRQ to Z80 extra card.</source>
+ <translation>Z80カードのIRQ割り込みを有効にします。</translation>
+ </message>
+ <message>
+ <source>Z80:FIRQ ON</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Turn ON FIRQ to IRQ of Z80 extra card.</source>
+ <translation>Z80カードのFIRQ割り込みを有効にします。</translation>
+ </message>
+ <message>
+ <source>Z80:NMI ON</source>
+ <translation></translation>
+ </message>
+ <message>
+ <source>Turn ON NMI to Z80 extra card.</source>
+ <translation>Z80カードのNMI割り込みを有効にします。</translation>
+ </message>
+ <message>
+ <source>Connect Japanese Communication Card.</source>
+ <translation>日本語通信カードを接続する</translation>
+ </message>
+ <message>
+ <source>Connect Japanese communication card.
+Need to restart this emulator if you change.</source>
+ <translation>日本語通信カードを接続します。エミュレータの再起動が必要です。</translation>
+ </message>
</context>
<context>
<name>MainWindow</name>
int sig_emu_update_config(void);
public slots:
# if defined(WITH_Z80)
+ void do_set_z80card_on(bool flag);
void do_set_z80_irq(bool flag);
void do_set_z80_firq(bool flag);
void do_set_z80_nmi(bool flag);
# else
void do_set_cyclesteal(bool flag);
# endif
+#if defined(_FM8) || defined(_FM7) || defined(_FMNEW7) || defined(_FM77_VARIANTS)
+ void do_set_jis78_emulation(bool flag);
+#endif
+#if defined(CAPABLE_JCOMMCARD)
+ void do_set_jcommcard(bool flag);
+#endif
void do_set_autokey_5_8(void);
};
# if defined(_FM77AV_VARIANTS) || defined(_FM77_VARIANTS)
class Action_Control_7 *actionExtRam;
# endif
-#if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
+# if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
class Action_Control_7 *actionKanjiRom;
-#endif
+# endif
+# if defined(_FM8) || defined(_FM7) || defined(_FMNEW7) || defined(_FM77_VARIANTS)
+ class Action_Control_7 *actionJIS78EMULATION;
+# endif
+# if defined(CAPABLE_JCOMMCARD)
+ class Action_Control_7 *actionJCOMMCARD;
+# endif
# if defined(_FM8)
class Action_Control_7 *actionRamProtect;
# else
class Action_Control_7 *action_1MFloppy;
# endif
# if defined(WITH_Z80)
+ class Action_Control_7 *actionZ80CARD_ON;
class Action_Control_7 *actionZ80_IRQ;
class Action_Control_7 *actionZ80_FIRQ;
class Action_Control_7 *actionZ80_NMI;
)
if(BUILD_FM8)
- set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} fm_bubblecasette.cpp)
+ set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} fm_bubblecasette.cpp)
+elseif(BUILD_FM7)
+ set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp)
+elseif(BUILD_FMNEW7)
+ set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp)
+elseif(BUILD_FM77)
+ set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp)
+elseif(BUILD_FM77L2)
+ set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp)
+elseif(BUILD_FM77L4)
+ set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp)
+elseif(BUILD_FM77AV)
+ set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} jcommcard.cpp)
endif()
if(USE_DEVICES_SHARED_LIB)
if(FM77AV_VARIANTS)
set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} mb61vh010.cpp)
endif()
+
if(BUILD_FM77AV20EX)
set(VM_FM7_LIB_SRCS ${VM_FM7_LIB_SRCS} hd6844.cpp)
elseif(BUILD_FM77AV40)
#include "./joystick.h"
#include "./kanjirom.h"
+#if defined(CAPABLE_JCOMMCARD)
+#include "./jcommcard.h"
+#endif
VM::VM(EMU* parent_emu): emu(parent_emu)
{
g_substat_mainhalt = new AND(this, emu);
#ifdef WITH_Z80
- z80cpu = new Z80(this, emu);
+ if((config.dipswitch & FM7_DIPSW_Z80CARD_ON) != 0) {
+ z80cpu = new Z80(this, emu);
+ } else {
+ z80cpu = NULL;
+ }
g_mainstat = new AND(this, emu);
g_intr = new OR(this, emu);
g_intr_firq = new AND(this, emu);
g_nmi = new AND(this, emu);
#endif
+#if defined(CAPABLE_JCOMMCARD)
+ if((config.dipswitch & FM7_DIPSW_JSUBCARD_ON) != 0) {
+ jsubcpu = new MC6809(this, parent_emu);
+ jcommcard = new FM7_JCOMMCARD(this, parent_emu);
+ } else {
+ jsubcpu = NULL;
+ jcommcard = NULL;
+ }
+#endif
+
// basic devices
// I/Os
#if defined(HAS_DMA)
maincpu->set_context_bus_ba(g_mainstat, SIG_AND_BIT_0, 0xffffffff);
maincpu->set_context_bus_bs(g_mainstat, SIG_AND_BIT_1, 0xffffffff);
g_mainstat->set_context_out(mainio, FM7_MAINIO_RUN_Z80, 0xffffffff);
-
- z80cpu->set_context_busack(mainio, FM7_MAINIO_RUN_6809, 0xffffffff);
- mainio->set_context_z80cpu(z80cpu);
+ if(z80cpu != NULL) {
+ z80cpu->set_context_busack(mainio, FM7_MAINIO_RUN_6809, 0xffffffff);
+ mainio->set_context_z80cpu(z80cpu);
+ }
#endif
#if defined(_USE_QT)
event->set_device_name(_T("EVENT"));
subcpu->set_device_name(_T("SUBCPU(MC6809)"));
dummycpu->set_device_name(_T("DUMMY CPU"));
# ifdef WITH_Z80
- z80cpu->set_device_name(_T("Z80 CPU"));
+ if(z80cpu != NULL) z80cpu->set_device_name(_T("Z80 CPU"));
# endif
if(fdc != NULL) fdc->set_device_name(_T("MB8877 FDC(320KB)"));
event->set_context_cpu(subcpu, subclock);
#ifdef WITH_Z80
- event->set_context_cpu(z80cpu, 4000000);
- z80cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
+ if(z80cpu != NULL) {
+ event->set_context_cpu(z80cpu, 4000000);
+ z80cpu->write_signal(SIG_CPU_BUSREQ, 1, 1);
+ }
maincpu->write_signal(SIG_CPU_HALTREQ, 0, 1);
g_intr_irq->set_mask(SIG_AND_BIT_0);
mainio->set_context_firq(g_intr_firq, SIG_AND_BIT_1, 0xffffffff);
g_intr_firq->set_context_out(g_intr, SIG_OR_BIT_0, 0xffffffff);
- g_intr->set_context_out(z80cpu, SIG_CPU_IRQ, 0xffffffff);
+ if(z80cpu != NULL) g_intr->set_context_out(z80cpu, SIG_CPU_IRQ, 0xffffffff);
mainio->set_context_nmi(g_nmi, SIG_AND_BIT_1, 0xffffffff);
- g_nmi->set_context_out(z80cpu, SIG_CPU_NMI, 0xffffffff);
+ if(z80cpu != NULL) g_nmi->set_context_out(z80cpu, SIG_CPU_NMI, 0xffffffff);
+#endif
+#if defined(CAPABLE_JCOMMCARD)
+ if((jsubcpu != NULL) && (jcommcard != NULL)) {
+ event->set_context_cpu(jsubcpu, JCOMMCARD_CLOCK);
+ jcommcard->set_context_cpu(jsubcpu);
+ jsubcpu->set_context_bus_ba(jcommcard, FM7_JCOMMCARD_BUS_BA, 0x00000001);
+ jsubcpu->set_context_bus_bs(jcommcard, FM7_JCOMMCARD_BUS_BS, 0x00000001);
+ mainio->set_context_jcommcard(jcommcard);
+ }
#endif
-
event->set_context_sound(pcm1bit);
#if defined(_FM8)
event->set_context_sound(psg);
maincpu->set_context_mem(mainmem);
subcpu->set_context_mem(display);
#ifdef WITH_Z80
- z80cpu->set_context_mem(mainmem);
+ if(z80cpu != NULL) z80cpu->set_context_mem(mainmem);
+#endif
+#if defined(CAPABLE_JCOMMCARD)
+ if((jsubcpu != NULL) && (jcommcard != NULL)) {
+ jsubcpu->set_context_mem(jcommcard);
+ }
#endif
#ifdef USE_DEBUGGER
maincpu->set_context_debugger(new DEBUGGER(this, emu));
subcpu->set_context_debugger(new DEBUGGER(this, emu));
# ifdef WITH_Z80
- z80cpu->set_context_debugger(new DEBUGGER(this, emu));
+ if(z80cpu != NULL) z80cpu->set_context_debugger(new DEBUGGER(this, emu));
+# endif
+# if defined(CAPABLE_JCOMMCARD)
+ if(jsubcpu != NULL) {
+ jsubcpu->set_context_debugger(new DEBUGGER(this, emu));
+ }
# endif
#endif
for(DEVICE* device = first_device; device; device = device->next_device) {
}
#if defined(WITH_Z80)
else if(index == 2) {
+# if defined(CAPABLE_JCOMMCARD)
+ if(z80cpu == NULL) {
+ return jsubcpu;
+ }
+# endif
return z80cpu;
}
+# if defined(CAPABLE_JCOMMCARD)
+ else if(index == 3) {
+ return jsubcpu;
+ }
+# endif
+#else
+# if defined(CAPABLE_JCOMMCARD)
+ else if(index == 2) {
+ return jsubcpu;
+ }
+# endif
#endif
return NULL;
}
#define CAPABLE_Z80
#define DIPSWITCH_DEFAULT 0x000000000
#define MAX_DRIVE 4
+#define CAPABLE_JCOMMCARD 1
#elif defined(_FMNEW7)
#define DEVICE_NAME "FUJITSU FM-NEW7"
#define CAPABLE_Z80
#define DIPSWITCH_DEFAULT 0x000000000
#define MAX_DRIVE 4
+#define CAPABLE_JCOMMCARD 1
#elif defined(_FM77) || defined(_FM77L2)
# if defined(_FM77)
# endif
#define DIPSWITCH_DEFAULT 0x00000003
#define MAX_DRIVE 4
+#define CAPABLE_JCOMMCARD 1
#elif defined(_FM77AV)
#define DEVICE_NAME "FUJITSU FM77AV"
#define _FM77AV_VARIANTS
#define DIPSWITCH_DEFAULT 0x80000001
#define MAX_DRIVE 2
+#define CAPABLE_JCOMMCARD 1
#elif defined(_FM77AV20)
#define DEVICE_NAME "FUJITSU FM77AV20"
class Z80;
class OR;
#endif
+#ifdef CAPABLE_JCOMMCARD
+class FM7_JCOMMCARD;
+#endif
+
class VM {
protected:
EMU* emu;
#ifdef CAPABLE_KANJI_CLASS2
KANJIROM *kanjiclass2;
#endif
+#if defined(CAPABLE_JCOMMCARD)
+ MC6809 *jsubcpu;
+ FM7_JCOMMCARD *jcommcard;
+#endif
bool connect_320kfdc;
bool connect_1Mfdc;
public:
#define FM7_DIPSW_Z80_IRQ_ON 0x00001000
#define FM7_DIPSW_Z80_FIRQ_ON 0x00002000
#define FM7_DIPSW_Z80_NMI_ON 0x00004000
+#define FM7_DIPSW_JIS78EMU_ON 0x00008000
+#define FM7_DIPSW_JSUBCARD_ON 0x00010000
+#define FM7_DIPSW_Z80CARD_ON 0x00020000
#define FM7_DIPSW_FRAMESKIP 0x30000000
#define FM7_DIPSW_SYNC_TO_HSYNC 0x80000000
#define SUBCLOCK_NORMAL 2000000
#define SUBCLOCK_SLOW 999000
+#define JCOMMCARD_CLOCK 1228000
#define FM7_SUBMEM_OFFSET_DPALETTE 0x0100000
#define FM7_SUBMEM_OFFSET_APALETTE_B 0x0200000
FM7_MAINCLOCK_MMRSLOW,
FM7_MAINCLOCK_MMRHIGH
};
+enum {
+ FM7_JCOMMCARD_BUS_BA = 0x400000,
+ FM7_JCOMMCARD_BUS_BS,
+};
enum {
FM7_MAINIO_IS_BASICROM = 0x200000,
#ifdef WITH_Z80
z80 = NULL;
#endif
+#if defined(CAPABLE_JCOMMCARD)
+ jcommcard = NULL;
+#endif
#if defined(_FM8)
bubble_casette[0] = NULL;
bubble_casette[1] = NULL;
reg_fd12 = 0xbc; // 0b10111100
#endif
#if defined(WITH_Z80)
- z80->write_signal(SIG_CPU_BUSREQ, 0xffffffff, 0xffffffff);
+ if(z80 != NULL) z80->write_signal(SIG_CPU_BUSREQ, 0xffffffff, 0xffffffff);
#endif
maincpu->write_signal(SIG_CPU_BUSREQ, 0, 0xffffffff);
maincpu->write_signal(SIG_CPU_HALTREQ, 0, 0xffffffff);
req_z80run = true;
} else {
req_z80run = false;
- z80->write_signal(SIG_CPU_BUSREQ, 1, 1);
+ if(z80 != NULL) z80->write_signal(SIG_CPU_BUSREQ, 1, 1);
}
#endif
}
#if defined(WITH_Z80)
case FM7_MAINIO_RUN_Z80:
if((req_z80run)/* && (val_b) */) {
- z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
+ if(z80 != NULL) z80->write_signal(SIG_CPU_BUSREQ, 0, 1);
z80_run = true;
//z80->reset(); // OK?
}
case 0x23: // Kanji ROM
retval = (uint32_t) read_kanjidata_right();
break;
+#if defined(CAPABLE_JCOMMCARD)
+ case 0x28:
+ case 0x29:
+ case 0x2a:
+ case 0x2b:
+ if(jcommcard != NULL) {
+ retval = (uint32_t)(jcommcard->read_io8(addr));
+ } else {
+ retval = 0xff;
+ }
+ break;
+#endif
#if defined(CAPABLE_KANJI_CLASS2)
case 0x2e: // Kanji ROM Level2
retval = (uint32_t) read_kanjidata_left_l2();
//write_kanjiaddr_lo((uint8_t)data);
#endif
break;
+#if defined(CAPABLE_JCOMMCARD)
+ case 0x28:
+ case 0x29:
+ case 0x2a:
+ case 0x2b:
+ if(jcommcard != NULL) jcommcard->write_io8(addr, data);
+ break;
+#endif
#if defined(CAPABLE_DICTROM)
case 0x2e: //
mainmem->write_signal(FM7_MAINIO_EXTBANK, data, 0xff);
#ifdef WITH_Z80
Z80 *z80;
#endif
+#if defined(CAPABLE_JCOMMCARD)
+ DEVICE *jcommcard;
+#endif
#if defined(_FM8)
BUBBLECASETTE *bubble_casette[2];
#endif
}
#endif
- void set_context_z80cpu(Z80 *p){
+ void set_context_z80cpu(Z80 *p) {
#ifdef WITH_Z80
z80 = p;
#endif
}
+ void set_context_jcommcard(DEVICE *p) {
+#if defined(CAPABLE_JCOMMCARD)
+ jcommcard = p;
+#endif
+ }
+
#if defined(HAS_DMA)
- void set_context_dmac(HD6844 *p){
+ void set_context_dmac(HD6844 *p) {
dmac = p;
}
#endif
--- /dev/null
+/*
+ * Emulation of Fujitsu Japanese Communication Card.
+ * (C) 2018 K.Ohta.
+ * Note:
+ * Based on XM7 L70 , with permittion from Ryu Takegami.
+ */
+
+#include "vm.h"
+#include "../../fileio.h"
+#include "emu.h"
+
+#include "fm7_common.h"
+
+#include "../mc6809.h"
+#include "./jcommcard.h"
+
+FM7_JCOMMCARD::FM7_JCOMMCARD(VM *parent_vm, EMU *parent_emu) : DEVICE(parent_vm, parent_emu)
+{
+ n_bank = 0;
+ rcb_address = 0;
+ cpu_ba = cpu_bs = false;
+ halted = false;
+ kanji_address = 0x00000;
+ jis78_emulation = false;
+
+ memset(prog_rom, 0xff, sizeof(prog_rom));
+ memset(dict_rom, 0xff, sizeof(dict_rom));
+ memset(kanji_rom, 0xff, sizeof(kanji_rom));
+ memset(backup_ram, 0x00, sizeof(backup_ram));
+ cpu = NULL;
+ modified = true;
+ firmware_ok = false;
+}
+
+FM7_JCOMMCARD::~FM7_JCOMMCARD()
+{
+}
+
+void FM7_JCOMMCARD::initialize(void)
+{
+ FILEIO *fio = new FILEIO();
+
+ if(fio->Fopen(create_local_path(_T("JSUBSYS.ROM")), FILEIO_READ_BINARY)) {
+ fio->Fread(prog_rom, sizeof(prog_rom), 1);
+ fio->Fclose();
+ firmware_ok = true;
+ }
+
+ /* Patch from XM7/VM/jsubsys.c */
+ if(prog_rom[0x000d] == 0x8f) {
+ prog_rom[0x000d] = 0x88;
+ }
+ /* Change: DICT.ROM to JSUBDICT.ROM */
+ if(fio->Fopen(create_local_path(_T("JSUBDICT.ROM")), FILEIO_READ_BINARY)) {
+ fio->Fread(dict_rom, sizeof(dict_rom), 1);
+ fio->Fclose();
+ }
+ /* KANJI ROM */
+ if(fio->Fopen(create_local_path(_T("JSUBKANJI.ROM")), FILEIO_READ_BINARY)) {
+ fio->Fread(kanji_rom, sizeof(kanji_rom), 1);
+ fio->Fclose();
+ } else if(fio->Fopen(create_local_path(_T("KANJI.ROM")), FILEIO_READ_BINARY)) {
+ fio->Fread(kanji_rom, sizeof(kanji_rom), 1);
+ fio->Fclose();
+ } else if(fio->Fopen(create_local_path(_T("KANJI1.ROM")), FILEIO_READ_BINARY)) {
+ fio->Fread(kanji_rom, sizeof(kanji_rom), 1);
+ fio->Fclose();
+ }
+
+ if(fio->Fopen(create_local_path(_T("JCOMMCARD.bin")), FILEIO_READ_BINARY)) {
+ fio->Fread(backup_ram, sizeof(backup_ram), 1);
+ fio->Fclose();
+ modified = false;
+ }
+ delete fio;
+
+#if defined(_FM77AV_VARIANTS)
+ jis78_emulation = true;
+#else
+ jis78_emulation = ((config.dipswitch & FM7_DIPSW_JIS78EMU_ON) != 0);
+#endif
+}
+
+void FM7_JCOMMCARD::write_signal(int id, uint32_t data, uint32_t mask)
+{
+ switch(id) {
+ case FM7_JCOMMCARD_BUS_BA:
+ cpu_ba = ((data & mask) != 0);
+ halted = cpu_ba & cpu_bs;
+ break;
+ case FM7_JCOMMCARD_BUS_BS:
+ cpu_bs = ((data & mask) != 0);
+ halted = cpu_ba & cpu_bs;
+ break;
+ }
+}
+
+uint32_t FM7_JCOMMCARD::read_io8(uint32_t address)
+{
+ uint32_t data;
+ switch(address & 3) {
+ case 0:
+ data = 0x7f;
+ if(!halted) {
+ data |= 0x80;
+ }
+ break;
+ case 1:
+ data = backup_ram[0x1f00 | rcb_address];
+ rcb_address++;
+ break;
+ case 2:
+ case 3:
+ /* Kanji Data */
+ if((jis78_emulation) && (kanji_address >= 0x3000) && (kanji_address < 0x4000)) {
+ /* JIS78 */
+ data = address & 1;
+ } else {
+ data = kanji_rom[(kanji_address << 1) + (address & 1)];
+ }
+ break;
+ }
+ return data;
+}
+
+void FM7_JCOMMCARD::write_io8(uint32_t address, uint32_t data)
+{
+ switch(address & 3) {
+ case 0:
+ /* Kanji Address High */
+ kanji_address = (kanji_address & 0x0000ff) | ((data & 0x000000ff) << 8);
+ break;
+ case 1:
+ /* Kanji Address Low */
+ kanji_address = (kanji_address & 0x00ff00) | (data & 0x000000ff);
+ break;
+ case 2:
+ if((data & 0x80) != 0) {
+ if(cpu != NULL) cpu->write_signal(SIG_CPU_HALTREQ, 0xffffffff, 0xffffffff);
+ }
+ break;
+ }
+}
+
+uint32_t FM7_JCOMMCARD::read_data8(uint32_t address)
+{
+ /*
+ * $8000-$9FFE : SRAM
+ * $9FFF : SYNC/BANK REG
+ * $A000-$AFFF : DICT
+ * $C000-$FFFF : SUB SYSTEM
+ */
+ if(address < 0x8000) return 0xff; /* NOOP */
+ if(address <= 0x9ffe) { /* SRAM */
+ return (uint32_t)backup_ram[address & 0x1fff];
+ } else if(address == 0x9fff) { /* RCB BANK REGISTER */
+ return (uint32_t)n_bank;
+ } else if(address <= 0xafff) { /* DICT ROM */
+ return (uint32_t)(dict_rom[(address & 0x0fff) | (((uint32_t)n_bank) << 12)]);
+ } else if(address < 0xc000) {
+ return 0xff;
+ } else if(address < 0x10000) {
+ return (uint32_t)prog_rom[address & 0x3fff];
+ }
+ return 0xff;
+}
+
+void FM7_JCOMMCARD::write_data8(uint32_t address, uint32_t data)
+{
+ if((address >= 0xa000) || (address < 0x8000)) return;
+ if(address == 0x9fff) {
+ if(cpu != NULL) cpu->write_signal(SIG_CPU_HALTREQ, ((data & 0x80) != 0) ? 0 : 0xffffffff, 0xffffffff);
+ n_bank = (uint8_t)(data & 0x3f);
+ } else if(address < 0x9fff) {
+ modified = true;
+ backup_ram[address & 0x1fff] = (uint8_t)data;
+ }
+}
+
+void FM7_JCOMMCARD::release(void)
+{
+ FILEIO *fio = new FILEIO();
+ if(modified) {
+ if(fio->Fopen(create_local_path(_T("JCOMMCARD.bin")), FILEIO_WRITE_BINARY)) {
+ fio->Fwrite(backup_ram, sizeof(backup_ram), 1);
+ fio->Fclose();
+ modified = false;
+ }
+ }
+}
+
+void FM7_JCOMMCARD::reset(void)
+{
+ rcb_address = 0x00;
+ kanji_address = 0x00000;
+ if(cpu != NULL) cpu->write_signal(SIG_CPU_HALTREQ, 0, 0xffffffff);
+ cpu_ba = cpu_bs = false;
+ halted = false;
+#if defined(_FM77AV_VARIANTS)
+ jis78_emulation = false;
+#else
+ jis78_emulation = ((config.dipswitch & FM7_DIPSW_JIS78EMU_ON) != 0);
+#endif
+}
+
+#define STATE_VERSION 1
+
+void FM7_JCOMMCARD::save_state(FILEIO *state_fio)
+{
+ state_fio->FputUint32_BE(STATE_VERSION);
+ state_fio->FputInt32_BE(this_device_id);
+ this->out_debug_log(_T("Save State: JCOMM CARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
+
+ state_fio->FputUint8(n_bank);
+ state_fio->FputUint8(rcb_address);
+ state_fio->FputUint32_BE(kanji_address);
+
+ state_fio->FputBool(cpu_ba);
+ state_fio->FputBool(cpu_bs);
+
+ state_fio->Fwrite(prog_rom, sizeof(prog_rom), 1);
+ state_fio->Fwrite(dict_rom, sizeof(dict_rom), 1);
+ state_fio->Fwrite(kanji_rom, sizeof(kanji_rom), 1);
+ state_fio->Fwrite(backup_ram, sizeof(backup_ram), 1);
+ state_fio->FputBool(firmware_ok);
+
+#if !defined(_FM77AV_VARIANTS)
+ state_fio->FputBool(jis78_emulation);
+#endif
+}
+
+bool FM7_JCOMMCARD::load_state(FILEIO *state_fio)
+{
+ uint32_t version;
+ version = state_fio->FgetUint32_BE();
+ if(this_device_id != state_fio->FgetInt32_BE()) return false;
+ this->out_debug_log(_T("Load State: JCOMM CARD: id=%d ver=%d\n"), this_device_id, STATE_VERSION);
+
+ if(version >= 1) {
+ n_bank = state_fio->FgetUint8();
+ rcb_address = state_fio->FgetUint8();
+ kanji_address = state_fio->FgetUint32_BE();
+
+ cpu_ba = state_fio->FgetBool();
+ cpu_bs = state_fio->FgetBool();
+ halted = cpu_ba & cpu_bs;
+
+ state_fio->Fread(prog_rom, sizeof(prog_rom), 1);
+ state_fio->Fread(dict_rom, sizeof(dict_rom), 1);
+ state_fio->Fread(kanji_rom, sizeof(kanji_rom), 1);
+ state_fio->Fread(backup_ram, sizeof(backup_ram), 1);
+ firmware_ok = state_fio->FgetBool();
+ modified = true;
+
+#if !defined(_FM77AV_VARIANTS)
+ jis78_emulation = state_fio->FgetBool();
+#else
+ jis78_emulation = false;
+#endif
+ }
+ return true;
+}
--- /dev/null
+/*
+ * Emulation of Fujitsu Japanese Communication Card.
+ * (C) 2018 K.Ohta.
+ * Note:
+ * Based on XM7 L70 , with permittion from Ryu Takegami.
+ */
+
+#include "../device.h"
+class MC6809;
+
+class FM7_JCOMMCARD : public DEVICE {
+private:
+ MC6809 *cpu;
+
+ uint8_t n_bank;
+ uint8_t rcb_address;
+ uint32_t kanji_address;
+
+ bool jis78_emulation;
+
+ bool cpu_ba;
+ bool cpu_bs;
+ bool halted;
+
+ bool modified;
+ bool firmware_ok;
+
+ uint8_t prog_rom[0x4000];
+ uint8_t dict_rom[0x40000];
+ uint8_t kanji_rom[0x20000];
+ uint8_t backup_ram[0x2000];
+public:
+ FM7_JCOMMCARD(VM *parent_vm, EMU *parent_emu);
+ ~FM7_JCOMMCARD();
+ void initialize(void);
+ void release(void);
+
+ void reset(void);
+ void write_signal(int id, uint32_t data, uint32_t mask);
+ /*
+ * I/O port:
+ * Read: $FD28 : SYNC Flag (JSUB HALTED = 0x7F)
+ * $FD29 : RCB Data.
+ * $FD2A : KANJI ROM UPPER
+ * $FD2B : KANJI ROM LOWER
+ *
+ * Write : $FD28 : KANJI ROM ADDRESS LOWER
+ * $FD29 : KANJI ROM ADDRESS UPPER
+ * $FD2A : Bit7: "0" = HALTREQ. Clear address.
+ * $FD2B : Write Data to RCB.
+ */
+ uint32_t read_io8(uint32_t address);
+ void write_io8(uint32_t address, uint32_t data);
+ uint32_t read_data8(uint32_t address);
+ void write_data8(uint32_t address, uint32_t data);
+
+ void set_context_cpu(MC6809 *p) {
+ cpu = p;
+ }
+ void save_state(FILEIO *state_fio);
+ bool load_state(FILEIO *state_fio);
+
+
+};
+
memset(data_table, 0xff, 0x20000);
// read_table[0].memory = data_table;
p_emu = parent_emu;
+
+#if !defined(_FM77AV_VARIANTS)
+ jis78_emulation = ((config.dipswitch & FM7_DIPSW_JIS78EMU_ON) != 0);
+#else
+ jis78_emulation = false;
+#endif
if(type_2std) {
class2 = true;
if(fio->Fopen(create_local_path(_T("KANJI2.ROM")), FILEIO_READ_BINARY)) {
fio->Fread(data_table, 0x20000, 1);
fio->Fclose();
read_ok = true;
+ jis78_emulation = false;
}
} else {
class2 = false;
void KANJIROM::reset(void)
{
kanjiaddr.d = 0;
+#if defined(_FM77AV_VARIANTS)
+ jis78_emulation = false;
+#else
+ jis78_emulation = ((config.dipswitch & FM7_DIPSW_JIS78EMU_ON) != 0);
+#endif
}
void KANJIROM::write_data8(uint32_t addr, uint32_t data)
uint32_t KANJIROM::read_data8(uint32_t addr)
{
if(addr == KANJIROM_DATA_HI) {
+ if((jis78_emulation) && (kanjiaddr.d >= 0x3000) && (kanjiaddr.d < 0x4000)) {
+ return 0;
+ }
return data_table[(kanjiaddr.d << 1) & 0x1ffff];
} else if(addr == KANJIROM_DATA_LO) {
+ if((jis78_emulation) && (kanjiaddr.d >= 0x3000) && (kanjiaddr.d < 0x4000)) {
+ return 1;
+ }
return data_table[((kanjiaddr.d << 1) & 0x1ffff) + 1];
} else if(addr == KANJIROM_READSTAT) {
return (read_ok) ? 0xffffffff : 0x00000000;
{
}
-#define STATE_VERSION 2
+#define STATE_VERSION 3
void KANJIROM::save_state(FILEIO *state_fio)
{
state_fio->FputUint32_BE(STATE_VERSION);
state_fio->FputBool(read_ok);
state_fio->Fwrite(data_table, sizeof(data_table), 1);
state_fio->FputUint16_BE(kanjiaddr.w.l);
+
+#if !defined(_FM77AV_VARIANTS)
+ state_fio->FputBool(jis78_emulation);
+#endif
}
bool KANJIROM::load_state(FILEIO *state_fio)
kanjiaddr.w.l = state_fio->FgetUint16_BE();
if(version == 2) return true;
}
+#if !defined(_FM77AV_VARIANTS)
+ if(version >= 3) {
+ jis78_emulation = state_fio->FgetBool();
+ }
+#else
+ jis78_emulation = false;
+#endif
return false;
}
bool read_ok;
bool class2;
pair_t kanjiaddr;
+
+ bool jis78_emulation;
public:
KANJIROM(VM *parent_vm, EMU* parent_emu, bool type_2std);
~KANJIROM();