mirror of
https://github.com/holub/mame
synced 2025-05-18 19:49:35 +03:00
z8536: Various improvements (nw)
- Create provisional Z8036 variant for Z8000 bus compatibility, splitting out Z8536-specific state machine logic - Convert mask #defines into enums - Register device variables for save states - Add a few comments about the Z8036 and Z8536
This commit is contained in:
parent
e2d7b45434
commit
84e516a892
@ -2,7 +2,20 @@
|
|||||||
// copyright-holders:Curt Coder
|
// copyright-holders:Curt Coder
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
|
||||||
Zilog Z8536 Counter/Timer and Parallel I/O emulation
|
Zilog Z8036/Z8536 Counter/Timer and Parallel I/O Unit
|
||||||
|
|
||||||
|
Much like the SCC, two alternate versions of this peripheral
|
||||||
|
were developed by Zilog. The Z8036 (Z-CIO) was compatible with
|
||||||
|
the Z8000's address-latched Z-Bus and could write to any
|
||||||
|
register directly, while the Z8536 interfaced to a generic bus
|
||||||
|
using two address bits, requiring sequential writes to its
|
||||||
|
control register in order to access any of the internal registers
|
||||||
|
besides the three for port data.
|
||||||
|
|
||||||
|
Both versions of the CIO can be reset through hardware as well as
|
||||||
|
software, despite that neither provides a dedicated RESET pin.
|
||||||
|
Pulling AS and DS active low at the same time resets the Z8036,
|
||||||
|
and Z8536 is reset by activating RD and WR simultaneously.
|
||||||
|
|
||||||
**********************************************************************/
|
**********************************************************************/
|
||||||
|
|
||||||
@ -28,7 +41,8 @@
|
|||||||
#include "logmacro.h"
|
#include "logmacro.h"
|
||||||
|
|
||||||
|
|
||||||
// device type definition
|
// device type definitions
|
||||||
|
DEFINE_DEVICE_TYPE(Z8036, z8036_device, "z8036", "Zilog Z8036 Z-CIO")
|
||||||
DEFINE_DEVICE_TYPE(Z8536, z8536_device, "z8536", "Zilog Z8536 CIO")
|
DEFINE_DEVICE_TYPE(Z8536, z8536_device, "z8536", "Zilog Z8536 CIO")
|
||||||
|
|
||||||
|
|
||||||
@ -42,76 +56,6 @@ static char const *const PMS_PMS[] = { "Disabled", "AND", "OR", "OR-PEV" };
|
|||||||
static char const *const CTMS_DCS[] = { "Pulse", "One-shot", "Square Wave", "Do not use" };
|
static char const *const CTMS_DCS[] = { "Pulse", "One-shot", "Square Wave", "Do not use" };
|
||||||
|
|
||||||
|
|
||||||
// master interrupt control register
|
|
||||||
#define MICR_RESET 0x01 // reset
|
|
||||||
#define MICR_RJA 0x02 // right justified address
|
|
||||||
#define MICR_CT_VIS 0x04 // counter/timer vector includes status
|
|
||||||
#define MICR_PB_VIS 0x08 // port B vector includes status
|
|
||||||
#define MICR_PA_VIS 0x10 // port A vector includes status
|
|
||||||
#define MICR_NV 0x20 // no vector
|
|
||||||
#define MICR_DLC 0x40 // disable lower chain
|
|
||||||
#define MICR_MIE 0x80 // master interrupt enable
|
|
||||||
|
|
||||||
|
|
||||||
// master configuration control register
|
|
||||||
#define MCCR_LC_MASK 0x03 // counter/timer link controls
|
|
||||||
#define MCCR_PAE 0x04 // port A enable
|
|
||||||
#define MCCR_PLC 0x08 // port link control
|
|
||||||
#define MCCR_PCE_CT3E 0x10 // port C and counter/timer 3 enable
|
|
||||||
#define MCCR_CT2E 0x20 // counter/timer 2 enable
|
|
||||||
#define MCCR_CT1E 0x40 // counter/timer 1 enable
|
|
||||||
#define MCCR_PBE 0x80 // port B enable
|
|
||||||
|
|
||||||
|
|
||||||
// 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
|
|
||||||
#define PMS_ITB 0x20 // interrupt on two bytes
|
|
||||||
#define PMS_PTS_MASK 0xc0 // port type select
|
|
||||||
|
|
||||||
|
|
||||||
// port handshake specification registers
|
|
||||||
#define PHS_DTS_MASK 0x07 // deskew time specification
|
|
||||||
#define PHS_RWS_MASK 0x38 // request/wait specification
|
|
||||||
#define PHS_HTS_MASK 0xc0 // handshake type specification
|
|
||||||
|
|
||||||
|
|
||||||
// port command and status registers
|
|
||||||
#define PCS_IOE 0x01 // interrupt on error
|
|
||||||
#define PCS_PMF 0x02 // pattern match flag (read only)
|
|
||||||
#define PCS_IRF 0x04 // input register full (read only)
|
|
||||||
#define PCS_ORE 0x08 // output register empty (read only)
|
|
||||||
#define PCS_ERR 0x10 // interrupt error (read only)
|
|
||||||
#define PCS_IP 0x20 // interrupt pending
|
|
||||||
#define PCS_IE 0x40 // interrupt enable
|
|
||||||
#define PCS_IUS 0x80 // interrupt under service
|
|
||||||
|
|
||||||
|
|
||||||
// counter/timer mode specification registers
|
|
||||||
#define CTMS_DCS_MASK 0x03 // output duty cycle
|
|
||||||
#define CTMS_REB 0x04 // retrigger enable bit
|
|
||||||
#define CTMS_EDE 0x08 // external gate enable
|
|
||||||
#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
|
|
||||||
|
|
||||||
|
|
||||||
// counter/timer command and status registers
|
|
||||||
#define CTCS_CIP 0x01 // count in progress (read only)
|
|
||||||
#define CTCS_TCB 0x02 // trigger command bit (write only - read returns 0)
|
|
||||||
#define CTCS_GCB 0x04 // gate command bit
|
|
||||||
#define CTCS_RCC 0x08 // read counter control (read/set only - cleared by reading CCR LSB)
|
|
||||||
#define CTCS_ERR 0x10 // interrupt error (read only)
|
|
||||||
#define CTCS_IP 0x20 // interrupt pending
|
|
||||||
#define CTCS_IE 0x40 // interrupt enable
|
|
||||||
#define CTCS_IUS 0x80 // interrupt under service
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// INLINE HELPERS
|
// INLINE HELPERS
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
@ -120,7 +64,7 @@ static char const *const CTMS_DCS[] = { "Pulse", "One-shot", "Square Wave", "Do
|
|||||||
// get_interrupt_vector -
|
// get_interrupt_vector -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::get_interrupt_vector()
|
void cio_base_device::get_interrupt_vector()
|
||||||
{
|
{
|
||||||
uint8_t vector = 0xff;
|
uint8_t vector = 0xff;
|
||||||
|
|
||||||
@ -213,7 +157,7 @@ void z8536_device::get_interrupt_vector()
|
|||||||
// check_interrupt - check interrupt status
|
// check_interrupt - check interrupt status
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::check_interrupt()
|
void cio_base_device::check_interrupt()
|
||||||
{
|
{
|
||||||
int state;
|
int state;
|
||||||
|
|
||||||
@ -239,7 +183,7 @@ void z8536_device::check_interrupt()
|
|||||||
|
|
||||||
if (m_irq != state)
|
if (m_irq != state)
|
||||||
{
|
{
|
||||||
LOG("%s Z8536 Interrupt: %u\n", machine().describe_context(), state);
|
LOG("%s CIO Interrupt: %u\n", machine().describe_context(), state);
|
||||||
m_irq = state;
|
m_irq = state;
|
||||||
m_write_irq(state);
|
m_write_irq(state);
|
||||||
}
|
}
|
||||||
@ -250,7 +194,7 @@ void z8536_device::check_interrupt()
|
|||||||
// read_register - read from register
|
// read_register - read from register
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
uint8_t z8536_device::read_register(offs_t offset)
|
uint8_t cio_base_device::read_register(offs_t offset)
|
||||||
{
|
{
|
||||||
uint8_t data;
|
uint8_t data;
|
||||||
|
|
||||||
@ -327,7 +271,7 @@ uint8_t z8536_device::read_register(offs_t offset)
|
|||||||
// read_register - masked read from register
|
// read_register - masked read from register
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
uint8_t z8536_device::read_register(offs_t offset, uint8_t mask)
|
uint8_t cio_base_device::read_register(offs_t offset, uint8_t mask)
|
||||||
{
|
{
|
||||||
return read_register(offset) & mask;
|
return read_register(offset) & mask;
|
||||||
}
|
}
|
||||||
@ -337,43 +281,38 @@ uint8_t z8536_device::read_register(offs_t offset, uint8_t mask)
|
|||||||
// write_register - write to register
|
// write_register - write to register
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::write_register(offs_t offset, uint8_t data)
|
void cio_base_device::write_register(offs_t offset, uint8_t data)
|
||||||
{
|
{
|
||||||
switch (offset)
|
switch (offset)
|
||||||
{
|
{
|
||||||
case MASTER_INTERRUPT_CONTROL:
|
case MASTER_INTERRUPT_CONTROL:
|
||||||
if (data & MICR_RESET)
|
if (data & MICR_RESET)
|
||||||
{
|
{
|
||||||
LOG("%s Z8536 Reset\n", machine().describe_context());
|
LOG("%s CIO Reset\n", machine().describe_context());
|
||||||
device_reset();
|
device_reset();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (m_state == STATE_RESET)
|
LOG("%s CIO Master Interrupt Enable: %u\n", machine().describe_context(), (data & MICR_MIE) ? 1 : 0);
|
||||||
{
|
LOG("%s CIO Disable Lower Chain: %u\n", machine().describe_context(), (data & MICR_DLC) ? 1 : 0);
|
||||||
m_state = STATE_0;
|
LOG("%s CIO No Vector: %u\n", machine().describe_context(), (data & MICR_NV) ? 1 : 0);
|
||||||
}
|
LOG("%s CIO Port A Vector Includes Status: %u\n", machine().describe_context(), (data & MICR_PA_VIS) ? 1 : 0);
|
||||||
|
LOG("%s CIO Port B Vector Includes Status: %u\n", machine().describe_context(), (data & MICR_PB_VIS) ? 1 : 0);
|
||||||
LOG("%s Z8536 Master Interrupt Enable: %u\n", machine().describe_context(), (data & MICR_MIE) ? 1 : 0);
|
LOG("%s CIO Counter/Timer Vector Includes Status: %u\n", machine().describe_context(), (data & MICR_CT_VIS) ? 1 : 0);
|
||||||
LOG("%s Z8536 Disable Lower Chain: %u\n", machine().describe_context(), (data & MICR_DLC) ? 1 : 0);
|
LOG("%s CIO Right Justified Address: %u\n", machine().describe_context(), (data & MICR_RJA) ? 1 : 0);
|
||||||
LOG("%s Z8536 No Vector: %u\n", machine().describe_context(), (data & MICR_NV) ? 1 : 0);
|
|
||||||
LOG("%s Z8536 Port A Vector Includes Status: %u\n", machine().describe_context(), (data & MICR_PA_VIS) ? 1 : 0);
|
|
||||||
LOG("%s Z8536 Port B Vector Includes Status: %u\n", machine().describe_context(), (data & MICR_PB_VIS) ? 1 : 0);
|
|
||||||
LOG("%s Z8536 Counter/Timer Vector Includes Status: %u\n", machine().describe_context(), (data & MICR_CT_VIS) ? 1 : 0);
|
|
||||||
LOG("%s Z8536 Right Justified Address: %u\n", machine().describe_context(), (data & MICR_RJA) ? 1 : 0);
|
|
||||||
|
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MASTER_CONFIGURATION_CONTROL:
|
case MASTER_CONFIGURATION_CONTROL:
|
||||||
LOG("%s Z8536 Port B Enable: %u\n", machine().describe_context(), (data & MCCR_PBE) ? 1 : 0);
|
LOG("%s CIO Port B Enable: %u\n", machine().describe_context(), (data & MCCR_PBE) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer 1 Enable: %u\n", machine().describe_context(), (data & MCCR_CT1E) ? 1 : 0);
|
LOG("%s CIO Counter/Timer 1 Enable: %u\n", machine().describe_context(), (data & MCCR_CT1E) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer 2 Enable: %u\n", machine().describe_context(), (data & MCCR_CT2E) ? 1 : 0);
|
LOG("%s CIO Counter/Timer 2 Enable: %u\n", machine().describe_context(), (data & MCCR_CT2E) ? 1 : 0);
|
||||||
LOG("%s Z8536 Port C and Counter/Timer 3 Enable: %u\n", machine().describe_context(), (data & MCCR_PCE_CT3E) ? 1 : 0);
|
LOG("%s CIO Port C and Counter/Timer 3 Enable: %u\n", machine().describe_context(), (data & MCCR_PCE_CT3E) ? 1 : 0);
|
||||||
LOG("%s Z8536 Port A Enable: %u\n", machine().describe_context(), (data & MCCR_PAE) ? 1 : 0);
|
LOG("%s CIO Port A Enable: %u\n", machine().describe_context(), (data & MCCR_PAE) ? 1 : 0);
|
||||||
LOG("%s Z8536 Port Link Control: %u\n", machine().describe_context(), (data & MCCR_PLC) ? 1 : 0);
|
LOG("%s CIO Port Link Control: %u\n", machine().describe_context(), (data & MCCR_PLC) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer Link Controls: %u\n", machine().describe_context(), data & MCCR_LC_MASK);
|
LOG("%s CIO Counter/Timer Link Controls: %u\n", machine().describe_context(), data & MCCR_LC_MASK);
|
||||||
|
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
|
|
||||||
@ -385,32 +324,32 @@ void z8536_device::write_register(offs_t offset, uint8_t data)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_A_INTERRUPT_VECTOR:
|
case PORT_A_INTERRUPT_VECTOR:
|
||||||
LOG("%s Z8536 Port A Interrupt Vector: %02x\n", machine().describe_context(), data);
|
LOG("%s CIO Port A Interrupt Vector: %02x\n", machine().describe_context(), data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_B_INTERRUPT_VECTOR:
|
case PORT_B_INTERRUPT_VECTOR:
|
||||||
LOG("%s Z8536 Port B Interrupt Vector: %02x\n", machine().describe_context(), data);
|
LOG("%s CIO Port B Interrupt Vector: %02x\n", machine().describe_context(), data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case COUNTER_TIMER_INTERRUPT_VECTOR:
|
case COUNTER_TIMER_INTERRUPT_VECTOR:
|
||||||
LOG("%s Z8536 Counter/Timer Interrupt Vector: %02x\n", machine().describe_context(), data);
|
LOG("%s CIO Counter/Timer Interrupt Vector: %02x\n", machine().describe_context(), data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_C_DATA_PATH_POLARITY:
|
case PORT_C_DATA_PATH_POLARITY:
|
||||||
LOG("%s Z8536 Port C Data Path Polarity: %02x\n", machine().describe_context(), data);
|
LOG("%s CIO Port C Data Path Polarity: %02x\n", machine().describe_context(), data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_C_DATA_DIRECTION:
|
case PORT_C_DATA_DIRECTION:
|
||||||
LOG("%s Z8536 Port C Data Direction: %02x\n", machine().describe_context(), data);
|
LOG("%s CIO Port C Data Direction: %02x\n", machine().describe_context(), data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_C_SPECIAL_IO_CONTROL:
|
case PORT_C_SPECIAL_IO_CONTROL:
|
||||||
LOG("%s Z8536 Port C Special I/O Control: %02x\n", machine().describe_context(), data);
|
LOG("%s CIO Port C Special I/O Control: %02x\n", machine().describe_context(), data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -419,17 +358,17 @@ void z8536_device::write_register(offs_t offset, uint8_t data)
|
|||||||
{
|
{
|
||||||
char port = 'A' + offset - PORT_A_COMMAND_AND_STATUS;
|
char port = 'A' + offset - PORT_A_COMMAND_AND_STATUS;
|
||||||
|
|
||||||
LOG("%s Z8536 Port %c Interrupt on Error: %u\n", machine().describe_context(), port, (data & PCS_IOE) ? 1 : 0);
|
LOG("%s CIO Port %c Interrupt on Error: %u\n", machine().describe_context(), port, (data & PCS_IOE) ? 1 : 0);
|
||||||
|
|
||||||
switch (data >> 5)
|
switch (data >> 5)
|
||||||
{
|
{
|
||||||
case IC_CLEAR_IP_IUS: m_register[offset] &= ~(PCS_IP | PCS_IUS); LOG("%s Z8536 Port %c Clear IP/IUS\n", machine().describe_context(), port); break;
|
case IC_CLEAR_IP_IUS: m_register[offset] &= ~(PCS_IP | PCS_IUS); LOG("%s CIO Port %c Clear IP/IUS\n", machine().describe_context(), port); break;
|
||||||
case IC_SET_IUS: m_register[offset] |= PCS_IUS; LOG("%s Z8536 Port %c Set IUS\n", machine().describe_context(), port); break;
|
case IC_SET_IUS: m_register[offset] |= PCS_IUS; LOG("%s CIO Port %c Set IUS\n", machine().describe_context(), port); break;
|
||||||
case IC_CLEAR_IUS: m_register[offset] &= ~PCS_IUS; LOG("%s Z8536 Port %c Clear IUS\n", machine().describe_context(), port); break;
|
case IC_CLEAR_IUS: m_register[offset] &= ~PCS_IUS; LOG("%s CIO Port %c Clear IUS\n", machine().describe_context(), port); break;
|
||||||
case IC_SET_IP: m_register[offset] |= PCS_IP; LOG("%s Z8536 Port %c Set IP\n", machine().describe_context(), port); break;
|
case IC_SET_IP: m_register[offset] |= PCS_IP; LOG("%s CIO Port %c Set IP\n", machine().describe_context(), port); break;
|
||||||
case IC_CLEAR_IP: m_register[offset] &= ~PCS_IP; LOG("%s Z8536 Port %c Clear IP\n", machine().describe_context(), port); break;
|
case IC_CLEAR_IP: m_register[offset] &= ~PCS_IP; LOG("%s CIO Port %c Clear IP\n", machine().describe_context(), port); break;
|
||||||
case IC_SET_IE: m_register[offset] |= PCS_IE; LOG("%s Z8536 Port %c Set IE\n", machine().describe_context(), port); break;
|
case IC_SET_IE: m_register[offset] |= PCS_IE; LOG("%s CIO Port %c Set IE\n", machine().describe_context(), port); break;
|
||||||
case IC_CLEAR_IE: m_register[offset] &= ~PCS_IE; LOG("%s Z8536 Port %c Clear IE\n", machine().describe_context(), port); break;
|
case IC_CLEAR_IE: m_register[offset] &= ~PCS_IE; LOG("%s CIO Port %c Clear IE\n", machine().describe_context(), port); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_register[offset] = (m_register[offset] & ~PCS_IOE) | (data & PCS_IOE);
|
m_register[offset] = (m_register[offset] & ~PCS_IOE) | (data & PCS_IOE);
|
||||||
@ -445,19 +384,19 @@ void z8536_device::write_register(offs_t offset, uint8_t data)
|
|||||||
{
|
{
|
||||||
int counter = offset - COUNTER_TIMER_1_COMMAND_AND_STATUS;
|
int counter = offset - COUNTER_TIMER_1_COMMAND_AND_STATUS;
|
||||||
|
|
||||||
LOG("%s Z8536 Counter/Timer %u Trigger Command Bit: %u\n", machine().describe_context(), counter + 1, (data & CTCS_TCB) ? 1 : 0);
|
LOG("%s CIO Counter/Timer %u Trigger Command Bit: %u\n", machine().describe_context(), counter + 1, (data & CTCS_TCB) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer %u Gate Command Bit: %u\n", machine().describe_context(), counter + 1, (data & CTCS_GCB) ? 1 : 0);
|
LOG("%s CIO Counter/Timer %u Gate Command Bit: %u\n", machine().describe_context(), counter + 1, (data & CTCS_GCB) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer %u Read Counter Control: %u\n", machine().describe_context(), counter + 1, (data & CTCS_RCC) ? 1 : 0);
|
LOG("%s CIO Counter/Timer %u Read Counter Control: %u\n", machine().describe_context(), counter + 1, (data & CTCS_RCC) ? 1 : 0);
|
||||||
|
|
||||||
switch (data >> 5)
|
switch (data >> 5)
|
||||||
{
|
{
|
||||||
case IC_CLEAR_IP_IUS: m_register[offset] &= ~(CTCS_IP | CTCS_IUS);LOG("%s Z8536 Counter/Timer %u Clear IP/IUS\n", machine().describe_context(), counter + 1); break;
|
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 Z8536 Counter/Timer %u Set 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 Z8536 Counter/Timer %u Clear 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 Z8536 Counter/Timer %u Set IP\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 Z8536 Counter/Timer %u Clear 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 Z8536 Counter/Timer %u Set IE\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 Z8536 Counter/Timer %u Clear 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
|
// gate command bit
|
||||||
@ -503,7 +442,7 @@ void z8536_device::write_register(offs_t offset, uint8_t data)
|
|||||||
case COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE:
|
case COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE:
|
||||||
case COUNTER_TIMER_2_TIME_CONSTANT_MS_BYTE:
|
case COUNTER_TIMER_2_TIME_CONSTANT_MS_BYTE:
|
||||||
case COUNTER_TIMER_3_TIME_CONSTANT_MS_BYTE:
|
case COUNTER_TIMER_3_TIME_CONSTANT_MS_BYTE:
|
||||||
LOG("%s Z8536 Counter/Timer %u Time Constant MSB: %02x\n", machine().describe_context(), ((offset - COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE) >> 1) + 1, data);
|
LOG("%s CIO Counter/Timer %u Time Constant MSB: %02x\n", machine().describe_context(), ((offset - COUNTER_TIMER_1_TIME_CONSTANT_MS_BYTE) >> 1) + 1, data);
|
||||||
|
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
@ -511,7 +450,7 @@ void z8536_device::write_register(offs_t offset, uint8_t data)
|
|||||||
case COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE:
|
case COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE:
|
||||||
case COUNTER_TIMER_2_TIME_CONSTANT_LS_BYTE:
|
case COUNTER_TIMER_2_TIME_CONSTANT_LS_BYTE:
|
||||||
case COUNTER_TIMER_3_TIME_CONSTANT_LS_BYTE:
|
case COUNTER_TIMER_3_TIME_CONSTANT_LS_BYTE:
|
||||||
LOG("%s Z8536 Counter/Timer %u Time Constant LSB: %02x\n", machine().describe_context(), ((offset - COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE) >> 1) + 1, data);
|
LOG("%s CIO Counter/Timer %u Time Constant LSB: %02x\n", machine().describe_context(), ((offset - COUNTER_TIMER_1_TIME_CONSTANT_LS_BYTE) >> 1) + 1, data);
|
||||||
|
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
@ -524,13 +463,13 @@ void z8536_device::write_register(offs_t offset, uint8_t data)
|
|||||||
int const counter = offset - COUNTER_TIMER_1_MODE_SPECIFICATION;
|
int const counter = offset - COUNTER_TIMER_1_MODE_SPECIFICATION;
|
||||||
int const dcs = data & CTMS_DCS_MASK;
|
int const dcs = data & CTMS_DCS_MASK;
|
||||||
|
|
||||||
LOG("%s Z8536 Counter/Timer %u Mode: %s\n", machine().describe_context(), counter + 1, (data & CTMS_CSC) ? "Continuous" : "Single Cycle");
|
LOG("%s CIO Counter/Timer %u Mode: %s\n", machine().describe_context(), counter + 1, (data & CTMS_CSC) ? "Continuous" : "Single Cycle");
|
||||||
LOG("%s Z8536 Counter/Timer %u External Output Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_EOE) ? 1 : 0);
|
LOG("%s CIO Counter/Timer %u External Output Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_EOE) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer %u External Count Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_ECE) ? 1 : 0);
|
LOG("%s CIO Counter/Timer %u External Count Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_ECE) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer %u External Trigger Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_ETE) ? 1 : 0);
|
LOG("%s CIO Counter/Timer %u External Trigger Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_ETE) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer %u External Gate Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_EDE) ? 1 : 0);
|
LOG("%s CIO Counter/Timer %u External Gate Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_EDE) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer %u Retrigger Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_REB) ? 1 : 0);
|
LOG("%s CIO Counter/Timer %u Retrigger Enable: %u\n", machine().describe_context(), counter + 1, (data & CTMS_REB) ? 1 : 0);
|
||||||
LOG("%s Z8536 Counter/Timer %u Output Duty Cycle: %s\n", machine().describe_context(), counter + 1, CTMS_DCS[dcs]);
|
LOG("%s CIO Counter/Timer %u Output Duty Cycle: %s\n", machine().describe_context(), counter + 1, CTMS_DCS[dcs]);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
@ -544,16 +483,16 @@ void z8536_device::write_register(offs_t offset, uint8_t data)
|
|||||||
int const pts = (data & PMS_PTS_MASK) >> 6;
|
int const pts = (data & PMS_PTS_MASK) >> 6;
|
||||||
int const pms = (data & PMS_PMS_MASK) >> 1;
|
int const pms = (data & PMS_PMS_MASK) >> 1;
|
||||||
|
|
||||||
LOG("%s Z8536 Port %c Port Type: %s\n", machine().describe_context(), port, PMS_PTS[pts]);
|
LOG("%s CIO Port %c Port Type: %s\n", machine().describe_context(), port, PMS_PTS[pts]);
|
||||||
LOG("%s Z8536 Port %c Interrupt on 2 Bytes: %u\n", machine().describe_context(), port, (data & PMS_ITB) ? 1 : 0);
|
LOG("%s CIO Port %c Interrupt on 2 Bytes: %u\n", machine().describe_context(), port, (data & PMS_ITB) ? 1 : 0);
|
||||||
LOG("%s Z8536 Port %c Single Buffer: %u\n", machine().describe_context(), port, (data & PMS_SB) ? 1 : 0);
|
LOG("%s CIO Port %c Single Buffer: %u\n", machine().describe_context(), port, (data & PMS_SB) ? 1 : 0);
|
||||||
LOG("%s Z8536 Port %c Interrupt on Match Only: %u\n", machine().describe_context(), port, (data & PMS_IMO) ? 1 : 0);
|
LOG("%s CIO Port %c Interrupt on Match Only: %u\n", machine().describe_context(), port, (data & PMS_IMO) ? 1 : 0);
|
||||||
LOG("%s Z8536 Port %c Pattern Mode: %s\n", machine().describe_context(), port, PMS_PMS[pms]);
|
LOG("%s CIO Port %c Pattern Mode: %s\n", machine().describe_context(), port, PMS_PMS[pms]);
|
||||||
|
|
||||||
if (pts == PTS_BIT)
|
if (pts == PTS_BIT)
|
||||||
LOG("%s Z8536 Port %c Latch on Pattern Match: %u\n", machine().describe_context(), port, (data & PMS_LPM) ? 1 : 0);
|
LOG("%s CIO Port %c Latch on Pattern Match: %u\n", machine().describe_context(), port, (data & PMS_LPM) ? 1 : 0);
|
||||||
else
|
else
|
||||||
LOG("%s Z8536 Port %c Deskew Timer Enable: %u\n", machine().describe_context(), port, (data & PMS_DTE) ? 1 : 0);
|
LOG("%s CIO Port %c Deskew Timer Enable: %u\n", machine().describe_context(), port, (data & PMS_DTE) ? 1 : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
@ -566,37 +505,37 @@ void z8536_device::write_register(offs_t offset, uint8_t data)
|
|||||||
|
|
||||||
case PORT_A_DATA_PATH_POLARITY:
|
case PORT_A_DATA_PATH_POLARITY:
|
||||||
case PORT_B_DATA_PATH_POLARITY:
|
case PORT_B_DATA_PATH_POLARITY:
|
||||||
LOG("%s Z8536 Port %c Data Path Polarity: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
LOG("%s CIO Port %c Data Path Polarity: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_A_DATA_DIRECTION:
|
case PORT_A_DATA_DIRECTION:
|
||||||
case PORT_B_DATA_DIRECTION:
|
case PORT_B_DATA_DIRECTION:
|
||||||
LOG("%s Z8536 Port %c Data Direction: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
LOG("%s CIO Port %c Data Direction: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_A_SPECIAL_IO_CONTROL:
|
case PORT_A_SPECIAL_IO_CONTROL:
|
||||||
case PORT_B_SPECIAL_IO_CONTROL:
|
case PORT_B_SPECIAL_IO_CONTROL:
|
||||||
LOG("%s Z8536 Port %c Special I/O Control: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
LOG("%s CIO Port %c Special I/O Control: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_A_PATTERN_POLARITY:
|
case PORT_A_PATTERN_POLARITY:
|
||||||
case PORT_B_PATTERN_POLARITY:
|
case PORT_B_PATTERN_POLARITY:
|
||||||
LOG("%s Z8536 Port %c Pattern Polarity: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
LOG("%s CIO Port %c Pattern Polarity: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_A_PATTERN_TRANSITION:
|
case PORT_A_PATTERN_TRANSITION:
|
||||||
case PORT_B_PATTERN_TRANSITION:
|
case PORT_B_PATTERN_TRANSITION:
|
||||||
LOG("%s Z8536 Port %c Pattern Transition: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
LOG("%s CIO Port %c Pattern Transition: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PORT_A_PATTERN_MASK:
|
case PORT_A_PATTERN_MASK:
|
||||||
case PORT_B_PATTERN_MASK:
|
case PORT_B_PATTERN_MASK:
|
||||||
LOG("%s Z8536 Port %c Pattern Mask: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
LOG("%s CIO Port %c Pattern Mask: %02x\n", machine().describe_context(), BIT(offset, 3) ? 'B' : 'A', data);
|
||||||
m_register[offset] = data;
|
m_register[offset] = data;
|
||||||
match_pattern(BIT(offset, 3));
|
match_pattern(BIT(offset, 3));
|
||||||
check_interrupt();
|
check_interrupt();
|
||||||
@ -613,7 +552,7 @@ void z8536_device::write_register(offs_t offset, uint8_t data)
|
|||||||
// write_register - masked write to register
|
// write_register - masked write to register
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::write_register(offs_t offset, uint8_t data, uint8_t mask)
|
void cio_base_device::write_register(offs_t offset, uint8_t data, uint8_t mask)
|
||||||
{
|
{
|
||||||
uint8_t combined_data = (data & mask) | (m_register[offset] & (mask ^ 0xff));
|
uint8_t combined_data = (data & mask) | (m_register[offset] & (mask ^ 0xff));
|
||||||
|
|
||||||
@ -625,7 +564,7 @@ void z8536_device::write_register(offs_t offset, uint8_t data, uint8_t mask)
|
|||||||
// counter_enabled - is counter enabled?
|
// counter_enabled - is counter enabled?
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool z8536_device::counter_enabled(device_timer_id id)
|
bool cio_base_device::counter_enabled(device_timer_id id)
|
||||||
{
|
{
|
||||||
bool enabled = false;
|
bool enabled = false;
|
||||||
|
|
||||||
@ -652,7 +591,7 @@ bool z8536_device::counter_enabled(device_timer_id id)
|
|||||||
// counter_external_output -
|
// counter_external_output -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool z8536_device::counter_external_output(device_timer_id id)
|
bool cio_base_device::counter_external_output(device_timer_id id)
|
||||||
{
|
{
|
||||||
return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_EOE) ? true : false;
|
return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_EOE) ? true : false;
|
||||||
}
|
}
|
||||||
@ -662,7 +601,7 @@ bool z8536_device::counter_external_output(device_timer_id id)
|
|||||||
// counter_external_count -
|
// counter_external_count -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool z8536_device::counter_external_count(device_timer_id id)
|
bool cio_base_device::counter_external_count(device_timer_id id)
|
||||||
{
|
{
|
||||||
return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_ECE) ? true : false;
|
return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_ECE) ? true : false;
|
||||||
}
|
}
|
||||||
@ -672,7 +611,7 @@ bool z8536_device::counter_external_count(device_timer_id id)
|
|||||||
// counter_external_trigger -
|
// counter_external_trigger -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool z8536_device::counter_external_trigger(device_timer_id id)
|
bool cio_base_device::counter_external_trigger(device_timer_id id)
|
||||||
{
|
{
|
||||||
return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_ETE) ? true : false;
|
return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_ETE) ? true : false;
|
||||||
}
|
}
|
||||||
@ -682,7 +621,7 @@ bool z8536_device::counter_external_trigger(device_timer_id id)
|
|||||||
// counter_external_gate -
|
// counter_external_gate -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool z8536_device::counter_external_gate(device_timer_id id)
|
bool cio_base_device::counter_external_gate(device_timer_id id)
|
||||||
{
|
{
|
||||||
return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_EDE) ? true : false;
|
return (m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_EDE) ? true : false;
|
||||||
}
|
}
|
||||||
@ -692,7 +631,7 @@ bool z8536_device::counter_external_gate(device_timer_id id)
|
|||||||
// counter_gated -
|
// counter_gated -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
bool z8536_device::counter_gated(device_timer_id id)
|
bool cio_base_device::counter_gated(device_timer_id id)
|
||||||
{
|
{
|
||||||
return (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_GCB) ? true : false;
|
return (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_GCB) ? true : false;
|
||||||
}
|
}
|
||||||
@ -702,7 +641,7 @@ bool z8536_device::counter_gated(device_timer_id id)
|
|||||||
// count - count down
|
// count - count down
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::count(device_timer_id id)
|
void cio_base_device::count(device_timer_id id)
|
||||||
{
|
{
|
||||||
if (!counter_gated(id)) return;
|
if (!counter_gated(id)) return;
|
||||||
if (!(m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_CIP)) return;
|
if (!(m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_CIP)) return;
|
||||||
@ -719,7 +658,7 @@ void z8536_device::count(device_timer_id id)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG("%s Z8536 Counter/Timer %u Interrupt Pending\n", machine().describe_context(), id + 1);
|
LOG("%s CIO Counter/Timer %u Interrupt Pending\n", machine().describe_context(), id + 1);
|
||||||
|
|
||||||
// set interrupt pending bit
|
// set interrupt pending bit
|
||||||
m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_IP;
|
m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] |= CTCS_IP;
|
||||||
@ -732,7 +671,7 @@ void z8536_device::count(device_timer_id id)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LOG("%s Z8536 Counter/Timer %u Terminal Count\n", machine().describe_context(), id + 1);
|
LOG("%s CIO Counter/Timer %u Terminal Count\n", machine().describe_context(), id + 1);
|
||||||
|
|
||||||
// clear count in progress bit
|
// clear count in progress bit
|
||||||
m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] &= ~CTCS_CIP;
|
m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] &= ~CTCS_CIP;
|
||||||
@ -747,12 +686,12 @@ void z8536_device::count(device_timer_id id)
|
|||||||
// trigger -
|
// trigger -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::trigger(device_timer_id id)
|
void cio_base_device::trigger(device_timer_id id)
|
||||||
{
|
{
|
||||||
// ignore triggers during countdown if retrigger is disabled
|
// 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 (!(m_register[COUNTER_TIMER_1_MODE_SPECIFICATION + id] & CTMS_REB) && (m_register[COUNTER_TIMER_1_COMMAND_AND_STATUS + id] & CTCS_CIP)) return;
|
||||||
|
|
||||||
LOG("%s Z8536 Counter/Timer %u Trigger\n", machine().describe_context(), id + 1);
|
LOG("%s CIO Counter/Timer %u Trigger\n", machine().describe_context(), id + 1);
|
||||||
|
|
||||||
// load counter with time constant
|
// 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)];
|
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)];
|
||||||
@ -766,7 +705,7 @@ void z8536_device::trigger(device_timer_id id)
|
|||||||
// gate -
|
// gate -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::gate(device_timer_id id, int state)
|
void cio_base_device::gate(device_timer_id id, int state)
|
||||||
{
|
{
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
@ -776,7 +715,7 @@ void z8536_device::gate(device_timer_id id, int state)
|
|||||||
// match_pattern -
|
// match_pattern -
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::match_pattern(int port)
|
void cio_base_device::match_pattern(int port)
|
||||||
{
|
{
|
||||||
uint8_t pms = m_register[PORT_A_MODE_SPECIFICATION + (port << 3)];
|
uint8_t pms = m_register[PORT_A_MODE_SPECIFICATION + (port << 3)];
|
||||||
uint8_t pm = m_register[PORT_A_PATTERN_MASK + (port << 3)];
|
uint8_t pm = m_register[PORT_A_PATTERN_MASK + (port << 3)];
|
||||||
@ -789,7 +728,7 @@ void z8536_device::match_pattern(int port)
|
|||||||
|
|
||||||
if (m_match[port])
|
if (m_match[port])
|
||||||
{
|
{
|
||||||
LOG("%s Z8536 Port %c Interrupt Pending\n", machine().describe_context(), 'A' + port);
|
LOG("%s CIO Port %c Interrupt Pending\n", machine().describe_context(), 'A' + port);
|
||||||
m_register[PORT_A_COMMAND_AND_STATUS + port] |= PCS_IP;
|
m_register[PORT_A_COMMAND_AND_STATUS + port] |= PCS_IP;
|
||||||
check_interrupt();
|
check_interrupt();
|
||||||
}
|
}
|
||||||
@ -802,7 +741,7 @@ void z8536_device::match_pattern(int port)
|
|||||||
// external_port_w - external port write
|
// external_port_w - external port write
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::external_port_w(int port, int bit, int state)
|
void cio_base_device::external_port_w(int port, int bit, int state)
|
||||||
{
|
{
|
||||||
switch (port)
|
switch (port)
|
||||||
{
|
{
|
||||||
@ -814,7 +753,7 @@ void z8536_device::external_port_w(int port, int bit, int state)
|
|||||||
|
|
||||||
if (!BIT(ddr, bit)) return;
|
if (!BIT(ddr, bit)) return;
|
||||||
|
|
||||||
LOG("%s Z8536 Port %c Bit %u: %u\n", machine().describe_context(), 'A' + port, bit, state);
|
LOG("%s CIO Port %c Bit %u: %u\n", machine().describe_context(), 'A' + port, bit, state);
|
||||||
|
|
||||||
m_input[port] = (m_input[port] & ~(1 << bit)) | (state << bit);
|
m_input[port] = (m_input[port] & ~(1 << bit)) | (state << bit);
|
||||||
|
|
||||||
@ -834,12 +773,11 @@ void z8536_device::external_port_w(int port, int bit, int state)
|
|||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// z8536_device - constructor
|
// cio_base_device - constructor
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
z8536_device::z8536_device(const machine_config &mconfig, 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, uint32_t clock) :
|
||||||
device_t(mconfig, Z8536, tag, owner, clock),
|
device_t(mconfig, type, tag, owner, clock),
|
||||||
device_z80daisy_interface(mconfig, *this),
|
|
||||||
m_write_irq(*this),
|
m_write_irq(*this),
|
||||||
m_read_pa(*this),
|
m_read_pa(*this),
|
||||||
m_write_pa(*this),
|
m_write_pa(*this),
|
||||||
@ -852,11 +790,32 @@ z8536_device::z8536_device(const machine_config &mconfig, const char *tag, devic
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// z8036_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
z8036_device::z8036_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
cio_base_device(mconfig, Z8036, tag, owner, clock)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// z8536_device - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
z8536_device::z8536_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
|
||||||
|
cio_base_device(mconfig, Z8536, tag, owner, clock),
|
||||||
|
device_z80daisy_interface(mconfig, *this)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// device_start - device-specific startup
|
// device_start - device-specific startup
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::device_start()
|
void cio_base_device::device_start()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 3; i++)
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
@ -878,6 +837,22 @@ void z8536_device::device_start()
|
|||||||
m_write_pb.resolve_safe();
|
m_write_pb.resolve_safe();
|
||||||
m_read_pc.resolve_safe(0);
|
m_read_pc.resolve_safe(0);
|
||||||
m_write_pc.resolve_safe();
|
m_write_pc.resolve_safe();
|
||||||
|
|
||||||
|
save_item(NAME(m_irq));
|
||||||
|
save_item(NAME(m_register));
|
||||||
|
save_item(NAME(m_input));
|
||||||
|
save_item(NAME(m_output));
|
||||||
|
save_item(NAME(m_buffer));
|
||||||
|
save_item(NAME(m_match));
|
||||||
|
save_item(NAME(m_counter));
|
||||||
|
}
|
||||||
|
|
||||||
|
void z8536_device::device_start()
|
||||||
|
{
|
||||||
|
cio_base_device::device_start();
|
||||||
|
|
||||||
|
save_item(NAME(m_state0));
|
||||||
|
save_item(NAME(m_pointer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -885,10 +860,8 @@ void z8536_device::device_start()
|
|||||||
// device_start - device-specific reset
|
// device_start - device-specific reset
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::device_reset()
|
void cio_base_device::device_reset()
|
||||||
{
|
{
|
||||||
m_state = STATE_RESET;
|
|
||||||
|
|
||||||
for (auto & elem : m_register)
|
for (auto & elem : m_register)
|
||||||
{
|
{
|
||||||
elem = 0;
|
elem = 0;
|
||||||
@ -899,17 +872,23 @@ void z8536_device::device_reset()
|
|||||||
m_register[PORT_B_COMMAND_AND_STATUS] = PCS_ORE;
|
m_register[PORT_B_COMMAND_AND_STATUS] = PCS_ORE;
|
||||||
m_register[CURRENT_VECTOR] = 0xff;
|
m_register[CURRENT_VECTOR] = 0xff;
|
||||||
|
|
||||||
m_pointer = 0;
|
|
||||||
|
|
||||||
check_interrupt();
|
check_interrupt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void z8536_device::device_reset()
|
||||||
|
{
|
||||||
|
m_pointer = 0;
|
||||||
|
m_state0 = false;
|
||||||
|
|
||||||
|
cio_base_device::device_reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// device_timer - handler timer events
|
// device_timer - handler timer events
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
void z8536_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
void cio_base_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
|
||||||
{
|
{
|
||||||
if (counter_enabled(TIMER_1) && !counter_external_count(TIMER_1))
|
if (counter_enabled(TIMER_1) && !counter_external_count(TIMER_1))
|
||||||
{
|
{
|
||||||
@ -965,114 +944,16 @@ void z8536_device::z80daisy_irq_reti()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
|
||||||
// INTERNAL STATE MANAGEMENT
|
|
||||||
//**************************************************************************
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// read - register read
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
READ8_MEMBER( z8536_device::read )
|
|
||||||
{
|
|
||||||
uint8_t data = 0;
|
|
||||||
|
|
||||||
if (m_state == STATE_RESET)
|
|
||||||
{
|
|
||||||
// read RESET bit
|
|
||||||
data = read_register(m_pointer, 0x01);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (offset & 0x03)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
data = read_register(PORT_C_DATA);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
data = read_register(PORT_B_DATA);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
data = read_register(PORT_A_DATA);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
switch (m_state)
|
|
||||||
{
|
|
||||||
case STATE_1:
|
|
||||||
m_state = STATE_0;
|
|
||||||
// fallthru
|
|
||||||
case STATE_0:
|
|
||||||
data = read_register(m_pointer);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
|
||||||
// write - register write
|
|
||||||
//-------------------------------------------------
|
|
||||||
|
|
||||||
WRITE8_MEMBER( z8536_device::write )
|
|
||||||
{
|
|
||||||
if (m_state == STATE_RESET)
|
|
||||||
{
|
|
||||||
// write RESET bit
|
|
||||||
write_register(m_pointer, data, 0x01);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch (offset & 0x03)
|
|
||||||
{
|
|
||||||
case PORT_C:
|
|
||||||
write_register(PORT_C_DATA, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PORT_B:
|
|
||||||
write_register(PORT_B_DATA, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case PORT_A:
|
|
||||||
write_register(PORT_A_DATA, data);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CONTROL:
|
|
||||||
switch (m_state)
|
|
||||||
{
|
|
||||||
case STATE_0:
|
|
||||||
m_pointer = data;
|
|
||||||
m_state = STATE_1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case STATE_1:
|
|
||||||
write_register(m_pointer, data);
|
|
||||||
if (m_state != STATE_RESET)
|
|
||||||
m_state = STATE_0;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// intack_r - interrupt acknowledge
|
// intack_r - interrupt acknowledge
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
|
|
||||||
int z8536_device::intack_r()
|
int cio_base_device::intack_r()
|
||||||
{
|
{
|
||||||
get_interrupt_vector();
|
get_interrupt_vector();
|
||||||
int data = m_register[CURRENT_VECTOR];
|
int data = m_register[CURRENT_VECTOR];
|
||||||
|
|
||||||
LOG("%s Z8536 Interrupt Acknowledge: %02x\n", machine().describe_context(), data);
|
LOG("%s CIO Interrupt Acknowledge: %02x\n", machine().describe_context(), data);
|
||||||
|
|
||||||
// set interrupt under service bit
|
// set interrupt under service bit
|
||||||
if ((m_register[COUNTER_TIMER_3_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE)) == (CTCS_IP | CTCS_IE))
|
if ((m_register[COUNTER_TIMER_3_COMMAND_AND_STATUS] & (CTCS_IP | CTCS_IE)) == (CTCS_IP | CTCS_IE))
|
||||||
@ -1106,3 +987,130 @@ int z8536_device::intack_r()
|
|||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// INTERNAL STATE MANAGEMENT
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// read - register read (Z-Bus)
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
READ8_MEMBER( z8036_device::read )
|
||||||
|
{
|
||||||
|
return is_reset() ? 0 : read_register(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// read - register read (universal bus)
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
READ8_MEMBER( z8536_device::read )
|
||||||
|
{
|
||||||
|
uint8_t data = 0;
|
||||||
|
|
||||||
|
if (!is_reset())
|
||||||
|
{
|
||||||
|
switch (offset & 0x03)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
data = read_register(PORT_C_DATA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
data = read_register(PORT_B_DATA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
data = read_register(PORT_A_DATA);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
// state 0 or state 1: read data
|
||||||
|
data = read_register(m_pointer);
|
||||||
|
|
||||||
|
// return to state 0 after read
|
||||||
|
if (!machine().side_effect_disabled())
|
||||||
|
m_state0 = true;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// write - register write (Z-Bus)
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
WRITE8_MEMBER( z8036_device::write )
|
||||||
|
{
|
||||||
|
if (is_reset())
|
||||||
|
{
|
||||||
|
// writes to other registers are ignored during reset
|
||||||
|
if (offset != MASTER_INTERRUPT_CONTROL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// RESET bit must be written before all others
|
||||||
|
data &= 0x01;
|
||||||
|
}
|
||||||
|
|
||||||
|
write_register(offset, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// write - register write (universal bus)
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
WRITE8_MEMBER( z8536_device::write )
|
||||||
|
{
|
||||||
|
if (is_reset())
|
||||||
|
{
|
||||||
|
// write RESET bit
|
||||||
|
write_register(m_pointer, data, 0x01);
|
||||||
|
|
||||||
|
// proceed to state 0 if no longer reset
|
||||||
|
m_state0 = !is_reset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switch (offset & 0x03)
|
||||||
|
{
|
||||||
|
case PORT_C:
|
||||||
|
write_register(PORT_C_DATA, data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PORT_B:
|
||||||
|
write_register(PORT_B_DATA, data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PORT_A:
|
||||||
|
write_register(PORT_A_DATA, data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CONTROL:
|
||||||
|
if (m_state0)
|
||||||
|
{
|
||||||
|
// state 0: write pointer
|
||||||
|
m_pointer = data;
|
||||||
|
|
||||||
|
// proceed to state 1
|
||||||
|
m_state0 = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// state 1: write data
|
||||||
|
write_register(m_pointer, data);
|
||||||
|
|
||||||
|
// return to state 0 unless reset
|
||||||
|
m_state0 = !is_reset();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -2,9 +2,31 @@
|
|||||||
// copyright-holders:Curt Coder
|
// copyright-holders:Curt Coder
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
|
|
||||||
Zilog Z8536 Counter/Timer and Parallel I/O emulation
|
Zilog Z8036/Z8536 Counter/Timer and Parallel I/O Unit
|
||||||
|
|
||||||
**********************************************************************
|
**********************************************************************
|
||||||
|
_____ _____
|
||||||
|
AD4 1 |* \_/ | 40 AD3
|
||||||
|
AD5 2 | | 39 AD2
|
||||||
|
AD6 3 | | 38 AD1
|
||||||
|
AD7 4 | | 37 AD0
|
||||||
|
_DS 5 | | 36 _CS0
|
||||||
|
R/_W 6 | | 35 CS1
|
||||||
|
GND 7 | | 34 _AS
|
||||||
|
PB0 8 | | 33 PA0
|
||||||
|
PB1 9 | | 32 PA1
|
||||||
|
PB2 10 | Z8036 | 31 PA2
|
||||||
|
PB3 11 | | 30 PA3
|
||||||
|
PB4 12 | | 29 PA4
|
||||||
|
PB5 13 | | 28 PA5
|
||||||
|
PB6 14 | | 27 PA6
|
||||||
|
PB7 15 | | 26 PA7
|
||||||
|
PCLK 16 | | 25 _INTACK
|
||||||
|
IEI 17 | | 24 _INT
|
||||||
|
IEO 18 | | 23 +5 V
|
||||||
|
PC0 19 | | 22 PC3
|
||||||
|
PC1 20 |_____________| 21 PC2
|
||||||
|
|
||||||
_____ _____
|
_____ _____
|
||||||
D4 1 |* \_/ | 40 D3
|
D4 1 |* \_/ | 40 D3
|
||||||
D5 2 | | 39 D2
|
D5 2 | | 39 D2
|
||||||
@ -69,27 +91,19 @@
|
|||||||
// TYPE DEFINITIONS
|
// TYPE DEFINITIONS
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
|
||||||
// ======================> z8536_device
|
// ======================> cio_base_device
|
||||||
|
|
||||||
class z8536_device : public device_t,
|
class cio_base_device : public device_t
|
||||||
public device_z80daisy_interface
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
|
||||||
z8536_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
|
||||||
|
|
||||||
template <class Object> static devcb_base &set_irq_wr_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_write_irq.set_callback(std::forward<Object>(cb)); }
|
template <class Object> static devcb_base &set_irq_wr_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_write_irq.set_callback(std::forward<Object>(cb)); }
|
||||||
template <class Object> static devcb_base &set_pa_rd_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_read_pa.set_callback(std::forward<Object>(cb)); }
|
template <class Object> static devcb_base &set_pa_rd_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_read_pa.set_callback(std::forward<Object>(cb)); }
|
||||||
template <class Object> static devcb_base &set_pa_wr_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_write_pa.set_callback(std::forward<Object>(cb)); }
|
template <class Object> static devcb_base &set_pa_wr_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_write_pa.set_callback(std::forward<Object>(cb)); }
|
||||||
template <class Object> static devcb_base &set_pb_rd_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_read_pb.set_callback(std::forward<Object>(cb)); }
|
template <class Object> static devcb_base &set_pb_rd_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_read_pb.set_callback(std::forward<Object>(cb)); }
|
||||||
template <class Object> static devcb_base &set_pb_wr_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_write_pb.set_callback(std::forward<Object>(cb)); }
|
template <class Object> static devcb_base &set_pb_wr_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_write_pb.set_callback(std::forward<Object>(cb)); }
|
||||||
template <class Object> static devcb_base &set_pc_rd_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_read_pc.set_callback(std::forward<Object>(cb)); }
|
template <class Object> static devcb_base &set_pc_rd_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_read_pc.set_callback(std::forward<Object>(cb)); }
|
||||||
template <class Object> static devcb_base &set_pc_wr_callback(device_t &device, Object &&cb) { return downcast<z8536_device &>(device).m_write_pc.set_callback(std::forward<Object>(cb)); }
|
template <class Object> static devcb_base &set_pc_wr_callback(device_t &device, Object &&cb) { return downcast<cio_base_device &>(device).m_write_pc.set_callback(std::forward<Object>(cb)); }
|
||||||
|
|
||||||
DECLARE_READ8_MEMBER( read );
|
|
||||||
DECLARE_WRITE8_MEMBER( write );
|
|
||||||
|
|
||||||
int intack_r();
|
|
||||||
|
|
||||||
DECLARE_WRITE_LINE_MEMBER( pa0_w ) { external_port_w(PORT_A, 0, state); }
|
DECLARE_WRITE_LINE_MEMBER( pa0_w ) { external_port_w(PORT_A, 0, state); }
|
||||||
DECLARE_WRITE_LINE_MEMBER( pa1_w ) { external_port_w(PORT_A, 1, state); }
|
DECLARE_WRITE_LINE_MEMBER( pa1_w ) { external_port_w(PORT_A, 1, state); }
|
||||||
@ -114,18 +128,19 @@ public:
|
|||||||
DECLARE_WRITE_LINE_MEMBER( pc2_w ) { external_port_w(PORT_C, 2, state); }
|
DECLARE_WRITE_LINE_MEMBER( pc2_w ) { external_port_w(PORT_C, 2, state); }
|
||||||
DECLARE_WRITE_LINE_MEMBER( pc3_w ) { external_port_w(PORT_C, 3, state); }
|
DECLARE_WRITE_LINE_MEMBER( pc3_w ) { external_port_w(PORT_C, 3, state); }
|
||||||
|
|
||||||
|
int intack_r();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// construction/destruction
|
||||||
|
cio_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
// device-level overrides
|
// device-level overrides
|
||||||
virtual void device_start() override;
|
virtual void device_start() override;
|
||||||
virtual void device_reset() override;
|
virtual void device_reset() override;
|
||||||
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
|
||||||
|
|
||||||
// device_z80daisy_interface overrides
|
bool is_reset() const { return (m_register[MASTER_INTERRUPT_CONTROL] & MICR_RESET) != 0; }
|
||||||
virtual int z80daisy_irq_state() override;
|
|
||||||
virtual int z80daisy_irq_ack() override;
|
|
||||||
virtual void z80daisy_irq_reti() override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
TIMER_1 = 0,
|
TIMER_1 = 0,
|
||||||
@ -133,15 +148,6 @@ private:
|
|||||||
TIMER_3
|
TIMER_3
|
||||||
};
|
};
|
||||||
|
|
||||||
// states
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
STATE_RESET = -1,
|
|
||||||
STATE_0,
|
|
||||||
STATE_1
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
// ports
|
// ports
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -155,7 +161,7 @@ private:
|
|||||||
// registers
|
// registers
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
MASTER_INTERRUPT_CONTROL = 0,
|
MASTER_INTERRUPT_CONTROL = 0x00,
|
||||||
MASTER_CONFIGURATION_CONTROL,
|
MASTER_CONFIGURATION_CONTROL,
|
||||||
PORT_A_INTERRUPT_VECTOR,
|
PORT_A_INTERRUPT_VECTOR,
|
||||||
PORT_B_INTERRUPT_VECTOR,
|
PORT_B_INTERRUPT_VECTOR,
|
||||||
@ -171,7 +177,7 @@ private:
|
|||||||
PORT_A_DATA,
|
PORT_A_DATA,
|
||||||
PORT_B_DATA,
|
PORT_B_DATA,
|
||||||
PORT_C_DATA,
|
PORT_C_DATA,
|
||||||
COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE,
|
COUNTER_TIMER_1_CURRENT_COUNT_MS_BYTE = 0x10,
|
||||||
COUNTER_TIMER_1_CURRENT_COUNT_LS_BYTE,
|
COUNTER_TIMER_1_CURRENT_COUNT_LS_BYTE,
|
||||||
COUNTER_TIMER_2_CURRENT_COUNT_MS_BYTE,
|
COUNTER_TIMER_2_CURRENT_COUNT_MS_BYTE,
|
||||||
COUNTER_TIMER_2_CURRENT_COUNT_LS_BYTE,
|
COUNTER_TIMER_2_CURRENT_COUNT_LS_BYTE,
|
||||||
@ -187,7 +193,7 @@ private:
|
|||||||
COUNTER_TIMER_2_MODE_SPECIFICATION,
|
COUNTER_TIMER_2_MODE_SPECIFICATION,
|
||||||
COUNTER_TIMER_3_MODE_SPECIFICATION,
|
COUNTER_TIMER_3_MODE_SPECIFICATION,
|
||||||
CURRENT_VECTOR,
|
CURRENT_VECTOR,
|
||||||
PORT_A_MODE_SPECIFICATION,
|
PORT_A_MODE_SPECIFICATION = 0x20,
|
||||||
PORT_A_HANDSHAKE_SPECIFICATION,
|
PORT_A_HANDSHAKE_SPECIFICATION,
|
||||||
PORT_A_DATA_PATH_POLARITY,
|
PORT_A_DATA_PATH_POLARITY,
|
||||||
PORT_A_DATA_DIRECTION,
|
PORT_A_DATA_DIRECTION,
|
||||||
@ -206,6 +212,96 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// master interrupt control register
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
MICR_RESET = 0x01, // reset
|
||||||
|
MICR_RJA = 0x02, // right justified address
|
||||||
|
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_MIE = 0x80 // master interrupt enable
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 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_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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// 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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// port command and status registers
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PCS_IOE = 0x01, // interrupt on error
|
||||||
|
PCS_PMF = 0x02, // pattern match flag (read only)
|
||||||
|
PCS_IRF = 0x04, // input register full (read only)
|
||||||
|
PCS_ORE = 0x08, // output register empty (read only)
|
||||||
|
PCS_ERR = 0x10, // interrupt error (read only)
|
||||||
|
PCS_IP = 0x20, // interrupt pending
|
||||||
|
PCS_IE = 0x40, // interrupt enable
|
||||||
|
PCS_IUS = 0x80 // interrupt under service
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// counter/timer mode specification registers
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CTMS_DCS_MASK = 0x03, // output duty cycle
|
||||||
|
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_CSC = 0x80 // continuous/single cycle
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// counter/timer command and status registers
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
CTCS_CIP = 0x01, // count in progress (read only)
|
||||||
|
CTCS_TCB = 0x02, // trigger command bit (write only - read returns 0)
|
||||||
|
CTCS_GCB = 0x04, // gate command bit
|
||||||
|
CTCS_RCC = 0x08, // read counter control (read/set only - cleared by reading CCR LSB)
|
||||||
|
CTCS_ERR = 0x10, // interrupt error (read only)
|
||||||
|
CTCS_IP = 0x20, // interrupt pending
|
||||||
|
CTCS_IE = 0x40, // interrupt enable
|
||||||
|
CTCS_IUS = 0x80 // interrupt under service
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// interrupt control
|
// interrupt control
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
@ -313,6 +409,7 @@ private:
|
|||||||
void match_pattern(int port);
|
void match_pattern(int port);
|
||||||
void external_port_w(int port, int bit, int state);
|
void external_port_w(int port, int bit, int state);
|
||||||
|
|
||||||
|
private:
|
||||||
devcb_write_line m_write_irq;
|
devcb_write_line m_write_irq;
|
||||||
|
|
||||||
devcb_read8 m_read_pa;
|
devcb_read8 m_read_pa;
|
||||||
@ -328,9 +425,7 @@ private:
|
|||||||
int m_irq;
|
int m_irq;
|
||||||
|
|
||||||
// register state
|
// register state
|
||||||
int m_state;
|
|
||||||
uint8_t m_register[48];
|
uint8_t m_register[48];
|
||||||
uint8_t m_pointer;
|
|
||||||
|
|
||||||
// input/output port state
|
// input/output port state
|
||||||
uint8_t m_input[3];
|
uint8_t m_input[3];
|
||||||
@ -343,8 +438,48 @@ private:
|
|||||||
uint16_t m_counter[3];
|
uint16_t m_counter[3];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// ======================> z8036_device
|
||||||
|
|
||||||
|
class z8036_device : public cio_base_device
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
z8036_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
DECLARE_READ8_MEMBER( read );
|
||||||
|
DECLARE_WRITE8_MEMBER( write );
|
||||||
|
};
|
||||||
|
|
||||||
|
// ======================> z8536_device
|
||||||
|
|
||||||
|
class z8536_device : public cio_base_device, public device_z80daisy_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
z8536_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||||
|
|
||||||
|
DECLARE_READ8_MEMBER( read );
|
||||||
|
DECLARE_WRITE8_MEMBER( write );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// device-level overrides
|
||||||
|
virtual void device_start() override;
|
||||||
|
virtual void device_reset() override;
|
||||||
|
|
||||||
|
// device_z80daisy_interface overrides
|
||||||
|
virtual int z80daisy_irq_state() override;
|
||||||
|
virtual int z80daisy_irq_ack() override;
|
||||||
|
virtual void z80daisy_irq_reti() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// control state machine
|
||||||
|
bool m_state0;
|
||||||
|
uint8_t m_pointer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// device type definition
|
// device type definition
|
||||||
|
DECLARE_DEVICE_TYPE(Z8036, z8036_device)
|
||||||
DECLARE_DEVICE_TYPE(Z8536, z8536_device)
|
DECLARE_DEVICE_TYPE(Z8536, z8536_device)
|
||||||
|
|
||||||
#endif // MAME_MACHINE_Z8536_H
|
#endif // MAME_MACHINE_Z8536_H
|
||||||
|
@ -30,6 +30,7 @@ into the weeds (jumps to 00000).
|
|||||||
//#include "machine/z80scc.h"
|
//#include "machine/z80scc.h"
|
||||||
//#include "bus/rs232/rs232.h"
|
//#include "bus/rs232/rs232.h"
|
||||||
#include "machine/terminal.h"
|
#include "machine/terminal.h"
|
||||||
|
#include "machine/z8536.h"
|
||||||
|
|
||||||
|
|
||||||
class c900_state : public driver_device
|
class c900_state : public driver_device
|
||||||
@ -41,7 +42,6 @@ public:
|
|||||||
, m_terminal(*this, "terminal")
|
, m_terminal(*this, "terminal")
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
DECLARE_READ16_MEMBER(port1e_r);
|
|
||||||
DECLARE_READ16_MEMBER(key_r);
|
DECLARE_READ16_MEMBER(key_r);
|
||||||
DECLARE_READ16_MEMBER(stat_r);
|
DECLARE_READ16_MEMBER(stat_r);
|
||||||
void kbd_put(u8 data);
|
void kbd_put(u8 data);
|
||||||
@ -62,10 +62,8 @@ static ADDRESS_MAP_START(data_map, AS_DATA, 16, c900_state)
|
|||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
|
|
||||||
static ADDRESS_MAP_START(io_map, AS_IO, 16, c900_state)
|
static ADDRESS_MAP_START(io_map, AS_IO, 16, c900_state)
|
||||||
|
AM_RANGE(0x0000, 0x007f) AM_DEVREADWRITE8("cio", z8036_device, read, write, 0x00ff)
|
||||||
//AM_RANGE(0x0100, 0x011f) AM_DEVREADWRITE8("scc", scc8030_device, zbus_r, zbus_w, 0x00ff) // range for one channel
|
//AM_RANGE(0x0100, 0x011f) AM_DEVREADWRITE8("scc", scc8030_device, zbus_r, zbus_w, 0x00ff) // range for one channel
|
||||||
AM_RANGE(0x0010, 0x0011) AM_READ(stat_r)
|
|
||||||
AM_RANGE(0x001A, 0x001B) AM_READ(key_r)
|
|
||||||
AM_RANGE(0x001E, 0x001F) AM_READ(port1e_r)
|
|
||||||
AM_RANGE(0x0100, 0x0101) AM_READ(stat_r)
|
AM_RANGE(0x0100, 0x0101) AM_READ(stat_r)
|
||||||
AM_RANGE(0x0110, 0x0111) AM_READ(key_r) AM_DEVWRITE8("terminal", generic_terminal_device, write, 0x00ff)
|
AM_RANGE(0x0110, 0x0111) AM_READ(key_r) AM_DEVWRITE8("terminal", generic_terminal_device, write, 0x00ff)
|
||||||
ADDRESS_MAP_END
|
ADDRESS_MAP_END
|
||||||
@ -73,11 +71,6 @@ ADDRESS_MAP_END
|
|||||||
static INPUT_PORTS_START( c900 )
|
static INPUT_PORTS_START( c900 )
|
||||||
INPUT_PORTS_END
|
INPUT_PORTS_END
|
||||||
|
|
||||||
READ16_MEMBER( c900_state::port1e_r )
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
READ16_MEMBER( c900_state::key_r )
|
READ16_MEMBER( c900_state::key_r )
|
||||||
{
|
{
|
||||||
uint8_t ret = m_term_data;
|
uint8_t ret = m_term_data;
|
||||||
@ -125,6 +118,8 @@ static MACHINE_CONFIG_START( c900 )
|
|||||||
MCFG_GFXDECODE_ADD("gfxdecode", "palette", c900)
|
MCFG_GFXDECODE_ADD("gfxdecode", "palette", c900)
|
||||||
MCFG_PALETTE_ADD_MONOCHROME("palette")
|
MCFG_PALETTE_ADD_MONOCHROME("palette")
|
||||||
|
|
||||||
|
MCFG_DEVICE_ADD("cio", Z8036, 6'000'000)
|
||||||
|
|
||||||
//MCFG_SCC8030_ADD("scc", 6'000'000, 326400, 0, 326400, 0)
|
//MCFG_SCC8030_ADD("scc", 6'000'000, 326400, 0, 326400, 0)
|
||||||
/* Port A */
|
/* Port A */
|
||||||
//MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE("rs232a", rs232_port_device, write_txd))
|
//MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE("rs232a", rs232_port_device, write_txd))
|
||||||
|
Loading…
Reference in New Issue
Block a user