From 2ce38beb1968cf38cdb6529d9626baaaa210fcee Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Sun, 2 Nov 2014 23:35:55 +0100 Subject: [PATCH 1/4] upd7810: remove gamemaster hack for INTFE1 The extended timer has been properly implemented in upd7810. Tested with Continental Galaxy 2020. --- src/emu/cpu/upd7810/upd7810.c | 4 ---- src/mess/drivers/gmaster.c | 7 ------- 2 files changed, 11 deletions(-) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index bc62fa33ffa..589e1a093ae 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -1987,10 +1987,6 @@ void upd7810_device::execute_set_input(int irqline, int state) else if ( irqline == UPD7810_INTF2 && ( MKL & 0x20 ) ) IRR |= INTF2; - // gamemaster hack - else - if (irqline == UPD7810_INTFE1) - IRR |= INTFE1; else logerror("upd7810_set_irq_line invalid irq line #%d\n", irqline); } diff --git a/src/mess/drivers/gmaster.c b/src/mess/drivers/gmaster.c index 9c7cf293929..8b5fe019f5c 100644 --- a/src/mess/drivers/gmaster.c +++ b/src/mess/drivers/gmaster.c @@ -28,7 +28,6 @@ public: DECLARE_WRITE8_MEMBER(gmaster_port_w); DECLARE_DRIVER_INIT(gmaster) { memset(&m_video, 0, sizeof(m_video)); memset(m_ram, 0, sizeof(m_ram)); } UINT32 screen_update_gmaster(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(gmaster_interrupt); private: virtual void machine_start(); @@ -278,16 +277,10 @@ void gmaster_state::machine_start() } -INTERRUPT_GEN_MEMBER(gmaster_state::gmaster_interrupt) -{ - m_maincpu->set_input_line(UPD7810_INTFE1, ASSERT_LINE); -} - static MACHINE_CONFIG_START( gmaster, gmaster_state ) MCFG_CPU_ADD("maincpu", UPD7810, XTAL_12MHz/2/*?*/) // upd78c11 in the unit MCFG_CPU_PROGRAM_MAP(gmaster_mem) MCFG_CPU_IO_MAP( gmaster_io) - MCFG_CPU_VBLANK_INT_DRIVER("screen", gmaster_state, gmaster_interrupt) MCFG_SCREEN_ADD("screen", LCD) MCFG_SCREEN_REFRESH_RATE(60) From 10e440875759c191b55e8ff8c57c585726c36ead Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Sun, 2 Nov 2014 23:14:49 +0100 Subject: [PATCH 2/4] upd7810: treat NMI like other interrupts --- src/emu/cpu/upd7810/upd7810.c | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index 589e1a093ae..ec7e136f5e4 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -709,6 +709,14 @@ void upd7810_device::upd7810_take_irq() return; /* check the interrupts in priority sequence */ + if (IRR & INTNMI) + { + /* Nonmaskable interrupt */ + irqline = INPUT_LINE_NMI; + vector = 0x0004; + IRR &= ~INTNMI; + } + else if ((IRR & INTFT0) && 0 == (MKL & 0x02)) { vector = 0x0008; @@ -1968,18 +1976,7 @@ void upd7810_device::execute_set_input(int irqline, int state) { /* no nested NMIs ? */ // if (0 == (IRR & INTNMI)) - { - IRR |= INTNMI; - SP--; - WM( SP, PSW ); - SP--; - WM( SP, PCH ); - SP--; - WM( SP, PCL ); - IFF = 0; - PSW &= ~(SK|L0|L1); - PC = 0x0004; - } + IRR |= INTNMI; } else if (irqline == UPD7810_INTF1) From adffc17cf5fd3887d06073480dae26c85e5202eb Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Sun, 2 Nov 2014 23:40:49 +0100 Subject: [PATCH 3/4] upd7810: correctly deal with external interrupts --- src/emu/cpu/upd7810/upd7810.c | 37 +++++++++++++++++++++++------------ src/emu/cpu/upd7810/upd7810.h | 5 +++-- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index ec7e136f5e4..319f08f78a6 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -1616,6 +1616,7 @@ void upd7810_device::base_device_start() save_item(NAME(m_ovcf)); save_item(NAME(m_ovcs)); save_item(NAME(m_edges)); + save_item(NAME(m_nmi)); save_item(NAME(m_int1)); save_item(NAME(m_int2)); @@ -1797,6 +1798,7 @@ void upd7810_device::device_reset() m_co1 = 0; m_irr = 0; m_itf = 0; + m_nmi = 0; m_int1 = 0; m_int2 = 0; @@ -1970,22 +1972,31 @@ void upd7801_device::execute_set_input(int irqline, int state) void upd7810_device::execute_set_input(int irqline, int state) { - if (state != CLEAR_LINE) - { - if (irqline == INPUT_LINE_NMI) - { - /* no nested NMIs ? */ -// if (0 == (IRR & INTNMI)) + switch (irqline) { + case INPUT_LINE_NMI: + /* NMI is falling edge sensitive */ + if ( m_nmi == ASSERT_LINE && state == CLEAR_LINE ) IRR |= INTNMI; - } - else - if (irqline == UPD7810_INTF1) + + m_nmi = state; + break; + case UPD7810_INTF1: + /* INT1 is rising edge sensitive */ + if ( m_int1 == CLEAR_LINE && state == ASSERT_LINE ) IRR |= INTF1; - else - if ( irqline == UPD7810_INTF2 && ( MKL & 0x20 ) ) + + m_int1 = state; + break; + case UPD7810_INTF2: + /* INT2 is falling edge sensitive */ + if ( m_int2 == ASSERT_LINE && state == CLEAR_LINE ) IRR |= INTF2; - else - logerror("upd7810_set_irq_line invalid irq line #%d\n", irqline); + + m_int2 = state; + break; + default: + logerror("upd7810_set_irq_line invalid irq line #%d\n", irqline); + break; } /* resetting interrupt requests is done with the SKIT/SKNIT opcodes only! */ } diff --git a/src/emu/cpu/upd7810/upd7810.h b/src/emu/cpu/upd7810/upd7810.h index f975c88c7c7..45dbbfc8df9 100644 --- a/src/emu/cpu/upd7810/upd7810.h +++ b/src/emu/cpu/upd7810/upd7810.h @@ -294,8 +294,9 @@ protected: UINT8 m_co1; UINT16 m_irr; /* interrupt request register */ UINT16 m_itf; /* interrupt test flag register */ - int m_int1; /* keep track of current int1 state. Needed for 7801 irq checking. */ - int m_int2; /* keep track to current int2 state. Needed for 7801 irq checking. */ + int m_nmi; /* keep track of current nmi state. Needed for 7810 irq checking. */ + int m_int1; /* keep track of current int1 state. Needed for irq checking. */ + int m_int2; /* keep track to current int2 state. Needed for irq checking. */ /* internal helper variables */ UINT16 m_txs; /* transmitter shift register */ From ff2a135bd3f748aff061cc3abfda43c8bc72d784 Mon Sep 17 00:00:00 2001 From: Ramiro Polla Date: Tue, 4 Nov 2014 19:47:28 +0100 Subject: [PATCH 4/4] upd7810: return meaningful value when PC3 is in control mode When PC3 is in control mode, it acts as INT2 and external Timer Input. INT2 may be set by connected devices through set_input_line(), so its value can be used when reading or writing to PC3. There is currently no code to support external timer input. --- src/emu/cpu/upd7810/upd7810.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/emu/cpu/upd7810/upd7810.c b/src/emu/cpu/upd7810/upd7810.c index 319f08f78a6..70bdeafe766 100644 --- a/src/emu/cpu/upd7810/upd7810.c +++ b/src/emu/cpu/upd7810/upd7810.c @@ -567,8 +567,8 @@ UINT8 upd7810_device::RP(offs_t port) data = (data & ~0x02) | (m_rxd & 1 ? 0x02 : 0x00); if (m_mcc & 0x04) /* PC2 = SCK input/output */ data = (data & ~0x04) | (m_sck & 1 ? 0x04 : 0x00); - if (m_mcc & 0x08) /* PC3 = TI input */ - data = (data & ~0x08) | (m_ti & 1 ? 0x08 : 0x00); + if (m_mcc & 0x08) /* PC3 = TI/INT2 input */ + data = (data & ~0x08) | (m_int2 & 1 ? 0x08 : 0x00); if (m_mcc & 0x10) /* PC4 = TO output */ data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00); if (m_mcc & 0x20) /* PC5 = CI input */ @@ -648,8 +648,8 @@ void upd7810_device::WP(offs_t port, UINT8 data) data = (data & ~0x02) | (m_rxd & 1 ? 0x02 : 0x00); if (m_mcc & 0x04) /* PC2 = SCK input/output */ data = (data & ~0x04) | (m_sck & 1 ? 0x04 : 0x00); - if (m_mcc & 0x08) /* PC3 = TI input */ - data = (data & ~0x08) | (m_ti & 1 ? 0x08 : 0x00); + if (m_mcc & 0x08) /* PC3 = TI/INT2 input */ + data = (data & ~0x08) | (m_int2 & 1 ? 0x08 : 0x00); if (m_mcc & 0x10) /* PC4 = TO output */ data = (data & ~0x10) | (m_to & 1 ? 0x10 : 0x00); if (m_mcc & 0x20) /* PC5 = CI input */