summaryrefslogtreecommitdiffstatshomepage
path: root/src/mame/drivers/sun4.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mame/drivers/sun4.cpp')
-rw-r--r--src/mame/drivers/sun4.cpp160
1 files changed, 141 insertions, 19 deletions
diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp
index fec52c0a6c8..a6ad2be131a 100644
--- a/src/mame/drivers/sun4.cpp
+++ b/src/mame/drivers/sun4.cpp
@@ -541,7 +541,7 @@ public:
, m_scc2(*this, SCC2_TAG)
, m_fdc(*this, FDC_TAG)
, m_scsibus(*this, "scsibus")
- , m_scsi(*this, "scsibus:7:ncr5390")
+ , m_scsi(*this, "scsibus:7:ncr53c90a")
, m_type0space(*this, "type0")
, m_type1space(*this, "type1")
, m_ram(*this, RAM_TAG)
@@ -584,6 +584,8 @@ private:
DECLARE_WRITE8_MEMBER( fdc_w );
DECLARE_READ32_MEMBER( dma_r );
DECLARE_WRITE32_MEMBER( dma_w );
+ DECLARE_READ16_MEMBER( lance_r );
+ DECLARE_WRITE16_MEMBER( lance_w );
DECLARE_WRITE_LINE_MEMBER( scsi_irq );
DECLARE_WRITE_LINE_MEMBER( scsi_drq );
@@ -595,7 +597,7 @@ private:
uint32_t bw2_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
- void ncr5390(device_t *device);
+ void ncr53c90a(device_t *device);
void sun4_mem(address_map &map);
void sun4c_mem(address_map &map);
@@ -612,7 +614,7 @@ private:
required_device<n82077aa_device> m_fdc;
required_device<nscsi_bus_device> m_scsibus;
- required_device<ncr5390_device> m_scsi;
+ required_device<ncr53c90a_device> m_scsi;
optional_device<address_map_bank_device> m_type0space, m_type1space;
required_device<ram_device> m_ram;
@@ -642,6 +644,9 @@ private:
uint8_t m_diag;
int m_arch;
+ uint16_t m_lance_rap;
+ uint16_t m_lance_csr[4];
+
emu_timer *m_c0_timer, *m_c1_timer;
emu_timer *m_reset_timer;
@@ -905,7 +910,7 @@ WRITE32_MEMBER( sun4_state::sun4c_mmu_w )
{
m_reset_timer->adjust(attotime::from_usec(1));
m_maincpu->set_input_line(SPARC_RESET, ASSERT_LINE);
- printf("Asserting reset line\n");
+ //printf("Asserting reset line\n");
}
//printf("%08x to system enable, mask %08x\n", data, mem_mask);
if (m_system_enable & ENA_RESET)
@@ -1347,6 +1352,30 @@ void sun4_state::sun4c_mem(address_map &map)
static INPUT_PORTS_START( sun4 )
INPUT_PORTS_END
+enum
+{
+ LANCE_CSR0_ERR = 0x8000,
+ LANCE_CSR0_BABL = 0x4000,
+ LANCE_CSR0_CERR = 0x2000,
+ LANCE_CSR0_MISS = 0x1000,
+ LANCE_CSR0_MERR = 0x0800,
+ LANCE_CSR0_RINT = 0x0400,
+ LANCE_CSR0_TINT = 0x0200,
+ LANCE_CSR0_IDON = 0x0100,
+ LANCE_CSR0_INTR = 0x0080,
+ LANCE_CSR0_INEA = 0x0040,
+ LANCE_CSR0_RXON = 0x0020,
+ LANCE_CSR0_TXON = 0x0010,
+ LANCE_CSR0_TDMD = 0x0008,
+ LANCE_CSR0_STOP = 0x0004,
+ LANCE_CSR0_STRT = 0x0002,
+ LANCE_CSR0_INIT = 0x0001,
+ LANCE_CSR0_ANY_ERR = LANCE_CSR0_BABL | LANCE_CSR0_CERR | LANCE_CSR0_MISS | LANCE_CSR0_MERR,
+
+ LANCE_CSR3_BSWP = 0x0004,
+ LANCE_CSR3_ACON = 0x0002,
+ LANCE_CSR3_BCON = 0x0001
+};
void sun4_state::machine_reset()
{
@@ -1358,6 +1387,10 @@ void sun4_state::machine_reset()
m_dma_tc_read = false;
m_dma_pack_register = 0;
+ m_lance_rap = 0;
+ memset(m_lance_csr, 0, sizeof(uint16_t) * 4);
+ m_lance_csr[0] = LANCE_CSR0_STOP;
+
memset(m_counter, 0, sizeof(m_counter));
memset(m_dma, 0, sizeof(m_dma));
}
@@ -1480,7 +1513,8 @@ void sun4_state::type1space_map(address_map &map)
map(0x07200000, 0x07200003).rw(FUNC(sun4_state::fdc_r), FUNC(sun4_state::fdc_w));
map(0x08000000, 0x08000003).r(FUNC(sun4_state::ss1_sl0_id)); // slot 0 contains SCSI/DMA/Ethernet
map(0x08400000, 0x0840000f).rw(FUNC(sun4_state::dma_r), FUNC(sun4_state::dma_w));
- map(0x08800000, 0x0880001f).m(m_scsi, FUNC(ncr5390_device::map)).umask32(0xff000000);
+ map(0x08800000, 0x0880001f).m(m_scsi, FUNC(ncr53c90a_device::map)).umask32(0xff000000);
+ map(0x08c00000, 0x08c00003).rw(FUNC(sun4_state::lance_r), FUNC(sun4_state::lance_w));
map(0x0e000000, 0x0e000003).r(FUNC(sun4_state::ss1_sl3_id)); // slot 3 contains video board
map(0x0e800000, 0x0e8fffff).ram().share("bw2_vram");
}
@@ -1546,7 +1580,6 @@ WRITE8_MEMBER( sun4_state::irq_w )
WRITE_LINE_MEMBER( sun4_state::scc1_int )
{
- printf("scc1 int: %d\n", state);
m_scc1_int = state;
m_maincpu->set_input_line(SPARC_IRQ12, ((m_scc1_int || m_scc2_int) && (m_irq_reg & 0x01)) ? ASSERT_LINE : CLEAR_LINE);
@@ -1554,7 +1587,6 @@ WRITE_LINE_MEMBER( sun4_state::scc1_int )
WRITE_LINE_MEMBER( sun4_state::scc2_int )
{
- printf("scc2 int: %d\n", state);
m_scc2_int = state;
m_maincpu->set_input_line(SPARC_IRQ12, ((m_scc1_int || m_scc2_int) && (m_irq_reg & 0x01)) ? ASSERT_LINE : CLEAR_LINE);
@@ -1708,7 +1740,7 @@ void sun4_state::dma_transfer_write()
{
int bit_index = (3 - pack_cnt) * 8;
uint8_t dma_value = m_scsi->dma_r();
- logerror("Read from device: %02x\n", dma_value);
+ logerror("Read from device: %02x, pack count %d\n", dma_value, pack_cnt);
m_dma_pack_register |= dma_value << bit_index;
if ((m_dma[DMA_CTRL] & DMA_EN_CNT) != 0)
@@ -1717,7 +1749,7 @@ void sun4_state::dma_transfer_write()
pack_cnt++;
if (pack_cnt == 4)
{
- logerror("Writing pack register %08x\n", m_dma_pack_register);
+ logerror("Writing pack register %08x to %08x\n", m_dma_pack_register, m_dma[DMA_ADDR]);
if (m_arch == ARCH_SUN4C)
{
write_insn_data_4c(11, space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0);
@@ -1729,6 +1761,7 @@ void sun4_state::dma_transfer_write()
pack_cnt = 0;
m_dma_pack_register = 0;
+ m_dma[DMA_ADDR] += 4;
}
}
@@ -1756,6 +1789,7 @@ void sun4_state::dma_transfer_read()
{
current_word = read_insn_data(11, space, m_dma[DMA_ADDR] >> 2, ~0);
}
+ word_cached = true;
logerror("Current word: %08x\n", current_word);
}
@@ -1764,12 +1798,12 @@ void sun4_state::dma_transfer_read()
logerror("Write to device: %02x\n", dma_value);
m_scsi->dma_w(dma_value);
+ if ((m_dma[DMA_ADDR] & 3) == 3)
+ word_cached = false;
+
m_dma[DMA_ADDR]++;
if ((m_dma[DMA_CTRL] & DMA_EN_CNT) != 0)
m_dma[DMA_BYTE_COUNT]--;
-
- if ((m_dma[DMA_ADDR] & 3) == 3)
- word_cached = false;
}
}
@@ -1784,7 +1818,7 @@ void sun4_state::dma_transfer()
dma_transfer_read();
}
- if (m_dma[DMA_BYTE_COUNT] == 0 && (m_dma[DMA_CTRL] & DMA_EN_CNT) != 0)
+ if (m_dma[DMA_BYTE_COUNT] == 0)
{
m_dma[DMA_CTRL] |= DMA_TC;
m_dma_tc_read = false;
@@ -1815,13 +1849,32 @@ WRITE32_MEMBER( sun4_state::dma_w )
COMBINE_DATA(&m_dma[DMA_CTRL]);
if (data & DMA_RESET)
+ {
+ logerror("dma_w: reset\n");
m_dma[DMA_CTRL] &= ~(DMA_ERR_PEND | DMA_PACK_CNT | DMA_INT_EN | DMA_FLUSH | DMA_DRAIN | DMA_WRITE | DMA_EN_DMA | DMA_REQ_PEND | DMA_EN_CNT | DMA_TC);
+ }
else if (data & DMA_FLUSH)
{
+ logerror("dma_w: flush\n");
m_dma[DMA_CTRL] &= ~(DMA_PACK_CNT | DMA_ERR_PEND | DMA_TC);
dma_check_interrupts();
}
+ else if (data & DMA_DRAIN)
+ {
+ m_dma[DMA_CTRL] &= ~DMA_DRAIN;
+ const uint8_t pack_cnt = (m_dma[DMA_CTRL] & DMA_PACK_CNT) >> DMA_PACK_CNT_SHIFT;
+ for (uint8_t i = 0; i < pack_cnt; i++)
+ {
+ const uint32_t bit_index = (3 - i) * 8;
+ const uint32_t value = m_dma_pack_register & (0xff << bit_index);
+ logerror("dma_w: draining %02x to RAM address %08x & %08x\n", value >> bit_index, m_dma[DMA_ADDR], 0xff << (24 - bit_index));
+ write_insn_data_4c(11, space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index);
+ m_dma[DMA_ADDR]++;
+ }
+ m_dma_pack_register = 0;
+ m_dma[DMA_CTRL] &= ~DMA_PACK_CNT;
+ }
// TODO: DMA_DRAIN
if (data & DMA_EN_DMA && (m_dma[DMA_CTRL] & DMA_REQ_PEND))
@@ -1878,6 +1931,75 @@ READ32_MEMBER( sun4_state::ss1_sl3_id )
return 0xfe010101;
}
+READ16_MEMBER( sun4_state::lance_r )
+{
+ uint16_t ret = 0;
+ if (offset)
+ {
+ ret = m_lance_rap;
+ logerror("%s: lance_r: RAP = %04x\n", machine().describe_context(), ret);
+ }
+ else
+ {
+ ret = m_lance_csr[m_lance_rap];
+ logerror("%s: lance_r: CSR%d = %04x\n", machine().describe_context(), m_lance_rap, ret);
+ }
+ return ret;
+}
+
+WRITE16_MEMBER( sun4_state::lance_w )
+{
+ if (offset)
+ {
+ logerror("%s: lance_r: RAP = %d\n", machine().describe_context(), data & 3);
+ m_lance_rap = data & 3;
+ }
+ else
+ {
+ logerror("%s: lance_w: CSR%d = %04x\n", machine().describe_context(), m_lance_rap, data);
+ switch (m_lance_rap)
+ {
+ case 0: // Control/Status
+ m_lance_csr[0] &= ~(data & (LANCE_CSR0_ANY_ERR | LANCE_CSR0_IDON));
+ if (m_lance_csr[0] & LANCE_CSR0_ANY_ERR)
+ m_lance_csr[0] |= LANCE_CSR0_ERR;
+ else
+ m_lance_csr[0] &= ~LANCE_CSR0_ERR;
+ if (data & LANCE_CSR0_STOP)
+ {
+ data &= ~(LANCE_CSR0_RXON | LANCE_CSR0_TXON | LANCE_CSR0_TDMD | LANCE_CSR0_STRT | LANCE_CSR0_INIT);
+ m_lance_csr[0] &= ~(LANCE_CSR0_IDON | LANCE_CSR0_RXON | LANCE_CSR0_TXON | LANCE_CSR0_TDMD | LANCE_CSR0_STRT | LANCE_CSR0_INIT);
+ m_lance_csr[3] = 0;
+ }
+ if (data & LANCE_CSR0_INIT)
+ {
+ // TODO: Actually parse initialization block
+ m_lance_csr[0] &= ~LANCE_CSR0_STOP;
+ m_lance_csr[0] |= LANCE_CSR0_IDON | LANCE_CSR0_INIT;
+ }
+ if (data & LANCE_CSR0_STRT)
+ {
+ m_lance_csr[0] &= ~LANCE_CSR0_STOP;
+ m_lance_csr[0] |= (LANCE_CSR0_RXON | LANCE_CSR0_TXON | LANCE_CSR0_TINT | LANCE_CSR0_RINT); // TODO: Handle DTX/DRX in initialization block
+ }
+ if (data & (LANCE_CSR0_BABL | LANCE_CSR0_MISS | LANCE_CSR0_MERR | LANCE_CSR0_RINT | LANCE_CSR0_TINT | LANCE_CSR0_IDON))
+ {
+ m_lance_csr[0] |= LANCE_CSR0_INTR;
+ }
+ break;
+ case 1: // Least significant 15 bits of the Initialization Block
+ m_lance_csr[1] = data & 0xfffe;
+ break;
+ case 2: // Most significant 8 bits of the Initialization Block
+ m_lance_csr[2] = data & 0x00ff;
+ break;
+ case 3: // Bus master interface
+ m_lance_csr[3] = data & 0x0007;
+ break;
+ }
+ }
+}
+
FLOPPY_FORMATS_MEMBER( sun4_state::floppy_formats )
FLOPPY_PC_FORMAT
FLOPPY_FORMATS_END
@@ -1891,10 +2013,10 @@ static void sun_scsi_devices(device_slot_interface &device)
{
device.option_add("cdrom", NSCSI_CDROM);
device.option_add("harddisk", NSCSI_HARDDISK);
- device.option_add_internal("ncr5390", NCR5390);
+ device.option_add_internal("ncr53c90a", NCR53C90A);
}
-void sun4_state::ncr5390(device_t *device)
+void sun4_state::ncr53c90a(device_t *device)
{
devcb_base *devcb;
(void)devcb;
@@ -1954,8 +2076,8 @@ MACHINE_CONFIG_START(sun4_state::sun4)
MCFG_NSCSI_ADD("scsibus:4", sun_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD("scsibus:5", sun_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD("scsibus:6", sun_scsi_devices, nullptr, false)
- MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr5390", true)
- MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr5390", [this] (device_t *device) { ncr5390(device); })
+ MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr53c90a", true)
+ MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr53c90a", [this] (device_t *device) { ncr53c90a(device); })
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sun4_state::sun4c)
@@ -2008,8 +2130,8 @@ MACHINE_CONFIG_START(sun4_state::sun4c)
MCFG_NSCSI_ADD("scsibus:4", sun_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD("scsibus:5", sun_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD("scsibus:6", sun_scsi_devices, nullptr, false)
- MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr5390", true)
- MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr5390", [this] (device_t *device) { ncr5390(device); })
+ MCFG_NSCSI_ADD("scsibus:7", sun_scsi_devices, "ncr53c90a", true)
+ MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr53c90a", [this] (device_t *device) { ncr53c90a(device); })
MCFG_SCREEN_ADD("bwtwo", RASTER)
MCFG_SCREEN_UPDATE_DRIVER(sun4_state, bw2_update)