mirror of
https://github.com/holub/mame
synced 2025-05-16 10:52:43 +03:00
Expanded the Z80-DART interface to allow future implementation of Z80-SIO features: [Curt Coder]
- added separate clock inputs for channel B - added SYNC inputs/outputs for both channels
This commit is contained in:
parent
e5e8a7b4d9
commit
6791eb9adb
@ -5,12 +5,19 @@
|
||||
Copyright (c) 2008, The MESS Team.
|
||||
Visit http://mamedev.org for licensing and usage restrictions.
|
||||
|
||||
The z80dart/z80sio itself is based on an older intel serial chip, the i8274 MPSC
|
||||
(see http://doc.chipfind.ru/pdf/intel/8274.pdf), which also has almost identical
|
||||
behavior, except lacks the interrupt daisy chaining and has its own interrupt/dma
|
||||
scheme which uses write register 2 on channel A, that register which is unused on
|
||||
the z80dart and z80sio.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
/*
|
||||
|
||||
TODO:
|
||||
|
||||
- synchronous mode (Z80-SIO/1,2)
|
||||
- break detection
|
||||
- wr0 reset tx interrupt pending
|
||||
- wait/ready
|
||||
@ -193,17 +200,19 @@ void z80dart_device_config::device_config_complete()
|
||||
// or initialize to defaults if none provided
|
||||
else
|
||||
{
|
||||
m_rx_clock_a = m_tx_clock_a = m_rx_tx_clock_b = 0;
|
||||
m_rx_clock_a = m_tx_clock_a = m_rx_clock_b = m_tx_clock_b = 0;
|
||||
memset(&m_in_rxda_func, 0, sizeof(m_in_rxda_func));
|
||||
memset(&m_out_txda_func, 0, sizeof(m_out_txda_func));
|
||||
memset(&m_out_dtra_func, 0, sizeof(m_out_dtra_func));
|
||||
memset(&m_out_rtsa_func, 0, sizeof(m_out_rtsa_func));
|
||||
memset(&m_out_wrdya_func, 0, sizeof(m_out_wrdya_func));
|
||||
memset(&m_out_synca_func, 0, sizeof(m_out_synca_func));
|
||||
memset(&m_in_rxdb_func, 0, sizeof(m_in_rxdb_func));
|
||||
memset(&m_out_txdb_func, 0, sizeof(m_out_txdb_func));
|
||||
memset(&m_out_dtrb_func, 0, sizeof(m_out_dtrb_func));
|
||||
memset(&m_out_rtsb_func, 0, sizeof(m_out_rtsb_func));
|
||||
memset(&m_out_wrdyb_func, 0, sizeof(m_out_wrdyb_func));
|
||||
memset(&m_out_syncb_func, 0, sizeof(m_out_syncb_func));
|
||||
memset(&m_out_int_func, 0, sizeof(m_out_int_func));
|
||||
}
|
||||
}
|
||||
@ -237,28 +246,35 @@ void z80dart_device::device_start()
|
||||
// resolve callbacks
|
||||
devcb_resolve_write_line(&m_out_int_func, &m_config.m_out_int_func, this);
|
||||
|
||||
m_channel[Z80DART_CH_A].start(this, Z80DART_CH_A, m_config.m_in_rxda_func, m_config.m_out_txda_func, m_config.m_out_dtra_func, m_config.m_out_rtsa_func, m_config.m_out_wrdya_func);
|
||||
m_channel[Z80DART_CH_B].start(this, Z80DART_CH_B, m_config.m_in_rxdb_func, m_config.m_out_txdb_func, m_config.m_out_dtrb_func, m_config.m_out_rtsb_func, m_config.m_out_wrdyb_func);
|
||||
m_channel[Z80DART_CH_A].start(this, Z80DART_CH_A, m_config.m_in_rxda_func, m_config.m_out_txda_func, m_config.m_out_dtra_func, m_config.m_out_rtsa_func, m_config.m_out_wrdya_func, m_config.m_out_synca_func);
|
||||
m_channel[Z80DART_CH_B].start(this, Z80DART_CH_B, m_config.m_in_rxdb_func, m_config.m_out_txdb_func, m_config.m_out_dtrb_func, m_config.m_out_rtsb_func, m_config.m_out_wrdyb_func, m_config.m_out_syncb_func);
|
||||
|
||||
if (m_config.m_rx_clock_a != 0)
|
||||
{
|
||||
// allocate channel A receive timer
|
||||
m_rxca_timer = timer_alloc(&m_machine, dart_channel::static_rxca_tick, (void *)&m_channel[Z80DART_CH_A]);
|
||||
m_rxca_timer = timer_alloc(&m_machine, dart_channel::static_rxc_tick, (void *)&m_channel[Z80DART_CH_A]);
|
||||
timer_adjust_periodic(m_rxca_timer, attotime_zero, 0, ATTOTIME_IN_HZ(m_config.m_rx_clock_a));
|
||||
}
|
||||
|
||||
if (m_config.m_tx_clock_a != 0)
|
||||
{
|
||||
// allocate channel A transmit timer
|
||||
m_txca_timer = timer_alloc(&m_machine, dart_channel::static_txca_tick, (void *)&m_channel[Z80DART_CH_A]);
|
||||
m_txca_timer = timer_alloc(&m_machine, dart_channel::static_txc_tick, (void *)&m_channel[Z80DART_CH_A]);
|
||||
timer_adjust_periodic(m_txca_timer, attotime_zero, 0, ATTOTIME_IN_HZ(m_config.m_tx_clock_a));
|
||||
}
|
||||
|
||||
if (m_config.m_rx_tx_clock_b != 0)
|
||||
if (m_config.m_rx_clock_b != 0)
|
||||
{
|
||||
// allocate channel B receive/transmit timer
|
||||
m_rxtxcb_timer = timer_alloc(&m_machine, dart_channel::static_rxtxcb_tick, (void *)&m_channel[Z80DART_CH_B]);
|
||||
timer_adjust_periodic(m_rxtxcb_timer, attotime_zero, 0, ATTOTIME_IN_HZ(m_config.m_rx_tx_clock_b));
|
||||
// allocate channel B receive timer
|
||||
m_rxcb_timer = timer_alloc(&m_machine, dart_channel::static_rxc_tick, (void *)&m_channel[Z80DART_CH_B]);
|
||||
timer_adjust_periodic(m_rxcb_timer, attotime_zero, 0, ATTOTIME_IN_HZ(m_config.m_rx_clock_b));
|
||||
}
|
||||
|
||||
if (m_config.m_tx_clock_b != 0)
|
||||
{
|
||||
// allocate channel B transmit timer
|
||||
m_txcb_timer = timer_alloc(&m_machine, dart_channel::static_txc_tick, (void *)&m_channel[Z80DART_CH_B]);
|
||||
timer_adjust_periodic(m_txcb_timer, attotime_zero, 0, ATTOTIME_IN_HZ(m_config.m_tx_clock_b));
|
||||
}
|
||||
|
||||
state_save_register_device_item_array(this, 0, m_int_state);
|
||||
@ -456,7 +472,7 @@ z80dart_device::dart_channel::dart_channel()
|
||||
// start - channel startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80dart_device::dart_channel::start(z80dart_device *device, int index, const devcb_read_line &in_rxd, const devcb_write_line &out_txd, const devcb_write_line &out_dtr, const devcb_write_line &out_rts, const devcb_write_line &out_wrdy)
|
||||
void z80dart_device::dart_channel::start(z80dart_device *device, int index, const devcb_read_line &in_rxd, const devcb_write_line &out_txd, const devcb_write_line &out_dtr, const devcb_write_line &out_rts, const devcb_write_line &out_wrdy, const devcb_write_line &out_sync)
|
||||
{
|
||||
m_index = index;
|
||||
m_device = device;
|
||||
@ -466,6 +482,7 @@ void z80dart_device::dart_channel::start(z80dart_device *device, int index, cons
|
||||
devcb_resolve_write_line(&m_out_dtr_func, &out_dtr, m_device);
|
||||
devcb_resolve_write_line(&m_out_rts_func, &out_rts, m_device);
|
||||
devcb_resolve_write_line(&m_out_wrdy_func, &out_wrdy, m_device);
|
||||
devcb_resolve_write_line(&m_out_sync_func, &out_sync, m_device);
|
||||
|
||||
state_save_register_device_item_array(m_device, m_index, m_rr);
|
||||
state_save_register_device_item_array(m_device, m_index, m_wr);
|
||||
@ -1314,6 +1331,16 @@ void z80dart_device::dart_channel::ri_w(int state)
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sync_w - sync handler
|
||||
//-------------------------------------------------
|
||||
|
||||
void z80dart_device::dart_channel::sync_w(int state)
|
||||
{
|
||||
LOG(("Z80DART \"%s\" Channel %c : SYNC %u\n", m_device->tag(), 'A' + m_index, state));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// rx_w - receive clock
|
||||
//-------------------------------------------------
|
||||
@ -1373,9 +1400,13 @@ WRITE_LINE_DEVICE_HANDLER( z80dart_dcda_w ) { downcast<z80dart_device *>(device)
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_dcdb_w ) { downcast<z80dart_device *>(device)->dcd_w(Z80DART_CH_B, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_ria_w ) { downcast<z80dart_device *>(device)->ri_w(Z80DART_CH_A, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rib_w ) { downcast<z80dart_device *>(device)->ri_w(Z80DART_CH_B, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_synca_w ) { downcast<z80dart_device *>(device)->sync_w(Z80DART_CH_A, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_syncb_w ) { downcast<z80dart_device *>(device)->sync_w(Z80DART_CH_B, state); }
|
||||
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rxca_w ) { downcast<z80dart_device *>(device)->rx_w(Z80DART_CH_A, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_txca_w ) { downcast<z80dart_device *>(device)->tx_w(Z80DART_CH_A, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rxcb_w ) { downcast<z80dart_device *>(device)->rx_w(Z80DART_CH_B, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_txcb_w ) { downcast<z80dart_device *>(device)->tx_w(Z80DART_CH_B, state); }
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rxtxcb_w ) { downcast<z80dart_device *>(device)->rx_w(Z80DART_CH_B, state); downcast<z80dart_device *>(device)->tx_w(Z80DART_CH_B, state); }
|
||||
|
||||
READ8_DEVICE_HANDLER( z80dart_cd_ba_r )
|
||||
@ -1409,3 +1440,6 @@ WRITE8_DEVICE_HANDLER( z80dart_ba_cd_w )
|
||||
}
|
||||
|
||||
const device_type Z80DART = z80dart_device_config::static_alloc_device_config;
|
||||
const device_type Z80SIO0 = z80dart_device_config::static_alloc_device_config; // FIXME
|
||||
const device_type Z80SIO1 = z80dart_device_config::static_alloc_device_config; // FIXME
|
||||
const device_type Z80SIO2 = z80dart_device_config::static_alloc_device_config; // FIXME
|
||||
|
@ -17,7 +17,7 @@
|
||||
_M1 8 | | 33 C/_D
|
||||
Vdd 9 | | 32 _RD
|
||||
_W/RDYA 10 | Z80-DART | 31 GND
|
||||
_RIA 11 | | 30 _W/RDYB
|
||||
_RIA 11 | Z80-SIO/0 | 30 _W/RDYB
|
||||
RxDA 12 | | 29 _RIB
|
||||
_RxCA 13 | | 28 RxDB
|
||||
_TxCA 14 | | 27 _RxTxCB
|
||||
@ -28,6 +28,50 @@
|
||||
_DCDA 19 | | 22 _DCDB
|
||||
CLK 20 |_____________| 21 _RESET
|
||||
|
||||
_____ _____
|
||||
D1 1 |* \_/ | 40 D0
|
||||
D3 2 | | 39 D2
|
||||
D5 3 | | 38 D4
|
||||
D7 4 | | 37 D6
|
||||
_INT 5 | | 36 _IORQ
|
||||
IEI 6 | | 35 _CE
|
||||
IEO 7 | | 34 B/_A
|
||||
_M1 8 | | 33 C/_D
|
||||
Vdd 9 | | 32 _RD
|
||||
_W/RDYA 10 | Z80-SIO/1 | 31 GND
|
||||
_SYNCA 11 | | 30 _W/RDYB
|
||||
RxDA 12 | | 29 _SYNCB
|
||||
_RxCA 13 | | 28 RxDB
|
||||
_TxCA 14 | | 27 _RxCB
|
||||
TxDA 15 | | 26 _TxCB
|
||||
_DTRA 16 | | 25 TxDB
|
||||
_RTSA 17 | | 24 _RTSB
|
||||
_CTSA 18 | | 23 _CTSB
|
||||
_DCDA 19 | | 22 _DCDB
|
||||
CLK 20 |_____________| 21 _RESET
|
||||
|
||||
_____ _____
|
||||
D1 1 |* \_/ | 40 D0
|
||||
D3 2 | | 39 D2
|
||||
D5 3 | | 38 D4
|
||||
D7 4 | | 37 D6
|
||||
_INT 5 | | 36 _IORQ
|
||||
IEI 6 | | 35 _CE
|
||||
IEO 7 | | 34 B/_A
|
||||
_M1 8 | | 33 C/_D
|
||||
Vdd 9 | | 32 _RD
|
||||
_W/RDYA 10 | Z80-SIO/2 | 31 GND
|
||||
_SYNCA 11 | | 30 _W/RDYB
|
||||
RxDA 12 | | 29 _RxDB
|
||||
_RxCA 13 | | 28 _RxCB
|
||||
_TxCA 14 | | 27 _TxCB
|
||||
TxDA 15 | | 26 TxDB
|
||||
_DTRA 16 | | 25 _DTRB
|
||||
_RTSA 17 | | 24 _RTSB
|
||||
_CTSA 18 | | 23 _CTSB
|
||||
_DCDA 19 | | 22 _DCDB
|
||||
CLK 20 |_____________| 21 _RESET
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef __Z80DART_H__
|
||||
@ -57,6 +101,18 @@ enum
|
||||
MDRV_DEVICE_ADD(_tag, Z80DART, _clock) \
|
||||
MDRV_DEVICE_CONFIG(_config)
|
||||
|
||||
#define MDRV_Z80SIO0_ADD(_tag, _clock, _config) \
|
||||
MDRV_DEVICE_ADD(_tag, Z80SIO0, _clock) \
|
||||
MDRV_DEVICE_CONFIG(_config)
|
||||
|
||||
#define MDRV_Z80SIO1_ADD(_tag, _clock, _config) \
|
||||
MDRV_DEVICE_ADD(_tag, Z80SIO1, _clock) \
|
||||
MDRV_DEVICE_CONFIG(_config)
|
||||
|
||||
#define MDRV_Z80SIO2_ADD(_tag, _clock, _config) \
|
||||
MDRV_DEVICE_ADD(_tag, Z80SIO2, _clock) \
|
||||
MDRV_DEVICE_CONFIG(_config)
|
||||
|
||||
#define MDRV_Z80DART_REMOVE(_tag) \
|
||||
MDRV_DEVICE_REMOVE(_tag)
|
||||
|
||||
@ -76,19 +132,22 @@ struct z80dart_interface
|
||||
{
|
||||
int m_rx_clock_a; // channel A receive clock
|
||||
int m_tx_clock_a; // channel A transmit clock
|
||||
int m_rx_tx_clock_b; // channel B receive/transmit clock
|
||||
int m_rx_clock_b; // channel B receive clock
|
||||
int m_tx_clock_b; // channel B transmit clock
|
||||
|
||||
devcb_read_line m_in_rxda_func;
|
||||
devcb_write_line m_out_txda_func;
|
||||
devcb_write_line m_out_dtra_func;
|
||||
devcb_write_line m_out_rtsa_func;
|
||||
devcb_write_line m_out_wrdya_func;
|
||||
devcb_write_line m_out_synca_func;
|
||||
|
||||
devcb_read_line m_in_rxdb_func;
|
||||
devcb_write_line m_out_txdb_func;
|
||||
devcb_write_line m_out_dtrb_func;
|
||||
devcb_write_line m_out_rtsb_func;
|
||||
devcb_write_line m_out_wrdyb_func;
|
||||
devcb_write_line m_out_syncb_func;
|
||||
|
||||
devcb_write_line m_out_int_func;
|
||||
};
|
||||
@ -147,6 +206,7 @@ public:
|
||||
void ri_w(int which, int state) { m_channel[which].ri_w(state); }
|
||||
void rx_w(int which, int state) { m_channel[which].rx_w(state); }
|
||||
void tx_w(int which, int state) { m_channel[which].tx_w(state); }
|
||||
void sync_w(int which, int state) { m_channel[which].sync_w(state); }
|
||||
|
||||
private:
|
||||
// device-level overrides
|
||||
@ -170,7 +230,7 @@ private:
|
||||
public:
|
||||
dart_channel();
|
||||
|
||||
void start(z80dart_device *device, int index, const devcb_read_line &in_rxd, const devcb_write_line &out_txd, const devcb_write_line &out_dtr, const devcb_write_line &out_rts, const devcb_write_line &out_wrdy);
|
||||
void start(z80dart_device *device, int index, const devcb_read_line &in_rxd, const devcb_write_line &out_txd, const devcb_write_line &out_dtr, const devcb_write_line &out_rts, const devcb_write_line &out_wrdy, const devcb_write_line &out_sync);
|
||||
void reset();
|
||||
|
||||
UINT8 control_read();
|
||||
@ -186,6 +246,7 @@ private:
|
||||
void ri_w(int state);
|
||||
void rx_w(int state);
|
||||
void tx_w(int state);
|
||||
void sync_w(int state);
|
||||
|
||||
private:
|
||||
void take_interrupt(int level);
|
||||
@ -201,9 +262,8 @@ private:
|
||||
void receive();
|
||||
void transmit();
|
||||
|
||||
static TIMER_CALLBACK( static_rxca_tick ) { reinterpret_cast<dart_channel *>(ptr)->rx_w(1); }
|
||||
static TIMER_CALLBACK( static_txca_tick ) { reinterpret_cast<dart_channel *>(ptr)->tx_w(1); }
|
||||
static TIMER_CALLBACK( static_rxtxcb_tick ) { reinterpret_cast<dart_channel *>(ptr)->rx_w(1); reinterpret_cast<dart_channel *>(ptr)->tx_w(1); }
|
||||
static TIMER_CALLBACK( static_rxc_tick ) { reinterpret_cast<dart_channel *>(ptr)->rx_w(1); }
|
||||
static TIMER_CALLBACK( static_txc_tick ) { reinterpret_cast<dart_channel *>(ptr)->tx_w(1); }
|
||||
|
||||
z80dart_device *m_device;
|
||||
int m_index;
|
||||
@ -213,6 +273,7 @@ private:
|
||||
devcb_resolved_write_line m_out_dtr_func;
|
||||
devcb_resolved_write_line m_out_rts_func;
|
||||
devcb_resolved_write_line m_out_wrdy_func;
|
||||
devcb_resolved_write_line m_out_sync_func;
|
||||
|
||||
// register state
|
||||
UINT8 m_rr[3]; // read register
|
||||
@ -259,12 +320,16 @@ private:
|
||||
// timers
|
||||
emu_timer * m_rxca_timer;
|
||||
emu_timer * m_txca_timer;
|
||||
emu_timer * m_rxtxcb_timer;
|
||||
emu_timer * m_rxcb_timer;
|
||||
emu_timer * m_txcb_timer;
|
||||
};
|
||||
|
||||
|
||||
// device type definition
|
||||
extern const device_type Z80DART;
|
||||
extern const device_type Z80SIO0;
|
||||
extern const device_type Z80SIO1;
|
||||
extern const device_type Z80SIO2;
|
||||
/*
|
||||
#define Z8470 DEVICE_GET_INFO_NAME(z8470)
|
||||
#define LH0081 DEVICE_GET_INFO_NAME(lh0088)
|
||||
@ -295,6 +360,8 @@ READ8_DEVICE_HANDLER( z80dart_d_r );
|
||||
// serial clocks
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rxca_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_txca_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rxcb_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_txcb_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_rxtxcb_w );
|
||||
|
||||
// ring indicator
|
||||
@ -309,5 +376,8 @@ WRITE_LINE_DEVICE_HANDLER( z80dart_dcdb_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_ctsa_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_ctsb_w );
|
||||
|
||||
// sync
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_synca_w );
|
||||
WRITE_LINE_DEVICE_HANDLER( z80dart_syncb_w );
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user