OSDN Git Service

[VM][FM7] Add UARTs.RS-232C, MODEM and MIDI.Temporally implements.
authorK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 12 Jan 2018 16:07:36 +0000 (01:07 +0900)
committerK.Ohta <whatisthis.sowhat@gmail.com>
Fri, 12 Jan 2018 16:07:36 +0000 (01:07 +0900)
source/build-cmake/cmake/config_emufm7.cmake
source/src/qt/machines/fm7/MainWindow.cpp
source/src/qt/machines/fm7/menuclasses.h
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

index e26be62..50fb83f 100644 (file)
@@ -28,6 +28,7 @@ set(VMFILES_LIB
                   prnfile.cpp
                   or.cpp
                   noise.cpp
+                  i8251.cpp
 )
 
 set(FLAG_USE_MC6809 ON)
index fecb22b..928b375 100644 (file)
@@ -69,6 +69,32 @@ void Object_Menu_Control_7::do_set_z80_nmi(bool flag)
        emit sig_emu_update_config();
 }
 #endif
+void Object_Menu_Control_7::do_set_uart(bool flag)
+{
+       uint32_t nval;
+       int num = getValue1();
+       switch(num) {
+       case 0:
+               nval = FM7_DIPSW_RS232C_ON;
+               break;
+       case 1:
+               nval = FM7_DIPSW_MODEM_ON;
+               break;
+       case 2:
+               nval = FM7_DIPSW_MIDI_ON;
+               break;
+       default:
+               return;
+               break;
+       }
+       if(flag) {
+               config.dipswitch = config.dipswitch | nval;
+       } else {
+               nval = (uint32_t)(~nval);
+               config.dipswitch = config.dipswitch & nval;
+       }
+}
+
 #if defined(CAPABLE_JCOMMCARD)
 void Object_Menu_Control_7::do_set_jcommcard(bool flag)
 {
@@ -445,8 +471,14 @@ void META_MainWindow::retranslateUi(void)
 #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));
+       actionJCOMMCARD->setToolTip(QApplication::translate("Machine", "Connect Japanese communication board.\nNeed to restart this emulator if you change.", 0));
 #endif
+       actionUART[0]->setText(QApplication::translate("Machine", "Connect RS-232C (need restart).", 0));
+       actionUART[0]->setToolTip(QApplication::translate("Machine", "Connect extra RS-232C board.\nNeed to restart this emulator if changed.", 0));
+       actionUART[1]->setText(QApplication::translate("Machine", "Connect MODEM (need restart).", 0));
+       actionUART[1]->setToolTip(QApplication::translate("Machine", "Connect extra MODEM board.\nNeed to restart this emulator if changed.", 0));
+       actionUART[2]->setText(QApplication::translate("Machine", "Connect MIDI (need restart).", 0));
+       actionUART[2]->setToolTip(QApplication::translate("Machine", "Connect extra MIDI board.\nNeed to restart this emulator if changed.", 0));
        
        menuCpuType->setToolTipsVisible(true);
        menuBootMode->setToolTipsVisible(true);
@@ -544,6 +576,20 @@ void META_MainWindow::setupUI_Emu(void)
                actionZ80_NMI->setVisible(false);
        }
 #endif
+       menuMachine->addSeparator();
+       for(i = 0; i < 3; i++) {
+               actionUART[i] = new Action_Control_7(this, using_flags);
+               actionUART[i]->setCheckable(true);
+               actionUART[i]->setVisible(true);
+               actionUART[i]->fm7_binds->setValue1(i);
+               menuMachine->addAction(actionUART[i]);
+               connect(actionUART[i], SIGNAL(toggled(bool)), actionUART[i]->fm7_binds, SLOT(do_set_uart(bool)));
+       }
+       if((config.dipswitch & FM7_DIPSW_RS232C_ON) != 0) actionUART[0]->setChecked(true);
+       if((config.dipswitch & FM7_DIPSW_MODEM_ON) != 0) actionUART[1]->setChecked(true);
+       if((config.dipswitch & FM7_DIPSW_MIDI_ON) != 0) actionUART[2]->setChecked(true);
+       
+       
 #if defined(CAPABLE_JCOMMCARD)
        actionJCOMMCARD = new Action_Control_7(this, using_flags);
        menuMachine->addAction(actionJCOMMCARD);
