summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Curt Coder <curtcoder@mail.com>2025-08-15 12:43:41 +0300
committer Curt Coder <curtcoder@mail.com>2025-08-15 12:43:46 +0300
commitf7400ab86a6daa0f128271cd86f7eecd825ac586 (patch)
treea581ddf31410326beaef11cc205e6c265b569b29
parent14d8b5f6ba08baafb8871b9fbac3e8a99b188150 (diff)
machine/z8536: Fix counter/timer enable and interrupt error clear. [Curt Coder]
-rw-r--r--src/devices/machine/z8536.cpp60
-rw-r--r--src/devices/machine/z8536.h46
2 files changed, 59 insertions, 47 deletions
diff --git a/src/devices/machine/z8536.cpp b/src/devices/machine/z8536.cpp
index 6d4062b0a29..d69bc5d13ff 100644
--- a/src/devices/machine/z8536.cpp
+++ b/src/devices/machine/z8536.cpp
@@ -19,21 +19,6 @@
**********************************************************************/
-/*
-
- TODO:
-
- - interrupts
- - vector
- - status affects vector
- - IE/IP/IUS
- - acknowledge
- - daisy chain
- - port I/O
- - counters/timers
-
-*/
-
#include "emu.h"
#include "z8536.h"
@@ -276,6 +261,8 @@ u8 cio_base_device::read_register(offs_t offset)
break;
}
+ LOG("%s %s CIO Read Register %02x: %02x\n", machine().time().as_string(), machine().describe_context(), offset, data);
+
return data;
}
@@ -296,6 +283,8 @@ u8 cio_base_device::read_register(offs_t offset, u8 mask)
void cio_base_device::write_register(offs_t offset, u8 data)
{
+ LOG("%s CIO Write Register %02x: %02x\n", machine().time().as_string(), offset, data);
+
switch (offset)
{
case MASTER_INTERRUPT_CONTROL:
@@ -334,6 +323,22 @@ void cio_base_device::write_register(offs_t offset, u8 data)
// clear RCC bit if counter disabled
if (!counter_enabled(counter)) m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + counter] &= ~CTCS_RCC;
}
+
+ if (!(m_register[MASTER_CONFIGURATION_CONTROL] & MCCR_CT1E)) {
+ // clear count in progress bit
+ m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS] &= ~CTCS_CIP;
+ }
+
+ if (!(m_register[MASTER_CONFIGURATION_CONTROL] & MCCR_CT2E)) {
+ // clear count in progress bit
+ m_register[COUNTER_TIMER_2_COMMAND_AND_STATUS] &= ~CTCS_CIP;
+ }
+
+ if (!(m_register[MASTER_CONFIGURATION_CONTROL] & MCCR_PCE_CT3E)) {
+ // clear count in progress bit
+ m_register[COUNTER_TIMER_3_COMMAND_AND_STATUS] &= ~CTCS_CIP;
+ }
+
break;
case PORT_A_INTERRUPT_VECTOR:
@@ -403,13 +408,13 @@ void cio_base_device::write_register(offs_t offset, u8 data)
switch (data >> 5)
{
- case IC_CLEAR_IP_IUS: m_register[offset] &= ~(CTCS_IP | CTCS_IUS);LOG("%s CIO Counter/Timer %u Clear IP/IUS\n", machine().describe_context(), counter + 1); break;
- case IC_SET_IUS: m_register[offset] |= CTCS_IUS; LOG("%s CIO Counter/Timer %u Set IUS\n", machine().describe_context(), counter + 1); break;
- case IC_CLEAR_IUS: m_register[offset] &= ~CTCS_IUS; LOG("%s CIO Counter/Timer %u Clear IUS\n", machine().describe_context(), counter + 1); break;
- case IC_SET_IP: m_register[offset] |= CTCS_IP; LOG("%s CIO Counter/Timer %u Set IP\n", machine().describe_context(), counter + 1); break;
- case IC_CLEAR_IP: m_register[offset] &= ~CTCS_IP; LOG("%s CIO Counter/Timer %u Clear IP\n", machine().describe_context(), counter + 1); break;
- case IC_SET_IE: m_register[offset] |= CTCS_IE; LOG("%s CIO Counter/Timer %u Set IE\n", machine().describe_context(), counter + 1); break;
- case IC_CLEAR_IE: m_register[offset] &= ~CTCS_IE; LOG("%s CIO Counter/Timer %u Clear IE\n", machine().describe_context(), counter + 1); break;
+ case IC_CLEAR_IP_IUS: m_register[offset] &= ~(CTCS_IP | CTCS_ERR | CTCS_IUS); LOG("%s CIO Counter/Timer %u Clear IP/IUS\n", machine().describe_context(), counter + 1); break;
+ case IC_SET_IUS: m_register[offset] |= CTCS_IUS; LOG("%s CIO Counter/Timer %u Set IUS\n", machine().describe_context(), counter + 1); break;
+ case IC_CLEAR_IUS: m_register[offset] &= ~CTCS_IUS; LOG("%s CIO Counter/Timer %u Clear IUS\n", machine().describe_context(), counter + 1); break;
+ case IC_SET_IP: m_register[offset] |= CTCS_IP; LOG("%s CIO Counter/Timer %u Set IP\n", machine().describe_context(), counter + 1); break;
+ case IC_CLEAR_IP: m_register[offset] &= ~(CTCS_IP | CTCS_ERR); LOG("%s CIO Counter/Timer %u Clear IP\n", machine().describe_context(), counter + 1); break;
+ case IC_SET_IE: m_register[offset] |= CTCS_IE; LOG("%s CIO Counter/Timer %u Set IE\n", machine().describe_context(), counter + 1); break;
+ case IC_CLEAR_IE: m_register[offset] &= ~CTCS_IE; LOG("%s CIO Counter/Timer %u Clear IE\n", machine().describe_context(), counter + 1); break;
}
// gate command bit
@@ -666,17 +671,21 @@ void cio_base_device::count(int id)
// count down
m_counter[id]--;
+
+ LOG("%s CIO Counter/Timer %u Count %04x\n", machine().time().as_string(), id + 1, m_counter[id]);
if (m_counter[id] == 0)
{
if (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_IP)
{
+ LOG("%s CIO Counter/Timer %u Error\n", machine().time().as_string(), id + 1);
+
// set interrupt error bit
m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_ERR;
}
else
{
- LOG("%s CIO Counter/Timer %u Interrupt Pending\n", machine().describe_context(), id + 1);
+ LOG("%s CIO Counter/Timer %u Interrupt Pending\n", machine().time().as_string(), id + 1);
// set interrupt pending bit
m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_IP;
@@ -689,7 +698,7 @@ void cio_base_device::count(int id)
}
else
{
- LOG("%s CIO Counter/Timer %u Terminal Count\n", machine().describe_context(), id + 1);
+ LOG("%s CIO Counter/Timer %u Terminal Count\n", machine().time().as_string(), id + 1);
// clear count in progress bit
m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] &= ~CTCS_CIP;
@@ -706,6 +715,9 @@ void cio_base_device::count(int id)
void cio_base_device::trigger(int id)
{
+ // ignore trigger if counter/timer is not enabled
+ if (!counter_enabled(id)) return;
+
// 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;
diff --git a/src/devices/machine/z8536.h b/src/devices/machine/z8536.h
index 5a75a6c7456..fc984fed527 100644
--- a/src/devices/machine/z8536.h
+++ b/src/devices/machine/z8536.h
@@ -189,12 +189,12 @@ protected:
enum
{
MICR_RESET = 0x01, // reset
- MICR_RJA = 0x02, // right justified address
+ MICR_RJA = 0x02, // right justified address (TODO)
MICR_CT_VIS = 0x04, // counter/timer vector includes status
MICR_PB_VIS = 0x08, // port B vector includes status
MICR_PA_VIS = 0x10, // port A vector includes status
MICR_NV = 0x20, // no vector
- MICR_DLC = 0x40, // disable lower chain
+ MICR_DLC = 0x40, // disable lower chain (TODO)
MICR_MIE = 0x80 // master interrupt enable
};
@@ -202,35 +202,35 @@ protected:
// master configuration control register
enum
{
- MCCR_LC_MASK = 0x03, // counter/timer link controls
- MCCR_PAE = 0x04, // port A enable
- MCCR_PLC = 0x08, // port link control
+ MCCR_LC_MASK = 0x03, // counter/timer link controls (TODO)
+ MCCR_PAE = 0x04, // port A enable (TODO)
+ MCCR_PLC = 0x08, // port link control (TODO)
MCCR_PCE_CT3E = 0x10, // port C and counter/timer 3 enable
MCCR_CT2E = 0x20, // counter/timer 2 enable
MCCR_CT1E = 0x40, // counter/timer 1 enable
- MCCR_PBE = 0x80 // port B enable
+ MCCR_PBE = 0x80 // port B enable (TODO)
};
// port mode specification registers
enum
{
- PMS_LPM = 0x01, // latch on pattern match
- PMS_DTE = 0x01, // deskew timer enable
- PMS_PMS_MASK = 0x06, // pattern mode specification
- PMS_IMO = 0x08, // interrupt on match only
- PMS_SB = 0x10, // single buffer
- PMS_ITB = 0x20, // interrupt on two bytes
- PMS_PTS_MASK = 0xc0 // port type select
+ PMS_LPM = 0x01, // latch on pattern match (TODO)
+ PMS_DTE = 0x01, // deskew timer enable (TODO)
+ PMS_PMS_MASK = 0x06, // pattern mode specification (TODO)
+ PMS_IMO = 0x08, // interrupt on match only (TODO)
+ PMS_SB = 0x10, // single buffer (TODO)
+ PMS_ITB = 0x20, // interrupt on two bytes (TODO)
+ PMS_PTS_MASK = 0xc0 // port type select (TODO)
};
// port handshake specification registers
enum
{
- PHS_DTS_MASK = 0x07, // deskew time specification
- PHS_RWS_MASK = 0x38, // request/wait specification
- PHS_HTS_MASK = 0xc0 // handshake type specification
+ PHS_DTS_MASK = 0x07, // deskew time specification (TODO)
+ PHS_RWS_MASK = 0x38, // request/wait specification (TODO)
+ PHS_HTS_MASK = 0xc0 // handshake type specification (TODO)
};
@@ -238,8 +238,8 @@ protected:
enum
{
PCS_IOE = 0x01, // interrupt on error
- PCS_PMF = 0x02, // pattern match flag (read only)
- PCS_IRF = 0x04, // input register full (read only)
+ PCS_PMF = 0x02, // pattern match flag (read only) (TODO)
+ PCS_IRF = 0x04, // input register full (read only) (TODO)
PCS_ORE = 0x08, // output register empty (read only)
PCS_ERR = 0x10, // interrupt error (read only)
PCS_IP = 0x20, // interrupt pending
@@ -251,12 +251,12 @@ protected:
// counter/timer mode specification registers
enum
{
- CTMS_DCS_MASK = 0x03, // output duty cycle
+ CTMS_DCS_MASK = 0x03, // output duty cycle (TODO)
CTMS_REB = 0x04, // retrigger enable bit
- CTMS_EDE = 0x08, // external gate enable
- CTMS_ETE = 0x10, // external trigger enable
- CTMS_ECE = 0x20, // external count enable
- CTMS_EOE = 0x40, // external output enable
+ CTMS_EDE = 0x08, // external gate enable (TODO)
+ CTMS_ETE = 0x10, // external trigger enable (TODO)
+ CTMS_ECE = 0x20, // external count enable (TODO)
+ CTMS_EOE = 0x40, // external output enable (TODO)
CTMS_CSC = 0x80 // continuous/single cycle
};