diff options
author | 2019-06-27 11:26:41 +0700 | |
---|---|---|
committer | 2019-06-27 11:26:41 +0700 | |
commit | c05e71651303cee9941af0e3f7e03b5943d4cbda (patch) | |
tree | a0d2979c5adfaad88e6f56713359901643a82950 | |
parent | b1689f37e965e85dd97501876f4bc06125b2acc0 (diff) |
edlc: read/write/reset handlers (nw)
-rw-r--r-- | src/devices/machine/edlc.cpp | 81 | ||||
-rw-r--r-- | src/devices/machine/edlc.h | 14 | ||||
-rw-r--r-- | src/mame/drivers/indy_indigo2.cpp | 6 |
3 files changed, 86 insertions, 15 deletions
diff --git a/src/devices/machine/edlc.cpp b/src/devices/machine/edlc.cpp index a9ebb8a853f..f276cb16a59 100644 --- a/src/devices/machine/edlc.cpp +++ b/src/devices/machine/edlc.cpp @@ -5,8 +5,9 @@ * An emulation of the SEEQ 8003 Ethernet Data Link Controller. * * This implementation uses transmit/receive fifos which hold entire frames, - * rather than the 16-byte fifos of the real device to simplify logic. Also, - * the bidirectional RxTxEOF line is split into separate read/write handlers + * rather than the 16-byte fifos of the real device to simplify logic. In + * hardware, RxTxEOF is effectively the 9th bit of the data bus, however to + * simplify emulation is implemented as two separate read/write line handlers * which must be used strictly as follows: * * - rxeof_r() must be read before fifo_r() @@ -52,16 +53,20 @@ void seeq8003_device::device_start() m_out_txrdy.resolve_safe(); save_item(NAME(m_int_state)); + save_item(NAME(m_reset_state)); save_item(NAME(m_station_address)); save_item(NAME(m_rx_status)); save_item(NAME(m_tx_status)); save_item(NAME(m_rx_command)); save_item(NAME(m_tx_command)); + //save_item(NAME(m_rx_fifo)); + //save_item(NAME(m_tx_fifo)); m_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(seeq8003_device::transmit), this)); m_int_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(seeq8003_device::interrupt), this)); m_int_state = 0; + m_reset_state = 1; } void seeq8003_device::device_reset() @@ -75,6 +80,8 @@ void seeq8003_device::device_reset() m_tx_fifo.clear(); m_out_rxrdy(0); + // TODO: deassert RxDC and TxRET + if (m_dev) m_out_txrdy(1); @@ -84,7 +91,7 @@ void seeq8003_device::device_reset() int seeq8003_device::recv_start_cb(u8 *buf, int length) { // check receiver disabled - if ((m_rx_command & RXC_M) == RXC_M0) + if (!m_reset_state || ((m_rx_command & RXC_M) == RXC_M0)) return 0; if (address_filter(buf)) @@ -112,8 +119,57 @@ void seeq8003_device::map(address_map &map) map(7, 7).rw(FUNC(seeq8003_device::tx_status_r), FUNC(seeq8003_device::tx_command_w)); } +u8 seeq8003_device::read(offs_t offset) +{ + u8 data = 0xff; + + switch (offset) + { + case 6: data = rx_status_r(); break; + case 7: data = tx_status_r(); break; + } + + return data; +} + +void seeq8003_device::write(offs_t offset, u8 data) +{ + switch (offset) + { + case 0: station_address_w<0>(data); break; + case 1: station_address_w<1>(data); break; + case 2: station_address_w<2>(data); break; + case 3: station_address_w<3>(data); break; + case 4: station_address_w<4>(data); break; + case 5: station_address_w<5>(data); break; + case 6: rx_command_w(data); break; + case 7: tx_command_w(data); break; + } +} + +void seeq8003_device::reset_w(int state) +{ + if (m_reset_state && !state) + { + // enter reset state + m_out_txrdy(0); + + // TODO: assert RxDC and TxRET + } + else if (!m_reset_state && state) + { + // leave reset state + device_reset(); + } + + m_reset_state = state; +} + u8 seeq8003_device::fifo_r() { + if (!m_reset_state) + return 0xff; + if (m_rx_fifo.empty()) fatalerror("seeq8003_device::fifo_r: fifo empty\n"); @@ -138,6 +194,9 @@ int seeq8003_device::rxeof_r() void seeq8003_device::fifo_w(u8 data) { + if (!m_reset_state) + return; + if (m_tx_fifo.full()) fatalerror("seeq8003_device::fifo_w: fifo full\n"); @@ -149,7 +208,7 @@ void seeq8003_device::fifo_w(u8 data) void seeq8003_device::txeof_w(int state) { - if (state) + if (m_reset_state && state) { // disable tx fifo m_out_txrdy(0); @@ -164,8 +223,11 @@ u8 seeq8003_device::rx_status_r() u8 const data = m_rx_status; // clear interrupt - m_rx_status |= RXS_O; - m_int_timer->adjust(attotime::zero); + if (m_reset_state && !machine().side_effects_disabled()) + { + m_rx_status |= RXS_O; + m_int_timer->adjust(attotime::zero); + } return data; } @@ -175,8 +237,11 @@ u8 seeq8003_device::tx_status_r() u8 const data = m_tx_status; // clear interrupt - m_tx_status |= TXS_O; - m_int_timer->adjust(attotime::zero); + if (m_reset_state && !machine().side_effects_disabled()) + { + m_tx_status |= TXS_O; + m_int_timer->adjust(attotime::zero); + } return data; } diff --git a/src/devices/machine/edlc.h b/src/devices/machine/edlc.h index 91bd37010d3..57e52b6159a 100644 --- a/src/devices/machine/edlc.h +++ b/src/devices/machine/edlc.h @@ -18,8 +18,13 @@ public: seeq8003_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0); - // host interface + // command/status interface void map(address_map &map); + u8 read(offs_t offset); + void write(offs_t offset, u8 data); + void reset_w(int state); + + // data interface u8 fifo_r(); int rxeof_r(); void fifo_w(u8 data); @@ -33,7 +38,7 @@ protected: // device_network_interface overrides virtual int recv_start_cb(u8 *buf, int length) override; - // command/status interface + // command/status registers template <unsigned N> void station_address_w(u8 data) { m_station_address[N] = data; } u8 rx_status_r(); u8 tx_status_r(); @@ -61,7 +66,7 @@ protected: RXS_G = 0x20, // received good frame RXS_O = 0x80, // old/new status - RXS_M = 0x3f, // mask + RXS_M = 0x3f, // interrupt mask }; enum rx_command_mask : u8 { @@ -88,7 +93,7 @@ protected: TXS_S = 0x08, // transmission successful TXS_O = 0x80, // old/new status - TXS_M = 0x0f, // mask + TXS_M = 0x0f, // interrupt mask }; enum tx_command_mask : u8 { @@ -110,6 +115,7 @@ private: devcb_write_line m_out_txrdy; int m_int_state; + int m_reset_state; u8 m_station_address[6]; u8 m_rx_status; u8 m_tx_status; diff --git a/src/mame/drivers/indy_indigo2.cpp b/src/mame/drivers/indy_indigo2.cpp index 39d29da1058..ca6b520801f 100644 --- a/src/mame/drivers/indy_indigo2.cpp +++ b/src/mame/drivers/indy_indigo2.cpp @@ -338,13 +338,13 @@ void ip24_state::ip24_base(machine_config &config) m_hpc3->set_addrmap(hpc3_device::AS_PIO0, &ip24_state::pio0_map); m_hpc3->set_addrmap(hpc3_device::AS_PIO1, &ip24_state::pio1_map); m_hpc3->set_addrmap(hpc3_device::AS_PIO2, &ip24_state::pio2_map); - //m_hpc3->enet_rd_cb().set(m_edlc, FUNC(seeq8003_device::read)); - //m_hpc3->enet_wr_cb().set(m_edlc, FUNC(seeq8003_device::write)); + m_hpc3->enet_rd_cb().set(m_edlc, FUNC(seeq8003_device::read)); + m_hpc3->enet_wr_cb().set(m_edlc, FUNC(seeq8003_device::write)); m_hpc3->enet_rxrd_cb().set(m_edlc, FUNC(seeq8003_device::fifo_r)); m_hpc3->enet_txwr_cb().set(m_edlc, FUNC(seeq8003_device::fifo_w)); m_hpc3->enet_d8_rd_cb().set(m_edlc, FUNC(seeq8003_device::rxeof_r)); m_hpc3->enet_d8_wr_cb().set(m_edlc, FUNC(seeq8003_device::txeof_w)); - //m_hpc3->enet_reset_cb().set(m_edlc, FUNC(seeq8003_device::reset_w)); + m_hpc3->enet_reset_cb().set(m_edlc, FUNC(seeq8003_device::reset_w)); m_hpc3->enet_intr_out_cb().set(m_ioc2, FUNC(ioc2_device::enet_int_w)); m_hpc3->hd_rd_cb<0>().set(m_scsi_ctrl, FUNC(wd33c93b_device::indir_r)); m_hpc3->hd_wr_cb<0>().set(m_scsi_ctrl, FUNC(wd33c93b_device::indir_w)); |