diff options
Diffstat (limited to 'src/devices/machine/z8536.cpp')
-rw-r--r-- | src/devices/machine/z8536.cpp | 156 |
1 files changed, 94 insertions, 62 deletions
diff --git a/src/devices/machine/z8536.cpp b/src/devices/machine/z8536.cpp index 038bfb4d55b..af1dd90c28a 100644 --- a/src/devices/machine/z8536.cpp +++ b/src/devices/machine/z8536.cpp @@ -66,7 +66,7 @@ static char const *const CTMS_DCS[] = { "Pulse", "One-shot", "Square Wave", "Do void cio_base_device::get_interrupt_vector() { - uint8_t vector = 0xff; + u8 vector = 0xff; if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_MIE) { @@ -194,22 +194,29 @@ void cio_base_device::check_interrupt() // read_register - read from register //------------------------------------------------- -uint8_t cio_base_device::read_register(offs_t offset) +u8 cio_base_device::read_register(offs_t offset) { - uint8_t data; + u8 data; switch (offset) { case PORT_A_DATA: - data = m_read_pa(0); + // TODO: take data path polarity into account + data = m_output[PORT_A]; + if (m_register[PORT_A_DATA_DIRECTION] != 0) + data = (data & ~m_register[PORT_A_DATA_DIRECTION]) | (m_read_pa() & m_register[PORT_A_DATA_DIRECTION]); break; case PORT_B_DATA: - data = m_read_pb(0); + // TODO: take data path polarity into account + data = m_output[PORT_B]; + if (m_register[PORT_B_DATA_DIRECTION] != 0) + data = (data & ~m_register[PORT_B_DATA_DIRECTION]) | (m_read_pb() & m_register[PORT_B_DATA_DIRECTION]); break; case PORT_C_DATA: - data = 0xf0 | (m_read_pc(0) & 0x0f); + // TODO: take data path polarity into account + data = 0xf0 | (m_read_pc() & 0x0f); break; case COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE: @@ -271,7 +278,7 @@ uint8_t cio_base_device::read_register(offs_t offset) // read_register - masked read from register //------------------------------------------------- -uint8_t cio_base_device::read_register(offs_t offset, uint8_t mask) +u8 cio_base_device::read_register(offs_t offset, u8 mask) { return read_register(offset) & mask; } @@ -281,7 +288,7 @@ uint8_t cio_base_device::read_register(offs_t offset, uint8_t mask) // write_register - write to register //------------------------------------------------- -void cio_base_device::write_register(offs_t offset, uint8_t data) +void cio_base_device::write_register(offs_t offset, u8 data) { switch (offset) { @@ -340,17 +347,17 @@ void cio_base_device::write_register(offs_t offset, uint8_t data) case PORT_C_DATA_PATH_POLARITY: LOG("%s CIO Port C Data Path Polarity: %02x\n", machine().describe_context(), data); - m_register[offset] = data; + m_register[offset] = data & 0x0f; break; case PORT_C_DATA_DIRECTION: LOG("%s CIO Port C Data Direction: %02x\n", machine().describe_context(), data); - m_register[offset] = data; + m_register[offset] = data & 0x0f; break; case PORT_C_SPECIAL_IO_CONTROL: LOG("%s CIO Port C Special I/O Control: %02x\n", machine().describe_context(), data); - m_register[offset] = data; + m_register[offset] = data & 0x0f; break; case PORT_A_COMMAND_AND_STATUS: @@ -422,20 +429,25 @@ void cio_base_device::write_register(offs_t offset, uint8_t data) break; case PORT_A_DATA: - m_write_pa((offs_t)0, data); + // TODO: take data path polarity into account + m_output[PORT_A] = data; + m_write_pa(data); break; case PORT_B_DATA: - m_write_pb((offs_t)0, data); + // TODO: take data path polarity into account + m_output[PORT_B] = data; + m_write_pb(data); break; case PORT_C_DATA: { - uint8_t mask = (data & 0xf0) | (data >> 4); + u8 mask = (data & 0xf0) | (data >> 4); m_output[PORT_C] = (m_output[PORT_C] & mask) | ((data & 0x0f) & (mask ^ 0xff)); - m_write_pc((offs_t)0, m_output[PORT_C]); + // TODO: take data path polarity into account + m_write_pc(m_output[PORT_C]); } break; @@ -552,9 +564,9 @@ void cio_base_device::write_register(offs_t offset, uint8_t data) // write_register - masked write to register //------------------------------------------------- -void cio_base_device::write_register(offs_t offset, uint8_t data, uint8_t mask) +void cio_base_device::write_register(offs_t offset, u8 data, u8 mask) { - uint8_t combined_data = (data & mask) | (m_register[offset] & (mask ^ 0xff)); + u8 combined_data = (data & mask) | (m_register[offset] & (mask ^ 0xff)); write_register(offset, combined_data); } @@ -564,7 +576,7 @@ void cio_base_device::write_register(offs_t offset, uint8_t data, uint8_t mask) // counter_enabled - is counter enabled? //------------------------------------------------- -bool cio_base_device::counter_enabled(device_timer_id id) +bool cio_base_device::counter_enabled(int id) { bool enabled = false; @@ -591,7 +603,7 @@ bool cio_base_device::counter_enabled(device_timer_id id) // counter_external_output - //------------------------------------------------- -bool cio_base_device::counter_external_output(device_timer_id id) +bool cio_base_device::counter_external_output(int id) { return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_EOE) ? true : false; } @@ -601,7 +613,7 @@ bool cio_base_device::counter_external_output(device_timer_id id) // counter_external_count - //------------------------------------------------- -bool cio_base_device::counter_external_count(device_timer_id id) +bool cio_base_device::counter_external_count(int id) { return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_ECE) ? true : false; } @@ -611,7 +623,7 @@ bool cio_base_device::counter_external_count(device_timer_id id) // counter_external_trigger - //------------------------------------------------- -bool cio_base_device::counter_external_trigger(device_timer_id id) +bool cio_base_device::counter_external_trigger(int id) { return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_ETE) ? true : false; } @@ -621,7 +633,7 @@ bool cio_base_device::counter_external_trigger(device_timer_id id) // counter_external_gate - //------------------------------------------------- -bool cio_base_device::counter_external_gate(device_timer_id id) +bool cio_base_device::counter_external_gate(int id) { return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_EDE) ? true : false; } @@ -631,7 +643,7 @@ bool cio_base_device::counter_external_gate(device_timer_id id) // counter_gated - //------------------------------------------------- -bool cio_base_device::counter_gated(device_timer_id id) +bool cio_base_device::counter_gated(int id) { return (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_GCB) ? true : false; } @@ -641,7 +653,7 @@ bool cio_base_device::counter_gated(device_timer_id id) // count - count down //------------------------------------------------- -void cio_base_device::count(device_timer_id id) +void cio_base_device::count(int id) { if (!counter_gated(id)) return; if (!(m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_CIP)) return; @@ -686,7 +698,7 @@ void cio_base_device::count(device_timer_id id) // trigger - //------------------------------------------------- -void cio_base_device::trigger(device_timer_id id) +void cio_base_device::trigger(int id) { // ignore triggers during countdown if retrigger is disabled if (!(m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_REB) && (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_CIP)) return; @@ -705,7 +717,7 @@ void cio_base_device::trigger(device_timer_id id) // gate - //------------------------------------------------- -void cio_base_device::gate(device_timer_id id, int state) +void cio_base_device::gate(int id, int state) { // TODO } @@ -717,9 +729,9 @@ void cio_base_device::gate(device_timer_id id, int state) void cio_base_device::match_pattern(int port) { - uint8_t pms = m_register[PORT_A_MODE_SPECIFICATION + (port << 3)]; - uint8_t pm = m_register[PORT_A_PATTERN_MASK + (port << 3)]; - uint8_t ddr = m_register[PORT_A_DATA_DIRECTION + (port << 3)]; + u8 pms = m_register[PORT_A_MODE_SPECIFICATION + (port << 3)]; + u8 pm = m_register[PORT_A_PATTERN_MASK + (port << 3)]; + u8 ddr = m_register[PORT_A_DATA_DIRECTION + (port << 3)]; switch ((pms & PMS_PMS_MASK) >> 1) { @@ -748,8 +760,8 @@ void cio_base_device::external_port_w(int port, int bit, int state) case PORT_A: case PORT_B: { - assert((PORT_A_DATA_DIRECTION + (port << 3)) >= 0 && (PORT_A_DATA_DIRECTION + (port << 3)) < ARRAY_LENGTH(m_register)); - uint8_t ddr = m_register[PORT_A_DATA_DIRECTION + (port << 3)]; + assert((PORT_A_DATA_DIRECTION + (port << 3)) >= 0 && (PORT_A_DATA_DIRECTION + (port << 3)) < std::size(m_register)); + u8 ddr = m_register[PORT_A_DATA_DIRECTION + (port << 3)]; if (!BIT(ddr, bit)) return; @@ -776,14 +788,14 @@ void cio_base_device::external_port_w(int port, int bit, int state) // cio_base_device - constructor //------------------------------------------------- -cio_base_device::cio_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock) : +cio_base_device::cio_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock) : device_t(mconfig, type, tag, owner, clock), m_write_irq(*this), - m_read_pa(*this), + m_read_pa(*this, 0), m_write_pa(*this), - m_read_pb(*this), + m_read_pb(*this, 0), m_write_pb(*this), - m_read_pc(*this), + m_read_pc(*this, 0), m_write_pc(*this), m_irq(CLEAR_LINE) { @@ -794,7 +806,7 @@ cio_base_device::cio_base_device(const machine_config &mconfig, device_type type // z8036_device - constructor //------------------------------------------------- -z8036_device::z8036_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +z8036_device::z8036_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : cio_base_device(mconfig, Z8036, tag, owner, clock) { } @@ -804,7 +816,7 @@ z8036_device::z8036_device(const machine_config &mconfig, const char *tag, devic // z8536_device - constructor //------------------------------------------------- -z8536_device::z8536_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) : +z8536_device::z8536_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) : cio_base_device(mconfig, Z8536, tag, owner, clock), device_z80daisy_interface(mconfig, *this) { @@ -826,18 +838,9 @@ void cio_base_device::device_start() } // allocate timer - m_timer = timer_alloc(); + m_timer = timer_alloc(FUNC(cio_base_device::advance_counters), this); m_timer->adjust(attotime::from_hz(clock() / 2), 0, attotime::from_hz(clock() / 2)); - // resolve callbacks - m_write_irq.resolve_safe(); - m_read_pa.resolve_safe(0); - m_write_pa.resolve_safe(); - m_read_pb.resolve_safe(0); - m_write_pb.resolve_safe(); - m_read_pc.resolve_safe(0); - m_write_pc.resolve_safe(); - save_item(NAME(m_irq)); save_item(NAME(m_register)); save_item(NAME(m_input)); @@ -871,6 +874,9 @@ void cio_base_device::device_reset() m_register[PORT_A_COMMAND_AND_STATUS] = PCS_ORE; m_register[PORT_B_COMMAND_AND_STATUS] = PCS_ORE; m_register[CURRENT_VECTOR] = 0xff; + m_register[PORT_A_DATA_DIRECTION] = 0xff; + m_register[PORT_B_DATA_DIRECTION] = 0xff; + m_register[PORT_C_DATA_DIRECTION] = 0x0f; check_interrupt(); } @@ -885,10 +891,10 @@ void z8536_device::device_reset() //------------------------------------------------- -// device_timer - handler timer events +// advance_counters - //------------------------------------------------- -void cio_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +TIMER_CALLBACK_MEMBER(cio_base_device::advance_counters) { if (counter_enabled(TIMER_1) && !counter_external_count(TIMER_1)) { @@ -919,6 +925,32 @@ void cio_base_device::device_timer(emu_timer &timer, device_timer_id id, int par int z8536_device::z80daisy_irq_state() { + static const int prio[] = + { + COUNTER_TIMER_3_COMMAND_AND_STATUS, + PORT_A_COMMAND_AND_STATUS, + COUNTER_TIMER_2_COMMAND_AND_STATUS, + PORT_B_COMMAND_AND_STATUS, + COUNTER_TIMER_1_COMMAND_AND_STATUS + }; + + if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_MIE) + { + for (int i = 0; i < 5; i++) + { + if (m_register[prio[i]] & PCS_IUS) + { + // we are currently servicing an interrupt request + return Z80_DAISY_IEO; + } + else if ((m_register[prio[i]] & PCS_IE) && (m_register[prio[i]] & PCS_IP)) + { + // indicate that we have an interrupt request waiting + return Z80_DAISY_INT; + } + } + } + return 0; } @@ -997,7 +1029,7 @@ int cio_base_device::intack_r() // read - register read (Z-Bus) //------------------------------------------------- -READ8_MEMBER( z8036_device::read ) +u8 z8036_device::read(offs_t offset) { return is_reset() ? 0 : read_register(offset); } @@ -1007,27 +1039,27 @@ READ8_MEMBER( z8036_device::read ) // read - register read (universal bus) //------------------------------------------------- -READ8_MEMBER( z8536_device::read ) +u8 z8536_device::read(offs_t offset) { - uint8_t data = 0; + u8 data = 0; if (!is_reset()) { switch (offset & 0x03) { - case 0: + case EXT_PORT_C: data = read_register(PORT_C_DATA); break; - case 1: + case EXT_PORT_B: data = read_register(PORT_B_DATA); break; - case 2: + case EXT_PORT_A: data = read_register(PORT_A_DATA); break; - case 3: + case EXT_CONTROL: // state 0 or state 1: read data data = read_register(m_pointer); @@ -1047,7 +1079,7 @@ READ8_MEMBER( z8536_device::read ) // write - register write (Z-Bus) //------------------------------------------------- -WRITE8_MEMBER( z8036_device::write ) +void z8036_device::write(offs_t offset, u8 data) { if (is_reset()) { @@ -1067,7 +1099,7 @@ WRITE8_MEMBER( z8036_device::write ) // write - register write (universal bus) //------------------------------------------------- -WRITE8_MEMBER( z8536_device::write ) +void z8536_device::write(offs_t offset, u8 data) { if (is_reset()) { @@ -1081,19 +1113,19 @@ WRITE8_MEMBER( z8536_device::write ) { switch (offset & 0x03) { - case PORT_C: + case EXT_PORT_C: write_register(PORT_C_DATA, data); break; - case PORT_B: + case EXT_PORT_B: write_register(PORT_B_DATA, data); break; - case PORT_A: + case EXT_PORT_A: write_register(PORT_A_DATA, data); break; - case CONTROL: + case EXT_CONTROL: if (m_state0) { // state 0: write pointer |