index b792a95..d534d84 100644 (file)
@@ -47,6 +47,7 @@ public slots:
 #if defined(CAPABLE_JCOMMCARD)
        void do_set_jcommcard(bool flag);
 #endif
+       void do_set_uart(bool flag);
        void do_set_autokey_5_8(void);
 };
 
@@ -106,7 +107,9 @@ protected:
        class Action_Control_7 *actionZ80_IRQ;
        class Action_Control_7 *actionZ80_FIRQ;
        class Action_Control_7 *actionZ80_NMI;
-#endif 
+#endif
+       class Action_Control_7 *actionUART[3];
+       
        void setupUI_Emu(void);
        void retranslateUi(void);
        void retranslateVolumeLabels(Ui_SoundDialog *p);
index dbda170..ca8822e 100644 (file)
@@ -30,6 +30,7 @@
 #include "../ay_3_891x.h"
 #include "../and.h"
 #include "../or.h"
+#include "../i8251.h"
 
 #if defined(_FM77AV_VARIANTS)
 #include "mb61vh010.h"
@@ -67,6 +68,8 @@ VM::VM(EMU* parent_emu): emu(parent_emu)
        psg = NULL; 
 # endif
 #endif
+       for(int i = 0; i < 3; i++) uart[i] = NULL;
+       
        dummy = new DEVICE(this, emu);  // must be 1st device
        event = new EVENT(this, emu);   // must be 2nd device
        
@@ -75,6 +78,7 @@ VM::VM(EMU* parent_emu): emu(parent_emu)
        subcpu = new MC6809(this, emu);
        g_substat_display = new AND(this, emu);
        g_substat_mainhalt = new AND(this, emu);
+
        
 #ifdef WITH_Z80
        if((config.dipswitch & FM7_DIPSW_Z80CARD_ON) != 0) {
@@ -98,6 +102,17 @@ VM::VM(EMU* parent_emu): emu(parent_emu)
                jcommcard = NULL;
        }
 #endif
+# if defined(_FM77AV40) || defined(_FM77AV40SX) || defined(_FM77AV40EX) || defined(_FM77AV20) || defined(_FM77AV20EX)
+       uart[0] = new I8251(this, emu);
+# else
+#  if defined(CAPABLE_JCOMMCARD)
+       if((config.dipswitch & FM7_DIPSW_JSUBCARD_ON) != 0) uart[0] = new I8251(this, emu);
+#  endif
+       if(((config.dipswitch & FM7_DIPSW_RS232C_ON) != 0) && (uart[0] == NULL)) uart[0] = new I8251(this, emu);
+# endif
+       if((config.dipswitch & FM7_DIPSW_MODEM_ON) != 0) uart[1] = new I8251(this, emu);
+       if((config.dipswitch & FM7_DIPSW_MIDI_ON) != 0) uart[2] = new I8251(this, emu);
+
                
        // basic devices
        // I/Os
@@ -172,7 +187,7 @@ VM::VM(EMU* parent_emu): emu(parent_emu)
 
        mainio  = new FM7_MAINIO(this, emu);
        mainmem = new FM7_MAINMEM(this, emu);
