OSDN Git Service

[VM][FM7] Add Japanese communication board (日本語通信カード) .
authorK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 12 Jan 2018 09:58:53 +0000 (18:58 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 12 Jan 2018 09:58:53 +0000 (18:58 +0900)
[VM][FM7] Add turning ON/OFF Z80 extra board.

17 files changed:
doc/VMs/fm7.txt
doc/VMs/fm77av.txt
source/src/qt/common/qt_utils.cpp
source/src/qt/machines/fm7/MainWindow.cpp
source/src/qt/machines/fm7/fm7.ts
source/src/qt/machines/fm7/menuclasses.h
source/src/res/i18n/ja/fm7.qm
source/src/vm/fm7/CMakeLists.txt
source/src/vm/fm7/fm7.cpp
source/src/vm/fm7/fm7.h
source/src/vm/fm7/fm7_common.h
source/src/vm/fm7/fm7_mainio.cpp
source/src/vm/fm7/fm7_mainio.h
source/src/vm/fm7/jcommcard.cpp [new file with mode: 0644]
source/src/vm/fm7/jcommcard.h [new file with mode: 0644]
source/src/vm/fm7/kanjirom.cpp
source/src/vm/fm7/kanjirom.h

index 6573212..9dcdaa1 100644 (file)
@@ -1,5 +1,5 @@
 "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
index 0b63b98..ba983d5 100644 (file)
@@ -1,7 +1,7 @@
 "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
 
index 0d5efa6..3c3e965 100644 (file)
@@ -692,7 +692,7 @@ void Ui_MainWindow::do_update_inner_bubble(int drv, QStringList base, class Acti
 
 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();
 
index 97b9d46..fecb22b 100644 (file)
@@ -30,6 +30,15 @@ Object_Menu_Control_7::~Object_Menu_Control_7()
 }
 
 #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) {
@@ -60,6 +69,16 @@ void Object_Menu_Control_7::do_set_z80_nmi(bool 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)
@@ -72,6 +91,17 @@ 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)
 {
@@ -194,6 +224,10 @@ void META_MainWindow::retranslateVolumeLabels(Ui_SoundDialog *p)
 
 void META_MainWindow::retranslateUi(void)
 {
+
+       int z80num, jcommnum;
+       z80num = -1;
+       jcommnum = -1;
        
        retranslateControlMenu("Hot Start (BREAK+RESET)", true);
        retranslateFloppyMenu(0, 0);
@@ -222,18 +256,41 @@ void META_MainWindow::retranslateUi(void)
        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));
@@ -354,6 +411,9 @@ void META_MainWindow::retranslateUi(void)
 #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));
@@ -364,12 +424,16 @@ void META_MainWindow::retranslateUi(void)
        // 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));
        
@@ -379,6 +443,11 @@ void META_MainWindow::retranslateUi(void)
        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
@@ -428,8 +497,24 @@ void META_MainWindow::setupUI_Emu(void)
        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);
@@ -453,7 +538,21 @@ void META_MainWindow::setupUI_Emu(void)
        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);
index 68f5127..cccd03e 100644 (file)
@@ -5,7 +5,7 @@
     <name>Machine</name>
     <message>
         <source>Frame skip</source>
-        <translation>フレームスキップ</translation>
+        <translation>  フレームスキップ</translation>
     </message>
     <message>
         <source>None</source>
@@ -138,18 +138,6 @@ This emulates extra PSG board made by third party.</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>
@@ -174,38 +162,6 @@ WHG(2枚目のFM音源)と
 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>
@@ -344,14 +300,6 @@ Useful for games using &apos;1 2 3 5&apos; to move character.</source>
         <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と
@@ -394,6 +342,116 @@ Reset with pressing BREAK key.</source>
         <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>
index 2899c27..b792a95 100644 (file)
@@ -21,6 +21,7 @@ signals:
        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);
@@ -40,6 +41,12 @@ public slots:
 # 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);
 };
 
@@ -66,9 +73,15 @@ protected:
 # 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 
@@ -89,6 +102,7 @@ protected:
        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;
index 6a79df0..4f19aab 100644 (file)
Binary files a/source/src/res/i18n/ja/fm7.qm and b/source/src/res/i18n/ja/fm7.qm differ
index 96b9697..fe4856a 100644 (file)
@@ -22,7 +22,19 @@ set(VM_FM7_LIB_SRCS
 )
 
 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)
@@ -31,6 +43,7 @@ else()
        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)
index 3c537e4..dbda170 100644 (file)
@@ -49,6 +49,9 @@
 #include "./joystick.h"
 
 #include "./kanjirom.h"
+#if defined(CAPABLE_JCOMMCARD)
+#include "./jcommcard.h"
+#endif
 
 VM::VM(EMU* parent_emu): emu(parent_emu)
 {
@@ -74,7 +77,11 @@ 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);
 
@@ -82,6 +89,16 @@ VM::VM(EMU* parent_emu): emu(parent_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)
@@ -174,10 +191,11 @@ VM::VM(EMU* parent_emu): emu(parent_emu)
        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"));
@@ -187,7 +205,7 @@ VM::VM(EMU* parent_emu): emu(parent_emu)
        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)"));
                                                
