summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author ajrhacker <ajrhacker@users.noreply.github.com>2017-03-19 18:40:42 -0400
committer GitHub <noreply@github.com>2017-03-19 18:40:42 -0400
commitae6377b4381d4c0c17483e2b4bbbd6b364f1e3ce (patch)
tree87a583a81e388ebb29199de61231f468a1073d49
parentf1a1928505693d0a51ffbb228e5e0c8cd712731b (diff)
parentbf2309aa290c4b432c3e048d4d8d49688f201c65 (diff)
Merge pull request #2167 from npwoods/coco3_gime_fix_alternative_interrupt_clearing
[CoCo 3] Fixed an issue clearing interrupts on the GIME implementation
-rw-r--r--src/mame/video/gime.cpp84
-rw-r--r--src/mame/video/gime.h8
2 files changed, 49 insertions, 43 deletions
diff --git a/src/mame/video/gime.cpp b/src/mame/video/gime.cpp
index a4ccfdd9419..d79eb39f2a6 100644
--- a/src/mame/video/gime.cpp
+++ b/src/mame/video/gime.cpp
@@ -624,15 +624,15 @@ uint8_t gime_base_device::read(offs_t offset)
switch(offset & 0xF0)
{
case 0x00:
- data = read_gime_register(offset);
+ data = read_gime_register(offset); // $FF90 - $FF9F
break;
case 0x10:
- data = read_mmu_register(offset);
+ data = read_mmu_register(offset); // $FFA0 - $FFAF
break;
case 0x20:
- data = read_palette_register(offset);
+ data = read_palette_register(offset); // $FFB0 - $FFBF
break;
default:
@@ -656,22 +656,14 @@ inline uint8_t gime_base_device::read_gime_register(offs_t offset)
uint8_t result;
switch(offset)
{
- case 2: // read pending IRQs
+ case 2: // $FF92 - read pending IRQs
result = m_irq;
- if (result != 0x00)
- {
- m_irq = 0x00;
- recalculate_irq();
- }
+ change_gime_irq(0x00);
break;
- case 3: // read pending FIRQs
+ case 3: // $FF93 - read pending FIRQs
result = m_firq;
- if (result != 0x00)
- {
- m_firq = 0x00;
- recalculate_firq();
- }
+ change_gime_firq(0x00);
break;
#ifdef NOPE_NOT_READABLE
@@ -741,20 +733,20 @@ void gime_base_device::write(offs_t offset, uint8_t data)
switch(offset & 0xF0)
{
case 0x00:
- write_gime_register(offset & 0x0F, data);
+ write_gime_register(offset & 0x0F, data); // $FF90 - $FF9F
break;
case 0x10:
- write_mmu_register(offset & 0x0F, data);
+ write_mmu_register(offset & 0x0F, data); // $FFA0 - $FFAF
break;
case 0x20:
- write_palette_register(offset & 0x0F, data & 0x3F);
+ write_palette_register(offset & 0x0F, data & 0x3F); // $FFB0 - $FFBF
break;
case 0x30:
case 0x40:
- write_sam_register(offset - 0x30);
+ write_sam_register(offset - 0x30); // $FFC0 - $FFDF
break;
}
}
@@ -836,6 +828,13 @@ inline void gime_base_device::write_gime_register(offs_t offset, uint8_t data)
(data & 0x02) ? "EI1 " : "",
(data & 0x01) ? "EI0 " : "");
}
+
+ // While normally interrupts are acknowledged by reading from this
+ // register and not writing to it, the act of disabling these interrupts
+ // has the exact same effect
+ //
+ // Kudos to Glen Hewlett for identifying this problem
+ change_gime_irq(m_irq & data);
break;
case 0x03:
@@ -859,6 +858,13 @@ inline void gime_base_device::write_gime_register(offs_t offset, uint8_t data)
(data & 0x02) ? "EI1 " : "",
(data & 0x01) ? "EI0 " : "");
}
+
+ // While normally interrupts are acknowledged by reading from this
+ // register and not writing to it, the act of disabling these interrupts
+ // has the exact same effect
+ //
+ // Kudos to Glen Hewlett for identifying this problem
+ change_gime_firq(m_firq & data);
break;
case 0x04:
@@ -1041,52 +1047,52 @@ inline void gime_base_device::write_sam_register(offs_t offset)
}
-
//-------------------------------------------------
// interrupt_rising_edge
//-------------------------------------------------
void gime_base_device::interrupt_rising_edge(uint8_t interrupt)
{
- /* evaluate IRQ */
+ // evaluate IRQ
if ((m_gime_registers[0x00] & 0x20) && (m_gime_registers[0x02] & interrupt))
- {
- m_irq |= interrupt;
- recalculate_irq();
- }
+ change_gime_irq(m_irq | interrupt);
- /* evaluate FIRQ */
+ // evaluate FIRQ
if ((m_gime_registers[0x00] & 0x10) && (m_gime_registers[0x03] & interrupt))
- {
- m_firq |= interrupt;
- recalculate_firq();
- }
+ change_gime_firq(m_firq | interrupt);
}
-
//-------------------------------------------------
-// recalculate_irq
+// change_gime_irq
//-------------------------------------------------
-void gime_base_device::recalculate_irq(void)
+void gime_base_device::change_gime_irq(uint8_t data)
{
- m_write_irq(irq_r());
+ // did the value actually change?
+ if (m_irq != data)
+ {
+ m_irq = data;
+ m_write_irq(irq_r());
+ }
}
-
//-------------------------------------------------
-// recalculate_firq
+// change_gime_firq
//-------------------------------------------------
-void gime_base_device::recalculate_firq(void)
+void gime_base_device::change_gime_firq(uint8_t data)
{
- m_write_firq(firq_r());
+ // did the value actually change?
+ if (m_firq != data)
+ {
+ m_firq = data;
+ m_write_firq(firq_r());
+ }
}
-
//**************************************************************************
// VIDEO STATE
//**************************************************************************
diff --git a/src/mame/video/gime.h b/src/mame/video/gime.h
index 3e141df22a4..52e4aeca021 100644
--- a/src/mame/video/gime.h
+++ b/src/mame/video/gime.h
@@ -82,8 +82,8 @@ public:
bool update_rgb(bitmap_rgb32 &bitmap, const rectangle &cliprect);
// interrupt outputs
- bool firq_r(void) { return m_firq != 0x00; }
- bool irq_r(void) { return m_irq != 0x00; }
+ bool firq_r() const { return m_firq != 0x00; }
+ bool irq_r() const { return m_irq != 0x00; }
// interrupt inputs
void set_il0(bool value) { set_interrupt_value(INTERRUPT_EI0, value); }
@@ -233,8 +233,8 @@ private:
// interrupts
void interrupt_rising_edge(uint8_t interrupt);
- void recalculate_irq(void);
- void recalculate_firq(void);
+ void change_gime_irq(uint8_t data);
+ void change_gime_firq(uint8_t data);
ATTR_FORCE_INLINE void set_interrupt_value(uint8_t interrupt, bool value)
{