diff options
author | 2010-08-21 00:03:37 +0000 | |
---|---|---|
committer | 2010-08-21 00:03:37 +0000 | |
commit | 6791eb9adb17a1f11a461c311b9dd066033f5187 (patch) | |
tree | e25de46eb0ae028a6d33d89451f28353531689cb /src/emu/machine | |
parent | e5e8a7b4d91dc51a5f005b5edbb5134577a50912 (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.c | 54 | ||||
-rw-r--r-- | src/emu/machine/z80dart.h | 84 |
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 |