summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/6525tpi.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/6525tpi.cpp')
-rw-r--r--src/devices/machine/6525tpi.cpp199
1 files changed, 64 insertions, 135 deletions
diff --git a/src/devices/machine/6525tpi.cpp b/src/devices/machine/6525tpi.cpp
index addebf837b1..ed399e0f27c 100644
--- a/src/devices/machine/6525tpi.cpp
+++ b/src/devices/machine/6525tpi.cpp
@@ -119,23 +119,17 @@ tpi6525_device::tpi6525_device(const machine_config &mconfig, const char *tag, d
m_out_cb_cb(*this),
m_port_a(0),
m_ddr_a(0),
- m_in_a(0),
+ m_in_a(0xff),
m_port_b(0),
m_ddr_b(0),
- m_in_b(0),
+ m_in_b(0xff),
m_port_c(0),
m_ddr_c(0),
- m_in_c(0),
- m_ca_level(0),
- m_cb_level(0),
- m_interrupt_level(0),
+ m_in_c(0xff),
m_cr(0),
- m_air(0)
+ m_air(0),
+ m_irq_latch(0)
{
- for (auto & elem : m_irq_level)
- {
- elem = 0;
- }
}
//-------------------------------------------------
@@ -144,12 +138,7 @@ tpi6525_device::tpi6525_device(const machine_config &mconfig, const char *tag, d
void tpi6525_device::device_start()
{
- /* setup some initial values */
- m_in_a = 0xff;
- m_in_b = 0xff;
- m_in_c = 0xff;
-
- /* register for state saving */
+ // register for state saving
save_item(NAME(m_port_a));
save_item(NAME(m_ddr_a));
save_item(NAME(m_in_a));
@@ -159,12 +148,9 @@ void tpi6525_device::device_start()
save_item(NAME(m_port_c));
save_item(NAME(m_ddr_c));
save_item(NAME(m_in_c));
- save_item(NAME(m_ca_level));
- save_item(NAME(m_cb_level));
- save_item(NAME(m_interrupt_level));
save_item(NAME(m_cr));
save_item(NAME(m_air));
- save_item(NAME(m_irq_level));
+ save_item(NAME(m_irq_latch));
}
//-------------------------------------------------
@@ -182,108 +168,74 @@ void tpi6525_device::device_reset()
void tpi6525_device::set_interrupt()
{
- if (!m_interrupt_level && (m_air != 0))
+ if ((BIT(m_irq_latch, 5) == 0) && (m_air != 0))
{
- m_interrupt_level = 1;
+ m_irq_latch |= 1 << 5;
DBG_LOG(machine(), 3, "tpi6525", ("%s set interrupt\n", tag()));
- m_out_irq_cb(m_interrupt_level);
+ m_out_irq_cb(1);
}
}
void tpi6525_device::clear_interrupt()
{
- if (m_interrupt_level && (m_air == 0))
+ if ((BIT(m_irq_latch, 5) == 1) && (m_air == 0))
{
- m_interrupt_level = 0;
+ m_irq_latch &= ~(1 << 5);
DBG_LOG(machine(), 3, "tpi6525", ("%s clear interrupt\n", tag()));
- m_out_irq_cb(m_interrupt_level);
- }
-}
-
-
-void tpi6525_device::i0_w(int state)
-{
- if (INTERRUPT_MODE && (state != m_irq_level[0]))
- {
- m_irq_level[0] = state;
-
- if ((state == 0) && !(m_air & 1) && (m_ddr_c & 1))
- {
- m_air |= 1;
- set_interrupt();
- }
+ m_out_irq_cb(0);
}
}
-void tpi6525_device::i1_w(int state)
+void tpi6525_device::portc_line_w(int line, int state)
{
- if (INTERRUPT_MODE && (state != m_irq_level[1]))
- {
- m_irq_level[1] = state;
-
- if ((state == 0) && !(m_air & 2) && (m_ddr_c & 2))
- {
- m_air |= 2;
- set_interrupt();
- }
- }
-}
-
+ bool active = false;
-void tpi6525_device::i2_w(int state)
-{
- if (INTERRUPT_MODE && (state != m_irq_level[2]))
+ switch (line)
{
- m_irq_level[2] = state;
-
- if ((state == 0) && !(m_air & 4) && (m_ddr_c & 4))
- {
- m_air |= 4;
- set_interrupt();
- }
+ case 0:
+ case 1:
+ case 2:
+ active = (state == 0) && (BIT(m_in_c, line) == 1);
+ break;
+
+ case 3:
+ if (INTERRUPT3_RISING_EDGE)
+ active = (state == 1) && (BIT(m_in_c, line) == 0);
+ else
+ active = (state == 0) && (BIT(m_in_c, line) == 1);
+ break;
+
+ case 4:
+ if (INTERRUPT4_RISING_EDGE)
+ active = (state == 1) && (BIT(m_in_c, line) == 0);
+ else
+ active = (state == 0) && (BIT(m_in_c, line) == 1);
+ break;
}
-}
+ m_in_c &= ~(1 << line);
+ m_in_c |= state << line;
-void tpi6525_device::i3_w(int state)
-{
- if (INTERRUPT_MODE && (state != m_irq_level[3]))
+ if (INTERRUPT_MODE && active)
{
- m_irq_level[3] = state;
+ m_irq_latch |= 1 << line;
- if (((INTERRUPT3_RISING_EDGE && (state == 1))
- || (!INTERRUPT3_RISING_EDGE && (state == 0)))
- && !(m_air & 8) && (m_ddr_c & 8))
+ // set interrupt if not yet active and not masked
+ if (BIT(m_air, line) == 0 && BIT(m_ddr_c, line) == 1)
{
- m_air |= 8;
+ m_air |= 1 << line;
set_interrupt();
}
}
}
-void tpi6525_device::i4_w(int state)
-{
- if (INTERRUPT_MODE && (state != m_irq_level[4]) )
- {
- m_irq_level[4] = state;
-
- if (((INTERRUPT4_RISING_EDGE && (state == 1))
- ||(!INTERRUPT4_RISING_EDGE&&(state == 0)))
- && !(m_air & 0x10) && (m_ddr_c & 0x10))
- {
- m_air |= 0x10;
- set_interrupt();
- }
- }
-}
-
uint8_t tpi6525_device::pa_r()
{
uint8_t data = m_in_a;
@@ -370,16 +322,7 @@ uint8_t tpi6525_device::read(offs_t offset)
case 2:
if (INTERRUPT_MODE)
{
- data = 0;
-
- if (m_irq_level[0]) data |= 0x01;
- if (m_irq_level[1]) data |= 0x02;
- if (m_irq_level[2]) data |= 0x04;
- if (m_irq_level[3]) data |= 0x08;
- if (m_irq_level[4]) data |= 0x10;
- if (!m_interrupt_level) data |= 0x20;
- if (m_ca_level) data |= 0x40;
- if (m_cb_level) data |= 0x80;
+ data = m_irq_latch;
}
else
{
@@ -413,36 +356,22 @@ uint8_t tpi6525_device::read(offs_t offset)
case 7: /* air */
if (PRIORIZED_INTERRUPTS)
{
- if (m_air & 0x10)
- {
- data = 0x10;
- m_air &= ~0x10;
- }
- else if (m_air & 8)
- {
- data = 8;
- m_air &= ~8;
- }
- else if (m_air & 4)
- {
- data = 4;
- m_air &= ~4;
- }
- else if (m_air & 2)
- {
- data = 2;
- m_air &= ~2;
- }
- else if (m_air & 1)
+ for (int i = 4; i >= 0; i--)
{
- data = 1;
- m_air &= ~1;
+ if (BIT(m_air, i))
+ {
+ data = 1 << i;
+ m_air &= ~(1 << i);
+ m_irq_latch &= ~(1 << i);
+ break;
+ }
}
}
else
{
data = m_air;
m_air = 0;
+ m_irq_latch &= 0xe0;
}
clear_interrupt();
@@ -481,12 +410,10 @@ void tpi6525_device::write(offs_t offset, uint8_t data)
}
else
{
- // clear latches
- if (BIT(data, 0) == 0) m_irq_level[0] = 1;
- if (BIT(data, 1) == 0) m_irq_level[1] = 1;
- if (BIT(data, 2) == 0) m_irq_level[2] = 1;
- if (BIT(data, 3) == 0) m_irq_level[3] = INTERRUPT3_RISING_EDGE ? 0 : 1;
- if (BIT(data, 4) == 0) m_irq_level[4] = INTERRUPT4_RISING_EDGE ? 0 : 1;
+ for (int i = 0; i <= 4; i++)
+ if (BIT(data, i) == 0)
+ m_irq_latch &= ~(1 << i);
+
}
break;
@@ -514,18 +441,20 @@ void tpi6525_device::write(offs_t offset, uint8_t data)
{
if (CA_MANUAL_OUT)
{
- if (m_ca_level != CA_MANUAL_LEVEL)
+ if (BIT(m_irq_latch, 6) != CA_MANUAL_LEVEL)
{
- m_ca_level = CA_MANUAL_LEVEL;
- m_out_ca_cb(m_ca_level);
+ m_irq_latch &= ~(1 << 6);
+ m_irq_latch |= CA_MANUAL_LEVEL << 6;
+ m_out_ca_cb(BIT(m_irq_latch, 6));
}
}
if (CB_MANUAL_OUT)
{
- if (m_cb_level != CB_MANUAL_LEVEL)
+ if (BIT(m_irq_latch, 7) != CB_MANUAL_LEVEL)
{
- m_cb_level = CB_MANUAL_LEVEL;
- m_out_cb_cb(m_cb_level);
+ m_irq_latch &= ~(1 << 7);
+ m_irq_latch |= CB_MANUAL_LEVEL << 7;
+ m_out_ca_cb(BIT(m_irq_latch, 7));
}
}
}