summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2020-03-16 17:13:24 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2020-03-16 17:13:24 +0700
commite302ab780a35c896834163a4618385d6a3ec28c6 (patch)
treed0838de01b4690d6058c57444ea844740bb2ab58
parentbed1c30c1caab5d0e6d4937ad9f279bbff85e295 (diff)
indy_indigo2: networking
* hook up edlc ethernet device * implement ethernet dma
-rw-r--r--src/mame/drivers/indy_indigo2.cpp15
-rw-r--r--src/mame/machine/hpc3.cpp350
-rw-r--r--src/mame/machine/hpc3.h117
3 files changed, 328 insertions, 154 deletions
diff --git a/src/mame/drivers/indy_indigo2.cpp b/src/mame/drivers/indy_indigo2.cpp
index bf6da2eedac..fe9ba3d88c3 100644
--- a/src/mame/drivers/indy_indigo2.cpp
+++ b/src/mame/drivers/indy_indigo2.cpp
@@ -137,7 +137,7 @@ protected:
required_shared_ptr<uint64_t> m_mainram;
required_device<sgi_mc_device> m_mem_ctrl;
required_device<wd33c93b_device> m_scsi_ctrl;
- required_device<seeq8003_device> m_edlc;
+ required_device<seeq80c03_device> m_edlc;
required_device<eeprom_serial_93cxx_device> m_eeprom;
required_device<hal2_device> m_hal2;
required_device<hpc3_device> m_hpc3;
@@ -357,13 +357,6 @@ 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_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_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));
@@ -379,12 +372,10 @@ void ip24_state::ip24_base(machine_config &config)
//m_hpc3->eeprom_pre_cb().set(m_eeprom, FUNC(eeprom_serial_93cxx_device::pre_write));
m_hpc3->dma_complete_int_cb().set(m_ioc2, FUNC(ioc2_device::hpc_dma_done_w));
- SEEQ8003(config, m_edlc);
+ SEEQ80C03(config, m_edlc);
m_edlc->out_int_cb().set(m_hpc3, FUNC(hpc3_device::enet_intr_in_w));
m_edlc->out_rxrdy_cb().set(m_hpc3, FUNC(hpc3_device::enet_rxrdy_w));
- m_edlc->out_txrdy_cb().set(m_hpc3, FUNC(hpc3_device::enet_txrdy_w));
- //m_edlc->out_rxdc_cb().set(m_hpc3, FUNC(hpc3_device::enet_rxdc_w));
- //m_edlc->out_txret_cb().set(m_hpc3, FUNC(hpc3_device::enet_txret_w));
+ m_hpc3->set_enet(m_edlc);
SGI_HAL2(config, m_hal2);
EEPROM_93C56_16BIT(config, m_eeprom);
diff --git a/src/mame/machine/hpc3.cpp b/src/mame/machine/hpc3.cpp
index cd88932d6e3..aabe5da6908 100644
--- a/src/mame/machine/hpc3.cpp
+++ b/src/mame/machine/hpc3.cpp
@@ -40,14 +40,7 @@ hpc3_device::hpc3_device(const machine_config &mconfig, const char *tag, device_
{"PIO channel 9", ENDIANNESS_LITTLE, 16, 8, -1}}
, m_gio64_space(*this, finder_base::DUMMY_TAG, -1)
, m_hal2(*this, finder_base::DUMMY_TAG)
- , m_enet_rd_cb(*this)
- , m_enet_wr_cb(*this)
- , m_enet_rxrd_cb(*this)
- , m_enet_txwr_cb(*this)
- , m_enet_d8_rd_cb(*this)
- , m_enet_d8_wr_cb(*this)
- , m_enet_reset_cb(*this)
- , m_enet_loopback_cb(*this)
+ , m_enet(*this, finder_base::DUMMY_TAG)
, m_enet_intr_out_cb(*this)
, m_hd_rd_cb(*this)
, m_hd_wr_cb(*this)
@@ -83,14 +76,6 @@ device_memory_interface::space_config_vector hpc3_device::memory_space_config()
void hpc3_device::device_resolve_objects()
{
- m_enet_rd_cb.resolve();
- m_enet_wr_cb.resolve_safe();
- m_enet_rxrd_cb.resolve_safe(0);
- m_enet_txwr_cb.resolve_safe();
- m_enet_d8_rd_cb.resolve_safe(0);
- m_enet_d8_wr_cb.resolve_safe();
- m_enet_reset_cb.resolve_safe();
- m_enet_loopback_cb.resolve_safe();
m_enet_intr_out_cb.resolve_safe();
m_hd_rd_cb.resolve_all();
m_hd_wr_cb.resolve_all();
@@ -132,19 +117,28 @@ void hpc3_device::device_start()
save_item(NAME(m_scsi_dma[i].m_active), i);
}
- for (uint32_t i = 0; i < 2; i++)
- {
- save_item(NAME(m_enet_dma[i].m_cbp), i);
- save_item(NAME(m_enet_dma[i].m_nbdp), i);
- save_item(NAME(m_enet_dma[i].m_bc), i);
- save_item(NAME(m_enet_dma[i].m_ctrl), i);
- save_item(NAME(m_enet_dma[i].m_gio_fifo_ptr), i);
- save_item(NAME(m_enet_dma[i].m_dev_fifo_ptr), i);
- }
- save_item(NAME(m_enet_reset));
+ save_item(NAME(m_enet_rx_cbp));
+ save_item(NAME(m_enet_rx_nbdp));
+ save_item(NAME(m_enet_rx_bc));
+ save_item(NAME(m_enet_rx_ctrl));
+ save_item(NAME(m_enet_rx_gio));
+ save_item(NAME(m_enet_rx_dev));
+
+ save_item(NAME(m_enet_misc));
save_item(NAME(m_enet_dmacfg));
save_item(NAME(m_enet_piocfg));
+ save_item(NAME(m_enet_tx_cbp));
+ save_item(NAME(m_enet_tx_nbdp));
+ save_item(NAME(m_enet_tx_bc));
+ save_item(NAME(m_enet_tx_ctrl));
+ save_item(NAME(m_enet_tx_gio));
+ save_item(NAME(m_enet_tx_dev));
+
+ save_item(NAME(m_enet_rx_cbdp));
+ save_item(NAME(m_enet_tx_cpfbdp));
+ save_item(NAME(m_enet_tx_ppfbdp));
+
for (uint32_t i = 0; i < 8; i++)
{
save_item(NAME(m_pbus_dma[i].m_active), i);
@@ -171,6 +165,8 @@ void hpc3_device::device_start()
save_pointer(NAME(m_scsi_fifo[1]), 96);
save_pointer(NAME(m_enet_fifo[ENET_RECV]), 32);
save_pointer(NAME(m_enet_fifo[ENET_XMIT]), 40);
+
+ m_enet_tx_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(hpc3_device::enet_transmit), this));
}
void hpc3_device::device_reset()
@@ -178,14 +174,6 @@ void hpc3_device::device_reset()
m_cpu_aux_ctrl = 0;
memset(m_scsi_dma, 0, sizeof(scsi_dma_t) * 2);
- memset(m_enet_dma, 0, sizeof(enet_dma_t) * 2);
- m_enet_dmacfg = 0;
- m_enet_piocfg = 0;
-
- m_enet_dma[ENET_RECV].m_cbp = 0x80000000;
- m_enet_dma[ENET_XMIT].m_cbp = 0x80000000;
- m_enet_dma[ENET_RECV].m_nbdp = 0x80000000;
- m_enet_dma[ENET_XMIT].m_nbdp = 0x80000000;
for (uint32_t i = 0; i < 8; i++)
{
@@ -204,6 +192,8 @@ void hpc3_device::device_reset()
m_intstat = 0;
m_dma_complete_int_cb(0);
+
+ m_enet_misc = MISC_RESET;
}
void hpc3_device::map(address_map &map)
@@ -221,7 +211,7 @@ void hpc3_device::map(address_map &map)
map(0x0003000c, 0x0003000f).r(FUNC(hpc3_device::intstat_r));
map(0x00040000, 0x00047fff).rw(FUNC(hpc3_device::hd_r<0>), FUNC(hpc3_device::hd_w<0>));
map(0x00048000, 0x0004ffff).rw(FUNC(hpc3_device::hd_r<1>), FUNC(hpc3_device::hd_w<1>));
- map(0x00054000, 0x000544ff).rw(FUNC(hpc3_device::enet_r), FUNC(hpc3_device::enet_w));
+ map(0x00054000, 0x000544ff).m(m_enet, FUNC(seeq80c03_device::map)).umask64(0x000000ff000000ff);
map(0x00058000, 0x0005bfff).rw(FUNC(hpc3_device::pio_data_r), FUNC(hpc3_device::pio_data_w));
map(0x0005c000, 0x0005cfff).rw(FUNC(hpc3_device::dma_config_r), FUNC(hpc3_device::dma_config_w));
map(0x0005d000, 0x0005dfff).rw(FUNC(hpc3_device::pio_config_r), FUNC(hpc3_device::pio_config_w));
@@ -298,29 +288,6 @@ void hpc3_device::do_pbus_dma(uint32_t channel)
}
}
-READ32_MEMBER(hpc3_device::enet_r)
-{
- switch (offset)
- {
- case 0x000/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3: enet_r: Read MAC Address bytes 0-3, 0x80675309 & %08x\n", machine().describe_context(), mem_mask);
- return 0x80675309;
- default:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3: enet_r: Read Unknown Register %08x & %08x\n", machine().describe_context(), 0x1fbd4000 + (offset << 2), mem_mask);
- return 0;
- }
-}
-
-WRITE32_MEMBER(hpc3_device::enet_w)
-{
- switch (offset)
- {
- default:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3: enet_w: Write Unknown Register %08x = %08x & %08x\n", machine().describe_context(), 0x1fbd4000 + (offset << 2), data, mem_mask);
- break;
- }
-}
-
READ32_MEMBER(hpc3_device::hd_enet_r)
{
switch (offset)
@@ -395,26 +362,26 @@ READ32_MEMBER(hpc3_device::hd_enet_r)
return m_scsi_dma[channel].m_piocfg;
}
case 0x4000/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Current Buffer Pointer Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_RECV].m_cbp);
- return m_enet_dma[ENET_RECV].m_cbp;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Current Buffer Pointer Read: %08x\n", machine().describe_context(), m_enet_rx_cbp);
+ return m_enet_rx_cbp;
case 0x4004/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Next Buffer Desc Pointer Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_RECV].m_nbdp);
- return m_enet_dma[ENET_RECV].m_nbdp;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Next Buffer Desc Pointer Read: %08x\n", machine().describe_context(), m_enet_rx_nbdp);
+ return m_enet_rx_nbdp;
case 0x5000/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Buffer Count Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_RECV].m_bc);
- return m_enet_dma[ENET_RECV].m_bc;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Buffer Count Read: %08x\n", machine().describe_context(), m_enet_rx_bc);
+ return m_enet_rx_bc;
case 0x5004/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver DMA Control Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_RECV].m_ctrl);
- return m_enet_dma[ENET_RECV].m_ctrl;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver DMA Control Read: %08x\n", machine().describe_context(), m_enet_rx_ctrl);
+ return m_enet_rx_ctrl;
case 0x5008/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver GIO FIFO Pointer Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_RECV].m_gio_fifo_ptr);
- return m_enet_dma[ENET_RECV].m_gio_fifo_ptr;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver GIO FIFO Pointer Read: %08x\n", machine().describe_context(), m_enet_rx_gio);
+ return m_enet_rx_gio;
case 0x500c/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Device FIFO Pointer Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_RECV].m_dev_fifo_ptr);
- return m_enet_dma[ENET_RECV].m_dev_fifo_ptr;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Device FIFO Pointer Read: %08x\n", machine().describe_context(), m_enet_rx_dev);
+ return m_enet_rx_dev;
case 0x5014/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Reset Register Read: %08x\n", machine().describe_context(), m_enet_reset);
- return m_enet_reset;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Reset Register Read: %08x\n", machine().describe_context(), m_enet_misc);
+ return m_enet_misc;
case 0x5018/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet DMA Config Read: %08x\n", machine().describe_context(), m_enet_dmacfg);
return m_enet_dmacfg;
@@ -422,23 +389,32 @@ READ32_MEMBER(hpc3_device::hd_enet_r)
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet PIO Config Read: %08x\n", machine().describe_context(), m_enet_piocfg);
return m_enet_piocfg;
case 0x6000/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Current Buffer Pointer Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_XMIT].m_cbp);
- return m_enet_dma[ENET_XMIT].m_cbp;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Current Buffer Pointer Read: %08x\n", machine().describe_context(), m_enet_tx_cbp);
+ return m_enet_tx_cbp;
case 0x6004/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Next Buffer Desc Pointer Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_XMIT].m_nbdp);
- return m_enet_dma[ENET_XMIT].m_nbdp;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Next Buffer Desc Pointer Read: %08x\n", machine().describe_context(), m_enet_tx_nbdp);
+ return m_enet_tx_nbdp;
case 0x7000/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Buffer Count Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_XMIT].m_bc);
- return m_enet_dma[ENET_XMIT].m_bc;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Buffer Count Read: %08x\n", machine().describe_context(), m_enet_tx_bc);
+ return m_enet_tx_bc;
case 0x7004/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter DMA Control Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_XMIT].m_ctrl);
- return m_enet_dma[ENET_XMIT].m_ctrl;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter DMA Control Read: %08x\n", machine().describe_context(), m_enet_tx_ctrl);
+ return m_enet_tx_ctrl;
case 0x7008/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter GIO FIFO Pointer Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_XMIT].m_gio_fifo_ptr);
- return m_enet_dma[ENET_XMIT].m_gio_fifo_ptr;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter GIO FIFO Pointer Read: %08x\n", machine().describe_context(), m_enet_tx_gio);
+ return m_enet_tx_gio;
case 0x700c/4:
- LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Device FIFO Pointer Read: %08x\n", machine().describe_context(), m_enet_dma[ENET_XMIT].m_dev_fifo_ptr);
- return m_enet_dma[ENET_XMIT].m_dev_fifo_ptr;
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Device FIFO Pointer Read: %08x\n", machine().describe_context(), m_enet_tx_dev);
+ return m_enet_tx_dev;
+ case 0x8000/4:
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Current Buffer Descriptor Pointer Read: %08x\n", machine().describe_context(), m_enet_rx_cbdp);
+ return m_enet_rx_cbdp;
+ case 0xa000/4:
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Current/Previous First Buffer Descriptor Pointer Read: %08x\n", machine().describe_context(), m_enet_tx_cpfbdp);
+ return m_enet_tx_cpfbdp;
+ case 0xa004/4:
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Previous/Previous First Buffer Descriptor Pointer Read: %08x\n", machine().describe_context(), m_enet_tx_ppfbdp);
+ return m_enet_tx_ppfbdp;
default:
LOGMASKED(LOG_UNKNOWN, "%s: Unknown HPC3 ENET/HDx Read: %08x & %08x\n", machine().describe_context(), 0x1fb90000 + (offset << 2), mem_mask);
return 0;
@@ -463,6 +439,7 @@ WRITE32_MEMBER(hpc3_device::hd_enet_w)
const uint32_t channel = (offset & 0x2000/4) ? 1 : 0;
LOGMASKED(LOG_SCSI, "%s: HPC3 SCSI%d Buffer Count Write: %08x\n", machine().describe_context(), channel, data);
m_scsi_dma[channel].m_bc = data;
+ break;
}
case 0x1004/4:
case 0x3004/4:
@@ -516,18 +493,21 @@ WRITE32_MEMBER(hpc3_device::hd_enet_w)
}
case 0x4000/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Current Buffer Pointer Write: %08x\n", machine().describe_context(), data);
- m_enet_dma[ENET_RECV].m_cbp = data;
+ m_enet_rx_cbp = data;
break;
case 0x4004/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Next Buffer Desc Pointer Write: %08x\n", machine().describe_context(), data);
- m_enet_dma[ENET_RECV].m_nbdp = data;
+ m_enet_rx_nbdp = data;
break;
case 0x5000/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Buffer Count Write (ignored): %08x\n", machine().describe_context(), data);
break;
case 0x5004/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver DMA Control Write: %08x\n", machine().describe_context(), data);
- m_enet_dma[ENET_RECV].m_ctrl = data;
+ if (m_enet_rx_ctrl & RXC_CAM)
+ m_enet_rx_ctrl = (m_enet_rx_ctrl & (RXC_LC | RXC_ST)) | (data & ~(RXC_CA | RXC_LC | RXC_ST));
+ else
+ m_enet_rx_ctrl = (m_enet_rx_ctrl & (RXC_LC | RXC_ST)) | (data & ~((RXC_LC | RXC_ST)));
break;
case 0x5008/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver GIO FIFO Pointer Write (ignored): %08x\n", machine().describe_context(), data);
@@ -537,7 +517,7 @@ WRITE32_MEMBER(hpc3_device::hd_enet_w)
break;
case 0x5014/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Reset Register Write: %08x\n", machine().describe_context(), data);
- m_enet_reset = data;
+ enet_misc_w(data);
break;
case 0x5018/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet DMA Config Write: %08x\n", machine().describe_context(), data);
@@ -552,14 +532,20 @@ WRITE32_MEMBER(hpc3_device::hd_enet_w)
break;
case 0x6004/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Next Buffer Desc Pointer Write: %08x\n", machine().describe_context(), data);
- m_enet_dma[ENET_XMIT].m_nbdp = data;
+ m_enet_tx_nbdp = data;
break;
case 0x7000/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Buffer Count Write (ignored): %08x\n", machine().describe_context(), data);
break;
case 0x7004/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter DMA Control Write: %08x\n", machine().describe_context(), data);
- m_enet_dma[ENET_XMIT].m_ctrl = data;
+ if (m_enet_tx_ctrl & RXC_CAM)
+ m_enet_tx_ctrl = (m_enet_tx_ctrl & (TXC_LC | TXC_ST)) | (data & ~(TXC_CA | TXC_LC | TXC_ST));
+ else
+ m_enet_tx_ctrl = (m_enet_tx_ctrl & (TXC_LC | TXC_ST)) | (data & ~((TXC_LC | TXC_ST)));
+
+ if ((m_enet_tx_ctrl & TXC_CA) && !m_enet_tx_timer->enabled())
+ m_enet_tx_timer->adjust(attotime::zero);
break;
case 0x7008/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter GIO FIFO Pointer Write (ignored): %08x\n", machine().describe_context(), data);
@@ -567,35 +553,115 @@ WRITE32_MEMBER(hpc3_device::hd_enet_w)
case 0x700c/4:
LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Device FIFO Pointer Write (ignored): %08x\n", machine().describe_context(), data);
break;
+ case 0x8000/4:
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Receiver Current Buffer Descriptor Pointer Write: %08x\n", machine().describe_context(), data);
+ m_enet_rx_cbdp = data;
+ break;
+ case 0xa000/4:
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Current/Previous Buffer Descriptor Pointer Write: %08x\n", machine().describe_context(), data);
+ m_enet_tx_cpfbdp = data;
+ break;
+ case 0xa004/4:
+ LOGMASKED(LOG_ETHERNET, "%s: HPC3 Ethernet Transmitter Previous/Previous Buffer Descriptor Pointer Write: %08x\n", machine().describe_context(), data);
+ m_enet_tx_ppfbdp = data;
+ break;
+
default:
LOGMASKED(LOG_UNKNOWN, "%s: Unknown HPC3 ENET/HDx write: %08x = %08x & %08x\n", machine().describe_context(), 0x1fb90000 + (offset << 2), data, mem_mask);
break;
}
}
-WRITE_LINE_MEMBER(hpc3_device::enet_txrdy_w)
+void hpc3_device::enet_rxrdy_w(int state)
{
- // TODO
-}
+ // check receive dma enabled
+ if (state && (m_enet_rx_ctrl & RXC_CA))
+ {
+ // next descriptor becomes current
+ m_enet_rx_cbdp = m_enet_rx_nbdp;
-WRITE_LINE_MEMBER(hpc3_device::enet_rxrdy_w)
-{
- // TODO
-}
+ // fetch the current descriptor
+ m_enet_rx_cbp = m_gio64_space->read_dword(m_enet_rx_cbdp + 0);
+ m_enet_rx_bc = m_gio64_space->read_dword(m_enet_rx_cbdp + 4);
+ m_enet_rx_nbdp = m_gio64_space->read_dword(m_enet_rx_cbdp + 8);
-WRITE_LINE_MEMBER(hpc3_device::enet_rxdc_w)
-{
- // TODO
-}
+ LOGMASKED(LOG_ETHERNET, "enet rx dma chain 0x%08x cbp 0x%08x bc 0x%08x nbdp 0x%08x\n",
+ m_enet_rx_cbdp, m_enet_rx_cbp, m_enet_rx_bc, m_enet_rx_nbdp);
-WRITE_LINE_MEMBER(hpc3_device::enet_txret_w)
-{
- // TODO
+ // skip buffer alignment bytes
+ if (enet_rx_bc_dec(2))
+ m_enet_rx_cbp += 2;
+
+ // transfer data from edlc fifo to memory
+ while (!m_enet->rxeof_r())
+ if (enet_rx_bc_dec())
+ m_gio64_space->write_byte(m_enet_rx_cbp++, m_enet->fifo_r());
+ }
}
-WRITE_LINE_MEMBER(hpc3_device::enet_intr_in_w)
+void hpc3_device::enet_intr_in_w(int state)
{
- // TODO
+ if (state)
+ {
+ bool interrupt = false;
+
+ // copy edlc status registers
+ m_enet_rx_ctrl &= ~RXC_ST;
+ m_enet_rx_ctrl |= m_enet->read(6) & RXC_ST;
+ m_enet_tx_ctrl &= ~TXC_ST;
+ m_enet_tx_ctrl |= m_enet->read(7) & TXC_ST;
+
+ LOGMASKED(LOG_ETHERNET, "rx status 0x%02x tx status 0x%02x\n",
+ u8(m_enet_rx_ctrl), u8(m_enet_tx_ctrl));
+
+ // tx interrupt
+ if (!(m_enet_tx_ctrl & TXC_ST_O))
+ {
+ // write txd and clear byte count
+ if (m_enet_tx_ctrl & TXC_ST_S)
+ m_gio64_space->write_word(m_enet_tx_cpfbdp + 6, BC_TXD);
+
+ // interrupt host if xie or error
+ if ((m_enet_tx_bc & BC_XIE) || (m_enet_tx_ctrl & (TXC_ST_U | TXC_ST_C | TXC_ST_R)))
+ {
+ // stop dma
+ // FIXME: do we always stop dma, or only on errors?
+ m_enet_tx_ctrl &= ~TXC_CA;
+
+ interrupt = true;
+ }
+
+ // transmit next packet
+ if (m_enet_tx_ctrl & TXC_CA)
+ m_enet_tx_timer->adjust(attotime::zero);
+ }
+
+ // rx interrupt
+ if (!(m_enet_rx_ctrl & RXC_ST_O))
+ {
+ // transfer the status byte
+ if (enet_rx_bc_dec())
+ m_gio64_space->write_byte(m_enet_rx_cbp++, u8(m_enet_rx_ctrl));
+
+ // store the remaining buffer length
+ m_gio64_space->write_word(m_enet_rx_cbdp + 6, u16(m_enet_rx_bc & BC_BC));
+
+ // check for edlc overflow, receive buffer overflow or end of descriptor chain
+ if ((m_enet_rx_ctrl & (RXC_ST_V | RXC_RBO)) || (m_enet_rx_bc & BC_EOX))
+ {
+ m_enet_rx_ctrl &= ~RXC_CA;
+ interrupt = true;
+ }
+ else if (m_enet_rx_bc & BC_XIE)
+ interrupt = true;
+ }
+
+ if (interrupt && !BIT(m_enet_misc, 1))
+ {
+ m_enet_misc |= MISC_INT;
+ m_enet_intr_out_cb(interrupt);
+ }
+ }
}
template<hpc3_device::fifo_type_t Type>
@@ -1042,3 +1108,75 @@ void hpc3_device::eeprom_w(uint32_t data)
m_eeprom_cs_cb(BIT(data, 1));
m_eeprom_clk_cb(BIT(data, 2));
}
+
+void hpc3_device::enet_transmit(void *ptr, int param)
+{
+ // save the first transmit buffer descriptor pointer
+ // TODO: not sure how cpfbdp and ppfbdp work, perhaps round-robin?
+ m_enet_tx_cpfbdp = m_enet_tx_nbdp;
+
+ bool done = false;
+ while (!done)
+ {
+ // fetch the current descriptor
+ m_enet_tx_cbp = m_gio64_space->read_dword(m_enet_tx_nbdp + 0);
+ m_enet_tx_bc = m_gio64_space->read_dword(m_enet_tx_nbdp + 4);
+ m_enet_tx_nbdp = m_gio64_space->read_dword(m_enet_tx_nbdp + 8);
+
+ LOGMASKED(LOG_ETHERNET, "enet tx dma chain 0x%08x cbp 0x%08x bc 0x%08x nbdp 0x%08x\n",
+ m_enet_tx_cpfbdp, m_enet_tx_cbp, m_enet_tx_bc, m_enet_tx_nbdp);
+
+ // TODO: write inter-packet gap from first descriptor to seeq
+ //if (BIT(m_enet_dmacfg, 12))
+ // m_enet->write(2, u8(m_enet_tx_bc >> 16));
+
+ // transfer data from memory to edlc fifo
+ unsigned const count = m_enet_tx_bc & BC_BC;
+ for (unsigned i = 0; i < count; i++)
+ m_enet->fifo_w(m_gio64_space->read_byte(m_enet_tx_cbp + i));
+
+ // check for end of packet
+ if (m_enet_tx_bc & BC_EOXP)
+ {
+ m_enet->txeof_w(1);
+ done = true;
+ }
+
+ // check for end of chain
+ if (m_enet_tx_bc & BC_EOX)
+ {
+ // stop dma
+ m_enet_tx_ctrl &= ~TXC_CA;
+ done = true;
+ }
+ }
+}
+
+void hpc3_device::enet_misc_w(u32 data)
+{
+ // channel reset
+ m_enet->reset_w(!(data & MISC_RESET));
+ // TODO: reset ethernet dma state
+
+ // clear channel interrupt
+ if (data & MISC_INT)
+ m_enet_intr_out_cb(0);
+
+ // TODO: loopback
+
+ m_enet_misc = data & ~MISC_INT;
+}
+
+bool hpc3_device::enet_rx_bc_dec(unsigned const count)
+{
+ if ((m_enet_rx_bc & BC_BC) >= count)
+ {
+ m_enet_rx_bc = (m_enet_rx_bc & ~BC_BC) | (((m_enet_rx_bc & BC_BC) - count) & BC_BC);
+
+ return true;
+ }
+
+ // receive buffer overflow
+ m_enet_rx_ctrl |= RXC_RBO;
+ return false;
+}
diff --git a/src/mame/machine/hpc3.h b/src/mame/machine/hpc3.h
index aa59275eb9d..3630cbf9058 100644
--- a/src/mame/machine/hpc3.h
+++ b/src/mame/machine/hpc3.h
@@ -12,6 +12,7 @@
#pragma once
#include "machine/hal2.h"
+#include "machine/edlc.h"
class hpc3_device : public device_t, public device_memory_interface
{
@@ -41,15 +42,8 @@ public:
template <typename T> void set_gio64_space(T &&tag, int spacenum) { m_gio64_space.set_tag(std::forward<T>(tag), spacenum); }
template <typename T> void set_hal2_tag(T &&tag) { m_hal2.set_tag(std::forward<T>(tag)); }
+ template <typename T> void set_enet(T &&tag) { m_enet.set_tag(std::forward<T>(tag)); }
- auto enet_rd_cb() { return m_enet_rd_cb.bind(); }
- auto enet_wr_cb() { return m_enet_wr_cb.bind(); }
- auto enet_rxrd_cb() { return m_enet_rxrd_cb.bind(); }
- auto enet_txwr_cb() { return m_enet_txwr_cb.bind(); }
- auto enet_d8_rd_cb() { return m_enet_d8_rd_cb.bind(); }
- auto enet_d8_wr_cb() { return m_enet_d8_wr_cb.bind(); }
- auto enet_reset_cb() { return m_enet_reset_cb.bind(); }
- auto enet_loopback_cb() { return m_enet_loopback_cb.bind(); }
auto enet_intr_out_cb() { return m_enet_intr_out_cb.bind(); }
template <int N> auto hd_rd_cb() { return m_hd_rd_cb[N].bind(); }
template <int N> auto hd_wr_cb() { return m_hd_wr_cb[N].bind(); }
@@ -67,11 +61,8 @@ public:
void map(address_map &map);
- DECLARE_WRITE_LINE_MEMBER(enet_txrdy_w);
- DECLARE_WRITE_LINE_MEMBER(enet_rxrdy_w);
- DECLARE_WRITE_LINE_MEMBER(enet_rxdc_w);
- DECLARE_WRITE_LINE_MEMBER(enet_txret_w);
- DECLARE_WRITE_LINE_MEMBER(enet_intr_in_w);
+ void enet_rxrdy_w(int state);
+ void enet_intr_in_w(int state);
DECLARE_WRITE_LINE_MEMBER(scsi0_drq);
DECLARE_WRITE_LINE_MEMBER(scsi1_drq);
@@ -128,6 +119,10 @@ protected:
void scsi_drq(bool state, int channel);
//void scsi_dma(int channel);
+ void enet_transmit(void *ptr = nullptr, int param = 0);
+ void enet_misc_w(u32 data);
+ bool enet_rx_bc_dec(unsigned const count = 1);
+
static const device_timer_id TIMER_PBUS_DMA = 0;
struct pbus_dma_t
@@ -187,15 +182,8 @@ protected:
required_address_space m_gio64_space;
address_space *m_pio_space[10];
required_device<hal2_device> m_hal2;
+ required_device<seeq80c03_device> m_enet;
- devcb_read8 m_enet_rd_cb;
- devcb_write8 m_enet_wr_cb;
- devcb_read8 m_enet_rxrd_cb;
- devcb_write8 m_enet_txwr_cb;
- devcb_read_line m_enet_d8_rd_cb;
- devcb_write_line m_enet_d8_wr_cb;
- devcb_write_line m_enet_reset_cb;
- devcb_write_line m_enet_loopback_cb;
devcb_write_line m_enet_intr_out_cb;
devcb_read8::array<2> m_hd_rd_cb;
devcb_write8::array<2> m_hd_wr_cb;
@@ -230,21 +218,6 @@ protected:
bool m_active;
};
- struct enet_dma_t
- {
- uint32_t m_cbp;
- uint32_t m_nbdp;
- uint32_t m_bc;
- uint32_t m_ctrl;
- uint32_t m_gio_fifo_ptr;
- uint32_t m_dev_fifo_ptr;
- };
-
- enet_dma_t m_enet_dma[2];
- uint32_t m_enet_reset;
- uint32_t m_enet_dmacfg;
- uint32_t m_enet_piocfg;
-
scsi_dma_t m_scsi_dma[2];
pbus_dma_t m_pbus_dma[8];
uint32_t m_pio_config[10];
@@ -252,6 +225,78 @@ protected:
std::unique_ptr<uint32_t[]> m_pbus_fifo;
std::unique_ptr<uint32_t[]> m_scsi_fifo[2];
std::unique_ptr<uint32_t[]> m_enet_fifo[2];
+
+private:
+ emu_timer *m_enet_tx_timer;
+
+ enum enet_dma_rx_ctrl : u32
+ {
+ RXC_ST = 0x0000'00bf, // edlc receive status
+ RXC_LC = 0x0000'0040, // late receive collision
+ RXC_LE = 0x0000'0100, // receive little endian
+ RXC_CA = 0x0000'0200, // receive channel active
+ RXC_CAM = 0x0000'0400, // receive channel active mask
+ RXC_RBO = 0x0000'0800, // receive buffer overflow
+
+ // individual receive status bits
+ RXC_ST_V = 0x0000'0001, // received frame with overflow error
+ RXC_ST_C = 0x0000'0002, // received frame with crc error
+ RXC_ST_D = 0x0000'0004, // received frame with dribble error
+ RXC_ST_S = 0x0000'0008, // received short frame
+ RXC_ST_E = 0x0000'0010, // received end of frame
+ RXC_ST_G = 0x0000'0020, // received good frame
+ RXC_ST_O = 0x0000'0080, // old/new status
+ };
+ enum enet_dma_tx_ctrl : u32
+ {
+ TXC_ST = 0x0000'00ef, // edlc transmit status
+ TXC_LC = 0x0000'0010, // late transmit collision
+ TXC_LE = 0x0000'0100, // transmit little endian
+ TXC_CA = 0x0000'0200, // transmit channel active
+ TXC_CAM = 0x0000'0400, // transmit channel active mask
+
+ // individual transmit status bits
+ TXC_ST_U = 0x0000'0001, // transmit underflow
+ TXC_ST_C = 0x0000'0002, // transmit collision
+ TXC_ST_R = 0x0000'0004, // 16 transmission attempts
+ TXC_ST_S = 0x0000'0008, // transmission successful
+ TXC_ST_O = 0x0000'0080, // old/new status
+ };
+ enum enet_dma_bc : u32
+ {
+ BC_BC = 0x0000'3fff, // byte count
+ BC_TXD = 0x0000'8000, // transmit done
+ BC_IPG = 0x00ff'0000, // inter-packet gap
+ BC_XIE = 0x2000'0000, // transmit interrupt enable
+ BC_EOXP = 0x4000'0000, // end of packet
+ BC_EOX = 0x8000'0000, // end of descriptor chain
+ };
+ enum enet_enet_misc : u32
+ {
+ MISC_RESET = 0x0000'0001, // channel reset
+ MISC_INT = 0x0000'0002, // interrupt
+ MISC_LOOPBACK = 0x0000'0004, // loopback
+ };
+
+ // ethernet registers
+ u32 m_enet_rx_cbp; // current receive buffer pointer
+ u32 m_enet_rx_nbdp; // next receive buffer descriptor pointer
+ u32 m_enet_rx_bc; // receive byte count
+ u32 m_enet_rx_ctrl; // receive status
+ u32 m_enet_rx_gio; // receive gio fifo pointer
+ u32 m_enet_rx_dev; // receive device fifo pointer
+ u32 m_enet_misc; // reset, clear interrupt, loopback
+ u32 m_enet_piocfg; // pio configuration
+ u32 m_enet_dmacfg; // dma configuration
+ u32 m_enet_tx_cbp; // current transmit buffer pointer
+ u32 m_enet_tx_nbdp; // next transmit buffer descriptor pointer
+ u32 m_enet_tx_bc; // transmit byte count
+ u32 m_enet_tx_ctrl; // transmit status
+ u32 m_enet_tx_gio; // transmit gio fifo pointer
+ u32 m_enet_tx_dev; // transmit device fifo pointer
+ u32 m_enet_rx_cbdp; // current receive buffer descriptor pointer
+ u32 m_enet_tx_cpfbdp; // current/previous first transmit buffer descriptor pointer
+ u32 m_enet_tx_ppfbdp; // previous/previous? first transmit buffer descriptor pointer
};
DECLARE_DEVICE_TYPE(SGI_HPC3, hpc3_device)