summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/machine/z8536.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/machine/z8536.cpp')
-rw-r--r--src/devices/machine/z8536.cpp156
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