-       
+
 #if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
        if((config.dipswitch & FM7_DIPSW_CONNECT_KANJIROM) != 0) {
                kanjiclass1 = new KANJIROM(this, emu, false);
@@ -185,6 +200,14 @@ VM::VM(EMU* parent_emu): emu(parent_emu)
 #ifdef CAPABLE_KANJI_CLASS2
        kanjiclass2 = new KANJIROM(this, emu, true);
 #endif
+
+# if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       g_rs232c_dtr = new AND(this, emu);
+       g_rs232c_dtr->set_mask(SIG_AND_BIT_0);
+       g_rs232c_dtr->set_mask(SIG_AND_BIT_1);
+
+       // DCD
+#endif
 #ifdef WITH_Z80
        g_mainstat->set_mask(SIG_AND_BIT_0);
        g_mainstat->set_mask(SIG_AND_BIT_1);
@@ -201,13 +224,38 @@ VM::VM(EMU* parent_emu): emu(parent_emu)
        event->set_device_name(_T("EVENT"));
        dummy->set_device_name(_T("1st Dummy"));
        
-       maincpu->set_device_name(_T("MAINCPU(MC6809)"));
-       subcpu->set_device_name(_T("SUBCPU(MC6809)"));
+       maincpu->set_device_name(_T("MAINCPU(MC6809B)"));
+       subcpu->set_device_name(_T("SUBCPU(MC6809B)"));
        dummycpu->set_device_name(_T("DUMMY CPU"));
+#if defined(CAPABLE_JCOMMCARD)
+       if(jsubcpu != NULL) {
+               jsubcpu->set_device_name(_T("J.COMM BOARD CPU(MC6809)"));
+       }
+       if(jcommcard != NULL) {
+               jcommcard->set_device_name(_T("Japanese COMM BOARD"));
+       }
 # ifdef WITH_Z80
-       if(z80cpu != NULL) z80cpu->set_device_name(_T("Z80 CPU"));
+       if(z80cpu != NULL) z80cpu->set_device_name(_T("Z80 CPU BOARD"));
 # endif
        if(fdc != NULL) fdc->set_device_name(_T("MB8877 FDC(320KB)"));
+       
+       if(uart[0] != NULL) {
+               uart[0]->set_device_name(_T("RS-232C BOARD(I8251 SIO)"));
+       }
+# if defined(CAPABLE_JCOMMCARD)
+       if((config.dipswitch & FM7_DIPSW_JSUBCARD_ON) != 0) {
+               if(uart[0] != NULL) uart[0]->set_device_name(_T("J.COMM BOARD RS-232C(I8251 SIO)"));
+       }
+# elif defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       if(uart[0] != NULL) uart[0]->set_device_name(_T("RS-232C(I8251 SIO)"));
+# endif
+               
+       if(uart[1] != NULL) {
+               uart[1]->set_device_name(_T("MODEM BOARD(I8251 SIO)"));
+       }
+       if(uart[2] != NULL) {
+               uart[2]->set_device_name(_T("MIDI BOARD(I8251 SIO)"));
+       }
                                                
        // basic devices
        // I/Os
@@ -235,6 +283,19 @@ VM::VM(EMU* parent_emu): emu(parent_emu)
        bubble_casette[1]->set_device_name(_T("BUBBLE CASETTE #1"));
 # endif        
 #endif
+# if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       g_rs232c_dtr->set_device_name(_T("RS232C DTR(AND)"));
+#endif
+#ifdef WITH_Z80
+       g_intr->set_device_name(_T("Z80 INTR(OR)"));
+       g_mainstat->set_device_name(_T("Z80 HALT/RUN(AND)"));
+       g_intr_irq->set_device_name(_T("Z80 IRQ(AND)"));
+       g_intr_firq->set_device_name(_T("Z80 FIRQ(AND)"));
+       g_nmi->set_device_name(_T("Z80 NMI(AND)"));
+#endif
+       g_substat_display->set_device_name(_T("DISPLAY STATUS(AND)"));
+       g_substat_mainhalt->set_device_name(_T("SUBSYSTEM HALT STATUS(AND)"));
+#endif 
        this->connect_bus();
        
 }
@@ -381,6 +442,31 @@ void VM::connect_bus(void)
        mainio->set_context_irq(maincpu, SIG_CPU_IRQ, 0xffffffff);
        mainio->set_context_firq(maincpu, SIG_CPU_FIRQ, 0xffffffff);
        mainio->set_context_nmi(maincpu, SIG_CPU_NMI, 0xffffffff);
