summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/machine
diff options
context:
space:
mode:
author Curt Coder <curtcoder@mail.com>2010-08-21 00:03:37 +0000
committer Curt Coder <curtcoder@mail.com>2010-08-21 00:03:37 +0000
commit6791eb9adb17a1f11a461c311b9dd066033f5187 (patch)
treee25de46eb0ae028a6d33d89451f28353531689cb /src/emu/machine
parente5e8a7b4d91dc51a5f005b5edbb5134577a50912 (diff)
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
Diffstat (limited to 'src/emu/machine')
-rw-r--r--src/emu/machine/z80dart.c54
-rw-r--r--src/emu/machine/z80dart.h84
2 files changed, 121 insertions, 17 deletions
diff --git a/src/emu/machine/z80dart.c b/src/emu/machine/z80dart.c
index 2afeb9c3018..344d0de2146 100644
--- a/src/emu/machine/z80dart.c
+++ b/src/emu/machine/z80dart.c
@@ -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 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 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 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);
@@ -1315,6 +1332,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
diff --git a/src/emu/machine/z80dart.h b/src/emu/machine/z80dart.h
index 5c3c55b4482..bb72c559933 100644
--- a/src/emu/machine/z80dart.h
+++ b/src/emu/machine/z80dart.h
@@ -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