diff options
| author | 2025-08-15 12:43:41 +0300 | |
|---|---|---|
| committer | 2025-08-15 12:43:46 +0300 | |
| commit | f7400ab86a6daa0f128271cd86f7eecd825ac586 (patch) | |
| tree | a581ddf31410326beaef11cc205e6c265b569b29 | |
| parent | 14d8b5f6ba08baafb8871b9fbac3e8a99b188150 (diff) | |
machine/z8536: Fix counter/timer enable and interrupt error clear. [Curt Coder]
| -rw-r--r-- | src/devices/machine/z8536.cpp | 60 | ||||
| -rw-r--r-- | src/devices/machine/z8536.h | 46 |
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 }; |
