summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
author Miodrag Milanovic <mmicko@gmail.com>2011-10-04 10:14:46 +0000
committer Miodrag Milanovic <mmicko@gmail.com>2011-10-04 10:14:46 +0000
commitb829e84ac6c456cc3949a6d61d80949149f66302 (patch)
treee0bd3a5e5b2c0c6318aa389b4a9a7cacd4172118 /src/emu
parent6730bf8cc77123a52c12cb05f8b6c23730438fc7 (diff)
Sync with MESS (no whatsnew)
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/machine/z8536.c824
-rw-r--r--src/emu/machine/z8536.h46
2 files changed, 829 insertions, 41 deletions
diff --git a/src/emu/machine/z8536.c b/src/emu/machine/z8536.c
index 979dce43e91..4c6ee8c0b6c 100644
--- a/src/emu/machine/z8536.c
+++ b/src/emu/machine/z8536.c
@@ -7,6 +7,21 @@
**********************************************************************/
+/*
+
+ TODO:
+
+ - interrupts
+ - vector
+ - status affects vector
+ - IE/IP/IUS
+ - acknowledge
+ - daisy chain
+ - port I/O
+ - counters/timers
+
+*/
+
#include "emu.h"
#include "z8536.h"
#include "machine/devhelpr.h"
@@ -20,6 +35,9 @@ const device_type Z8536 = &device_creator<z8536_device>;
// MACROS / CONSTANTS
//**************************************************************************
+#define LOG 1
+
+
// states
enum
{
@@ -93,6 +111,20 @@ enum
};
+// interrupt control
+enum
+{
+ IC_NULL = 0,
+ IC_CLEAR_IP_IUS,
+ IC_SET_IUS,
+ IC_CLEAR_IUS,
+ IC_SET_IP,
+ IC_CLEAR_IP,
+ IC_SET_IE,
+ IC_CLEAR_IE
+};
+
+
// counter/timer link control
enum
{
@@ -112,6 +144,8 @@ enum
PTS_BIDIRECTIONAL
};
+static const char *PMS_PTS[] = { "Bit", "Input", "Output", "Bidirectional" };
+
// pattern mode specification
enum
@@ -119,9 +153,11 @@ enum
PMS_DISABLE = 0,
PMS_AND,
PMS_OR,
- PMS_VECTOR
+ PMS_OR_PEV
};
+static const char *PMS_PMS[] = { "Disabled", "AND", "OR", "OR-PEV" };
+
// handshake specification
enum
@@ -166,6 +202,8 @@ enum
DCS_DO_NOT_USE
};
+static const char *CTMS_DCS[] = { "Pulse", "One-shot", "Square Wave", "Do not use" };
+
// master interrupt control register
#define MICR_RESET 0x01 // reset
@@ -190,6 +228,7 @@ enum
// port mode specification registers
#define PMS_LPM 0x01 // latch on pattern match
+#define PMS_DTE 0x01 // deskew timer enable
#define PMS_PMS_MASK 0x06 // pattern mode specification
#define PMS_IMO 0x08 // interrupt on match only
#define PMS_SB 0x10 // single buffer
@@ -221,7 +260,7 @@ enum
#define CTMS_ETE 0x10 // external trigger enable
#define CTMS_ECE 0x20 // external count enable
#define CTMS_EOE 0x40 // external output enable
-#define CTMS_CSC 0x80 // continuous single cycle
+#define CTMS_CSC 0x80 // continuous/single cycle
// counter/timer command and status registers
@@ -241,6 +280,136 @@ enum
//**************************************************************************
//-------------------------------------------------
+// get_interrupt_vector -
+//-------------------------------------------------
+
+inline void z8536_device::get_interrupt_vector()
+{
+ UINT8 vector = 0xff;
+
+ if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_MIE)
+ {
+ if ((m_register[COUNTER_TIMER_3_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE | CTCS_IUS)) == (CTCS_IP | CTCS_IE))
+ {
+ vector = m_register[COUNTER_TIMER_INTERRUPT_VECTOR];
+
+ if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_CT_VIS)
+ {
+ vector = (vector & 0xf9) | 0;
+ }
+ }
+ else if ((m_register[PORT_A_COMMAND_AND_STATUS] & (PCS_IP | PCS_IE | PCS_IUS)) == (PCS_IP | PCS_IE))
+ {
+ vector = m_register[PORT_A_INTERRUPT_VECTOR];
+
+ if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_PA_VIS)
+ {
+ vector &= 0xf1;
+
+ if (((m_register[PORT_A_MODE_SPECIFICATION] & PMS_PMS_MASK) >> 1) == PMS_OR_PEV)
+ {
+ if (m_match[PORT_A] & 0x80) vector |= 7 << 1;
+ else if (m_match[PORT_A] & 0x40) vector |= 6 << 1;
+ else if (m_match[PORT_A] & 0x20) vector |= 5 << 1;
+ else if (m_match[PORT_A] & 0x10) vector |= 4 << 1;
+ else if (m_match[PORT_A] & 0x08) vector |= 3 << 1;
+ else if (m_match[PORT_A] & 0x04) vector |= 2 << 1;
+ else if (m_match[PORT_A] & 0x02) vector |= 1 << 1;
+ else if (m_match[PORT_A] & 0x01) vector |= 0 << 1;
+ }
+ else
+ {
+ vector |= (m_register[PORT_A_COMMAND_AND_STATUS] & 0x0e);
+ }
+ }
+ }
+ else if ((m_register[COUNTER_TIMER_2_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE | CTCS_IUS)) == (CTCS_IP | CTCS_IE))
+ {
+ vector = m_register[COUNTER_TIMER_INTERRUPT_VECTOR];
+
+ if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_CT_VIS)
+ {
+ vector = (vector & 0xf9) | 2;
+ }
+ }
+ else if ((m_register[PORT_B_COMMAND_AND_STATUS] & (PCS_IP | PCS_IE | PCS_IUS)) == (PCS_IP | PCS_IE))
+ {
+ vector = m_register[PORT_B_INTERRUPT_VECTOR];
+
+ if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_PB_VIS)
+ {
+ vector &= 0xf1;
+
+ if (((m_register[PORT_B_MODE_SPECIFICATION] & PMS_PMS_MASK) >> 1) == PMS_OR_PEV)
+ {
+ if (m_match[PORT_B] & 0x80) vector |= 7 << 1;
+ else if (m_match[PORT_B] & 0x40) vector |= 6 << 1;
+ else if (m_match[PORT_B] & 0x20) vector |= 5 << 1;
+ else if (m_match[PORT_B] & 0x10) vector |= 4 << 1;
+ else if (m_match[PORT_B] & 0x08) vector |= 3 << 1;
+ else if (m_match[PORT_B] & 0x04) vector |= 2 << 1;
+ else if (m_match[PORT_B] & 0x02) vector |= 1 << 1;
+ else if (m_match[PORT_B] & 0x01) vector |= 0 << 1;
+ }
+ else
+ {
+ vector |= (m_register[PORT_B_COMMAND_AND_STATUS] & 0x0e);
+ }
+ }
+ }
+ else if ((m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE | CTCS_IUS)) == (CTCS_IP | CTCS_IE))
+ {
+ vector = m_register[COUNTER_TIMER_INTERRUPT_VECTOR];
+
+ if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_CT_VIS)
+ {
+ vector = (vector & 0xf9) | 4;
+ }
+ }
+ }
+
+ m_register[CURRENT_VECTOR] = vector;
+}
+
+
+//-------------------------------------------------
+// check_interrupt - check interrupt status
+//-------------------------------------------------
+
+inline void z8536_device::check_interrupt()
+{
+ int state = ASSERT_LINE;
+
+ if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_MIE)
+ {
+ if (((m_register[COUNTER_TIMER_3_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE | CTCS_IUS)) == (CTCS_IP | CTCS_IE)) ||
+ ((m_register[PORT_A_COMMAND_AND_STATUS] & (PCS_IP | PCS_IE | PCS_IUS)) == (PCS_IP | PCS_IE)) ||
+ ((m_register[COUNTER_TIMER_2_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE | CTCS_IUS)) == (CTCS_IP | CTCS_IE)) ||
+ ((m_register[PORT_B_COMMAND_AND_STATUS] & (PCS_IP | PCS_IE | PCS_IUS)) == (PCS_IP | PCS_IE)) ||
+ ((m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE | CTCS_IUS)) == (CTCS_IP | CTCS_IE)))
+ {
+ state = ASSERT_LINE;
+ }
+ else
+ {
+ state = CLEAR_LINE;
+ }
+ }
+ else
+ {
+ state = CLEAR_LINE;
+ }
+
+ if (m_int != state)
+ {
+ if (LOG) logerror("%s Z8536 '%s' Interrupt: %u\n", machine().describe_context(), tag(), state);
+ m_int = state;
+ m_out_int_func(state);
+ }
+}
+
+
+//-------------------------------------------------
// read_register - read from register
//-------------------------------------------------
@@ -248,8 +417,6 @@ inline UINT8 z8536_device::read_register(offs_t offset)
{
UINT8 data = 0;
- data = m_register[offset]; // HACK
-
switch (offset)
{
case PORT_A_DATA:
@@ -264,8 +431,55 @@ inline UINT8 z8536_device::read_register(offs_t offset)
data = 0xf0 | (m_in_pc_func(0) & 0x0f);
break;
+ case COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE:
+ case COUNTER_TIMER_2_CURRENT_COUNT_MS_BYTE:
+ case COUNTER_TIMER_3_CURRENT_COUNT_MS_BYTE:
+ {
+ int timer = (offset - COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE) >> 1;
+
+ if (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + timer] & CTCS_RCC)
+ {
+ // read frozen value
+ data = m_register[offset];
+ }
+ else
+ {
+ // read current count
+ data = m_counter[timer] >> 8;
+ }
+ }
+ break;
+
+ case COUNTER_TIMER_1_CURRENT_COUNT_LS_BYTE:
+ case COUNTER_TIMER_2_CURRENT_COUNT_LS_BYTE:
+ case COUNTER_TIMER_3_CURRENT_COUNT_LS_BYTE:
+ {
+ int timer = (offset - COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE) >> 1;
+
+ if (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + timer] & CTCS_RCC)
+ {
+ // read frozen value
+ data = m_register[offset];
+ }
+ else
+ {
+ // read current count
+ data = m_counter[timer] & 0xff;
+ }
+
+ // clear RCC bit
+ m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + timer] &= ~CTCS_RCC;
+ }
+ break;
+
+ case CURRENT_VECTOR:
+ get_interrupt_vector();
+ data = m_register[offset];
+ break;
+
default:
- logerror("Z8536 '%s' Unimplemented read from register %u\n", tag(), offset);
+ data = m_register[offset];
+ break;
}
return data;
@@ -293,11 +507,150 @@ inline void z8536_device::write_register(offs_t offset, UINT8 data)
case MASTER_INTERRUPT_CONTROL:
if (data & MICR_RESET)
{
+ if (LOG) logerror("%s Z8536 '%s' Reset\n", machine().describe_context(), tag());
device_reset();
}
- else if (m_state == STATE_RESET)
+ else
+ {
+ if (m_state == STATE_RESET)
+ {
+ m_state = STATE_0;
+ }
+
+ if (LOG)
+ {
+ if (LOG) logerror("%s Z8536 '%s' Master Interrupt Enable: %u\n", machine().describe_context(), tag(), (data & MICR_MIE) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Disable Lower Chain: %u\n", machine().describe_context(), tag(), (data & MICR_DLC) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' No Vector: %u\n", machine().describe_context(), tag(), (data & MICR_NV) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Port A Vector Includes Status: %u\n", machine().describe_context(), tag(), (data & MICR_PA_VIS) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Port B Vector Includes Status: %u\n", machine().describe_context(), tag(), (data & MICR_PB_VIS) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer Vector Includes Status: %u\n", machine().describe_context(), tag(), (data & MICR_CT_VIS) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Right Justified Address: %u\n", machine().describe_context(), tag(), (data & MICR_RJA) ? 1 : 0);
+ }
+
+ m_register[offset] = data;
+ }
+ break;
+
+ case MASTER_CONFIGURATION_CONTROL:
+ if (LOG)
+ {
+ if (LOG) logerror("%s Z8536 '%s' Port B Enable: %u\n", machine().describe_context(), tag(), (data & MCCR_PBE) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer 1 Enable: %u\n", machine().describe_context(), tag(), (data & MCCR_CT1E) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer 2 Enable: %u\n", machine().describe_context(), tag(), (data & MCCR_CT2E) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Port C and Counter/Timer 3 Enable: %u\n", machine().describe_context(), tag(), (data & MCCR_PCE_CT3E) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Port A Enable: %u\n", machine().describe_context(), tag(), (data & MCCR_PAE) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Port Link Control: %u\n", machine().describe_context(), tag(), (data & MCCR_PLC) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer Link Controls: %u\n", machine().describe_context(), tag(), data & MCCR_LC_MASK);
+ }
+
+ m_register[offset] = data;
+
+ for (int counter = 0; counter < 3; counter++)
+ {
+ // clear RCC bit if counter disabled
+ if (!counter_enabled(counter)) m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + counter] &= ~CTCS_RCC;
+ }
+ break;
+
+ case PORT_A_INTERRUPT_VECTOR:
+ if (LOG) logerror("%s Z8536 '%s' Port A Interrupt Vector: %02x\n", machine().describe_context(), tag(), data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_B_INTERRUPT_VECTOR:
+ if (LOG) logerror("%s Z8536 '%s' Port B Interrupt Vector: %02x\n", machine().describe_context(), tag(), data);
+ m_register[offset] = data;
+ break;
+
+ case COUNTER_TIMER_INTERRUPT_VECTOR:
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer Interrupt Vector: %02x\n", machine().describe_context(), tag(), data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_C_DATA_PATH_POLARITY:
+ if (LOG) logerror("%s Z8536 '%s' Port C Data Path Polarity: %02x\n", machine().describe_context(), tag(), data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_C_DATA_DIRECTION:
+ if (LOG) logerror("%s Z8536 '%s' Port C Data Direction: %02x\n", machine().describe_context(), tag(), data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_C_SPECIAL_IO_CONTROL:
+ if (LOG) logerror("%s Z8536 '%s' Port C Special I/O Control: %02x\n", machine().describe_context(), tag(), data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_A_COMMAND_AND_STATUS:
+ case PORT_B_COMMAND_AND_STATUS:
+ {
+ char port = 'A' + offset - PORT_A_COMMAND_AND_STATUS;
+
+ if (LOG) logerror("%s Z8536 '%s' Port %c Interrupt on Error: %u\n", machine().describe_context(), tag(), port, (data & PCS_IOE) ? 1 : 0);
+
+ switch (data >> 5)
+ {
+ case IC_CLEAR_IP_IUS: m_register[offset] &= ~(PCS_IP | PCS_IUS); if (LOG) logerror("%s Z8536 '%s' Port %c Clear IP/IUS\n", machine().describe_context(), tag(), port); break;
+ case IC_SET_IUS: m_register[offset] |= PCS_IUS; if (LOG) logerror("%s Z8536 '%s' Port %c Set IUS\n", machine().describe_context(), tag(), port); break;
+ case IC_CLEAR_IUS: m_register[offset] &= ~PCS_IUS; if (LOG) logerror("%s Z8536 '%s' Port %c Clear IUS\n", machine().describe_context(), tag(), port); break;
+ case IC_SET_IP: m_register[offset] |= PCS_IP; if (LOG) logerror("%s Z8536 '%s' Port %c Set IP\n", machine().describe_context(), tag(), port); break;
+ case IC_CLEAR_IP: m_register[offset] &= ~PCS_IP; if (LOG) logerror("%s Z8536 '%s' Port %c Clear IP\n", machine().describe_context(), tag(), port); break;
+ case IC_SET_IE: m_register[offset] |= PCS_IE; if (LOG) logerror("%s Z8536 '%s' Port %c Set IE\n", machine().describe_context(), tag(), port); break;
+ case IC_CLEAR_IE: m_register[offset] &= ~PCS_IE; if (LOG) logerror("%s Z8536 '%s' Port %c Clear IE\n", machine().describe_context(), tag(), port); break;
+ }
+
+ m_register[offset] = (m_register[offset] & ~PCS_IOE) | (data & PCS_IOE);
+
+ match_pattern(offset - PORT_A_COMMAND_AND_STATUS);
+ check_interrupt();
+ }
+ break;
+
+ case COUNTER_TIMER_1_COMMAND_AND_STATUS:
+ case COUNTER_TIMER_2_COMMAND_AND_STATUS:
+ case COUNTER_TIMER_3_COMMAND_AND_STATUS:
+ {
+ int counter = offset - COUNTER_TIMER_1_COMMAND_AND_STATUS;
+
+ if (LOG)
+ {
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Trigger Command Bit: %u\n", machine().describe_context(), tag(), counter + 1, (data & CTCS_TCB) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Gate Command Bit: %u\n", machine().describe_context(), tag(), counter + 1, (data & CTCS_GCB) ? 1 : 0);
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Read Counter Control: %u\n", machine().describe_context(), tag(), counter + 1, (data & CTCS_RCC) ? 1 : 0);
+ }
+
+ switch (data >> 5)
+ {
+ case IC_CLEAR_IP_IUS: m_register[offset] &= ~(CTCS_IP | CTCS_IUS);if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Clear IP/IUS\n", machine().describe_context(), tag(), counter + 1); break;
+ case IC_SET_IUS: m_register[offset] |= CTCS_IUS; if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Set IUS\n", machine().describe_context(), tag(), counter + 1); break;
+ case IC_CLEAR_IUS: m_register[offset] &= ~CTCS_IUS; if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Clear IUS\n", machine().describe_context(), tag(), counter + 1); break;
+ case IC_SET_IP: m_register[offset] |= CTCS_IP; if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Set IP\n", machine().describe_context(), tag(), counter + 1); break;
+ case IC_CLEAR_IP: m_register[offset] &= ~CTCS_IP; if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Clear IP\n", machine().describe_context(), tag(), counter + 1); break;
+ case IC_SET_IE: m_register[offset] |= CTCS_IE; if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Set IE\n", machine().describe_context(), tag(), counter + 1); break;
+ case IC_CLEAR_IE: m_register[offset] &= ~CTCS_IE; if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Clear IE\n", machine().describe_context(), tag(), counter + 1); break;
+ }
+
+ // gate command bit
+ m_register[offset] = (m_register[offset] & ~CTCS_GCB) | (data & CTCS_GCB);
+
+ // trigger command bit
+ if (data & CTCS_TCB)
{
- m_state = STATE_0;
+ trigger(counter);
+ }
+
+ // read counter control
+ if (counter_enabled(counter) && (data & CTCS_RCC))
+ {
+ // freeze current count register
+ m_register[offset] |= CTCS_RCC;
+ m_register[COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE + (counter << 1)] = m_counter[counter] >> 8;
+ m_register[COUNTER_TIMER_1_CURRENT_COUNT_LS_BYTE + (counter << 1)] = m_counter[counter] & 0xff;
+ }
+
+ check_interrupt();
}
break;
@@ -319,11 +672,120 @@ inline void z8536_device::write_register(offs_t offset, UINT8 data)
}
break;
+ case COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE:
+ case COUNTER_TIMER_2_TIME_CONSTANT_MS_BYTE:
+ case COUNTER_TIMER_3_TIME_CONSTANT_MS_BYTE:
+ if (LOG)
+ {
+ int counter = (offset - COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE) >> 1;
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Time Constant MSB: %02x\n", machine().describe_context(), tag(), counter + 1, data);
+ }
+
+ m_register[offset] = data;
+ break;
+
+ case COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE:
+ case COUNTER_TIMER_2_TIME_CONSTANT_LS_BYTE:
+ case COUNTER_TIMER_3_TIME_CONSTANT_LS_BYTE:
+ if (LOG)
+ {
+ int counter = (offset - COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE) >> 1;
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Time Constant LSB: %02x\n", machine().describe_context(), tag(), counter + 1, data);
+ }
+
+ m_register[offset] = data;
+ break;
+
+ case COUNTER_TIMER_1_MODE_SPECIFICATION:
+ case COUNTER_TIMER_2_MODE_SPECIFICATION:
+ case COUNTER_TIMER_3_MODE_SPECIFICATION:
+ if (LOG)
+ {
+ int counter = offset - COUNTER_TIMER_1_MODE_SPECIFICATION;
+ int dcs = data & CTMS_DCS_MASK;
+
+ logerror("%s Z8536 '%s' Counter/Timer %u Mode: %s\n", machine().describe_context(), tag(), counter + 1, (data & CTMS_CSC) ? "Continuous" : "Single Cycle");
+ logerror("%s Z8536 '%s' Counter/Timer %u External Output Enable: %u\n", machine().describe_context(), tag(), counter + 1, (data & CTMS_EOE) ? 1 : 0);
+ logerror("%s Z8536 '%s' Counter/Timer %u External Count Enable: %u\n", machine().describe_context(), tag(), counter + 1, (data & CTMS_ECE) ? 1 : 0);
+ logerror("%s Z8536 '%s' Counter/Timer %u External Trigger Enable: %u\n", machine().describe_context(), tag(), counter + 1, (data & CTMS_ETE) ? 1 : 0);
+ logerror("%s Z8536 '%s' Counter/Timer %u External Gate Enable: %u\n", machine().describe_context(), tag(), counter + 1, (data & CTMS_EDE) ? 1 : 0);
+ logerror("%s Z8536 '%s' Counter/Timer %u Retrigger Enable: %u\n", machine().describe_context(), tag(), counter + 1, (data & CTMS_REB) ? 1 : 0);
+ logerror("%s Z8536 '%s' Counter/Timer %u Output Duty Cycle: %s\n", machine().describe_context(), tag(), counter + 1, CTMS_DCS[dcs]);
+ }
+
+ m_register[offset] = data;
+ break;
+
+ case PORT_A_MODE_SPECIFICATION:
+ case PORT_B_MODE_SPECIFICATION:
+ if (LOG)
+ {
+ char port = BIT(offset, 3) ? 'B' : 'A';
+ int pts = (data & PMS_PTS_MASK) >> 6;
+ int pms = (data & PMS_PMS_MASK) >> 1;
+
+ logerror("%s Z8536 '%s' Port %c Port Type: %s\n", machine().describe_context(), tag(), port, PMS_PTS[pts]);
+ logerror("%s Z8536 '%s' Port %c Interrupt on 2 Bytes: %u\n", machine().describe_context(), tag(), port, (data & PMS_ITB) ? 1 : 0);
+ logerror("%s Z8536 '%s' Port %c Single Buffer: %u\n", machine().describe_context(), tag(), port, (data & PMS_SB) ? 1 : 0);
+ logerror("%s Z8536 '%s' Port %c Interrupt on Match Only: %u\n", machine().describe_context(), tag(), port, (data & PMS_IMO) ? 1 : 0);
+ logerror("%s Z8536 '%s' Port %c Pattern Mode: %s\n", machine().describe_context(), tag(), port, PMS_PMS[pms]);
+
+ if (pts == PTS_BIT)
+ logerror("%s Z8536 '%s' Port %c Latch on Pattern Match: %u\n", machine().describe_context(), tag(), port, (data & PMS_LPM) ? 1 : 0);
+ else
+ logerror("%s Z8536 '%s' Port %c Deskew Timer Enable: %u\n", machine().describe_context(), tag(), port, (data & PMS_DTE) ? 1 : 0);
+ }
+
+ m_register[offset] = data;
+ break;
+
+ case PORT_A_HANDSHAKE_SPECIFICATION:
+ case PORT_B_HANDSHAKE_SPECIFICATION:
+ // TODO
+ break;
+
+ case PORT_A_DATA_PATH_POLARITY:
+ case PORT_B_DATA_PATH_POLARITY:
+ if (LOG) logerror("%s Z8536 '%s' Port %c Data Path Polarity: %02x\n", machine().describe_context(), tag(), BIT(offset, 3) ? 'B' : 'A', data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_A_DATA_DIRECTION:
+ case PORT_B_DATA_DIRECTION:
+ if (LOG) logerror("%s Z8536 '%s' Port %c Data Direction: %02x\n", machine().describe_context(), tag(), BIT(offset, 3) ? 'B' : 'A', data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_A_SPECIAL_IO_CONTROL:
+ case PORT_B_SPECIAL_IO_CONTROL:
+ if (LOG) logerror("%s Z8536 '%s' Port %c Special I/O Control: %02x\n", machine().describe_context(), tag(), BIT(offset, 3) ? 'B' : 'A', data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_A_PATTERN_POLARITY:
+ case PORT_B_PATTERN_POLARITY:
+ if (LOG) logerror("%s Z8536 '%s' Port %c Pattern Polarity: %02x\n", machine().describe_context(), tag(), BIT(offset, 3) ? 'B' : 'A', data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_A_PATTERN_TRANSITION:
+ case PORT_B_PATTERN_TRANSITION:
+ if (LOG) logerror("%s Z8536 '%s' Port %c Pattern Transition: %02x\n", machine().describe_context(), tag(), BIT(offset, 3) ? 'B' : 'A', data);
+ m_register[offset] = data;
+ break;
+
+ case PORT_A_PATTERN_MASK:
+ case PORT_B_PATTERN_MASK:
+ if (LOG) logerror("%s Z8536 '%s' Port %c Pattern Mask: %02x\n", machine().describe_context(), tag(), BIT(offset, 3) ? 'B' : 'A', data);
+ m_register[offset] = data;
+ match_pattern(BIT(offset, 3));
+ check_interrupt();
+ break;
+
default:
- logerror("Z8536 '%s' Unimplemented write %02x to register %u\n", tag(), data, offset);
+ logerror("%s: Z8536 '%s' Unimplemented write %02x to register %u\n", machine().describe_context(), tag(), data, offset);
+ m_register[offset] = data;
}
-
- m_register[offset] = data; // HACK
}
@@ -340,11 +802,124 @@ inline void z8536_device::write_register(offs_t offset, UINT8 data, UINT8 mask)
//-------------------------------------------------
-// count -
+// counter_enabled - is counter enabled?
+//-------------------------------------------------
+
+inline bool z8536_device::counter_enabled(device_timer_id id)
+{
+ bool enabled = false;
+
+ switch (id)
+ {
+ case TIMER_1:
+ enabled = (m_register[MASTER_CONFIGURATION_CONTROL] & MCCR_CT1E) ? true : false;
+ break;
+
+ case TIMER_2:
+ enabled = (m_register[MASTER_CONFIGURATION_CONTROL] & MCCR_CT2E) ? true : false;
+ break;
+
+ case TIMER_3:
+ enabled = (m_register[MASTER_CONFIGURATION_CONTROL] & MCCR_PCE_CT3E) ? true : false;
+ break;
+ }
+
+ return enabled;
+}
+
+
+//-------------------------------------------------
+// counter_external_output -
+//-------------------------------------------------
+
+inline bool z8536_device::counter_external_output(device_timer_id id)
+{
+ return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_EOE) ? true : false;
+}
+
+
+//-------------------------------------------------
+// counter_external_count -
+//-------------------------------------------------
+
+inline bool z8536_device::counter_external_count(device_timer_id id)
+{
+ return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_ECE) ? true : false;
+}
+
+
+//-------------------------------------------------
+// counter_external_trigger -
+//-------------------------------------------------
+
+inline bool z8536_device::counter_external_trigger(device_timer_id id)
+{
+ return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_ETE) ? true : false;
+}
+
+
+//-------------------------------------------------
+// counter_external_gate -
+//-------------------------------------------------
+
+inline bool z8536_device::counter_external_gate(device_timer_id id)
+{
+ return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_EDE) ? true : false;
+}
+
+
+//-------------------------------------------------
+// counter_gated -
+//-------------------------------------------------
+
+inline bool z8536_device::counter_gated(device_timer_id id)
+{
+ return (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_GCB) ? true : false;
+}
+
+
+//-------------------------------------------------
+// count - count down
//-------------------------------------------------
inline void z8536_device::count(device_timer_id id)
{
+ if (!counter_gated(id)) return;
+ if (!m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_CIP) return;
+
+ // count down
+ m_counter[id]--;
+
+ if (m_counter[id] == 0)
+ {
+ if (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_IP)
+ {
+ // set interrupt error bit
+ m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_ERR;
+ }
+ else
+ {
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Interrupt Pending\n", machine().describe_context(), tag(), id + 1);
+
+ // set interrupt pending bit
+ m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_IP;
+ }
+
+ if (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_CSC)
+ {
+ // reload counter with time constant
+ m_counter[id] = (m_register[COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE + (id << 1)] << 8) | m_register[COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE + (id << 1)];
+ }
+ else
+ {
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Terminal Count\n", machine().describe_context(), tag(), id + 1);
+
+ // clear count in progress bit
+ m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] &= ~CTCS_CIP;
+ }
+
+ check_interrupt();
+ }
}
@@ -354,6 +929,16 @@ inline void z8536_device::count(device_timer_id id)
inline void z8536_device::trigger(device_timer_id 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;
+
+ if (LOG) logerror("%s Z8536 '%s' Counter/Timer %u Trigger\n", machine().describe_context(), tag(), id + 1);
+
+ // load counter with time constant
+ m_counter[id] = (m_register[COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE + (id << 1)] << 8) | m_register[COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE + (id << 1)];
+
+ // set count in progress bit
+ m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_CIP;
}
@@ -361,8 +946,64 @@ inline void z8536_device::trigger(device_timer_id id)
// gate -
//-------------------------------------------------
-inline void z8536_device::gate(device_timer_id id)
+inline void z8536_device::gate(device_timer_id id, int state)
{
+ // TODO
+}
+
+
+//-------------------------------------------------
+// match_pattern -
+//-------------------------------------------------
+
+inline void z8536_device::match_pattern(int port)
+{
+ UINT8 pms = m_register[PORT_A_MODE_SPECIFICATION + (port << 3)];
+ UINT8 pm = m_register[PORT_A_PATTERN_MASK + (port << 3)];
+ UINT8 ddr = m_register[PORT_A_DATA_DIRECTION + (port << 3)];
+
+ switch ((pms & PMS_PMS_MASK) >> 1)
+ {
+ case PMS_OR_PEV:
+ m_match[port] = m_input[port] & ddr & pm;
+
+ if (m_match[port])
+ {
+ if (LOG) logerror("%s Z8536 '%s' Port %c Interrupt Pending\n", machine().describe_context(), tag(), 'A' + port);
+ m_register[PORT_A_COMMAND_AND_STATUS + port] |= PCS_IP;
+ check_interrupt();
+ }
+ break;
+ }
+}
+
+
+//-------------------------------------------------
+// external_port_w - external port write
+//-------------------------------------------------
+
+inline void z8536_device::external_port_w(int port, int bit, int state)
+{
+ switch (port)
+ {
+ case PORT_A:
+ case PORT_B:
+ {
+ UINT8 ddr = m_register[PORT_A_DATA_DIRECTION + (port << 3)];
+
+ if (!BIT(ddr, bit)) return;
+
+ if (LOG) logerror("%s Z8536 '%s' Port %c Bit %u: %u\n", machine().describe_context(), tag(), 'A' + port, bit, state);
+
+ m_input[port] = (m_input[port] & ~(1 << bit)) | (state << bit);
+
+ match_pattern(port);
+ }
+ break;
+
+ case PORT_C:
+ break;
+ }
}
@@ -376,7 +1017,9 @@ inline void z8536_device::gate(device_timer_id id)
//-------------------------------------------------
z8536_device::z8536_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
- : device_t(mconfig, Z8536, "Zilog Z8536", tag, owner, clock)
+ : device_t(mconfig, Z8536, "Zilog Z8536", tag, owner, clock),
+ device_z80daisy_interface(mconfig, *this),
+ m_int(CLEAR_LINE)
{
}
@@ -414,10 +1057,17 @@ void z8536_device::device_config_complete()
void z8536_device::device_start()
{
- // allocate timers
- m_timer[TIMER_1] = timer_alloc(TIMER_1);
- m_timer[TIMER_2] = timer_alloc(TIMER_2);
- m_timer[TIMER_3] = timer_alloc(TIMER_3);
+ for (int i = 0; i < 3; i++)
+ {
+ m_input[i] = 0;
+ m_output[i] = 0;
+ m_buffer[i] = 0;
+ m_match[i] = 0;
+ }
+
+ // allocate timer
+ m_timer = timer_alloc();
+ m_timer->adjust(attotime::from_hz(clock() / 2), 0, attotime::from_hz(clock() / 2));
// resolve callbacks
m_out_int_func.resolve(m_out_int_cb, *this);
@@ -444,7 +1094,13 @@ void z8536_device::device_reset()
}
m_register[MASTER_INTERRUPT_CONTROL] = MICR_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_pointer = 0;
+
+ check_interrupt();
}
@@ -454,23 +1110,65 @@ void z8536_device::device_reset()
void z8536_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
{
- switch (id)
+ if (counter_enabled(TIMER_1) && !counter_external_count(TIMER_1))
{
- case TIMER_1:
count(TIMER_1);
- break;
+ }
- case TIMER_2:
+ if (counter_enabled(TIMER_2) && !counter_external_count(TIMER_2))
+ {
count(TIMER_2);
- break;
+ }
- case TIMER_3:
+ if (counter_enabled(TIMER_3) && !counter_external_count(TIMER_3))
+ {
count(TIMER_3);
- break;
}
}
+
+//**************************************************************************
+// DAISY CHAIN INTERFACE
+//**************************************************************************
+
+//-------------------------------------------------
+// z80daisy_irq_state - return the overall IRQ
+// state for this device
+//-------------------------------------------------
+
+int z8536_device::z80daisy_irq_state()
+{
+ return 0;
+}
+
+
+//-------------------------------------------------
+// z80daisy_irq_ack - acknowledge an IRQ and
+// return the appropriate vector
+//-------------------------------------------------
+
+int z8536_device::z80daisy_irq_ack()
+{
+ return intack_r();
+}
+
+
+//-------------------------------------------------
+// z80daisy_irq_reti - clear the interrupt
+// pending state to allow other interrupts through
+//-------------------------------------------------
+
+void z8536_device::z80daisy_irq_reti()
+{
+}
+
+
+
+//**************************************************************************
+// INTERNAL STATE MANAGEMENT
+//**************************************************************************
+
//-------------------------------------------------
// read - register read
//-------------------------------------------------
@@ -564,33 +1262,83 @@ WRITE8_MEMBER( z8536_device::write )
//-------------------------------------------------
-// intack_w - interrupt acknowledge
+// intack_r - interrupt acknowledge
//-------------------------------------------------
-WRITE_LINE_MEMBER( z8536_device::intack_w )
+int z8536_device::intack_r()
{
+ get_interrupt_vector();
+ int data = m_register[CURRENT_VECTOR];
+
+ if (LOG) logerror("%s Z8536 '%s' Interrupt Acknowledge: %02x\n", machine().describe_context(), tag(), data);
+
+ // set interrupt under service bit
+ if ((m_register[COUNTER_TIMER_3_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE)) == (CTCS_IP | CTCS_IE))
+ {
+ m_register[COUNTER_TIMER_3_COMMAND_AND_STATUS] |= CTCS_IUS;
+ }
+ else if ((m_register[PORT_A_COMMAND_AND_STATUS] & (PCS_IP | PCS_IE)) == (PCS_IP | PCS_IE))
+ {
+ m_register[PORT_A_COMMAND_AND_STATUS] |= PCS_IUS;
+ }
+ else if ((m_register[COUNTER_TIMER_2_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE)) == (CTCS_IP | CTCS_IE))
+ {
+ m_register[COUNTER_TIMER_2_COMMAND_AND_STATUS] |= CTCS_IUS;
+ }
+ else if ((m_register[PORT_B_COMMAND_AND_STATUS] & (PCS_IP | PCS_IE)) == (PCS_IP | PCS_IE))
+ {
+ m_register[PORT_B_COMMAND_AND_STATUS] |= PCS_IUS;
+ }
+ else if ((m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE)) == (CTCS_IP | CTCS_IE))
+ {
+ m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS] |= CTCS_IUS;
+ }
+
+ check_interrupt();
+
+ if (m_register[MASTER_INTERRUPT_CONTROL] & MICR_NV)
+ {
+ // no vector
+ data = -1;
+ }
+
+ return data;
}
//-------------------------------------------------
+// pa*_w - port A bits 0-7 write
+//-------------------------------------------------
+
+WRITE_LINE_MEMBER( z8536_device::pa0_w ) { external_port_w(PORT_A, 0, state); }
+WRITE_LINE_MEMBER( z8536_device::pa1_w ) { external_port_w(PORT_A, 1, state); }
+WRITE_LINE_MEMBER( z8536_device::pa2_w ) { external_port_w(PORT_A, 2, state); }
+WRITE_LINE_MEMBER( z8536_device::pa3_w ) { external_port_w(PORT_A, 3, state); }
+WRITE_LINE_MEMBER( z8536_device::pa4_w ) { external_port_w(PORT_A, 4, state); }
+WRITE_LINE_MEMBER( z8536_device::pa5_w ) { external_port_w(PORT_A, 5, state); }
+WRITE_LINE_MEMBER( z8536_device::pa6_w ) { external_port_w(PORT_A, 6, state); }
+WRITE_LINE_MEMBER( z8536_device::pa7_w ) { external_port_w(PORT_A, 7, state); }
+
+
+//-------------------------------------------------
// pb*_w - port B bits 0-7 write
//-------------------------------------------------
-WRITE_LINE_MEMBER( z8536_device::pb0_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pb1_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pb2_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pb3_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pb4_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pb5_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pb6_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pb7_w ) { }
+WRITE_LINE_MEMBER( z8536_device::pb0_w ) { external_port_w(PORT_B, 0, state); }
+WRITE_LINE_MEMBER( z8536_device::pb1_w ) { external_port_w(PORT_B, 1, state); }
+WRITE_LINE_MEMBER( z8536_device::pb2_w ) { external_port_w(PORT_B, 2, state); }
+WRITE_LINE_MEMBER( z8536_device::pb3_w ) { external_port_w(PORT_B, 3, state); }
+WRITE_LINE_MEMBER( z8536_device::pb4_w ) { external_port_w(PORT_B, 4, state); }
+WRITE_LINE_MEMBER( z8536_device::pb5_w ) { external_port_w(PORT_B, 5, state); }
+WRITE_LINE_MEMBER( z8536_device::pb6_w ) { external_port_w(PORT_B, 6, state); }
+WRITE_LINE_MEMBER( z8536_device::pb7_w ) { external_port_w(PORT_B, 7, state); }
//-------------------------------------------------
// pc*_w - port C bits 0-3 write
//-------------------------------------------------
-WRITE_LINE_MEMBER( z8536_device::pc0_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pc1_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pc2_w ) { }
-WRITE_LINE_MEMBER( z8536_device::pc3_w ) { }
+WRITE_LINE_MEMBER( z8536_device::pc0_w ) { external_port_w(PORT_C, 0, state); }
+WRITE_LINE_MEMBER( z8536_device::pc1_w ) { external_port_w(PORT_C, 1, state); }
+WRITE_LINE_MEMBER( z8536_device::pc2_w ) { external_port_w(PORT_C, 2, state); }
+WRITE_LINE_MEMBER( z8536_device::pc3_w ) { external_port_w(PORT_C, 3, state); }
diff --git a/src/emu/machine/z8536.h b/src/emu/machine/z8536.h
index 10862269ade..e4ff811e96d 100644
--- a/src/emu/machine/z8536.h
+++ b/src/emu/machine/z8536.h
@@ -36,6 +36,7 @@
#define __Z8536__
#include "emu.h"
+#include "cpu/z80/z80daisy.h"
@@ -83,6 +84,7 @@ struct z8536_interface
// ======================> z8536_device
class z8536_device : public device_t,
+ public device_z80daisy_interface,
public z8536_interface
{
public:
@@ -92,7 +94,16 @@ public:
DECLARE_READ8_MEMBER( read );
DECLARE_WRITE8_MEMBER( write );
- DECLARE_WRITE_LINE_MEMBER( intack_w );
+ int intack_r();
+
+ DECLARE_WRITE_LINE_MEMBER( pa0_w );
+ DECLARE_WRITE_LINE_MEMBER( pa1_w );
+ DECLARE_WRITE_LINE_MEMBER( pa2_w );
+ DECLARE_WRITE_LINE_MEMBER( pa3_w );
+ DECLARE_WRITE_LINE_MEMBER( pa4_w );
+ DECLARE_WRITE_LINE_MEMBER( pa5_w );
+ DECLARE_WRITE_LINE_MEMBER( pa6_w );
+ DECLARE_WRITE_LINE_MEMBER( pa7_w );
DECLARE_WRITE_LINE_MEMBER( pb0_w );
DECLARE_WRITE_LINE_MEMBER( pb1_w );
@@ -102,6 +113,7 @@ public:
DECLARE_WRITE_LINE_MEMBER( pb5_w );
DECLARE_WRITE_LINE_MEMBER( pb6_w );
DECLARE_WRITE_LINE_MEMBER( pb7_w );
+
DECLARE_WRITE_LINE_MEMBER( pc0_w );
DECLARE_WRITE_LINE_MEMBER( pc1_w );
DECLARE_WRITE_LINE_MEMBER( pc2_w );
@@ -114,19 +126,39 @@ protected:
virtual void device_reset();
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr);
+ // device_z80daisy_interface overrides
+ virtual int z80daisy_irq_state();
+ virtual int z80daisy_irq_ack();
+ virtual void z80daisy_irq_reti();
+
private:
static const device_timer_id TIMER_1 = 0;
static const device_timer_id TIMER_2 = 1;
static const device_timer_id TIMER_3 = 2;
+
+ static const int PORT_A = 0;
+ static const int PORT_B = 1;
+ static const int PORT_C = 2;
+
+ inline void get_interrupt_vector();
+ inline void check_interrupt();
inline UINT8 read_register(offs_t offset);
inline UINT8 read_register(offs_t offset, UINT8 mask);
inline void write_register(offs_t offset, UINT8 data);
inline void write_register(offs_t offset, UINT8 data, UINT8 mask);
+ inline bool counter_enabled(device_timer_id id);
+ inline bool counter_external_output(device_timer_id id);
+ inline bool counter_external_count(device_timer_id id);
+ inline bool counter_external_trigger(device_timer_id id);
+ inline bool counter_external_gate(device_timer_id id);
+ inline bool counter_gated(device_timer_id id);
inline void count(device_timer_id id);
inline void trigger(device_timer_id id);
- inline void gate(device_timer_id id);
+ inline void gate(device_timer_id id, int state);
+ inline void match_pattern(int port);
+ inline void external_port_w(int port, int bit, int state);
devcb_resolved_write_line m_out_int_func;
@@ -139,15 +171,23 @@ private:
devcb_resolved_read8 m_in_pc_func;
devcb_resolved_write8 m_out_pc_func;
+ // interrupt state
+ int m_int;
+
+ // register state
int m_state;
UINT8 m_register[48];
UINT8 m_pointer;
+
+ // input/output port state
UINT8 m_input[3];
UINT8 m_output[3];
UINT8 m_buffer[3];
+ UINT8 m_match[3];
// timers
- emu_timer *m_timer[3];
+ emu_timer *m_timer;
+ UINT16 m_counter[3];
};