mirror of
https://github.com/holub/mame
synced 2025-04-19 23:12:11 +03:00
removed old z80sio device
This commit is contained in:
parent
61ddbfb840
commit
8abfa8c0e1
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -2964,8 +2964,6 @@ src/emu/machine/z80dma.c svneol=native#text/plain
|
||||
src/emu/machine/z80dma.h svneol=native#text/plain
|
||||
src/emu/machine/z80pio.c svneol=native#text/plain
|
||||
src/emu/machine/z80pio.h svneol=native#text/plain
|
||||
src/emu/machine/z80sio.c svneol=native#text/plain
|
||||
src/emu/machine/z80sio.h svneol=native#text/plain
|
||||
src/emu/machine/z80sti.c svneol=native#text/plain
|
||||
src/emu/machine/z80sti.h svneol=native#text/plain
|
||||
src/emu/machine/z8536.c svneol=native#text/plain
|
||||
|
@ -1715,15 +1715,6 @@ ifneq ($(filter Z80PIO,$(MACHINES)),)
|
||||
MACHINEOBJS += $(MACHINEOBJ)/z80pio.o
|
||||
endif
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
#@src/emu/machine/z80sio.h,MACHINES += Z80SIO
|
||||
#-------------------------------------------------
|
||||
|
||||
ifneq ($(filter Z80SIO,$(MACHINES)),)
|
||||
MACHINEOBJS += $(MACHINEOBJ)/z80sio.o
|
||||
endif
|
||||
|
||||
#-------------------------------------------------
|
||||
#
|
||||
#@src/emu/machine/z80sti.h,MACHINES += Z80STI
|
||||
|
@ -1,846 +0,0 @@
|
||||
/***************************************************************************
|
||||
|
||||
!!! DEPRECATED DO NOT USE !!!
|
||||
|
||||
WILL BE DELETED WHEN src/mame/drivers/dlair.c USES z80dart.h
|
||||
|
||||
Z80 SIO (Z8440) implementation
|
||||
|
||||
Copyright Nicola Salmoria and the MAME Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "z80sio.h"
|
||||
#include "cpu/z80/z80.h"
|
||||
#include "cpu/z80/z80daisy.h"
|
||||
|
||||
|
||||
// device type definition
|
||||
const device_type Z80SIO = &device_creator<z80sio_device>;
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEBUGGING
|
||||
//**************************************************************************
|
||||
|
||||
#define VERBOSE 0
|
||||
|
||||
#define VPRINTF(x) do { if (VERBOSE) logerror x; } while (0)
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// CONSTANTS
|
||||
//**************************************************************************
|
||||
|
||||
// interrupt states
|
||||
const int INT_TRANSMIT = 0x00; // not confirmed
|
||||
const int INT_STATUS = 0x01;
|
||||
const int INT_RECEIVE = 0x02;
|
||||
const int INT_ERROR = 0x03;
|
||||
|
||||
const int INT_CHB_TRANSMIT = 0 + INT_TRANSMIT;
|
||||
const int INT_CHB_STATUS = 0 + INT_STATUS;
|
||||
const int INT_CHB_RECEIVE = 0 + INT_RECEIVE;
|
||||
const int INT_CHB_ERROR = 0 + INT_ERROR;
|
||||
const int INT_CHA_TRANSMIT = 4 + INT_TRANSMIT;
|
||||
const int INT_CHA_STATUS = 4 + INT_STATUS;
|
||||
const int INT_CHA_RECEIVE = 4 + INT_RECEIVE;
|
||||
const int INT_CHA_ERROR = 4 + INT_ERROR;
|
||||
|
||||
// SIO write register 0
|
||||
//const int SIO_WR0_RESET_MASK = 0xc0; // D7-D6: Reset control
|
||||
//const int SIO_WR0_RESET_NULL = 0x00; // 00 = NULL code
|
||||
//const int SIO_WR0_RESET_RX_CRC = 0x40; // 01 = Reset Rx CRC checker
|
||||
//const int SIO_WR0_RESET_TX_CRC = 0x80; // 10 = Reset Tx CRC generator
|
||||
//const int SIO_WR0_RESET_TX_LATCH = 0xc0; // 11 = Reset Tx Underrun/EOM latch
|
||||
const int SIO_WR0_COMMAND_MASK = 0x38; // D5-D3: Command
|
||||
//const int SIO_WR0_COMMAND_NULL = 0x00; // 000 = NULL code
|
||||
//const int SIO_WR0_COMMAND_SET_ABORT = 0x08; // 001 = Set abort (SDLC)
|
||||
const int SIO_WR0_COMMAND_RES_STATUS_INT = 0x10; // 010 = reset ext/status interrupts
|
||||
const int SIO_WR0_COMMAND_CH_RESET = 0x18; // 011 = Channel reset
|
||||
const int SIO_WR0_COMMAND_ENA_RX_INT = 0x20; // 100 = Enable int on next Rx character
|
||||
const int SIO_WR0_COMMAND_RES_TX_INT = 0x28; // 101 = Reset Tx int pending
|
||||
const int SIO_WR0_COMMAND_RES_ERROR = 0x30; // 110 = Error reset
|
||||
//const int SIO_WR0_COMMAND_RETI = 0x38; // 111 = Return from int (CH-A only)
|
||||
//const int SIO_WR0_REGISTER_MASK = 0x07; // D2-D0: Register select (0-7)
|
||||
|
||||
// SIO write register 1
|
||||
//const int SIO_WR1_READY_WAIT_ENA = 0x80; // D7 = READY/WAIT enable
|
||||
//const int SIO_WR1_READY_WAIT_FUNCTION = 0x40; // D6 = READY/WAIT function
|
||||
//const int SIO_WR1_READY_WAIT_ON_RT = 0x20; // D5 = READY/WAIT on R/T
|
||||
const int SIO_WR1_RXINT_MASK = 0x18; // D4-D3 = Rx int control
|
||||
//const int SIO_WR1_RXINT_DISABLE = 0x00; // 00 = Rx int disable
|
||||
const int SIO_WR1_RXINT_FIRST = 0x08; // 01 = Rx int on first character
|
||||
const int SIO_WR1_RXINT_ALL_PARITY = 0x10; // 10 = int on all Rx characters (parity affects vector)
|
||||
const int SIO_WR1_RXINT_ALL_NOPARITY = 0x18; // 11 = int on all Rx characters (parity ignored)
|
||||
//const int SIO_WR1_STATUS_AFFECTS_VECTOR = 0x04; // D2 = Status affects vector (CH-B only)
|
||||
const int SIO_WR1_TXINT_ENABLE = 0x02; // D1 = Tx int enable
|
||||
const int SIO_WR1_STATUSINT_ENABLE = 0x01; // D0 = Ext int enable
|
||||
|
||||
// SIO write register 2 (CH-B only)
|
||||
//const int SIO_WR2_INT_VECTOR_MASK = 0xff; // D7-D0 = interrupt vector
|
||||
|
||||
// SIO write register 3
|
||||
//const int SIO_WR3_RX_DATABITS_MASK = 0xc0; // D7-D6 = Rx Data bits
|
||||
//const int SIO_WR3_RX_DATABITS_5 = 0x00; // 00 = Rx 5 bits/character
|
||||
//const int SIO_WR3_RX_DATABITS_7 = 0x40; // 01 = Rx 7 bits/character
|
||||
//const int SIO_WR3_RX_DATABITS_6 = 0x80; // 10 = Rx 6 bits/character
|
||||
//const int SIO_WR3_RX_DATABITS_8 = 0xc0; // 11 = Rx 8 bits/character
|
||||
//const int SIO_WR3_AUTO_ENABLES = 0x20; // D5 = Auto enables
|
||||
//const int SIO_WR3_ENTER_HUNT_PHASE = 0x10; // D4 = Enter hunt phase
|
||||
//const int SIO_WR3_RX_CRC_ENABLE = 0x08; // D3 = Rx CRC enable
|
||||
//const int SIO_WR3_ADDR_SEARCH_MODE = 0x04; // D2 = Address search mode (SDLC)
|
||||
//const int SIO_WR3_SYNC_LOAD_INHIBIT = 0x02; // D1 = Sync character load inhibit
|
||||
const int SIO_WR3_RX_ENABLE = 0x01; // D0 = Rx enable
|
||||
|
||||
// SIO write register 4
|
||||
//const int SIO_WR4_CLOCK_MODE_MASK = 0xc0; // D7-D6 = Clock mode
|
||||
//const int SIO_WR4_CLOCK_MODE_x1 = 0x00; // 00 = x1 clock mode
|
||||
//const int SIO_WR4_CLOCK_MODE_x16 = 0x40; // 01 = x16 clock mode
|
||||
//const int SIO_WR4_CLOCK_MODE_x32 = 0x80; // 10 = x32 clock mode
|
||||
//const int SIO_WR4_CLOCK_MODE_x64 = 0xc0; // 11 = x64 clock mode
|
||||
//const int SIO_WR4_SYNC_MODE_MASK = 0x30; // D5-D4 = Sync mode
|
||||
//const int SIO_WR4_SYNC_MODE_8BIT = 0x00; // 00 = 8 bit sync character
|
||||
//const int SIO_WR4_SYNC_MODE_16BIT = 0x10; // 01 = 16 bit sync character
|
||||
//const int SIO_WR4_SYNC_MODE_SDLC = 0x20; // 10 = SDLC mode (01111110 flag)
|
||||
//const int SIO_WR4_SYNC_MODE_EXTERNAL = 0x30; // 11 = External sync mode
|
||||
//const int SIO_WR4_STOPBITS_MASK = 0x0c; // D3-D2 = Stop bits
|
||||
//const int SIO_WR4_STOPBITS_SYNC = 0x00; // 00 = Sync modes enable
|
||||
//const int SIO_WR4_STOPBITS_1 = 0x04; // 01 = 1 stop bit/character
|
||||
//const int SIO_WR4_STOPBITS_15 = 0x08; // 10 = 1.5 stop bits/character
|
||||
//const int SIO_WR4_STOPBITS_2 = 0x0c; // 11 = 2 stop bits/character
|
||||
//const int SIO_WR4_PARITY_EVEN = 0x02; // D1 = Parity even/odd
|
||||
//const int SIO_WR4_PARITY_ENABLE = 0x01; // D0 = Parity enable
|
||||
|
||||
// SIO write register 5
|
||||
const int SIO_WR5_DTR = 0x80; // D7 = DTR
|
||||
//const int SIO_WR5_TX_DATABITS_MASK = 0x60; // D6-D5 = Tx Data bits
|
||||
//const int SIO_WR5_TX_DATABITS_5 = 0x00; // 00 = Tx 5 bits/character
|
||||
//const int SIO_WR5_TX_DATABITS_7 = 0x20; // 01 = Tx 7 bits/character
|
||||
//const int SIO_WR5_TX_DATABITS_6 = 0x40; // 10 = Tx 6 bits/character
|
||||
//const int SIO_WR5_TX_DATABITS_8 = 0x60; // 11 = Tx 8 bits/character
|
||||
//const int SIO_WR5_SEND_BREAK = 0x10; // D4 = Send break
|
||||
const int SIO_WR5_TX_ENABLE = 0x08; // D3 = Tx Enable
|
||||
//const int SIO_WR5_CRC16_SDLC = 0x04; // D2 = CRC-16/SDLC
|
||||
const int SIO_WR5_RTS = 0x02; // D1 = RTS
|
||||
//const int SIO_WR5_TX_CRC_ENABLE = 0x01; // D0 = Tx CRC enable
|
||||
|
||||
// SIO write register 6
|
||||
//const int SIO_WR6_SYNC_7_0_MASK = 0xff; // D7-D0 = Sync bits 7-0
|
||||
|
||||
// SIO write register 7
|
||||
//const int SIO_WR7_SYNC_15_8_MASK = 0xff; // D7-D0 = Sync bits 15-8
|
||||
|
||||
// SIO read register 0
|
||||
//const int SIO_RR0_BREAK_ABORT = 0x80; // D7 = Break/abort
|
||||
//const int SIO_RR0_TX_UNDERRUN = 0x40; // D6 = Tx underrun/EOM
|
||||
const int SIO_RR0_CTS = 0x20; // D5 = CTS
|
||||
//const int SIO_RR0_SYNC_HUNT = 0x10; // D4 = Sync/hunt
|
||||
const int SIO_RR0_DCD = 0x08; // D3 = DCD
|
||||
const int SIO_RR0_TX_BUFFER_EMPTY = 0x04; // D2 = Tx buffer empty
|
||||
const int SIO_RR0_INT_PENDING = 0x02; // D1 = int pending (CH-A only)
|
||||
const int SIO_RR0_RX_CHAR_AVAILABLE = 0x01; // D0 = Rx character available
|
||||
|
||||
// SIO read register 1
|
||||
//const int SIO_RR1_END_OF_FRAME = 0x80; // D7 = End of frame (SDLC)
|
||||
//const int SIO_RR1_CRC_FRAMING_ERROR = 0x40; // D6 = CRC/Framing error
|
||||
//const int SIO_RR1_RX_OVERRUN_ERROR = 0x20; // D5 = Rx overrun error
|
||||
//const int SIO_RR1_PARITY_ERROR = 0x10; // D4 = Parity error
|
||||
//const int SIO_RR1_IFIELD_BITS_MASK = 0x0e; // D3-D1 = I field bits
|
||||
// 100 = 0 in prev, 3 in 2nd prev
|
||||
// 010 = 0 in prev, 4 in 2nd prev
|
||||
// 110 = 0 in prev, 5 in 2nd prev
|
||||
// 001 = 0 in prev, 6 in 2nd prev
|
||||
// 101 = 0 in prev, 7 in 2nd prev
|
||||
// 011 = 0 in prev, 8 in 2nd prev
|
||||
// 111 = 1 in prev, 8 in 2nd prev
|
||||
// 000 = 2 in prev, 8 in 2nd prev
|
||||
//const int SIO_RR1_ALL_SENT = 0x01; // D0 = All sent
|
||||
|
||||
// SIO read register 2 (CH-B only)
|
||||
//const int SIO_RR2_VECTOR_MASK = 0xff; // D7-D0 = Interrupt vector
|
||||
|
||||
|
||||
const UINT8 z80sio_device::k_int_priority[] =
|
||||
{
|
||||
INT_CHA_RECEIVE,
|
||||
INT_CHA_TRANSMIT,
|
||||
INT_CHA_STATUS,
|
||||
INT_CHA_ERROR,
|
||||
INT_CHB_RECEIVE,
|
||||
INT_CHB_TRANSMIT,
|
||||
INT_CHB_STATUS,
|
||||
INT_CHB_ERROR
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
FUNCTION PROTOTYPES
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
/*
|
||||
|
||||
Interrupt priorities:
|
||||
Ch A receive
|
||||
Ch A transmit
|
||||
Ch A external/status
|
||||
Ch B receive
|
||||
Ch B transmit
|
||||
Ch B external/status
|
||||
|
||||
|
||||
Initial configuration (both channels):
|
||||
005D:sio_reg_w(0,4) = 44
|
||||
01 = x16 clock mode
|
||||
00 = 8 bit sync character
|
||||
01 = 1 stop bit/character
|
||||
Parity odd
|
||||
Parity disabled
|
||||
|
||||
005D:sio_reg_w(0,3) = C1
|
||||
11 = Rx 8 bits/character
|
||||
No auto enables
|
||||
No enter hunt phase
|
||||
No Rx CRC enable
|
||||
No address search mode
|
||||
No sync character load inhibit
|
||||
Rx enable
|
||||
|
||||
005D:sio_reg_w(0,5) = 68
|
||||
DTR = 0
|
||||
11 = Tx 8 bits/character
|
||||
No send break
|
||||
Tx enable
|
||||
SDLC
|
||||
No RTS
|
||||
No CRC enable
|
||||
|
||||
005D:sio_reg_w(0,2) = 40
|
||||
Vector = 0x40
|
||||
|
||||
005D:sio_reg_w(0,1) = 1D
|
||||
No READY/WAIT
|
||||
No READY/WAIT function
|
||||
No READY/WAIT on R/T
|
||||
11 = int on all Rx characters (parity ignored)
|
||||
Status affects vector
|
||||
No Tx int enable
|
||||
Ext int enable
|
||||
|
||||
*/
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INLINE FUNCTIONS
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// update_interrupt_state - update the interrupt
|
||||
// state to the external world
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void z80sio_device::update_interrupt_state()
|
||||
{
|
||||
// if we have a callback, update it with the current state
|
||||
if (!m_irq.isnull())
|
||||
m_irq((z80daisy_irq_state() & Z80_DAISY_INT) ? ASSERT_LINE : CLEAR_LINE);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_interrupt - set the given interrupt state
|
||||
// on this channel and update the overall device
|
||||
// state
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void z80sio_device::sio_channel::set_interrupt(int type)
|
||||
{
|
||||
int inum = (this == &m_device->m_channel[0] ? 4 : 0) + type;
|
||||
m_device->m_int_state[inum] = Z80_DAISY_INT;
|
||||
m_device->update_interrupt_state();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// clear_interrupt - clear the given interrupt
|
||||
// state on this channel and update the overall
|
||||
// device state
|
||||
//-------------------------------------------------
|
||||
|
||||
inline void z80sio_device::sio_channel::clear_interrupt(int type)
|
||||
{
|
||||
int inum = (this == &m_device->m_channel[0] ? 4 : 0) + type;
|
||||
m_device->m_int_state[inum] &= ~Z80_DAISY_INT;
|
||||
m_device->update_interrupt_state();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// compute_time_per_character - compute the
|
||||
// serial clocking period
|
||||
//-------------------------------------------------
|
||||
|
||||
inline attotime z80sio_device::sio_channel::compute_time_per_character()
|
||||
{
|
||||
// fix me -- should compute properly and include data, stop, parity bit
|
||||
return attotime::from_hz(9600) * 10;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// z80sio_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
z80sio_device::z80sio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock)
|
||||
: device_t(mconfig, Z80SIO, "Z80 SIO", tag, owner, clock, "z80sio", __FILE__),
|
||||
device_z80daisy_interface(mconfig, *this),
|
||||
m_irq(*this),
|
||||
m_dtr_changed(*this),
|
||||
m_rts_changed(*this),
|
||||
m_break_changed(*this),
|
||||
m_transmit(*this),
|
||||
m_received_poll(*this)
|
||||
{
|
||||
for (int i = 0; i < 8; i++)
|
||||
m_int_state[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - device-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::device_start()
|
||||
{
|
||||
m_irq.resolve_safe();
|
||||
m_dtr_changed.resolve_safe();
|
||||
m_rts_changed.resolve_safe();
|
||||
m_break_changed.resolve_safe();
|
||||
m_transmit.resolve_safe();
|
||||
m_received_poll.resolve_safe(0);
|
||||
|
||||
m_channel[0].start(this, 0);
|
||||
m_channel[1].start(this, 1);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - device-specific reset
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::device_reset()
|
||||
{
|
||||
// loop over channels
|
||||
for (int ch = 0; ch < 2; ch++)
|
||||
m_channel[ch].reset();
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DAISY CHAIN INTERFACE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// z80daisy_irq_state - return the overall IRQ
|
||||
// state for this device
|
||||
//-------------------------------------------------
|
||||
|
||||
int z80sio_device::z80daisy_irq_state()
|
||||
{
|
||||
int state = 0;
|
||||
|
||||
VPRINTF(("sio IRQ state = B:%d%d%d%d A:%d%d%d%d\n",
|
||||
m_int_state[0], m_int_state[1], m_int_state[2], m_int_state[3],
|
||||
m_int_state[4], m_int_state[5], m_int_state[6], m_int_state[7]));
|
||||
|
||||
// loop over all interrupt sources
|
||||
for (int irqsource = 0; irqsource < 8; irqsource++)
|
||||
{
|
||||
int inum = k_int_priority[irqsource];
|
||||
|
||||
// if we're servicing a request, don't indicate more interrupts
|
||||
if (m_int_state[inum] & Z80_DAISY_IEO)
|
||||
{
|
||||
state |= Z80_DAISY_IEO;
|
||||
break;
|
||||
}
|
||||
state |= m_int_state[inum];
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// z80daisy_irq_ack - acknowledge an IRQ and
|
||||
// return the appropriate vector
|
||||
//-------------------------------------------------
|
||||
|
||||
int z80sio_device::z80daisy_irq_ack()
|
||||
{
|
||||
// loop over all interrupt sources
|
||||
for (int irqsource = 0; irqsource < 8; irqsource++)
|
||||
{
|
||||
int inum = k_int_priority[irqsource];
|
||||
|
||||
// find the first channel with an interrupt requested
|
||||
if (m_int_state[inum] & Z80_DAISY_INT)
|
||||
{
|
||||
VPRINTF(("sio IRQAck %d\n", inum));
|
||||
|
||||
// clear interrupt, switch to the IEO state, and update the IRQs
|
||||
m_int_state[inum] = Z80_DAISY_IEO;
|
||||
update_interrupt_state();
|
||||
return m_channel[1].m_regs[2] + inum * 2;
|
||||
}
|
||||
}
|
||||
|
||||
logerror("z80sio_irq_ack: failed to find an interrupt to ack!\n");
|
||||
return m_channel[1].m_regs[2];
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// z80daisy_irq_reti - clear the interrupt
|
||||
// pending state to allow other interrupts through
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::z80daisy_irq_reti()
|
||||
{
|
||||
// loop over all interrupt sources
|
||||
for (int irqsource = 0; irqsource < 8; irqsource++)
|
||||
{
|
||||
int inum = k_int_priority[irqsource];
|
||||
|
||||
// find the first channel with an IEO pending
|
||||
if (m_int_state[inum] & Z80_DAISY_IEO)
|
||||
{
|
||||
VPRINTF(("sio IRQReti %d\n", inum));
|
||||
|
||||
// clear the IEO state and update the IRQs
|
||||
m_int_state[inum] &= ~Z80_DAISY_IEO;
|
||||
update_interrupt_state();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
logerror("z80sio_irq_reti: failed to find an interrupt to clear IEO on!\n");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// SIO CHANNEL
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// sio_channel - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
z80sio_device::sio_channel::sio_channel()
|
||||
: m_device(NULL),
|
||||
m_index(0),
|
||||
m_inbuf(-1),
|
||||
m_outbuf(-1),
|
||||
m_int_on_next_rx(false),
|
||||
m_receive_timer(NULL),
|
||||
m_receive_inptr(0),
|
||||
m_receive_outptr(0)
|
||||
{
|
||||
memset(m_regs, 0, sizeof(m_regs));
|
||||
memset(m_status, 0, sizeof(m_status));
|
||||
memset(m_receive_buffer, 0, sizeof(m_receive_buffer));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// start - channel-specific startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::sio_channel::start(z80sio_device *device, int index)
|
||||
{
|
||||
m_device = device;
|
||||
m_index = index;
|
||||
m_receive_timer = device->machine().scheduler().timer_alloc(FUNC(static_serial_callback), this);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// reset - reset a single SIO channel
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::sio_channel::reset()
|
||||
{
|
||||
m_status[0] = SIO_RR0_TX_BUFFER_EMPTY;
|
||||
m_status[1] = 0x00;
|
||||
m_status[2] = 0x00;
|
||||
m_int_on_next_rx = false;
|
||||
m_outbuf = -1;
|
||||
|
||||
// reset interrupts
|
||||
clear_interrupt(INT_TRANSMIT);
|
||||
clear_interrupt(INT_STATUS);
|
||||
clear_interrupt(INT_RECEIVE);
|
||||
clear_interrupt(INT_ERROR);
|
||||
|
||||
// start the receive timer running
|
||||
attotime tpc = compute_time_per_character();
|
||||
m_receive_timer->adjust(tpc, 0, tpc);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// control_write - write to a control register
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::sio_channel::control_write(UINT8 data)
|
||||
{
|
||||
int regnum = m_regs[0] & 7;
|
||||
|
||||
if (regnum != 0 || (regnum & 0xf8) != 0)
|
||||
VPRINTF(("%s:sio_reg_w(%c,%d) = %02X\n", m_device->machine().describe_context(), 'A' + m_index, regnum, data));
|
||||
|
||||
// write a new value to the selected register
|
||||
//UINT8 old = m_regs[regnum];
|
||||
m_regs[regnum] = data;
|
||||
|
||||
// clear the register number for the next write
|
||||
if (regnum != 0)
|
||||
m_regs[0] &= ~7;
|
||||
|
||||
// switch off the register for live state changes
|
||||
switch (regnum)
|
||||
{
|
||||
// SIO write register 0
|
||||
case 0:
|
||||
switch (data & SIO_WR0_COMMAND_MASK)
|
||||
{
|
||||
case SIO_WR0_COMMAND_CH_RESET:
|
||||
VPRINTF(("%s:SIO reset channel %c\n", m_device->machine().describe_context(), 'A' + m_index));
|
||||
reset();
|
||||
break;
|
||||
|
||||
case SIO_WR0_COMMAND_RES_STATUS_INT:
|
||||
clear_interrupt(INT_STATUS);
|
||||
break;
|
||||
|
||||
case SIO_WR0_COMMAND_ENA_RX_INT:
|
||||
m_int_on_next_rx = true;
|
||||
m_device->update_interrupt_state();
|
||||
break;
|
||||
|
||||
case SIO_WR0_COMMAND_RES_TX_INT:
|
||||
clear_interrupt(INT_TRANSMIT);
|
||||
break;
|
||||
|
||||
case SIO_WR0_COMMAND_RES_ERROR:
|
||||
clear_interrupt(INT_ERROR);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// SIO write register 1
|
||||
case 1:
|
||||
m_device->update_interrupt_state();
|
||||
break;
|
||||
|
||||
// SIO write register 5
|
||||
case 5:
|
||||
/*
|
||||
if (((old ^ data) & SIO_WR5_DTR) && !m_device->m_dtr_changed.isnull())
|
||||
m_device->m_dtr_changed(m_index, (data & SIO_WR5_DTR) != 0);
|
||||
if (((old ^ data) & SIO_WR5_SEND_BREAK) && !m_device->m_break_changed.isnull())
|
||||
m_device->m_break_changed(m_index, (data & SIO_WR5_SEND_BREAK) != 0);
|
||||
if (((old ^ data) & SIO_WR5_RTS) && !m_device->m_rts_changed.isnull())
|
||||
m_device->m_rts_changed(m_index, (data & SIO_WR5_RTS) != 0);
|
||||
*/
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// control_read - read from a control register
|
||||
//-------------------------------------------------
|
||||
|
||||
UINT8 z80sio_device::sio_channel::control_read()
|
||||
{
|
||||
int regnum = m_regs[0] & 7;
|
||||
UINT8 result = m_status[regnum];
|
||||
|
||||
// switch off the register for live state changes
|
||||
switch (regnum)
|
||||
{
|
||||
// SIO read register 0
|
||||
case 0:
|
||||
result &= ~SIO_RR0_INT_PENDING;
|
||||
if (m_device->z80daisy_irq_state() & Z80_DAISY_INT)
|
||||
result |= SIO_RR0_INT_PENDING;
|
||||
break;
|
||||
}
|
||||
|
||||
VPRINTF(("%s:sio_reg_r(%c,%d) = %02x\n", m_device->machine().describe_context(), 'A' + m_index, regnum, m_status[regnum]));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// data_write - write to a data register
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::sio_channel::data_write(UINT8 data)
|
||||
{
|
||||
VPRINTF(("%s:sio_data_w(%c) = %02X\n", m_device->machine().describe_context(), 'A' + m_index, data));
|
||||
|
||||
// if tx not enabled, just ignore it
|
||||
if (!(m_regs[5] & SIO_WR5_TX_ENABLE))
|
||||
return;
|
||||
|
||||
// update the status register
|
||||
m_status[0] &= ~SIO_RR0_TX_BUFFER_EMPTY;
|
||||
|
||||
// reset the transmit interrupt
|
||||
clear_interrupt(INT_TRANSMIT);
|
||||
|
||||
// stash the character
|
||||
m_outbuf = data;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// data_read - read from a data register
|
||||
//-------------------------------------------------
|
||||
|
||||
UINT8 z80sio_device::sio_channel::data_read()
|
||||
{
|
||||
// update the status register
|
||||
m_status[0] &= ~SIO_RR0_RX_CHAR_AVAILABLE;
|
||||
|
||||
// reset the receive interrupt
|
||||
clear_interrupt(INT_RECEIVE);
|
||||
|
||||
VPRINTF(("%s:sio_data_r(%c) = %02X\n", m_device->machine().describe_context(), 'A' + m_index, m_inbuf));
|
||||
|
||||
return m_inbuf;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// dtr - return the state of the DTR line
|
||||
//-------------------------------------------------
|
||||
|
||||
int z80sio_device::sio_channel::dtr()
|
||||
{
|
||||
return ((m_regs[5] & SIO_WR5_DTR) != 0);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rts - return the state of the RTS line
|
||||
//-------------------------------------------------
|
||||
|
||||
int z80sio_device::sio_channel::rts()
|
||||
{
|
||||
return ((m_regs[5] & SIO_WR5_RTS) != 0);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_cts - set the state of the CTS line
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::sio_channel::set_cts(int state)
|
||||
{
|
||||
m_device->machine().scheduler().synchronize(FUNC(static_change_input_line), (SIO_RR0_CTS << 1) + (state != 0), this);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_dcd - set the state of the DCD line
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::sio_channel::set_dcd(int state)
|
||||
{
|
||||
m_device->machine().scheduler().synchronize(FUNC(static_change_input_line), (SIO_RR0_DCD << 1) + (state != 0), this);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// receive_data - receive data on the input lines
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::sio_channel::receive_data(int data)
|
||||
{
|
||||
// put it on the queue
|
||||
int newinptr = (m_receive_inptr + 1) % ARRAY_LENGTH(m_receive_buffer);
|
||||
if (newinptr != m_receive_outptr)
|
||||
{
|
||||
m_receive_buffer[m_receive_inptr] = data;
|
||||
m_receive_inptr = newinptr;
|
||||
}
|
||||
else
|
||||
logerror("z80sio_receive_data: buffer overrun\n");
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// change_input_line - generically change the
|
||||
// state of an input line; designed to be called
|
||||
// from a timer callback
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::sio_channel::change_input_line(int line, int state)
|
||||
{
|
||||
VPRINTF(("sio_change_input_line(%c, %s) = %d\n", 'A' + m_index, (line == SIO_RR0_CTS) ? "CTS" : "DCD", state));
|
||||
|
||||
// remember the old value
|
||||
UINT8 old = m_status[0];
|
||||
|
||||
// set the bit in the status register
|
||||
m_status[0] &= ~line;
|
||||
if (state)
|
||||
m_status[0] |= line;
|
||||
|
||||
// if state change interrupts are enabled, signal
|
||||
if (((old ^ m_status[0]) & line) && (m_regs[1] & SIO_WR1_STATUSINT_ENABLE))
|
||||
set_interrupt(INT_STATUS);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// serial_callback - callback to pump
|
||||
// data through
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80sio_device::sio_channel::serial_callback()
|
||||
{
|
||||
int data = -1;
|
||||
|
||||
// first perform any outstanding transmits
|
||||
if (m_outbuf != -1)
|
||||
{
|
||||
VPRINTF(("serial_callback(%c): Transmitting %02x\n", 'A' + m_index, m_outbuf));
|
||||
|
||||
// actually transmit the character
|
||||
if (!m_device->m_transmit.isnull())
|
||||
m_device->m_transmit(m_index, m_outbuf, 0xffff);
|
||||
|
||||
// update the status register
|
||||
m_status[0] |= SIO_RR0_TX_BUFFER_EMPTY;
|
||||
|
||||
// set the transmit buffer empty interrupt if enabled
|
||||
if (m_regs[1] & SIO_WR1_TXINT_ENABLE)
|
||||
set_interrupt(INT_TRANSMIT);
|
||||
|
||||
// reset the output buffer
|
||||
m_outbuf = -1;
|
||||
}
|
||||
|
||||
// ask the polling callback if there is data to receive
|
||||
if (!m_device->m_received_poll.isnull())
|
||||
data = INT16(m_device->m_received_poll(m_index, 0xffff));
|
||||
|
||||
// if we have buffered data, pull it
|
||||
if (m_receive_inptr != m_receive_outptr)
|
||||
{
|
||||
data = m_receive_buffer[m_receive_outptr];
|
||||
m_receive_outptr = (m_receive_outptr + 1) % ARRAY_LENGTH(m_receive_buffer);
|
||||
}
|
||||
|
||||
// if we have data, receive it
|
||||
if (data != -1)
|
||||
{
|
||||
VPRINTF(("serial_callback(%c): Receiving %02x\n", 'A' + m_index, data));
|
||||
|
||||
// if rx not enabled, just ignore it
|
||||
if (!(m_regs[3] & SIO_WR3_RX_ENABLE))
|
||||
{
|
||||
VPRINTF((" (ignored because receive is disabled)\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// stash the data and update the status
|
||||
m_inbuf = data;
|
||||
m_status[0] |= SIO_RR0_RX_CHAR_AVAILABLE;
|
||||
|
||||
// update our interrupt state
|
||||
switch (m_regs[1] & SIO_WR1_RXINT_MASK)
|
||||
{
|
||||
case SIO_WR1_RXINT_FIRST:
|
||||
if (!m_int_on_next_rx)
|
||||
break;
|
||||
|
||||
case SIO_WR1_RXINT_ALL_NOPARITY:
|
||||
case SIO_WR1_RXINT_ALL_PARITY:
|
||||
set_interrupt(INT_RECEIVE);
|
||||
break;
|
||||
}
|
||||
m_int_on_next_rx = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL STUBS
|
||||
//**************************************************************************
|
||||
|
||||
READ8_MEMBER( z80sio_device::read )
|
||||
{
|
||||
switch (offset & 3)
|
||||
{
|
||||
case 0: return data_read(0);
|
||||
case 1: return data_read(1);
|
||||
case 2: return control_read(0);
|
||||
case 3: return control_read(1);
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( z80sio_device::write )
|
||||
{
|
||||
switch (offset & 3)
|
||||
{
|
||||
case 0: data_write(0, data); break;
|
||||
case 1: data_write(1, data); break;
|
||||
case 2: control_write(0, data); break;
|
||||
case 3: control_write(1, data); break;
|
||||
}
|
||||
}
|
||||
|
||||
READ8_MEMBER( z80sio_device::read_alt )
|
||||
{
|
||||
switch (offset & 3)
|
||||
{
|
||||
case 0: return data_read(0);
|
||||
case 1: return control_read(0);
|
||||
case 2: return data_read(1);
|
||||
case 3: return control_read(1);
|
||||
}
|
||||
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
WRITE8_MEMBER( z80sio_device::write_alt )
|
||||
{
|
||||
switch (offset & 3)
|
||||
{
|
||||
case 0: data_write(0, data); break;
|
||||
case 1: control_write(0, data); break;
|
||||
case 2: data_write(1, data); break;
|
||||
case 3: control_write(1, data); break;
|
||||
}
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
/***************************************************************************
|
||||
|
||||
!!! DEPRECATED DO NOT USE !!!
|
||||
|
||||
WILL BE DELETED WHEN src/mame/drivers/dlair.c USES z80dart.h
|
||||
|
||||
Z80 SIO (Z8440) implementation
|
||||
|
||||
Copyright Nicola Salmoria and the MAME Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __Z80SIO_H__
|
||||
#define __Z80SIO_H__
|
||||
|
||||
#include "cpu/z80/z80daisy.h"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE CONFIGURATION MACROS
|
||||
//**************************************************************************
|
||||
|
||||
#define MCFG_Z80SIO_INT_CALLBACK(_write) \
|
||||
devcb = &z80sio_device::set_int_callback(*device, DEVCB_##_write);
|
||||
|
||||
#define MCFG_Z80SIO_TRANSMIT_CALLBACK(_write) \
|
||||
devcb = &z80sio_device::set_transmit_callback(*device, DEVCB_##_write);
|
||||
|
||||
#define MCFG_Z80SIO_RECEIVE_CALLBACK(_read) \
|
||||
devcb = &z80sio_device::set_receive_callback(*device, DEVCB_##_read);
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> z80sio_device
|
||||
|
||||
class z80sio_device : public device_t,
|
||||
public device_z80daisy_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
z80sio_device(const machine_config &mconfig, const char *tag, device_t *owner, UINT32 clock);
|
||||
|
||||
template<class _Object> static devcb_base &set_int_callback(device_t &device, _Object object) { return downcast<z80sio_device &>(device).m_irq.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_transmit_callback(device_t &device, _Object object) { return downcast<z80sio_device &>(device).m_transmit.set_callback(object); }
|
||||
template<class _Object> static devcb_base &set_receive_callback(device_t &device, _Object object) { return downcast<z80sio_device &>(device).m_received_poll.set_callback(object); }
|
||||
|
||||
// control register I/O
|
||||
UINT8 control_read(int ch) { return m_channel[ch].control_read(); }
|
||||
void control_write(int ch, UINT8 data) { m_channel[ch].control_write(data); }
|
||||
|
||||
// data register I/O
|
||||
UINT8 data_read(int ch) { return m_channel[ch].data_read(); }
|
||||
void data_write(int ch, UINT8 data) { m_channel[ch].data_write(data); }
|
||||
|
||||
// communication line I/O
|
||||
int dtr(int ch) { return m_channel[ch].dtr(); }
|
||||
int rts(int ch) { return m_channel[ch].rts(); }
|
||||
void set_cts(int ch, int state) { m_channel[ch].set_cts(state); }
|
||||
void set_dcd(int ch, int state) { m_channel[ch].set_dcd(state); }
|
||||
void receive_data(int ch, int data) { m_channel[ch].receive_data(data); }
|
||||
|
||||
// standard read/write, with C/D in bit 1, B/A in bit 0
|
||||
DECLARE_READ8_MEMBER( read );
|
||||
DECLARE_WRITE8_MEMBER( write );
|
||||
|
||||
// alternate read/write, with C/D in bit 0, B/A in bit 1
|
||||
DECLARE_READ8_MEMBER( read_alt );
|
||||
DECLARE_WRITE8_MEMBER( write_alt );
|
||||
|
||||
private:
|
||||
// device-level overrides
|
||||
virtual void device_start();
|
||||
virtual void device_reset();
|
||||
|
||||
// device_z80daisy_interface overrides
|
||||
virtual int z80daisy_irq_state();
|
||||
virtual int z80daisy_irq_ack();
|
||||
virtual void z80daisy_irq_reti();
|
||||
|
||||
// internal helpers
|
||||
void update_interrupt_state();
|
||||
|
||||
// a single SIO channel
|
||||
class sio_channel
|
||||
{
|
||||
public:
|
||||
sio_channel();
|
||||
|
||||
void start(z80sio_device *device, int index);
|
||||
void reset();
|
||||
|
||||
UINT8 control_read();
|
||||
UINT8 data_read();
|
||||
void control_write(UINT8 data);
|
||||
void data_write(UINT8 data);
|
||||
|
||||
int dtr();
|
||||
int rts();
|
||||
void set_cts(int state);
|
||||
void set_dcd(int state);
|
||||
void receive_data(int data);
|
||||
|
||||
private:
|
||||
void set_interrupt(int type);
|
||||
void clear_interrupt(int type);
|
||||
attotime compute_time_per_character();
|
||||
|
||||
static TIMER_CALLBACK( static_change_input_line ) { reinterpret_cast<sio_channel *>(ptr)->change_input_line(param >> 1, param & 1); }
|
||||
void change_input_line(int line, int state);
|
||||
|
||||
static TIMER_CALLBACK( static_serial_callback ) { reinterpret_cast<sio_channel *>(ptr)->serial_callback(); }
|
||||
void serial_callback();
|
||||
|
||||
public:
|
||||
UINT8 m_regs[8]; // 8 writeable registers
|
||||
|
||||
private:
|
||||
z80sio_device *m_device; // pointer back to our device
|
||||
int m_index; // our channel index
|
||||
UINT8 m_status[4]; // 3 readable registers
|
||||
int m_inbuf; // input buffer
|
||||
int m_outbuf; // output buffer
|
||||
bool m_int_on_next_rx; // interrupt on next rx?
|
||||
emu_timer * m_receive_timer; // timer to clock data in
|
||||
UINT8 m_receive_buffer[16]; // buffer for incoming data
|
||||
UINT8 m_receive_inptr; // index of data coming in
|
||||
UINT8 m_receive_outptr; // index of data going out
|
||||
};
|
||||
|
||||
// internal state
|
||||
sio_channel m_channel[2]; // 2 channels
|
||||
UINT8 m_int_state[8]; // interrupt states
|
||||
|
||||
// callbacks
|
||||
devcb_write_line m_irq;
|
||||
devcb_write8 m_dtr_changed;
|
||||
devcb_write8 m_rts_changed;
|
||||
devcb_write8 m_break_changed;
|
||||
devcb_write16 m_transmit;
|
||||
devcb_read16 m_received_poll;
|
||||
|
||||
static const UINT8 k_int_priority[];
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const ATTR_DEPRECATED device_type Z80SIO;
|
||||
|
||||
|
||||
#endif
|
@ -550,7 +550,6 @@ MACHINES += Z80CTC
|
||||
MACHINES += Z80DART
|
||||
MACHINES += Z80DMA
|
||||
MACHINES += Z80PIO
|
||||
MACHINES += Z80SIO
|
||||
MACHINES += Z80STI
|
||||
MACHINES += Z8536
|
||||
MACHINES += SECFLASH
|
||||
|
@ -541,7 +541,6 @@ MACHINES += Z80CTC
|
||||
MACHINES += Z80DART
|
||||
MACHINES += Z80DMA
|
||||
MACHINES += Z80PIO
|
||||
MACHINES += Z80SIO
|
||||
MACHINES += Z80STI
|
||||
MACHINES += Z8536
|
||||
#MACHINES += SECFLASH
|
||||
|
Loading…
Reference in New Issue
Block a user