diff options
Diffstat (limited to 'src/devices/machine/6525tpi.cpp')
| -rw-r--r-- | src/devices/machine/6525tpi.cpp | 199 |
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)); } } } |