+
+       mainio->set_context_uart(0, uart[0]); /* $FD06- : RS232C */
+       mainio->set_context_uart(1, uart[1]); /* $FD40- : MODEM */
+       mainio->set_context_uart(2, uart[2]); /* $FDEA- : MIDI */
+
+#if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       mainio->set_context_rs232c_dtr(g_rs232c_dtr);
+       if(uart[0] != NULL) uart[0]->set_context_dtr(g_rs232c_dtr, SIG_AND_BIT_1, 0xffffffff);
+#endif
+       if(uart[0] != NULL) {
+               uart[0]->set_context_rxrdy(mainio, FM7_MAINIO_UART0_RXRDY, 0xffffffff);
+               uart[0]->set_context_txrdy(mainio, FM7_MAINIO_UART0_TXRDY, 0xffffffff);
+               uart[0]->set_context_syndet(mainio, FM7_MAINIO_UART0_SYNDET, 0xffffffff);
+       }
+       if(uart[1] != NULL) {
+               uart[1]->set_context_rxrdy(mainio, FM7_MAINIO_MODEM_RXRDY, 0xffffffff);
+               uart[1]->set_context_txrdy(mainio, FM7_MAINIO_MODEM_TXRDY, 0xffffffff);
+               uart[1]->set_context_syndet(mainio, FM7_MAINIO_MODEM_SYNDET, 0xffffffff);
+       }
+       if(uart[2] != NULL) {
+               uart[2]->set_context_rxrdy(mainio, FM7_MAINIO_MIDI_RXRDY, 0xffffffff);
+               uart[2]->set_context_txrdy(mainio, FM7_MAINIO_MIDI_TXRDY, 0xffffffff);
+               uart[2]->set_context_syndet(mainio, FM7_MAINIO_MIDI_SYNDET, 0xffffffff);
+       }
+       
 #if defined(_FM8) || defined(_FM7) || defined(_FMNEW7)
        if((config.dipswitch & FM7_DIPSW_CONNECT_KANJIROM) != 0) {
                mainio->set_context_kanjirom_class1(kanjiclass1);
index 1315f92..33ae7b4 100644 (file)
@@ -394,6 +394,7 @@ class YM2203;
 class MB8877;
 class MEMORY;
 class DATAREC;
+class I8251;
 #if defined(USE_AY_3_8910_AS_PSG) && !defined(_FM77AV_VARIANTS)
 class AY_3_891X;
 #endif
@@ -455,6 +456,11 @@ protected:
 #if defined(_FM8)
        BUBBLECASETTE *bubble_casette[2];
 #endif
+       I8251 *uart[3];
+# if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       AND *g_rs232c_dtr;
+#endif
+       
        //BEEP* beep;
        PCM1BIT* pcm1bit;
        DATAREC *drec;
index 2f653ab..eeae4e5 100644 (file)
@@ -60,12 +60,17 @@ enum {
 // '1' is Auto 5 Key, '0' is Auto 8 Key
 #define FM7_DIPSW_SELECT_5_OR_8KEY   0x00000100 
 #define FM7_DIPSW_AUTO_5_OR_8KEY     0x00000200
+
 #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_RS232C_ON          0x00040000
+#define FM7_DIPSW_MODEM_ON           0x00080000
+#define FM7_DIPSW_MIDI_ON            0x00100000
+
 #define FM7_DIPSW_FRAMESKIP          0x30000000
 #define FM7_DIPSW_SYNC_TO_HSYNC      0x80000000
 
@@ -176,6 +181,17 @@ enum {
        FM7_MAINIO_MMR_EXTENDED,
        FM7_MAINIO_WINDOW_FAST,
        FM7_MAINMEM_REFRESH_FAST,
+       FM7_MAINIO_UART0_SYNDET,
+       FM7_MAINIO_UART0_RXRDY,
+       FM7_MAINIO_UART0_TXRDY,
+       FM7_MAINIO_UART0_DCD,
+       FM7_MAINIO_MODEM_SYNDET,
+       FM7_MAINIO_MODEM_RXRDY,
+       FM7_MAINIO_MODEM_TXRDY,
+       FM7_MAINIO_MIDI_SYNDET,
+       FM7_MAINIO_MIDI_RXRDY,
+       FM7_MAINIO_MIDI_TXRDY,
+       
        FM7_MAINIO_MMR_BANK = 0x200100,
 
 };
index f35b224..bb855a8 100644 (file)
 #include "../z80.h"
 
 #include "../datarec.h"
+#include "../i8251.h"
 #if defined(HAS_DMA)
 #include "hd6844.h"
 #endif
+# if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+#include "../and.h"
+#endif
+
 #if defined(_FM8)
 #include "bubblecasette.h"
 #endif
@@ -33,6 +38,17 @@ FM7_MAINIO::FM7_MAINIO(VM* parent_vm, EMU* parent_emu) : DEVICE(parent_vm, paren
        for(i = 0; i < 3; i++) {
                opn[i] = NULL;
        }
+       for(i = 0; i < 3; i++) {
+               uart[i] = NULL;
+               uart_enabled[i] = false;
+       }
+# if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       rs232c_enabled = false;
+       rs232c_dtr = NULL;
+# else
+       rs232c_enabled = true;
+       rs232c_dcd = false;
+# endif
 # if !defined(_FM77AV_VARIANTS)
        psg = NULL;
 #endif
@@ -244,6 +260,12 @@ void FM7_MAINIO::reset()
        lpt_type = config.printer_type;
        reset_printer();
        
+# if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       rs232c_enabled = false;
+# else
+       rs232c_enabled = true;
+# endif
+
 #if defined(_FM77AV_VARIANTS)
        sub_monitor_type = 0x00;
 #endif
@@ -276,6 +298,10 @@ void FM7_MAINIO::reset()
        irqreq_txrdy = false;
        irqreq_printer = false;
        irqreq_keyboard = false;
+
+       modem_irqmask_rxrdy = modem_irqmask_txrdy = true;
+       modem_syndet = modem_rxrdy = modem_txrdy = false;
+       midi_uart_irqmask = midi_syndet = midi_rxrdy = midi_txrdy = false;
        // FD00
        if(drec != NULL) {
                drec->write_signal(SIG_DATAREC_MIC, 0x00, 0x01);
@@ -599,6 +625,7 @@ void FM7_MAINIO::do_irq(void)
 {
        bool intstat;
        uint32_t nval;
+       
 #if defined(_FM8)
        intstat = intstat_txrdy | intstat_rxrdy | intstat_syndet;
 #else  
@@ -607,6 +634,9 @@ void FM7_MAINIO::do_irq(void)
        intstat = intstat | intstat_opn | intstat_whg | intstat_thg;
        intstat = intstat | intstat_txrdy | intstat_rxrdy | intstat_syndet;
        intstat = intstat | intstat_mouse;
+       intstat = intstat | ((modem_irqmask_txrdy & modem_txrdy) | (modem_irqmask_rxrdy & modem_rxrdy) | modem_syndet);
+       intstat = intstat | (!(midi_uart_irqmask) & (midi_syndet | midi_txrdy | midi_rxrdy));
+       
 # if defined(HAS_DMA)
        intstat = intstat | intstat_dma;
 # endif
@@ -965,6 +995,43 @@ void FM7_MAINIO::write_signal(int id, uint32_t data, uint32_t mask)
                        }
                        break;
 #endif
+               case FM7_MAINIO_UART0_RXRDY:
+                       set_irq_rxrdy(val_b & rs232c_enabled);
+                       break;
+               case FM7_MAINIO_UART0_TXRDY:
+                       set_irq_txrdy(val_b & rs232c_enabled);
+                       break;
+               case FM7_MAINIO_UART0_SYNDET:
+                       set_irq_syndet(val_b & rs232c_enabled);
+                       break;
+               case FM7_MAINIO_UART0_DCD:
+                       rs232c_dcd = val_b;
+                       break;
+               case FM7_MAINIO_MODEM_TXRDY:
+                       modem_txrdy = val_b;
+                       do_irq();
+                       break;
+               case FM7_MAINIO_MODEM_RXRDY:
+                       modem_rxrdy = val_b;
+                       do_irq();
+                       break;
+               case FM7_MAINIO_MODEM_SYNDET:
+                       modem_syndet = val_b;
+                       do_irq();
+                       break;
+               case FM7_MAINIO_MIDI_TXRDY:
+                       midi_txrdy = val_b;
+                       do_irq();
+                       break;
+               case FM7_MAINIO_MIDI_RXRDY:
+                       midi_rxrdy = val_b;
+                       do_irq();
+                       break;
+               case FM7_MAINIO_MIDI_SYNDET:
+                       midi_syndet = val_b;
+                       do_irq();
+                       break;
+                       
 #if !defined(_FM8)                     
                case FM7_MAINIO_OPN_IRQ:
                        if(!connect_opn) break;
@@ -1149,14 +1216,21 @@ uint32_t FM7_MAINIO::read_data8(uint32_t addr)
                        break;
                case 0x06: // RS-232C
                case 0x07:
+                       if(uart_enabled[0] && rs232c_enabled) {
+                               if(uart[0] != NULL) retval = uart[0]->read_io8(addr & 1);
+                       }
                        break;
                case 0x08: // Light pen
                case 0x09:
-               case 0x0a:
+               case 0x0a:
                        break;
 #if defined(_FM77AV_VARIANTS)
                case 0x0b:
                        retval = ((config.boot_mode & 3) == 0) ? 0xfe : 0xff;
+#if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+                       retval &= (uint32_t)(~0x04);
+                       if(!rs232c_dcd) retval |= 0x04;
+#endif
                        break;
 #endif                 
                case 0x0e: // PSG DATA
@@ -1253,6 +1327,14 @@ uint32_t FM7_MAINIO::read_data8(uint32_t addr)
                case 0x37: // Multi page
                        //retval = (uint32_t)display->read_data8(DISPLAY_ADDR_MULTIPAGE);
                        break;
+               case 0x40: // MODEM
+               case 0x41:
+                       if(uart_enabled[1]) {
+                               if(uart[1] != NULL) retval = uart[1]->read_io8(addr & 1);
+                       }
+                       break;
+               case 0x42:
+                       break;
                case 0x45: // WHG CMD
                        break;
                case 0x46: // WHG DATA
@@ -1294,6 +1376,12 @@ uint32_t FM7_MAINIO::read_data8(uint32_t addr)
                        retval = dmac->read_data8(dma_addr);
                        break;
 #endif                 
+               case 0xea: // MIDI
+               case 0xeb:
+                       if(uart_enabled[2]) {
+                               if(uart[2] != NULL) retval = uart[2]->read_io8(addr & 1);
+                       }
+                       break;
                default:
                        break;
                }
@@ -1388,11 +1476,26 @@ void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
                        break;
                case 0x06: // RS-232C
                case 0x07:
+                       if(uart_enabled[0] && rs232c_enabled) {
+                               if(uart[0] != NULL) uart[0]->write_io8(addr & 1, data);
+                       }
                        break;
                case 0x08: // Light pen
                case 0x09:
                case 0x0a:
                        break;
+               case 0x0c:
+#if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+                       if(rs232c_dtr != NULL) {
+                               if((data & 0x04) != 0) {
+                                       rs232c_dtr->write_signal(SIG_AND_BIT_1, 0, 1);
+                               } else {
+                                       rs232c_dtr->write_signal(SIG_AND_BIT_1, 1, 1);
+                               }
+                       }
+                       rs232c_enabled = ((data & 0x01) != 0) ? true : false;
+#endif
+                       break;
                case 0x0d:
                        //printf("PSG CMD WRITE val=%02x\n", data);
                        set_psg_cmd(data);
@@ -1527,6 +1630,18 @@ void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
                case 0x37: // Multi page
                        display->write_signal(SIG_DISPLAY_MULTIPAGE, data, 0x00ff);
                        break;
+               case 0x40: // MODEM
+               case 0x41:
+                       if(uart_enabled[1]) {
+                               if(uart[1] != NULL) uart[1]->write_io8(addr & 1, data);
+                       }
+                       break;
+               case 0x42:
+                       modem_irqmask_txrdy = ((data & 0x20) != 0);
+                       modem_irqmask_rxrdy = ((data & 0x40) != 0);
+                       do_irq();
+                       break;
+                       
                case 0x45: // WHG CMD
                        set_opn_cmd(1, data);
                        break;
@@ -1590,7 +1705,14 @@ void FM7_MAINIO::write_data8(uint32_t addr, uint32_t data)
                        dmac->write_data8(dma_addr, data);
                        //this->out_debug_log(_T("IO: Wrote DMA %02x to reg %02x\n"), data, dma_addr);
                        break;
-#endif                 
+#endif
+                       // MIDI
+               case 0xea: 
+               case 0xeb:
+                       if(uart_enabled[2]) {
+                               if(uart[2] != NULL) uart[2]->write_io8(addr & 1, data);
+                       }
+                       break;
                default:
                        //printf("MAIN: Write I/O Addr=%08x DATA=%02x\n", addr, data); 
                        break;
@@ -1673,7 +1795,7 @@ void FM7_MAINIO::event_vline(int v, int clock)
 {
 }
 
-#define STATE_VERSION 7
+#define STATE_VERSION 9
 void FM7_MAINIO::save_state(FILEIO *state_fio)
 {
        int ch;
@@ -1830,6 +1952,21 @@ void FM7_MAINIO::save_state(FILEIO *state_fio)
        // FD05
        state_fio->FputBool(req_z80run);
        state_fio->FputBool(z80_run);
+
+       // UART
+       state_fio->FputBool(rs232c_enabled);
+       state_fio->FputBool(rs232c_dcd);
+       for(int i = 0; i < 3; i++) state_fio->FputBool(uart_enabled[i]);
+       state_fio->FputBool(modem_irqmask_rxrdy);
+       state_fio->FputBool(modem_irqmask_txrdy);
+       state_fio->FputBool(modem_syndet);
+       state_fio->FputBool(modem_rxrdy);
+       state_fio->FputBool(modem_txrdy);
+
+       state_fio->FputBool(midi_uart_irqmask);
+       state_fio->FputBool(midi_syndet);
+       state_fio->FputBool(midi_rxrdy);
+       state_fio->FputBool(midi_txrdy);
 }
 
 bool FM7_MAINIO::load_state(FILEIO *state_fio)
@@ -1989,6 +2126,21 @@ bool FM7_MAINIO::load_state(FILEIO *state_fio)
        req_z80run = state_fio->FgetBool();
        z80_run = state_fio->FgetBool();
        
+       // UART
+       rs232c_enabled = state_fio->FgetBool();
+       rs232c_dcd = state_fio->FgetBool();
+       for(int i = 0; i < 3; i++) uart_enabled[i] = state_fio->FgetBool();
+       modem_irqmask_rxrdy = state_fio->FgetBool();
+       modem_irqmask_txrdy = state_fio->FgetBool();
+       modem_syndet = state_fio->FgetBool();
+       modem_rxrdy = state_fio->FgetBool();
+       modem_txrdy = state_fio->FgetBool();
+
+       midi_uart_irqmask = state_fio->FgetBool();
+       midi_syndet = state_fio->FgetBool();
+       midi_rxrdy = state_fio->FgetBool();
+       midi_txrdy = state_fio->FgetBool();
+       
        if(version != STATE_VERSION) return false;
        return true;
 }
index 70b0f21..20b2ba0 100644 (file)
@@ -24,6 +24,9 @@ class YM2203;
 class AY_3_891X;
 #endif
 class MB8877;
+class I8251;
+class AND;
+
 #if defined(_FM8)
 class BUBBLECASETTE;
 #endif
@@ -355,7 +358,25 @@ class FM7_MAINIO : public DEVICE {
        DEVICE* pcm1bit;
        DEVICE* joystick;
        
-        //DEVICE* beep;
+       I8251 *uart[3];
+# if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+       AND   *rs232c_dtr;
+#endif
+       bool uart_enabled[3];
+       bool rs232c_enabled;
+       bool rs232c_dcd;
+       
+       bool modem_irqmask_rxrdy;
+       bool modem_irqmask_txrdy;
+       bool modem_syndet;
+       bool modem_rxrdy;
+       bool modem_txrdy;
+       
+       bool midi_uart_irqmask;
+       bool midi_syndet;
+       bool midi_rxrdy;
+       bool midi_txrdy;
+       
        MB8877* fdc;
 #if defined(HAS_DMA)
        HD6844* dmac;
@@ -538,7 +559,21 @@ public:
                jcommcard = p;
 #endif
        }
-
+       void set_context_uart(int num, I8251 *p) {
+               if(num < 0) return;
+               if(num > 2) return;
+               uart[num] = p;
+               if(p != NULL) {
+                       uart_enabled[num] = true;
+               } else {
+                       uart_enabled[num] = false;
+               }
+       }
+       void set_context_rs232c_dtr(AND *p) {
+# if defined(_FM77AV20) || defined(_FM77AV40) || defined(_FM77AV20EX) || defined(_FM77AV40EX) || defined(_FM77AV40SX)
+               rs232c_dtr = p;
+# endif
+       }
 #if defined(HAS_DMA)
        void set_context_dmac(HD6844 *p) {
                dmac = p;