summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2019-06-27 11:26:41 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2019-06-27 11:26:41 +0700
commitc05e71651303cee9941af0e3f7e03b5943d4cbda (patch)
treea0d2979c5adfaad88e6f56713359901643a82950
parentb1689f37e965e85dd97501876f4bc06125b2acc0 (diff)
edlc: read/write/reset handlers (nw)
-rw-r--r--src/devices/machine/edlc.cpp81
-rw-r--r--src/devices/machine/edlc.h14
-rw-r--r--src/mame/drivers/indy_indigo2.cpp6
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));