mirror of
https://github.com/holub/mame
synced 2025-04-22 16:31:49 +03:00
[CoCo 3] Fixed an issue clearing interrupts on the GIME implementation
The normal way to acknowledge a GIME interrupt is by reading from $FF92/3. However, the act of disabling interrupts by writing to the same registers will also do the trick, and we were not emulating this technique. Thanks to Glen Hewlett and Tim Lindner for helping to identify this problem
This commit is contained in:
parent
f1a1928505
commit
bf2309aa29
@ -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))
|
||||
change_gime_firq(m_firq | interrupt);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// change_gime_irq
|
||||
//-------------------------------------------------
|
||||
|
||||
void gime_base_device::change_gime_irq(uint8_t data)
|
||||
{
|
||||
// did the value actually change?
|
||||
if (m_irq != data)
|
||||
{
|
||||
m_firq |= interrupt;
|
||||
recalculate_firq();
|
||||
m_irq = data;
|
||||
m_write_irq(irq_r());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// recalculate_irq
|
||||
// change_gime_firq
|
||||
//-------------------------------------------------
|
||||
|
||||
void gime_base_device::recalculate_irq(void)
|
||||
void gime_base_device::change_gime_firq(uint8_t data)
|
||||
{
|
||||
m_write_irq(irq_r());
|
||||
// did the value actually change?
|
||||
if (m_firq != data)
|
||||
{
|
||||
m_firq = data;
|
||||
m_write_firq(firq_r());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// recalculate_firq
|
||||
//-------------------------------------------------
|
||||
|
||||
void gime_base_device::recalculate_firq(void)
|
||||
{
|
||||
m_write_firq(firq_r());
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// VIDEO STATE
|
||||
//**************************************************************************
|
||||
|
@ -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)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user