@@ -291,8 +309,10 @@ void VM::connect_bus(void)
        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);
@@ -310,12 +330,20 @@ void VM::connect_bus(void)
        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);
@@ -468,13 +496,23 @@ void VM::connect_bus(void)
        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) {
@@ -596,8 +634,24 @@ DEVICE *VM::get_cpu(int index)
        }
 #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;
 }
index fae05f7..1315f92 100644 (file)
@@ -58,6 +58,7 @@
 #define CAPABLE_Z80
 #define DIPSWITCH_DEFAULT 0x000000000 
 #define MAX_DRIVE  4
+#define CAPABLE_JCOMMCARD 1
 
 #elif defined(_FMNEW7)
 #define DEVICE_NAME            "FUJITSU FM-NEW7"
@@ -65,6 +66,7 @@
 #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"
@@ -415,6 +419,10 @@ class JOYSTICK;
 class Z80;
 class OR;
 #endif
+#ifdef CAPABLE_JCOMMCARD
+class FM7_JCOMMCARD;
+#endif
+
 class VM {
 protected:
        EMU* emu;
@@ -482,6 +490,10 @@ protected:
 #ifdef CAPABLE_KANJI_CLASS2
        KANJIROM *kanjiclass2;
 #endif
+#if defined(CAPABLE_JCOMMCARD)
+       MC6809 *jsubcpu;
+       FM7_JCOMMCARD *jcommcard;
+#endif
        bool connect_320kfdc;
        bool connect_1Mfdc;
 public:
index c94ef00..2f653ab 100644 (file)
@@ -63,6 +63,9 @@ enum {
 #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
 
@@ -75,6 +78,7 @@ enum {
 #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
@@ -146,6 +150,10 @@ enum {
        FM7_MAINCLOCK_MMRSLOW,
        FM7_MAINCLOCK_MMRHIGH
 };
+enum {
+       FM7_JCOMMCARD_BUS_BA = 0x400000,
+       FM7_JCOMMCARD_BUS_BS,
+};
 
 enum {
        FM7_MAINIO_IS_BASICROM = 0x200000,
index fba7662..9d48ffc 100644 (file)
@@ -54,6 +54,9 @@ FM7_MAINIO::FM7_MAINIO(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, paren
 #ifdef WITH_Z80
        z80 = NULL;
 #endif 
+#if defined(CAPABLE_JCOMMCARD)
+       jcommcard = NULL;
+#endif
 #if defined(_FM8)
        bubble_casette[0] = NULL;
        bubble_casette[1] = NULL;
@@ -301,7 +304,7 @@ void FM7_MAINIO::reset()
        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);
@@ -717,7 +720,7 @@ void FM7_MAINIO::set_fd04(uint8_t val)
                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
 }
@@ -949,7 +952,7 @@ void FM7_MAINIO::write_signal(int id, uint32_t data, uint32_t mask)
 #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?
                        }
@@ -1226,6 +1229,18 @@ uint32_t FM7_MAINIO::read_data8(uint32_t addr)
                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();
@@ -1477,6 +1492,14 @@ void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
                        //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);
index 5da6b8b..70b0f21 100644 (file)
@@ -373,6 +373,9 @@ class FM7_MAINIO : public DEVICE {
 #ifdef WITH_Z80
        Z80 *z80;
 #endif
+#if defined(CAPABLE_JCOMMCARD)
+       DEVICE *jcommcard;
+#endif
 #if defined(_FM8)
        BUBBLECASETTE *bubble_casette[2];
 #endif
@@ -525,13 +528,19 @@ public:
        }
 #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
diff --git a/source/src/vm/fm7/jcommcard.cpp b/source/src/vm/fm7/jcommcard.cpp
new file mode 100644 (file)
index 0000000..a2db68c
--- /dev/null
@@ -0,0 +1,262 @@
+/*
+ * 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;
+}
diff --git a/source/src/vm/fm7/jcommcard.h b/source/src/vm/fm7/jcommcard.h
new file mode 100644 (file)
index 0000000..fca23c0
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ * 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);
+
+       
+};
+
index 0558eb6..d6da593 100644 (file)
@@ -21,12 +21,19 @@ KANJIROM::KANJIROM(VM *parent_vm, EMU* parent_emu, bool type_2std): DEVICE(paren
        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;
@@ -62,6 +69,11 @@ KANJIROM::~KANJIROM()
 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)
@@ -80,8 +92,14 @@ 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;
@@ -100,7 +118,7 @@ void KANJIROM::release()
 {
 }
 
-#define STATE_VERSION 2
+#define STATE_VERSION 3
 void KANJIROM::save_state(FILEIO *state_fio)
 {
        state_fio->FputUint32_BE(STATE_VERSION);
@@ -111,6 +129,10 @@ void KANJIROM::save_state(FILEIO *state_fio)
        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)
@@ -131,6 +153,13 @@ 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;
 }
 
index 970e815..04a789d 100644 (file)
@@ -21,6 +21,8 @@ private:
        bool read_ok;
        bool class2;
        pair_t kanjiaddr;
+
+       bool jis78_emulation;
 public:
        KANJIROM(VM *parent_vm, EMU* parent_emu, bool type_2std);
        ~KANJIROM();