summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/nubus/quadralink.cpp32
-rw-r--r--src/devices/bus/sbus/bwtwo.cpp40
-rw-r--r--src/devices/bus/sbus/bwtwo.h7
-rw-r--r--src/devices/cpu/sparc/mb86901.cpp448
-rw-r--r--src/devices/cpu/sparc/sparc.h50
-rw-r--r--src/devices/cpu/sparc/sparc_intf.h30
-rw-r--r--src/devices/cpu/sparc/sparcdefs.h2
-rw-r--r--src/devices/machine/ncr5390.cpp67
-rw-r--r--src/devices/machine/ncr5390.h9
-rw-r--r--src/devices/machine/sun4c_mmu.cpp497
-rw-r--r--src/devices/machine/sun4c_mmu.h149
-rw-r--r--src/devices/machine/z80scc.cpp8
-rw-r--r--src/devices/machine/z80scc.h18
-rw-r--r--src/mame/drivers/apple2gs.cpp16
-rw-r--r--src/mame/drivers/sun4.cpp712
-rw-r--r--src/mame/machine/iteagle_fpga.cpp18
16 files changed, 1228 insertions, 875 deletions
diff --git a/src/devices/bus/nubus/quadralink.cpp b/src/devices/bus/nubus/quadralink.cpp
index f38a0f3b57b..a2d138874e6 100644
--- a/src/devices/bus/nubus/quadralink.cpp
+++ b/src/devices/bus/nubus/quadralink.cpp
@@ -126,35 +126,35 @@ WRITE32_MEMBER( nubus_quadralink_device::dev_w )
switch (offset)
{
case 0x0000: // SCC 2 A control
- m_scc2->ca_w(space, 0, data & 0xff);
+ m_scc2->ca_w(0, data & 0xff);
break;
case 0x0002: // SCC 2 A data
- m_scc2->da_w(space, 0, data & 0xff);
+ m_scc2->da_w(0, data & 0xff);
break;
case 0x0004: // SCC 2 B control
- m_scc2->cb_w(space, 0, data & 0xff);
+ m_scc2->cb_w(0, data & 0xff);
break;
case 0x0006: // SCC 2 B data
- m_scc2->db_w(space, 0, data & 0xff);
+ m_scc2->db_w(0, data & 0xff);
break;
case 0x10000: // SCC 1 A control
- m_scc1->ca_w(space, 0, data & 0xff);
+ m_scc1->ca_w(0, data & 0xff);
break;
case 0x10002: // SCC 1 A data
- m_scc1->da_w(space, 0, data & 0xff);
+ m_scc1->da_w(0, data & 0xff);
break;
case 0x10004: // SCC 1 B control
- m_scc1->cb_w(space, 0, data & 0xff);
+ m_scc1->cb_w(0, data & 0xff);
break;
case 0x10006: // SCC 1 B data
- m_scc1->db_w(space, 0, data & 0xff);
+ m_scc1->db_w(0, data & 0xff);
break;
}
}
@@ -165,28 +165,28 @@ READ32_MEMBER( nubus_quadralink_device::dev_r )
switch (offset)
{
case 0x0000:
- return m_scc2->ca_r(space, 0);
+ return m_scc2->ca_r(0);
case 0x0002:
- return m_scc2->da_r(space, 0);
+ return m_scc2->da_r(0);
case 0x0004:
- return m_scc2->cb_r(space, 0);
+ return m_scc2->cb_r(0);
case 0x0006:
- return m_scc2->db_r(space, 0);
+ return m_scc2->db_r(0);
case 0x10000:
- return m_scc1->ca_r(space, 0);
+ return m_scc1->ca_r(0);
case 0x10002:
- return m_scc1->da_r(space, 0);
+ return m_scc1->da_r(0);
case 0x10004:
- return m_scc1->cb_r(space, 0);
+ return m_scc1->cb_r(0);
case 0x10006:
- return m_scc1->db_r(space, 0);
+ return m_scc1->db_r(0);
}
return 0xffffffff;
}
diff --git a/src/devices/bus/sbus/bwtwo.cpp b/src/devices/bus/sbus/bwtwo.cpp
index ab9fd194a88..553e040ec1a 100644
--- a/src/devices/bus/sbus/bwtwo.cpp
+++ b/src/devices/bus/sbus/bwtwo.cpp
@@ -54,7 +54,15 @@ sbus_bwtwo_device::sbus_bwtwo_device(const machine_config &mconfig, const char *
void sbus_bwtwo_device::device_start()
{
- m_vram = std::make_unique<uint32_t[]>(0x100000/4);
+ m_vram = std::make_unique<uint8_t[]>(0x100000);
+
+ for (int i = 0; i < 0x100; i++)
+ {
+ for (int bit = 7; bit >= 0; bit--)
+ {
+ m_mono_lut[i][7 - bit] = BIT(i, bit) ? 0 : ~0;
+ }
+ }
}
void sbus_bwtwo_device::install_device()
@@ -64,25 +72,15 @@ void sbus_bwtwo_device::install_device()
uint32_t sbus_bwtwo_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- static const uint32_t palette[2] = { 0xffffff, 0 };
- uint8_t *vram = (uint8_t *)&m_vram[0];
-
for (int y = 0; y < 900; y++)
{
uint32_t *scanline = &bitmap.pix32(y);
- uint8_t *line = vram + y * (1152/8);
+ uint8_t *line = &m_vram[y * 1152/8];
for (int x = 0; x < 1152/8; x++)
{
- const uint8_t pixels = line[BYTE4_XOR_BE(x)];
-
- *scanline++ = palette[BIT(pixels, 7)];
- *scanline++ = palette[BIT(pixels, 6)];
- *scanline++ = palette[BIT(pixels, 5)];
- *scanline++ = palette[BIT(pixels, 4)];
- *scanline++ = palette[BIT(pixels, 3)];
- *scanline++ = palette[BIT(pixels, 2)];
- *scanline++ = palette[BIT(pixels, 1)];
- *scanline++ = palette[BIT(pixels, 0)];
+ memcpy(scanline, m_mono_lut[*line], sizeof(uint32_t) * 8);
+ line++;
+ scanline += 8;
}
}
@@ -100,17 +98,17 @@ WRITE8_MEMBER(sbus_bwtwo_device::regs_w)
logerror("%s: regs_w (unimplemented): %08x = %02x\n", machine().describe_context(), 0x400000 + offset, data);
}
-READ32_MEMBER(sbus_bwtwo_device::vram_r)
+READ32_MEMBER(sbus_bwtwo_device::rom_r)
{
- return m_vram[offset];
+ return ((uint32_t*)m_rom->base())[offset];
}
-READ32_MEMBER(sbus_bwtwo_device::rom_r)
+READ8_MEMBER(sbus_bwtwo_device::vram_r)
{
- return ((uint32_t*)m_rom->base())[offset];
+ return m_vram[offset];
}
-WRITE32_MEMBER(sbus_bwtwo_device::vram_w)
+WRITE8_MEMBER(sbus_bwtwo_device::vram_w)
{
- COMBINE_DATA(&m_vram[offset]);
+ m_vram[offset] = data;
}
diff --git a/src/devices/bus/sbus/bwtwo.h b/src/devices/bus/sbus/bwtwo.h
index 0d4a96f2f39..fb3408db7d4 100644
--- a/src/devices/bus/sbus/bwtwo.h
+++ b/src/devices/bus/sbus/bwtwo.h
@@ -32,8 +32,8 @@ protected:
DECLARE_READ8_MEMBER(regs_r);
DECLARE_WRITE8_MEMBER(regs_w);
DECLARE_READ32_MEMBER(rom_r);
- DECLARE_READ32_MEMBER(vram_r);
- DECLARE_WRITE32_MEMBER(vram_w);
+ DECLARE_READ8_MEMBER(vram_r);
+ DECLARE_WRITE8_MEMBER(vram_w);
private:
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
@@ -41,8 +41,9 @@ private:
void mem_map(address_map &map) override;
required_memory_region m_rom;
- std::unique_ptr<uint32_t[]> m_vram;
+ std::unique_ptr<uint8_t[]> m_vram;
required_device<screen_device> m_screen;
+ uint32_t m_mono_lut[256][8];
};
diff --git a/src/devices/cpu/sparc/mb86901.cpp b/src/devices/cpu/sparc/mb86901.cpp
index 76ef7ac56e4..751e39610e3 100644
--- a/src/devices/cpu/sparc/mb86901.cpp
+++ b/src/devices/cpu/sparc/mb86901.cpp
@@ -8,6 +8,13 @@
// the integer instructions in a SPARC v7
// compatible instruction set.
//
+// Notes:
+// - The CPU core implementation has been simplified
+// somewhat compared to the spec. In particular, bus
+// holding on read/write accesses is disabled, as there
+// is currently no use made of it, and it is unlikely to
+// ever be.
+//
// To-Do:
// - Ops: FBFcc, LDF, STF
// - Test: SPARCv8 ops are untested
@@ -41,16 +48,9 @@ const int mb86901_device::NWINDOWS = 7;
mb86901_device::mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: cpu_device(mconfig, MB86901, tag, owner, clock)
+ , m_mmu(*this, finder_base::DUMMY_TAG)
{
m_default_config = address_space_config("program", ENDIANNESS_BIG, 32, 32);
-
- char buf[32];
- for (uint32_t i = 0; i < AS_COUNT; i++)
- {
- snprintf(buf, ARRAY_LENGTH(buf), "asi%d", i);
- m_asi_names[i] = buf;
- m_asi_config[i] = address_space_config(m_asi_names[i].c_str(), ENDIANNESS_BIG, 32, 32);
- }
}
@@ -153,6 +153,29 @@ void mb86901_device::device_start()
memset(m_privileged_asr, 1, 32 * sizeof(bool));
m_privileged_asr[0] = false;
+ memset(m_alu_setcc, 0, 64 * sizeof(bool));
+ m_alu_setcc[OP3_ADDCC] = true;
+ m_alu_setcc[OP3_ANDCC] = true;
+ m_alu_setcc[OP3_ORCC] = true;
+ m_alu_setcc[OP3_XORCC] = true;
+ m_alu_setcc[OP3_SUBCC] = true;
+ m_alu_setcc[OP3_ANDNCC] = true;
+ m_alu_setcc[OP3_ORNCC] = true;
+ m_alu_setcc[OP3_XNORCC] = true;
+ m_alu_setcc[OP3_ADDXCC] = true;
+ m_alu_setcc[OP3_SUBXCC] = true;
+ m_alu_setcc[OP3_TADDCC] = true;
+ m_alu_setcc[OP3_TSUBCC] = true;
+ m_alu_setcc[OP3_TADDCCTV] = true;
+ m_alu_setcc[OP3_TSUBCCTV] = true;
+ m_alu_setcc[OP3_MULSCC] = true;
+#if SPARCV8
+ m_alu_setcc[OP3_UMULCC] = true;
+ m_alu_setcc[OP3_SMULCC] = true;
+ m_alu_setcc[OP3_UDIVCC] = true;
+ m_alu_setcc[OP3_SDIVCC] = true;
+#endif
+
memset(m_alu_op3_assigned, 0, 64 * sizeof(bool));
m_alu_op3_assigned[OP3_ADD] = true;
m_alu_op3_assigned[OP3_AND] = true;
@@ -210,11 +233,6 @@ void mb86901_device::device_start()
m_alu_op3_assigned[OP3_UDIVCC] = true;
m_alu_op3_assigned[OP3_SDIVCC] = true;
#endif
- for (uint32_t i = 0; i < AS_COUNT; i++)
- {
- m_space[i] = &space(AS_START + i);
- m_access_cache[i] = m_space[i]->cache<2, 0, ENDIANNESS_BIG>();
- }
memset(m_ldst_op3_assigned, 0, 64 * sizeof(bool));
m_ldst_op3_assigned[OP3_LD] = true;
@@ -379,6 +397,10 @@ void mb86901_device::device_stop()
{
}
+void mb86901_device::device_resolve_objects()
+{
+ m_mmu->set_host(this);
+}
void mb86901_device::device_reset()
{
@@ -405,6 +427,8 @@ void mb86901_device::device_reset()
m_bp_irl = 0;
m_irq_state = 0;
+ m_stashed_icount = -1;
+
MAE = false;
HOLD_BUS = false;
m_annul = false;
@@ -420,7 +444,8 @@ void mb86901_device::device_reset()
PSR = PSR_S_MASK | PSR_PS_MASK;
m_s = true;
- m_fetch_space = 9;
+ m_insn_space = 9;
+ m_data_space = 11;
for (int i = 0; i < 8; i++)
{
@@ -448,10 +473,6 @@ device_memory_interface::space_config_vector mb86901_device::memory_space_config
{
space_config_vector config_vector;
config_vector.push_back(std::make_pair(AS_PROGRAM, &m_default_config));
- for (uint32_t i = 0; i < 32; i++)
- {
- config_vector.push_back(std::make_pair(AS_START + i, &m_asi_config[i]));
- }
return config_vector;
}
@@ -463,21 +484,10 @@ device_memory_interface::space_config_vector mb86901_device::memory_space_config
// a 32-bit word in a big-endian system.
//-------------------------------------------------
-uint32_t mb86901_device::read_sized_word(uint8_t asi, uint32_t address, int size)
+uint32_t mb86901_device::read_sized_word(const uint8_t asi, const uint32_t address, const uint32_t mem_mask)
{
assert(asi < 0x20); // We do not currently support ASIs outside the range used by actual Sun machines.
- if (size == 1)
- {
- return m_access_cache[asi]->read_byte(address) << ((3 - (address & 3)) * 8);
- }
- else if (size == 2)
- {
- return m_access_cache[asi]->read_word(address) << ((2 - (address & 2)) * 8);
- }
- else
- {
- return m_access_cache[asi]->read_dword(address);
- }
+ return m_mmu->read_asi(asi, address >> 2, mem_mask);
}
@@ -490,21 +500,10 @@ uint32_t mb86901_device::read_sized_word(uint8_t asi, uint32_t address, int size
// size handlers
//-------------------------------------------------
-void mb86901_device::write_sized_word(uint8_t asi, uint32_t address, uint32_t data, int size)
+void mb86901_device::write_sized_word(const uint8_t asi, const uint32_t address, const uint32_t data, const uint32_t mem_mask)
{
assert(asi < 0x20); // We do not currently support ASIs outside the range used by actual Sun machines.
- if (size == 1)
- {
- m_access_cache[asi]->write_byte(address, data >> ((3 - (address & 3)) * 8));
- }
- else if (size == 2)
- {
- m_access_cache[asi]->write_word(address, data >> ((2 - (address & 2)) * 8));
- }
- else
- {
- m_access_cache[asi]->write_dword(address, data);
- }
+ m_mmu->write_asi(asi, address >> 2, data, mem_mask);
}
@@ -911,10 +910,11 @@ void mb86901_device::execute_logical(uint32_t op)
);
*/
- uint32_t operand2 = USEIMM ? SIMM13 : RS2REG;
+ const uint32_t operand2 = USEIMM ? SIMM13 : RS2REG;
+ const uint32_t op3 = OP3;
uint32_t result = 0;
- switch (OP3)
+ switch (op3)
{
case OP3_AND:
case OP3_ANDCC:
@@ -945,11 +945,13 @@ void mb86901_device::execute_logical(uint32_t op)
if (RD != 0)
RDREG = result;
- if (ANDCC || ANDNCC || ORCC || ORNCC || XORCC || XNORCC)
+ if (m_alu_setcc[op3])
{
CLEAR_ICC;
- PSR |= (BIT31(result)) ? PSR_N_MASK : 0;
- PSR |= (result == 0) ? PSR_Z_MASK : 0;
+ if (result & 0x80000000)
+ PSR |= PSR_N_MASK;
+ else if (result == 0)
+ PSR |= PSR_Z_MASK;
}
PC = nPC;
@@ -1205,7 +1207,16 @@ void mb86901_device::execute_wrsr(uint32_t op)
m_et = PSR & PSR_ET_MASK;
m_pil = (PSR & PSR_PIL_MASK) >> PSR_PIL_SHIFT;
m_s = PSR & PSR_S_MASK;
- m_fetch_space = m_s ? 9 : 8;
+ if (m_s)
+ {
+ m_insn_space = 9;
+ m_data_space = 11;
+ }
+ else
+ {
+ m_insn_space = 8;
+ m_data_space = 10;
+ }
PC = nPC;
nPC = nPC + 4;
@@ -1304,6 +1315,8 @@ void mb86901_device::execute_rett(uint32_t op)
m_tt = 3;
m_execute_mode = 0;
m_error_mode = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if ((WIM & (1 << new_cwp)) != 0)
@@ -1313,6 +1326,8 @@ void mb86901_device::execute_rett(uint32_t op)
m_tt = 6;
m_execute_mode = 0;
m_error_mode = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if (address & 3)
@@ -1322,6 +1337,8 @@ void mb86901_device::execute_rett(uint32_t op)
m_tt = 7;
m_execute_mode = 0;
m_error_mode = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1337,13 +1354,15 @@ void mb86901_device::execute_rett(uint32_t op)
{
PSR |= PSR_S_MASK;
m_s = true;
- m_fetch_space = 9;
+ m_insn_space = 9;
+ m_data_space = 11;
}
else
{
PSR &= ~PSR_S_MASK;
m_s = false;
- m_fetch_space = 8;
+ m_insn_space = 8;
+ m_data_space = 10;
}
update_gpr_pointers();
@@ -1405,7 +1424,6 @@ void mb86901_device::execute_saverestore(uint32_t op)
result = rs1 + operand2;
PSR &= ~PSR_CWP_MASK;
PSR |= new_cwp;
- //BREAK_PSR;
}
else if (RESTORE)
{
@@ -1420,7 +1438,6 @@ void mb86901_device::execute_saverestore(uint32_t op)
result = rs1 + operand2;
PSR &= ~PSR_CWP_MASK;
PSR |= new_cwp;
- //BREAK_PSR;
}
update_gpr_pointers();
@@ -1475,7 +1492,7 @@ void mb86901_device::execute_jmpl(uint32_t op)
// mostly ALU ops
//-------------------------------------------------
-void mb86901_device::execute_group2(uint32_t op)
+inline void mb86901_device::execute_group2(uint32_t op)
{
switch (OP3)
{
@@ -1550,6 +1567,7 @@ void mb86901_device::execute_group2(uint32_t op)
m_trap = 1;
m_fp_disabled = 1;
}
+ complete_fp_execution(op);
return;
case OP3_JMPL:
@@ -1592,14 +1610,14 @@ void mb86901_device::execute_group2(uint32_t op)
case OP3_CPOP1:
case OP3_CPOP2:
- printf("fpop @ %08x: %08x\n", PC, op);
+ logerror("fpop @ %08x: %08x\n", PC, op);
m_trap = 1;
m_cp_disabled = 1;
return;
#endif
default:
- printf("illegal instruction at %08x: %08x\n", PC, op);
+ logerror("illegal instruction at %08x: %08x\n", PC, op);
m_trap = 1;
m_illegal_instruction = 1;
break;
@@ -1768,7 +1786,7 @@ void mb86901_device::execute_store(uint32_t op)
if (STD || ST || STH || STB || STF || STDF || STFSR || STDFQ || STCSR || STC || STDC || STDCQ)
{
address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ addr_space = m_data_space;
}
else if (STDA || STA || STHA || STBA)
{
@@ -1925,7 +1943,9 @@ void mb86901_device::execute_store(uint32_t op)
}
}
- write_sized_word(addr_space, address, data0, (ST || STA || STD || STDA || STF || STDF || STDFQ || STFSR || STC || STDC || STDCQ || STCSR) ? 4 : ((STH || STHA) ? 2 : 1));
+ static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
+ static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
+ m_mmu->write_asi(addr_space, address >> 2, data0, (ST || STA || STD || STDA || STF || STDF || STDFQ || STFSR || STC || STDC || STDCQ || STCSR) ? 0xffffffff : ((STH || STHA) ? mask16[address & 2] : mask8[address & 3]));
if (MAE)
{
m_trap = 1;
@@ -1957,7 +1977,7 @@ void mb86901_device::execute_store(uint32_t op)
data1 = 0;
}
- write_sized_word(addr_space, address + 4, data1, 4);
+ m_mmu->write_asi(addr_space, (address + 4) >> 2, data1, 0xffffffff);
if (MAE)
{
m_trap = 1;
@@ -2076,14 +2096,14 @@ void mb86901_device::execute_load(uint32_t op)
);
*/
- uint32_t address = 0;
- uint8_t addr_space = 0;
+ static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
+ static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
+
switch (OP3)
{
case OP3_LDD:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (address & 7)
{
@@ -2091,7 +2111,7 @@ void mb86901_device::execute_load(uint32_t op)
m_mem_address_not_aligned = 1;
}
- const uint32_t data = read_sized_word(addr_space, address, 4);
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
if (MAE)
{
@@ -2103,7 +2123,7 @@ void mb86901_device::execute_load(uint32_t op)
if (RD != 0)
RDREG = data;
- const uint32_t word1 = read_sized_word(addr_space, address + 4, 4);
+ const uint32_t word1 = m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
if (MAE)
{
m_trap = 1;
@@ -2116,8 +2136,7 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LD:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (address & 3)
{
@@ -2126,7 +2145,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 4);
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
if (m_mae)
{
@@ -2141,8 +2160,7 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDSH:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (address & 1)
{
@@ -2151,7 +2169,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 2);
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask16[address & 2]);
if (m_mae)
{
@@ -2169,8 +2187,7 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDUH:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (address & 1)
{
@@ -2179,7 +2196,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 2);
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask16[address & 2]);
if (m_mae)
{
@@ -2197,10 +2214,9 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDSB:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- const uint32_t data = read_sized_word(addr_space, address, 1);
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask8[address & 3]);
if (m_mae)
{
@@ -2220,10 +2236,9 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDUB:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- const uint32_t data = read_sized_word(addr_space, address, 1);
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask8[address & 3]);
if (m_mae)
{
@@ -2243,8 +2258,7 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDDFPR:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)
{
@@ -2276,7 +2290,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 4);
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
if (m_mae)
{
@@ -2287,7 +2301,7 @@ void mb86901_device::execute_load(uint32_t op)
FREG(RD & 0x1e) = data;
- const uint32_t word1 = read_sized_word(addr_space, address + 4, 4);
+ const uint32_t word1 = m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
if (MAE)
{
m_trap = 1;
@@ -2300,8 +2314,7 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDFPR:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)
{
@@ -2325,7 +2338,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 4);
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
if (m_mae)
{
@@ -2339,8 +2352,7 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDFSR:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)
{
@@ -2364,7 +2376,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 4);
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
if (m_mae)
{
@@ -2378,8 +2390,7 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDDCPR:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
{
@@ -2403,7 +2414,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- read_sized_word(addr_space, address, 4);
+ m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
if (MAE)
{
m_trap = 1;
@@ -2413,7 +2424,7 @@ void mb86901_device::execute_load(uint32_t op)
// implementation-dependent actions
- read_sized_word(addr_space, address + 4, 4);
+ m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
if (MAE)
{
m_trap = 1;
@@ -2426,8 +2437,7 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDCPR:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
{
@@ -2451,7 +2461,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- read_sized_word(addr_space, address, 4);
+ m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
if (MAE)
{
@@ -2465,8 +2475,7 @@ void mb86901_device::execute_load(uint32_t op)
}
case OP3_LDCSR:
{
- address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- addr_space = (IS_USER ? 10 : 11);
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
{
@@ -2490,7 +2499,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- read_sized_word(addr_space, address, 4);
+ m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
if (MAE)
{
@@ -2516,11 +2525,9 @@ void mb86901_device::execute_load(uint32_t op)
m_illegal_instruction = 1;
return;
}
- else
- {
- address = RS1REG + RS2REG;
- addr_space = ASI;
- }
+
+ const uint32_t address = RS1REG + RS2REG;
+ const uint32_t addr_space = ASI;
if (address & 7)
{
@@ -2529,7 +2536,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 4);
+ const uint32_t data = m_mmu->read_asi(addr_space, address >> 2, 0xffffffff);
if (m_mae)
{
@@ -2541,7 +2548,7 @@ void mb86901_device::execute_load(uint32_t op)
if (RD != 0)
RDREG = data;
- uint32_t word1 = read_sized_word(addr_space, address + 4, 4);
+ uint32_t word1 = m_mmu->read_asi(addr_space, (address + 4) >> 2, 0xffffffff);
if (MAE)
{
m_trap = 1;
@@ -2566,11 +2573,8 @@ void mb86901_device::execute_load(uint32_t op)
m_illegal_instruction = 1;
return;
}
- else
- {
- address = RS1REG + RS2REG;
- addr_space = ASI;
- }
+
+ const uint32_t address = RS1REG + RS2REG;
if (address & 3)
{
@@ -2579,7 +2583,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 4);
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, 0xffffffff);
if (m_mae)
{
@@ -2606,11 +2610,8 @@ void mb86901_device::execute_load(uint32_t op)
m_illegal_instruction = 1;
return;
}
- else
- {
- address = RS1REG + RS2REG;
- addr_space = ASI;
- }
+
+ const uint32_t address = RS1REG + RS2REG;
if (address & 1)
{
@@ -2619,7 +2620,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 2);
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask16[address & 2]);
if (m_mae)
{
@@ -2649,12 +2650,8 @@ void mb86901_device::execute_load(uint32_t op)
m_illegal_instruction = 1;
return;
}
- else
- {
- address = RS1REG + RS2REG;
- addr_space = ASI;
- }
+ const uint32_t address = RS1REG + RS2REG;
if (address & 1)
{
m_trap = 1;
@@ -2662,7 +2659,7 @@ void mb86901_device::execute_load(uint32_t op)
return;
}
- const uint32_t data = read_sized_word(addr_space, address, 2);
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask16[address & 2]);
if (m_mae)
{
@@ -2692,13 +2689,9 @@ void mb86901_device::execute_load(uint32_t op)
m_illegal_instruction = 1;
return;
}
- else
- {
- address = RS1REG + RS2REG;
- addr_space = ASI;
- }
- const uint32_t data = read_sized_word(addr_space, address, 1);
+ const uint32_t address = RS1REG + RS2REG;
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask8[address & 3]);
if (m_mae)
{
@@ -2730,13 +2723,9 @@ void mb86901_device::execute_load(uint32_t op)
m_illegal_instruction = 1;
return;
}
- else
- {
- address = RS1REG + RS2REG;
- addr_space = ASI;
- }
- const uint32_t data = read_sized_word(addr_space, address, 1);
+ const uint32_t address = RS1REG + RS2REG;
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask8[address & 3]);
if (m_mae)
{
@@ -2868,7 +2857,8 @@ void mb86901_device::execute_ldstub(uint32_t op)
m_pb_block_ldst_byte = 1;
- data = read_sized_word(addr_space, address, 1);
+ static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
+ data = m_mmu->read_asi(addr_space, address >> 2, mask8[address & 3]);
if (MAE)
{
@@ -2877,24 +2867,7 @@ void mb86901_device::execute_ldstub(uint32_t op)
return;
}
- //uint8_t byte_mask;
- if ((address & 3) == 0)
- {
- //byte_mask = 8;
- }
- else if ((address & 3) == 1)
- {
- //byte_mask = 4;
- }
- else if ((address & 3) == 2)
- {
- //byte_mask = 2;
- }
- else if ((address & 3) == 3)
- {
- //byte_mask = 1;
- }
- write_sized_word(addr_space, address, 0xffffffff, 1);
+ m_mmu->write_asi(addr_space, address >> 2, 0xffffffff, mask8[address & 3]);
m_pb_block_ldst_byte = 0;
@@ -2935,7 +2908,7 @@ void mb86901_device::execute_ldstub(uint32_t op)
// (load/store)
//-------------------------------------------------
-void mb86901_device::execute_group3(uint32_t op)
+inline void mb86901_device::execute_group3(uint32_t op)
{
static const int ldst_cycles[64] = {
1, 1, 1, 2, 2, 2, 2, 3,
@@ -3003,13 +2976,13 @@ void mb86901_device::execute_group3(uint32_t op)
#endif
default:
- printf("illegal instruction at %08x: %08x\n", PC, op);
+ logerror("illegal instruction at %08x: %08x\n", PC, op);
m_trap = 1;
m_illegal_instruction = 1;
break;
}
- if (MAE || HOLD_BUS)
+ if (MAE /*|| HOLD_BUS*/)
m_icount--;
else
m_icount -= ldst_cycles[OP3];
@@ -3186,6 +3159,8 @@ void mb86901_device::select_trap()
{
m_execute_mode = 0;
m_error_mode = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
}
else if (m_data_store_error)
m_tt = 0x2b;
@@ -3355,7 +3330,8 @@ void mb86901_device::execute_trap()
PSR |= PSR_S_MASK;
m_s = true;
- m_fetch_space = 9;
+ m_insn_space = 9;
+ m_data_space = 11;
int cwp = PSR & PSR_CWP_MASK;
int new_cwp = ((cwp + NWINDOWS) - 1) % NWINDOWS;
@@ -3425,13 +3401,14 @@ if (trap = 0) then (
inline void mb86901_device::dispatch_instruction(uint32_t op)
{
- switch (OP_NS)
+ const uint8_t op_type = OP;
+ switch (op_type)
{
- case OP_TYPE0_NS: // Bicc, SETHI, FBfcc
+ case OP_TYPE0: // Bicc, SETHI, FBfcc
switch (OP2)
{
case OP2_UNIMP: // unimp
- printf("unimp @ %x\n", PC);
+ logerror("unimp @ %x\n", PC);
break;
case OP2_BICC: // branch on integer condition codes
execute_bicc(op);
@@ -3446,7 +3423,7 @@ inline void mb86901_device::dispatch_instruction(uint32_t op)
case OP2_FBFCC: // branch on floating-point condition codes
if (!(PSR & PSR_EF_MASK) || !m_bp_fpu_present)
{
- //printf("fbfcc at %08x: %08x\n", PC, op);
+ logerror("fbfcc at %08x: %08x\n", PC, op);
m_trap = 1;
m_fp_disabled = 1;
return;
@@ -3456,7 +3433,7 @@ inline void mb86901_device::dispatch_instruction(uint32_t op)
case OP2_CBCCC: // branch on coprocessor condition codes, SPARCv8
if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
{
- printf("cbccc @ %08x: %08x\n", PC, op);
+ logerror("cbccc @ %08x: %08x\n", PC, op);
m_trap = 1;
m_cp_disabled = 1;
return;
@@ -3464,14 +3441,14 @@ inline void mb86901_device::dispatch_instruction(uint32_t op)
return;
#endif
default:
- printf("illegal instruction at %08x: %08x\n", PC, op);
+ logerror("illegal instruction at %08x: %08x\n", PC, op);
m_trap = 1;
m_illegal_instruction = 1;
return;
}
break;
- case OP_CALL_NS: // call
+ case OP_CALL:
{
uint32_t pc = PC;
uint32_t callpc = PC + DISP30;
@@ -3482,11 +3459,11 @@ inline void mb86901_device::dispatch_instruction(uint32_t op)
break;
}
- case OP_ALU_NS:
+ case OP_ALU:
execute_group2(op);
break;
- case OP_LDST_NS:
+ case OP_LDST:
execute_group3(op);
break;
}
@@ -3506,7 +3483,7 @@ void mb86901_device::complete_fp_execution(uint32_t /*op*/)
// mode (versus error or reset modes)
//-------------------------------------------------
-void mb86901_device::execute_step()
+inline void mb86901_device::execute_step()
{
/* The SPARC Instruction Manual: Version 8, page 156, "Appendix C - ISP Descriptions - C.5. Processor States and Instruction Dispatch" (SPARCv8.pdf, pg. 153)
@@ -3565,7 +3542,8 @@ void mb86901_device::execute_step()
m_execute_mode = 0;
m_error_mode = 0;
m_reset_mode = 1;
- //printf("Entering reset mode\n");
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if (m_et && (m_bp_irl == 15 || m_bp_irl > m_pil))
@@ -3577,51 +3555,35 @@ void mb86901_device::execute_step()
if (m_trap)
{
execute_trap();
- //BREAK_PSR;
- debugger_instruction_hook(PC);
}
- if (m_execute_mode)
- {
- // write-state-register delay not yet implemented
+ // write-state-register delay not yet implemented
- const uint32_t op = read_sized_word(m_fetch_space, PC, 4);
+ const uint32_t op = m_mmu->read_asi(m_insn_space, PC >> 2, 0xffffffff);
#if LOG_FCODES
- //if (m_log_fcodes)
- {
- log_fcodes();
- }
+ //if (m_log_fcodes)
+ {
+ log_fcodes();
+ }
#endif
- if (MAE && !m_annul)
+ if (MAE && !m_annul)
+ {
+ m_trap = 1;
+ m_instruction_access_exception = 1;
+ }
+ else
+ {
+ if (!m_annul)
{
- m_trap = 1;
- m_instruction_access_exception = 1;
+ dispatch_instruction(op);
}
else
{
- if (!m_annul)
- {
- dispatch_instruction(op);
-
- if (FPOP1 || FPOP2)
- {
- complete_fp_execution(op);
- }
-
- //if (m_trap == 0 && !(OP == OP_CALL || (OP == OP_TYPE0 && (OP2 == OP2_BICC || OP2 == OP2_FBFCC || OP2 == OP2_CBCCC)) || (OP == OP_ALU && (JMPL || TICC || RETT))))
- //{
- //PC = nPC;
- //nPC = nPC + 4;
- //}
- }
- else
- {
- m_annul = 0;
- PC = nPC;
- nPC = nPC + 4;
- }
+ m_annul = 0;
+ PC = nPC;
+ nPC = nPC + 4;
}
}
}
@@ -3651,7 +3613,8 @@ void mb86901_device::reset_step()
m_execute_mode = 1;
m_trap = 1;
m_reset_trap = 1;
- //printf("m_bp_reset_in is false, resetting\n");
+ m_stashed_icount = m_icount;
+ m_icount = 0;
}
}
@@ -3678,44 +3641,39 @@ void mb86901_device::error_step()
m_error_mode = 0;
m_reset_mode = 1;
m_pb_error = 0;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
}
}
-
-//-------------------------------------------------
-// execute_run - execute a timeslice's worth of
-// opcodes
-//-------------------------------------------------
-
-void mb86901_device::execute_run()
+template <bool CHECK_DEBUG, mb86901_device::running_mode MODE>
+void mb86901_device::run_loop()
{
- bool debug = machine().debug_flags & DEBUG_FLAG_ENABLED;
-
- while (m_icount > 0)
+ do
{
- if (HOLD_BUS)
+ /*if (HOLD_BUS)
{
m_icount--;
continue;
- }
+ }*/
- //BREAK_PSR;
- debugger_instruction_hook(PC);
+ if (CHECK_DEBUG)
+ debugger_instruction_hook(PC);
- if (m_reset_mode)
+ if (MODE == MODE_RESET)
{
reset_step();
}
- else if (m_error_mode)
+ else if (MODE == MODE_ERROR)
{
error_step();
}
- else if (m_execute_mode)
+ else if (MODE == MODE_EXECUTE)
{
execute_step();
}
- if (debug)
+ if (CHECK_DEBUG)
{
for (int i = 0; i < 8; i++)
{
@@ -3725,7 +3683,45 @@ void mb86901_device::execute_run()
}
}
--m_icount;
- }
+ } while (m_icount >= 0);
+}
+
+//-------------------------------------------------
+// execute_run - execute a timeslice's worth of
+// opcodes
+//-------------------------------------------------
+
+void mb86901_device::execute_run()
+{
+ bool debug = machine().debug_flags & DEBUG_FLAG_ENABLED;
+
+ do
+ {
+ if (debug)
+ {
+ if (m_reset_mode)
+ run_loop<true, MODE_RESET>();
+ else if (m_error_mode)
+ run_loop<true, MODE_ERROR>();
+ else
+ run_loop<true, MODE_EXECUTE>();
+ }
+ else
+ {
+ if (m_reset_mode)
+ run_loop<false, MODE_RESET>();
+ else if (m_error_mode)
+ run_loop<false, MODE_ERROR>();
+ else
+ run_loop<false, MODE_EXECUTE>();
+ }
+
+ if (m_stashed_icount >= 0)
+ {
+ m_icount = m_stashed_icount;
+ m_stashed_icount = -1;
+ }
+ } while (m_icount >= 0);
}
diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h
index 41264b6ed2b..1bbcccc44fe 100644
--- a/src/devices/cpu/sparc/sparc.h
+++ b/src/devices/cpu/sparc/sparc.h
@@ -10,6 +10,7 @@
#pragma once
#include "sparcdasm.h"
+#include "sparc_intf.h"
#define SPARCV8 (1)
#define LOG_FCODES (0)
@@ -22,28 +23,18 @@
#define MCFG_SPARC_ADD_ASI_DESC(desc) \
downcast<mb86901_device &>(*device).add_asi_desc([](sparc_disassembler *dasm) { dasm->add_asi_desc(desc); });
-class mb86901_device : public cpu_device, protected sparc_disassembler::config
+class mb86901_device : public cpu_device, public sparc_mmu_host_interface, protected sparc_disassembler::config
{
public:
mb86901_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
- enum
- {
- AS_COUNT = 32,
-
- AS_START = 128,
- AS_END = AS_START + (AS_COUNT - 1)
- };
-
- template <typename T> void set_asi_addrmap(int asi, T &&obj)
- {
- set_addrmap(asi + AS_START, std::forward<T>(obj));
- }
+ template <typename T> void set_mmu(T &&tag) { m_mmu.set_tag(std::forward<T>(tag)); }
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual void device_stop() override;
+ virtual void device_resolve_objects() override;
// device_execute_interface overrides
virtual uint32_t execute_min_cycles() const override;
@@ -63,7 +54,7 @@ public:
uint8_t get_asi() { return 0; }
uint32_t pc() { return m_pc; }
- void set_mae() { m_mae = 1; }
+ void set_mae() override { m_mae = 1; }
void add_asi_desc(std::function<void (sparc_disassembler *)> f) { m_asi_desc_adder = f; }
@@ -92,7 +83,7 @@ protected:
void execute_mul(uint32_t op);
void execute_div(uint32_t op);
#endif
- void execute_group2(uint32_t op);
+ inline void execute_group2(uint32_t op);
void execute_load(uint32_t op);
void execute_store(uint32_t op);
@@ -100,7 +91,7 @@ protected:
#if SPARCV8
void execute_swap(uint32_t op);
#endif
- void execute_group3(uint32_t op);
+ inline void execute_group3(uint32_t op);
bool evaluate_condition(uint32_t op);
void execute_bicc(uint32_t op);
@@ -111,26 +102,33 @@ protected:
void complete_instruction_execution(uint32_t op);
inline void dispatch_instruction(uint32_t op);
void complete_fp_execution(uint32_t /*op*/);
- void execute_step();
+ inline void execute_step();
void reset_step();
void error_step();
+ enum running_mode
+ {
+ MODE_RESET,
+ MODE_ERROR,
+ MODE_EXECUTE
+ };
+
+ template <bool CHECK_DEBUG, running_mode MODE> void run_loop();
#if LOG_FCODES
void indent();
void disassemble_ss1_fcode(uint32_t r5, uint32_t opcode, uint32_t handler_base, uint32_t entry_point, uint32_t stack);
void log_fcodes();
#endif
+ required_device<sparc_mmu_interface> m_mmu;
+
// address spaces
- std::string m_asi_names[AS_COUNT];
- address_space_config m_asi_config[AS_COUNT];
- memory_access_cache<2, 0, ENDIANNESS_BIG> *m_access_cache[AS_COUNT];
address_space_config m_default_config;
// memory access
- uint32_t read_sized_word(uint8_t asi, uint32_t address, int size);
- void write_sized_word(uint8_t asi, uint32_t address, uint32_t data, int size);
+ uint32_t read_sized_word(const uint8_t asi, const uint32_t address, const uint32_t mem_mask);
+ void write_sized_word(const uint8_t asi, const uint32_t address, const uint32_t data, const uint32_t mem_mask);
// helpers for the disassembler
virtual uint64_t get_reg_r(unsigned index) const override;
@@ -209,6 +207,7 @@ protected:
bool m_alu_op3_assigned[64];
bool m_ldst_op3_assigned[64];
+ bool m_alu_setcc[64];
// register windowing helpers
uint32_t* m_regs[32];
@@ -220,14 +219,13 @@ protected:
bool m_annul;
bool m_hold_bus;
int m_icount;
- int m_fetch_space;
+ int m_stashed_icount;
+ int m_insn_space;
+ int m_data_space;
// debugger helpers
uint32_t m_dbgregs[24];
- // address spaces
- address_space *m_space[32];
-
#if LOG_FCODES
uint32_t m_ss1_next_pc;
uint32_t m_ss1_next_opcode;
diff --git a/src/devices/cpu/sparc/sparc_intf.h b/src/devices/cpu/sparc/sparc_intf.h
new file mode 100644
index 00000000000..a203abd92ea
--- /dev/null
+++ b/src/devices/cpu/sparc/sparc_intf.h
@@ -0,0 +1,30 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/***************************************************************************
+
+ sparc_intf.h - Sun SPARC MMU interfaces
+
+***************************************************************************/
+
+#ifndef MAME_CPU_SPARC_SPARC_INTF_H
+#define MAME_CPU_SPARC_SPARC_INTF_H
+
+#pragma once
+
+class sparc_mmu_host_interface
+{
+public:
+ virtual ~sparc_mmu_host_interface() { }
+ virtual void set_mae() = 0;
+};
+
+class sparc_mmu_interface
+{
+public:
+ virtual ~sparc_mmu_interface() { }
+ virtual void set_host(sparc_mmu_host_interface *host) = 0;
+ virtual uint32_t read_asi(uint8_t asi, uint32_t offset, uint32_t mem_mask) = 0;
+ virtual void write_asi(uint8_t asi, uint32_t offset, uint32_t data, uint32_t mem_mask) = 0;
+};
+
+#endif // MAME_CPU_SPARC_SPARC_INTF_H \ No newline at end of file
diff --git a/src/devices/cpu/sparc/sparcdefs.h b/src/devices/cpu/sparc/sparcdefs.h
index 0ae566ad5a7..050f1aa1f74 100644
--- a/src/devices/cpu/sparc/sparcdefs.h
+++ b/src/devices/cpu/sparc/sparcdefs.h
@@ -105,7 +105,7 @@
#define SHCNT32 (op & 31)
#define SHCNT64 (op & 63)
#define IAMODE (op & 0x7)
-#define USEIMM ((op >> 13) & 1)
+#define USEIMM (op & (1 << 13))
#define USEEXT ((op >> 12) & 1)
diff --git a/src/devices/machine/ncr5390.cpp b/src/devices/machine/ncr5390.cpp
index 8d9f4b9641b..135bcdb9705 100644
--- a/src/devices/machine/ncr5390.cpp
+++ b/src/devices/machine/ncr5390.cpp
@@ -33,6 +33,42 @@ void ncr5390_device::map(address_map &map)
map(0x9, 0x9).w(FUNC(ncr5390_device::clock_w));
}
+READ8_MEMBER(ncr5390_device::read)
+{
+ switch (offset)
+ {
+ case 0: return tcounter_lo_r(space, 0);
+ case 1: return tcounter_hi_r(space, 0);
+ case 2: return fifo_r(space, 0);
+ case 3: return command_r(space, 0);
+ case 4: return status_r(space, 0);
+ case 5: return istatus_r(space, 0);
+ case 6: return seq_step_r(space, 0);
+ case 7: return fifo_flags_r(space, 0);
+ case 8: return conf_r(space, 0);
+ default: return 0;
+ }
+}
+
+WRITE8_MEMBER(ncr5390_device::write)
+{
+ switch (offset)
+ {
+ case 0: tcount_lo_w(space, 0, data); break;
+ case 1: tcount_hi_w(space, 0, data); break;
+ case 2: fifo_w(space, 0, data); break;
+ case 3: command_w(space, 0, data); break;
+ case 4: bus_id_w(space, 0, data); break;
+ case 5: timeout_w(space, 0, data); break;
+ case 6: sync_period_w(space, 0, data); break;
+ case 7: sync_offset_w(space, 0, data); break;
+ case 8: conf_w(space, 0, data); break;
+ case 9: clock_w(space, 0, data); break;
+ case 10: test_w(space, 0, data); break;
+ default: break;
+ }
+}
+
void ncr53c90a_device::map(address_map &map)
{
ncr5390_device::map(map);
@@ -40,6 +76,20 @@ void ncr53c90a_device::map(address_map &map)
map(0xb, 0xb).rw(FUNC(ncr53c90a_device::conf2_r), FUNC(ncr53c90a_device::conf2_w));
}
+READ8_MEMBER(ncr53c90a_device::read)
+{
+ if (offset == 11)
+ return conf2_r(space, 0);
+ return ncr5390_device::read(space, offset);
+}
+
+WRITE8_MEMBER(ncr53c90a_device::write)
+{
+ if (offset == 11)
+ return conf2_w(space, 0, data);
+ ncr5390_device::write(space, offset, data);
+}
+
void ncr53c94_device::map(address_map &map)
{
ncr53c90a_device::map(map);
@@ -48,6 +98,23 @@ void ncr53c94_device::map(address_map &map)
map(0xf, 0xf).w(FUNC(ncr53c94_device::fifo_align_w));
}
+READ8_MEMBER(ncr53c94_device::read)
+{
+ if (offset == 12)
+ return conf3_r(space, 0);
+ return ncr53c90a_device::read(space, offset);
+}
+
+WRITE8_MEMBER(ncr53c94_device::write)
+{
+ if (offset == 11)
+ conf3_w(space, 0, data);
+ else if (offset == 15)
+ fifo_align_w(space, 0, data);
+ else
+ ncr53c90a_device::write(space, offset, data);
+}
+
ncr5390_device::ncr5390_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: nscsi_device(mconfig, type, tag, owner, clock)
, tm(nullptr), config(0), status(0), istatus(0), clock_conv(0), sync_offset(0), sync_period(0), bus_id(0)
diff --git a/src/devices/machine/ncr5390.h b/src/devices/machine/ncr5390.h
index 9a2bed1bc28..d39b352ddb7 100644
--- a/src/devices/machine/ncr5390.h
+++ b/src/devices/machine/ncr5390.h
@@ -48,6 +48,9 @@ public:
DECLARE_WRITE8_MEMBER(test_w);
DECLARE_WRITE8_MEMBER(clock_w);
+ virtual DECLARE_READ8_MEMBER(read);
+ virtual DECLARE_WRITE8_MEMBER(write);
+
virtual void scsi_ctrl_changed() override;
uint8_t dma_r();
@@ -264,6 +267,9 @@ public:
DECLARE_READ8_MEMBER(conf2_r) { return config2; };
DECLARE_WRITE8_MEMBER(conf2_w) { config2 = data; };
+ DECLARE_READ8_MEMBER(read) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+
protected:
ncr53c90a_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
@@ -292,6 +298,9 @@ public:
DECLARE_WRITE8_MEMBER(conf3_w) { config3 = data; };
DECLARE_WRITE8_MEMBER(fifo_align_w) { fifo_align = data; };
+ DECLARE_READ8_MEMBER(read) override;
+ DECLARE_WRITE8_MEMBER(write) override;
+
protected:
virtual void device_start() override;
void reset_soft();
diff --git a/src/devices/machine/sun4c_mmu.cpp b/src/devices/machine/sun4c_mmu.cpp
new file mode 100644
index 00000000000..68290f1fac9
--- /dev/null
+++ b/src/devices/machine/sun4c_mmu.cpp
@@ -0,0 +1,497 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/***************************************************************************
+
+ sun4c_mmu.cpp - Sun 4c MMU emulation
+
+***************************************************************************/
+
+#include "emu.h"
+#include "sun4c_mmu.h"
+#include "cpu/sparc/sparc.h"
+
+DEFINE_DEVICE_TYPE(SUN4C_MMU, sun4c_mmu_device, "sun4c_mmu", "Sun 4C MMU")
+
+sun4c_mmu_device::sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, SUN4C_MMU, tag, owner, clock)
+ , m_cpu(*this, finder_base::DUMMY_TAG)
+ , m_ram(*this, finder_base::DUMMY_TAG)
+ , m_rom(*this, finder_base::DUMMY_TAG)
+ , m_scc(*this, finder_base::DUMMY_TAG)
+ , m_host(nullptr)
+ , m_type1_r(*this)
+ , m_type1_w(*this)
+ , m_rom_ptr(nullptr)
+ , m_ram_ptr(nullptr)
+ , m_ram_size(0)
+ , m_ram_size_words(0)
+ , m_context(0)
+ , m_context_masked(0)
+ , m_system_enable(0)
+ , m_fetch_bootrom(true)
+ , m_curr_segmap(nullptr)
+ , m_curr_segmap_masked(nullptr)
+{
+}
+
+void sun4c_mmu_device::device_start()
+{
+ m_type1_r.resolve_safe(0xffffffff);
+ m_type1_w.resolve_safe();
+
+ // allocate timer for system reset
+ m_reset_timer = timer_alloc(TIMER_RESET);
+ m_reset_timer->adjust(attotime::never);
+}
+
+void sun4c_mmu_device::device_reset()
+{
+ m_rom_ptr = (uint32_t *)m_rom->base();
+ m_ram_ptr = (uint32_t *)m_ram->pointer();
+ m_ram_size = m_ram->size();
+ m_ram_size_words = m_ram_size >> 2;
+
+ m_context = 0;
+ m_context_masked = 0;
+ m_curr_segmap = m_segmap[0];
+ m_curr_segmap_masked = m_segmap_masked[0];
+ m_system_enable = 0;
+ m_fetch_bootrom = true;
+
+ memset(m_buserr, 0, sizeof(uint32_t) * 4);
+ memset(m_segmap, 0, sizeof(uint8_t) * 16 * 4096);
+ memset(m_pagemap, 0, sizeof(page_entry_t) * 16384);
+ memset(m_cachetags, 0, sizeof(uint32_t) * 16384);
+ memset(m_cachedata, 0, sizeof(uint32_t) * 16384);
+}
+
+void sun4c_mmu_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ if (id == TIMER_RESET)
+ {
+ m_reset_timer->adjust(attotime::never);
+ m_cpu->set_input_line(SPARC_RESET, CLEAR_LINE);
+ //printf("Clearing reset line\n");
+ }
+}
+
+uint32_t sun4c_mmu_device::read_asi(uint8_t asi, uint32_t offset, uint32_t mem_mask)
+{
+ //logerror("read_asi %d: %08x & %08x\n", asi, offset << 2, mem_mask);
+ switch (asi)
+ {
+ case 2:
+ return system_r(offset, mem_mask);
+ case 3:
+ return segment_map_r(offset, mem_mask);
+ case 4:
+ return page_map_r(offset, mem_mask);
+ case 8:
+ return insn_data_r<USER_INSN>(offset, mem_mask);
+ case 9:
+ return insn_data_r<SUPER_INSN>(offset, mem_mask);
+ case 10:
+ return insn_data_r<USER_DATA>(offset, mem_mask);
+ case 11:
+ return insn_data_r<SUPER_DATA>(offset, mem_mask);
+ case 12:
+ case 13:
+ case 14:
+ cache_flush_r();
+ return 0;
+ default:
+ return ~0;
+ }
+}
+
+void sun4c_mmu_device::write_asi(uint8_t asi, uint32_t offset, uint32_t data, uint32_t mem_mask)
+{
+ //logerror("write_asi %d: %08x = %08x & %08x\n", asi, offset << 2, data, mem_mask);
+ switch (asi)
+ {
+ case 2:
+ system_w(offset, data, mem_mask);
+ return;
+ case 3:
+ segment_map_w(offset, data, mem_mask);
+ return;
+ case 4:
+ page_map_w(offset, data, mem_mask);
+ return;
+ case 8:
+ insn_data_w<USER_INSN>(offset, data, mem_mask);
+ return;
+ case 9:
+ insn_data_w<SUPER_INSN>(offset, data, mem_mask);
+ return;
+ case 10:
+ insn_data_w<USER_DATA>(offset, data, mem_mask);
+ return;
+ case 11:
+ insn_data_w<SUPER_DATA>(offset, data, mem_mask);
+ return;
+ case 12:
+ case 13:
+ case 14:
+ cache_flush_w();
+ return;
+ default:
+ return;
+ }
+}
+
+uint32_t sun4c_mmu_device::cache_flush_r()
+{
+ // Do nothing for now
+ return 0;
+}
+
+void sun4c_mmu_device::cache_flush_w()
+{
+ // Do nothing for now
+}
+
+uint32_t sun4c_mmu_device::system_r(const uint32_t offset, const uint32_t mem_mask)
+{
+ //logerror("%s: system_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
+ switch (offset >> 26)
+ {
+ case 3: // context reg
+ if (mem_mask == 0x00ff0000) return m_context<<16;
+ return m_context<<24;
+
+ case 4: // system enable reg
+ return m_system_enable<<24;
+
+ case 6: // bus error register
+ {
+ //printf("sun4c_mmu: read buserror %08x, PC=%x (mask %08x)\n", 0x60000000 | (offset << 2), m_cpu->pc(), mem_mask);
+ const uint32_t retval = m_buserr[offset & 0xf];
+ m_buserr[offset & 0xf] = 0; // clear on reading
+ return retval;
+ }
+
+ case 8: // (d-)cache tags
+ //logerror("sun4_mmu: read dcache tags @ %x, PC = %x\n", offset, m_cpu->pc());
+ return m_cachetags[(offset >> 3) & 0x3fff];
+
+ case 9: // (d-)cache data
+ //logerror("sun4c_mmu: read dcache data @ %x, PC = %x\n", offset, m_cpu->pc());
+ return m_cachedata[offset & 0x3fff];
+
+ case 0xf: // UART bypass
+ //printf("sun4c_mmu: read UART bypass @ %x mask %08x\n", offset<<2, mem_mask);
+ switch (offset & 3)
+ {
+ case 0: if (mem_mask == 0xff000000) return m_scc->cb_r(0)<<24; else return m_scc->db_r(0)<<8; break;
+ case 1: if (mem_mask == 0xff000000) return m_scc->ca_r(0)<<24; else return m_scc->da_r(0)<<8; break;
+ }
+ return 0xffffffff;
+
+ case 0: // IDPROM - SPARCstation-1 does not have an ID prom and a timeout should occur.
+ default:
+ logerror("%s: sun4c_mmu: ASI 2 space unhandled read @ %x\n", machine().describe_context(), offset<<2);
+ return 0;
+ }
+}
+
+void sun4c_mmu_device::system_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
+{
+ //logerror("%s: system_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
+ switch (offset >> 26)
+ {
+ case 3: // context reg
+ //printf("%08x to context, mask %08x, offset %x\n", data, mem_mask, offset);
+ m_context = data >> 24;
+ m_context_masked = m_context & m_ctx_mask;
+ m_curr_segmap = m_segmap[m_context_masked];
+ m_curr_segmap_masked = m_segmap_masked[m_context_masked];
+ return;
+
+ case 4: // system enable reg
+ {
+ m_system_enable = data >> 24;
+ m_fetch_bootrom = !(m_system_enable & ENA_NOTBOOT);
+
+ if (m_system_enable & ENA_RESET)
+ {
+ m_reset_timer->adjust(attotime::from_usec(1));
+ m_cpu->set_input_line(SPARC_RESET, ASSERT_LINE);
+ //logerror("%s: Asserting reset line\n", machine().describe_context());
+ }
+ //printf("%08x to system enable, mask %08x\n", data, mem_mask);
+ if (m_system_enable & ENA_RESET)
+ {
+ m_system_enable = 0;
+ m_cpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
+ m_cpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
+ }
+ return;
+ }
+
+ case 6: // bus error
+ //logerror("%08x to bus error @ %x, mask %08x\n", data, offset, mem_mask);
+ m_buserr[offset & 0xf] = data;
+ return;
+
+ case 8: // cache tags
+ //logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_cpu->pc());
+ m_cachetags[(offset>>3)&0x3fff] = data & 0x03f8fffc;
+ return;
+
+ case 9: // cache data
+ //logerror("sun4c: %08x to cache data @ %x, PC = %x\n", data, offset, m_cpu->pc());
+ m_cachedata[offset&0x3fff] = data;
+ return;
+
+ case 0xf: // UART bypass
+ //printf("%08x to UART bypass @ %x, mask %08x\n", data, offset<<2, mem_mask);
+ switch (offset & 3)
+ {
+ case 0: if (mem_mask == 0xff000000) m_scc->cb_w(0, data>>24); else m_scc->db_w(0, data>>8); break;
+ case 1: if (mem_mask == 0xff000000) m_scc->ca_w(0, data>>24); else { m_scc->da_w(0, data>>8); printf("%c", data>>8); } break;
+ }
+ return;
+
+ case 0: // IDPROM
+ default:
+ logerror("sun4c: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x, shift %x)\n", data, offset<<2, mem_mask, m_cpu->pc(), offset>>26);
+ return;
+ }
+}
+
+uint32_t sun4c_mmu_device::segment_map_r(const uint32_t offset, const uint32_t mem_mask)
+{
+ //logerror("%s: segment_map_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
+ if (mem_mask == 0xffff0000)
+ return m_curr_segmap[(offset>>16) & 0xfff]<<16;
+ else if (mem_mask == 0xff000000)
+ return m_curr_segmap[(offset>>16) & 0xfff]<<24;
+ else
+ logerror("sun4: read segment map w/ unknown mask %08x\n", mem_mask);
+ return 0;
+}
+
+void sun4c_mmu_device::segment_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
+{
+ //logerror("segment_map_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
+
+ uint8_t segdata = 0;
+ if (mem_mask == 0xffff0000) segdata = (data >> 16) & 0xff;
+ else if (mem_mask == 0xff000000) segdata = (data >> 24) & 0xff;
+ else logerror("sun4c: writing segment map with unknown mask %08x, PC=%x\n", mem_mask, m_cpu->pc());
+
+ const uint32_t seg = (offset>>16) & 0xfff;
+ m_curr_segmap[seg] = segdata;
+ m_curr_segmap_masked[seg] = (segdata & m_pmeg_mask) << 6;
+}
+
+uint32_t sun4c_mmu_device::page_map_r(const uint32_t offset, const uint32_t mem_mask)
+{
+ //logerror("%s: page_map_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
+ const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f);
+ return m_pagemap[page].to_uint();
+}
+
+void sun4c_mmu_device::page_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
+{
+ //logerror("%s: page_map_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
+ const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f);
+ m_pagemap[page].merge_uint(data, mem_mask);
+ m_page_valid[page] = m_pagemap[page].valid;
+}
+
+void sun4c_mmu_device::type0_timeout_r(const uint32_t offset)
+{
+ m_buserr[0] = 0x20; // read timeout
+ m_buserr[1] = 0x04000000 + (offset << 2);
+ m_host->set_mae();
+}
+
+void sun4c_mmu_device::type0_timeout_w(const uint32_t offset)
+{
+ m_buserr[0] = 0x8020; // write timeout
+ m_buserr[1] = 0x04000000 + (offset << 2);
+ m_host->set_mae();
+}
+
+uint32_t sun4c_mmu_device::page_entry_t::to_uint()
+{
+ return valid | writable | supervisor | uncached | (type << 26) | accessed | modified | (page >> 10);
+}
+
+void sun4c_mmu_device::page_entry_t::merge_uint(uint32_t data, uint32_t mem_mask)
+{
+ const uint32_t new_value = (to_uint() & ~mem_mask) | (data & mem_mask);
+ valid = new_value & PM_VALID;
+ writable = new_value & PM_WRITEMASK;
+ supervisor = new_value & PM_SYSMASK;
+ uncached = new_value & PM_CACHE;
+ type = (new_value & PM_TYPEMASK) >> 26;
+ accessed = new_value & PM_ACCESSED;
+ modified = new_value & PM_MODIFIED;
+ page = (new_value & 0xffff) << 10;
+}
+
+template uint32_t sun4c_mmu_device::insn_data_r<sun4c_mmu_device::USER_INSN>(const uint32_t, const uint32_t);
+template uint32_t sun4c_mmu_device::insn_data_r<sun4c_mmu_device::SUPER_INSN>(const uint32_t, const uint32_t);
+template uint32_t sun4c_mmu_device::insn_data_r<sun4c_mmu_device::USER_DATA>(const uint32_t, const uint32_t);
+template uint32_t sun4c_mmu_device::insn_data_r<sun4c_mmu_device::SUPER_DATA>(const uint32_t, const uint32_t);
+
+template <sun4c_mmu_device::insn_data_mode MODE>
+uint32_t sun4c_mmu_device::insn_data_r(const uint32_t offset, const uint32_t mem_mask)
+{
+ // supervisor program fetches in boot state are special
+ if (m_fetch_bootrom && MODE == SUPER_INSN)
+ {
+ return m_rom_ptr[offset & 0x1ffff];
+ }
+
+ // it's translation time
+ const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
+ const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f);
+
+ if (m_page_valid[entry_index])
+ {
+ page_entry_t &entry = m_pagemap[entry_index];
+ entry.accessed = PM_ACCESSED;
+
+ const uint32_t tmp = entry.page | (offset & 0x3ff);
+
+ //printf("sun4c: read translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint(), m_cpu->pc());
+
+ switch (entry.type)
+ {
+ case 0: // type 0 space
+ //return m_type0space->read32(space, tmp, mem_mask);
+ if (tmp < 0x1000000 >> 2)
+ {
+ return m_ram_ptr[tmp];
+ }
+ else if (tmp >= 0x4000000 >> 2 && tmp < 0x10000000 >> 2)
+ {
+ type0_timeout_r(tmp);
+ }
+ return ~0;
+
+ case 1: // type 1 space
+ return m_type1_r(tmp, mem_mask);
+
+ default:
+ //logerror("sun4c_mmu: access to memory type not defined in sun4c\n");
+ m_host->set_mae();
+ m_buserr[0] = 0x20;
+ m_buserr[1] = offset << 2;
+ return 0;
+ }
+ }
+ else
+ {
+ if (!machine().side_effects_disabled())
+ {
+ //logerror("sun4c: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), offset <<2, m_cpu->pc());
+ m_host->set_mae();
+ m_buserr[0] |= 0x80; // invalid PTE
+ m_buserr[0] &= ~0x8000; // read
+ m_buserr[1] = offset << 2;
+ if (mem_mask != ~0 && mem_mask != 0xffff0000 && mem_mask != 0xff000000)
+ {
+ if (mem_mask == 0x0000ffff || mem_mask == 0x0000ff00)
+ {
+ m_buserr[1] |= 2;
+ }
+ else if (mem_mask == 0x00ff0000)
+ {
+ m_buserr[1] |= 1;
+ }
+ else if (mem_mask == 0x000000ff)
+ {
+ m_buserr[1] |= 3;
+ }
+ }
+ }
+ return 0;
+ }
+}
+
+template void sun4c_mmu_device::insn_data_w<sun4c_mmu_device::USER_INSN>(const uint32_t, const uint32_t, const uint32_t);
+template void sun4c_mmu_device::insn_data_w<sun4c_mmu_device::SUPER_INSN>(const uint32_t, const uint32_t, const uint32_t);
+template void sun4c_mmu_device::insn_data_w<sun4c_mmu_device::USER_DATA>(const uint32_t, const uint32_t, const uint32_t);
+template void sun4c_mmu_device::insn_data_w<sun4c_mmu_device::SUPER_DATA>(const uint32_t, const uint32_t, const uint32_t);
+
+template <sun4c_mmu_device::insn_data_mode MODE>
+void sun4c_mmu_device::insn_data_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask)
+{
+ // it's translation time
+ const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
+ const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f);
+
+ if (m_page_valid[entry_index])
+ {
+ page_entry_t &entry = m_pagemap[entry_index];
+ if ((!entry.writable) || (entry.supervisor && MODE != SUPER_DATA && MODE != SUPER_INSN))
+ {
+ //logerror("sun4c: write protect MMU error (PC=%x)\n", m_cpu->pc());
+ m_buserr[0] |= 0x8040; // write, protection error
+ m_buserr[1] = offset << 2;
+ m_host->set_mae();
+ return;
+ }
+
+ entry.accessed = PM_ACCESSED;
+ entry.modified = PM_MODIFIED;
+
+ const uint32_t tmp = entry.page | (offset & 0x3ff);
+
+ //printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, ASI %d, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint(), asi, m_cpu->pc());
+
+ switch (entry.type)
+ {
+ case 0: // type 0
+ if (tmp < 0x1000000 >> 2)
+ {
+ COMBINE_DATA((m_ram_ptr + tmp));
+ }
+ else if (tmp >= 0x4000000 >> 2 && tmp < 0x10000000 >> 2)
+ {
+ type0_timeout_w(tmp);
+ }
+ return;
+
+ case 1: // type 1
+ //printf("write device space @ %x = %08x\n", tmp << 2, data);
+ m_type1_w(tmp, data, mem_mask);
+ return;
+
+ default:
+ //logerror("sun4c_mmu: access to memory type not defined\n");
+ m_host->set_mae();
+ m_buserr[0] = 0x8020;
+ m_buserr[1] = offset << 2;
+ return;
+ }
+ }
+ else
+ {
+ //logerror("sun4c: INVALID PTE entry %d %08x accessed! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), data, offset <<2, m_cpu->pc());
+ m_host->set_mae();
+ m_buserr[0] |= 0x8080; // write cycle, invalid PTE
+ m_buserr[1] = offset << 2;
+ if (mem_mask != ~0 && mem_mask != 0xffff0000 && mem_mask != 0xff000000)
+ {
+ if (mem_mask == 0x0000ffff || mem_mask == 0x0000ff00)
+ {
+ m_buserr[1] |= 2;
+ }
+ else if (mem_mask == 0x00ff0000)
+ {
+ m_buserr[1] |= 1;
+ }
+ else if (mem_mask == 0x000000ff)
+ {
+ m_buserr[1] |= 3;
+ }
+ }
+ }
+}
+
diff --git a/src/devices/machine/sun4c_mmu.h b/src/devices/machine/sun4c_mmu.h
new file mode 100644
index 00000000000..0beafb73c29
--- /dev/null
+++ b/src/devices/machine/sun4c_mmu.h
@@ -0,0 +1,149 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/***************************************************************************
+
+ sun4c_mmu.h - Sun 4c MMU emulation
+
+***************************************************************************/
+
+#ifndef MAME_MACHINE_SUN4C_MMU_H
+#define MAME_MACHINE_SUN4C_MMU_H
+
+#pragma once
+
+#include "cpu/sparc/sparc_intf.h"
+#include "machine/ram.h"
+#include "machine/z80scc.h"
+
+class sun4c_mmu_device : public device_t, public sparc_mmu_interface
+{
+public:
+ sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, uint8_t ctx_mask, uint8_t pmeg_mask)
+ : sun4c_mmu_device(mconfig, tag, owner, clock)
+ {
+ m_ctx_mask = ctx_mask;
+ m_pmeg_mask = pmeg_mask;
+ }
+
+ sun4c_mmu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ template <typename T> void set_cpu(T &&cpu_tag) { m_cpu.set_tag(std::forward<T>(cpu_tag)); }
+ template <typename T> void set_ram(T &&ram_tag) { m_ram.set_tag(std::forward<T>(ram_tag)); }
+ template <typename T> void set_rom(T &&rom_tag) { m_rom.set_tag(std::forward<T>(rom_tag)); }
+ template <typename T> void set_scc(T &&scc_tag) { m_scc.set_tag(std::forward<T>(scc_tag)); }
+
+ enum insn_data_mode
+ {
+ USER_INSN,
+ SUPER_INSN,
+ USER_DATA,
+ SUPER_DATA
+ };
+
+ template <insn_data_mode MODE> uint32_t insn_data_r(const uint32_t offset, const uint32_t mem_mask);
+ template <insn_data_mode MODE> void insn_data_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
+
+ auto type1_r() { return m_type1_r.bind(); }
+ auto type1_w() { return m_type1_w.bind(); }
+
+ // sparc_mmu_device overrides
+ uint32_t read_asi(uint8_t asi, uint32_t offset, uint32_t mem_mask) override;
+ void write_asi(uint8_t asi, uint32_t offset, uint32_t data, uint32_t mem_mask) override;
+ void set_host(sparc_mmu_host_interface *host) override { logerror("Setting host\n"); m_host = host; }
+
+protected:
+ static const device_timer_id TIMER_RESET = 0;
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ uint32_t cache_flush_r();
+ void cache_flush_w();
+ uint32_t system_r(const uint32_t offset, const uint32_t mem_mask);
+ void system_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
+ uint32_t segment_map_r(const uint32_t offset, const uint32_t mem_mask);
+ void segment_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
+ uint32_t page_map_r(const uint32_t offset, const uint32_t mem_mask);
+ void page_map_w(const uint32_t offset, const uint32_t data, const uint32_t mem_mask);
+ void type0_timeout_r(const uint32_t offset);
+ void type0_timeout_w(const uint32_t offset);
+
+ enum
+ {
+ // system enable constants
+ ENA_NOTBOOT = 0x80,
+ ENA_SDVMA = 0x20,
+ ENA_CACHE = 0x10,
+ ENA_RESET = 0x04,
+ ENA_DIAG = 0x01,
+
+ // page table entry constants
+ PM_VALID = 0x80000000, // page is valid
+ PM_WRITEMASK = 0x40000000, // writable?
+ PM_SYSMASK = 0x20000000, // system use only?
+ PM_CACHE = 0x10000000, // cachable?
+ PM_TYPEMASK = 0x0c000000, // type mask
+ PM_ACCESSED = 0x02000000, // accessed flag
+ PM_MODIFIED = 0x01000000 // modified flag
+ };
+
+ struct page_entry_t
+ {
+ uint32_t valid;
+ uint32_t writable;
+ uint32_t supervisor;
+ uint32_t uncached;
+ uint32_t accessed;
+ uint32_t modified;
+ uint32_t page;
+ uint8_t type;
+ uint8_t pad[3];
+
+ uint32_t to_uint();
+ void merge_uint(uint32_t data, uint32_t mem_mask);
+ };
+
+ required_device<cpu_device> m_cpu;
+ required_device<ram_device> m_ram;
+ required_memory_region m_rom;
+ required_device<z80scc_device> m_scc;
+
+ sparc_mmu_host_interface *m_host;
+
+ // Bus access callbacks
+ devcb_read32 m_type1_r;
+ devcb_write32 m_type1_w;
+
+ // Actual SRAM
+ uint8_t m_segmap[16][4096];
+ page_entry_t m_pagemap[16384];
+ uint32_t m_cachetags[16384];
+ uint32_t m_cachedata[16384];
+
+ uint32_t *m_rom_ptr;
+ uint32_t *m_ram_ptr;
+ uint32_t m_ram_size;
+ uint32_t m_ram_size_words;
+ uint32_t m_context;
+ uint32_t m_context_masked;
+ uint8_t m_system_enable;
+ bool m_fetch_bootrom;
+ uint32_t m_buserr[4];
+
+ // Pre-computed data for optimization purposes
+ uint32_t m_segmap_masked[16][4096];
+ uint8_t *m_curr_segmap;
+ uint32_t *m_curr_segmap_masked;
+ bool m_page_valid[16384];
+
+ // Internal MAME device state
+ uint8_t m_ctx_mask; // SS2 is sun4c but has 16 contexts; most have 8
+ uint8_t m_pmeg_mask; // SS2 is sun4c but has 16384 PTEs; most have 8192
+ emu_timer *m_reset_timer;
+};
+
+
+DECLARE_DEVICE_TYPE(SUN4C_MMU, sun4c_mmu_device)
+
+#endif // MAME_MACHINE_SUN4C_MMU_H \ No newline at end of file
diff --git a/src/devices/machine/z80scc.cpp b/src/devices/machine/z80scc.cpp
index dd967d6af27..711d58b8b49 100644
--- a/src/devices/machine/z80scc.cpp
+++ b/src/devices/machine/z80scc.cpp
@@ -2590,10 +2590,10 @@ void z80scc_channel::m_tx_fifo_rp_step()
}
}
-READ8_MEMBER (z80scc_device::da_r) { return m_chanA->data_read(); }
-WRITE8_MEMBER (z80scc_device::da_w) { m_chanA->data_write(data); }
-READ8_MEMBER (z80scc_device::db_r) { return m_chanB->data_read(); }
-WRITE8_MEMBER (z80scc_device::db_w) { m_chanB->data_write(data); }
+uint8_t z80scc_device::da_r(offs_t offset) { return m_chanA->data_read(); }
+void z80scc_device::da_w(offs_t offset, uint8_t data) { m_chanA->data_write(data); }
+uint8_t z80scc_device::db_r(offs_t offset) { return m_chanB->data_read(); }
+void z80scc_device::db_w(offs_t offset, uint8_t data) { m_chanB->data_write(data); }
//-------------------------------------------------
// data_write - write data register
diff --git a/src/devices/machine/z80scc.h b/src/devices/machine/z80scc.h
index 259536290da..e2cad9e660b 100644
--- a/src/devices/machine/z80scc.h
+++ b/src/devices/machine/z80scc.h
@@ -363,15 +363,15 @@ public:
DECLARE_WRITE8_MEMBER( ba_cd_inv_w );
/* Definitions moved to z80scc.c for enhancements */
- DECLARE_READ8_MEMBER( da_r ); // { return m_chanA->data_read(); }
- DECLARE_WRITE8_MEMBER( da_w ); // { m_chanA->data_write(data); }
- DECLARE_READ8_MEMBER( db_r ); // { return m_chanB->data_read(); }
- DECLARE_WRITE8_MEMBER( db_w ); // { m_chanB->data_write(data); }
-
- DECLARE_READ8_MEMBER( ca_r ) { return m_chanA->control_read(); }
- DECLARE_WRITE8_MEMBER( ca_w ) { m_chanA->control_write(data); }
- DECLARE_READ8_MEMBER( cb_r ) { return m_chanB->control_read(); }
- DECLARE_WRITE8_MEMBER( cb_w ) { m_chanB->control_write(data); }
+ uint8_t da_r(offs_t offset);
+ void da_w(offs_t offset, uint8_t data);
+ uint8_t db_r(offs_t offset);
+ void db_w(offs_t offset, uint8_t data);
+
+ uint8_t ca_r(offs_t offset) { return m_chanA->control_read(); }
+ void ca_w(offs_t offset, uint8_t data) { m_chanA->control_write(data); }
+ uint8_t cb_r(offs_t offset) { return m_chanB->control_read(); }
+ void cb_w(offs_t offset, uint8_t data) { m_chanB->control_write(data); }
DECLARE_READ8_MEMBER( zbus_r );
DECLARE_WRITE8_MEMBER( zbus_w );
diff --git a/src/mame/drivers/apple2gs.cpp b/src/mame/drivers/apple2gs.cpp
index 237e5b74ebc..237965808c5 100644
--- a/src/mame/drivers/apple2gs.cpp
+++ b/src/mame/drivers/apple2gs.cpp
@@ -2227,16 +2227,16 @@ READ8_MEMBER(apple2gs_state::c000_r)
return m_speed;
case 0x38: // SCCBREG
- return m_scc->cb_r(space, 0);
+ return m_scc->cb_r(0);
case 0x39: // SCCAREG
- return m_scc->ca_r(space, 0);
+ return m_scc->ca_r(0);
case 0x3a: // SCCBDATA
- return m_scc->db_r(space, 0);
+ return m_scc->db_r(0);
case 0x3b: // SCCADATA
- return m_scc->da_r(space, 0);
+ return m_scc->da_r(0);
case 0x3c: // SOUNDCTL
return m_sndglu_ctrl;
@@ -2549,19 +2549,19 @@ WRITE8_MEMBER(apple2gs_state::c000_w)
break;
case 0x38: // SCCBREG
- m_scc->cb_w(space, 0, data);
+ m_scc->cb_w(0, data);
break;
case 0x39: // SCCAREG
- m_scc->ca_w(space, 0, data);
+ m_scc->ca_w(0, data);
break;
case 0x3a: // SCCBDATA
- m_scc->db_w(space, 0, data);
+ m_scc->db_w(0, data);
break;
case 0x3b: // SCCADATA
- m_scc->da_w(space, 0, data);
+ m_scc->da_w(0, data);
break;
case 0x3c: // SOUNDCTL
diff --git a/src/mame/drivers/sun4.cpp b/src/mame/drivers/sun4.cpp
index 8127d3258e3..8855cfa70a6 100644
--- a/src/mame/drivers/sun4.cpp
+++ b/src/mame/drivers/sun4.cpp
@@ -425,6 +425,7 @@
#include "machine/nscsi_hd.h"
#include "machine/nvram.h"
#include "machine/ram.h"
+#include "machine/sun4c_mmu.h"
#include "machine/timekpr.h"
#include "machine/upd765.h"
#include "machine/z80scc.h"
@@ -449,23 +450,6 @@
#define FDC_TAG "fdc"
#define LANCE_TAG "lance"
-#define ENA_NOTBOOT (0x80)
-#define ENA_SDVMA (0x20)
-#define ENA_CACHE (0x10)
-#define ENA_RESET (0x04)
-#define ENA_DIAG (0x01)
-
-// page table entry constants
-#define PM_VALID (0x80000000) // page is valid
-#define PM_WRITEMASK (0x40000000) // writable?
-#define PM_SYSMASK (0x20000000) // system use only?
-#define PM_CACHE (0x10000000) // cachable?
-#define PM_TYPEMASK (0x0c000000) // type mask
-#define PM_ACCESSED (0x02000000) // accessed flag
-#define PM_MODIFIED (0x01000000) // modified flag
-
-#define PAGE_SIZE (0x00000400)
-
// DMA controller constants
#define DMA_DEV_ID (0x80000000)
#define DMA_L (0x00008000) // use ILACC
@@ -547,6 +531,7 @@ public:
sun4_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
+ , m_mmu(*this, "mmu")
, m_timekpr(*this, TIMEKEEPER_TAG)
, m_scc1(*this, SCC1_TAG)
, m_scc2(*this, SCC2_TAG)
@@ -561,13 +546,13 @@ public:
, m_ram(*this, RAM_TAG)
, m_rom(*this, "user1")
, m_rom_ptr(nullptr)
- , m_system_enable(0)
{
}
void sun4c(machine_config &config);
void sun4_40(machine_config &config);
void sun4_60(machine_config &config);
+ void sun4_75(machine_config &config);
void sun4(machine_config &config);
void init_sun4();
@@ -591,6 +576,25 @@ private:
SUPER_DATA
};
+ enum
+ {
+ // system enable constants
+ ENA_NOTBOOT = 0x80,
+ ENA_SDVMA = 0x20,
+ ENA_CACHE = 0x10,
+ ENA_RESET = 0x04,
+ ENA_DIAG = 0x01,
+
+ // page table entry constants
+ PM_VALID = 0x80000000, // page is valid
+ PM_WRITEMASK = 0x40000000, // writable?
+ PM_SYSMASK = 0x20000000, // system use only?
+ PM_CACHE = 0x10000000, // cachable?
+ PM_TYPEMASK = 0x0c000000, // type mask
+ PM_ACCESSED = 0x02000000, // accessed flag
+ PM_MODIFIED = 0x01000000 // modified flag
+ };
+
DECLARE_READ32_MEMBER( sun4_cache_flush_r );
DECLARE_WRITE32_MEMBER( sun4_cache_flush_w );
DECLARE_READ32_MEMBER( sun4_system_r );
@@ -602,16 +606,8 @@ private:
template <insn_data_mode MODE> DECLARE_READ32_MEMBER( sun4_insn_data_r );
DECLARE_WRITE32_MEMBER( sun4_insn_data_w );
- DECLARE_READ32_MEMBER( sun4c_cache_flush_r );
- DECLARE_WRITE32_MEMBER( sun4c_cache_flush_w );
- DECLARE_READ32_MEMBER( sun4c_system_r );
- DECLARE_WRITE32_MEMBER( sun4c_system_w );
- DECLARE_READ32_MEMBER( sun4c_segment_map_r );
- DECLARE_WRITE32_MEMBER( sun4c_segment_map_w );
- DECLARE_READ32_MEMBER( sun4c_page_map_r );
- DECLARE_WRITE32_MEMBER( sun4c_page_map_w );
- template <insn_data_mode MODE> DECLARE_READ32_MEMBER( sun4c_insn_data_r );
- template <insn_data_mode MODE> DECLARE_WRITE32_MEMBER( sun4c_insn_data_w );
+ DECLARE_READ32_MEMBER( sun4c_debugger_r );
+ DECLARE_WRITE32_MEMBER( sun4c_debugger_w );
DECLARE_READ32_MEMBER( sun4_mmu_r );
DECLARE_WRITE32_MEMBER( sun4_mmu_w );
@@ -656,14 +652,7 @@ private:
void sun4_data_map(address_map &map);
void sun4_supervisor_data_map(address_map &map);
- void sun4c_system_map(address_map &map);
- void sun4c_segment_map(address_map &map);
- void sun4c_page_map(address_map &map);
- void sun4c_insn_map(address_map &map);
- void sun4c_supervisor_insn_map(address_map &map);
- void sun4c_data_map(address_map &map);
- void sun4c_supervisor_data_map(address_map &map);
- void sun4c_cache_flush_map(address_map &map);
+ void sun4c_debugger_map(address_map &map);
void type0space_map(address_map &map);
void type1space_map(address_map &map);
@@ -677,6 +666,7 @@ private:
};
required_device<mb86901_device> m_maincpu;
+ required_device<sun4c_mmu_device> m_mmu;
required_device<m48t02_device> m_timekpr;
@@ -696,21 +686,6 @@ private:
required_device<ram_device> m_ram;
required_memory_region m_rom;
- uint32_t *m_rom_ptr;
- uint32_t m_context;
- uint32_t m_context_masked;
- uint8_t m_system_enable;
- bool m_fetch_bootrom;
- uint8_t m_auxio;
- uint32_t m_buserr[4];
- uint32_t m_counter[4];
- uint32_t m_dma[4];
- bool m_dma_irq;
- bool m_dma_tc_read;
- uint32_t m_dma_pack_register;
- int m_scsi_irq;
- int m_fdc_irq;
-
struct page_entry_t
{
uint32_t valid;
@@ -723,16 +698,14 @@ private:
uint8_t type;
uint8_t pad[3];
- template <sun4_arch ARCH_4C>
uint32_t to_uint()
{
- return valid | writable | supervisor | uncached | (type << 26) | accessed | modified | (ARCH_4C ? (page >> 10) : (page >> 11));
+ return valid | writable | supervisor | uncached | (type << 26) | accessed | modified | (page >> 11);
}
- template <sun4_arch ARCH_4C>
void merge_uint(uint32_t data, uint32_t mem_mask)
{
- const uint32_t new_value = (to_uint<ARCH_4C>() & ~mem_mask) | (data & mem_mask);
+ const uint32_t new_value = (to_uint() & ~mem_mask) | (data & mem_mask);
valid = new_value & PM_VALID;
writable = new_value & PM_WRITEMASK;
supervisor = new_value & PM_SYSMASK;
@@ -740,23 +713,39 @@ private:
type = (new_value & PM_TYPEMASK) >> 26;
accessed = new_value & PM_ACCESSED;
modified = new_value & PM_MODIFIED;
- page = ARCH_4C ? ((new_value & 0xffff) << 10) : ((new_value & 0x7ffff) << 11);
+ page = (new_value & 0x7ffff) << 11;
}
};
- uint32_t *m_ram_ptr;
uint8_t m_segmap[16][4096];
- uint8_t *m_curr_segmap;
- uint32_t m_segmap_masked[16][4096];
- uint32_t *m_curr_segmap_masked;
page_entry_t m_pagemap[16384];
- bool m_page_valid[16384];
- uint32_t m_cachetags[0x4000];
- uint32_t m_cachedata[0x4000];
+ uint32_t m_cachetags[16384];
+ uint32_t m_cachedata[16384];
+
+ uint32_t *m_rom_ptr;
+ uint32_t *m_ram_ptr;
uint32_t m_ram_size;
uint32_t m_ram_size_words;
- uint8_t m_ctx_mask; // SS2 is sun4c but has 16 contexts; most have 8
- uint8_t m_pmeg_mask; // SS2 is sun4c but has 16384 PTEs; most have 8192
+ uint32_t m_context;
+ uint32_t m_context_masked;
+ uint8_t m_system_enable;
+ bool m_fetch_bootrom;
+ uint32_t m_buserr[4];
+
+ uint32_t m_segmap_masked[16][4096];
+ uint8_t *m_curr_segmap;
+ uint32_t *m_curr_segmap_masked;
+ bool m_page_valid[16384];
+
+ uint8_t m_auxio;
+ uint32_t m_counter[4];
+ uint32_t m_dma[4];
+ bool m_dma_irq;
+ bool m_dma_tc_read;
+ uint32_t m_dma_pack_register;
+ int m_scsi_irq;
+ int m_fdc_irq;
+
uint8_t m_irq_reg; // IRQ control
uint8_t m_scc1_int, m_scc2_int;
uint8_t m_diag;
@@ -776,353 +765,6 @@ private:
void fcodes_command(int ref, const std::vector<std::string> &params);
};
-READ32_MEMBER( sun4_state::sun4c_cache_flush_r )
-{
- // Do nothing for now
- return 0;
-}
-
-WRITE32_MEMBER( sun4_state::sun4c_cache_flush_w )
-{
- // Do nothing for now
-}
-
-READ32_MEMBER( sun4_state::sun4c_system_r )
-{
- //logerror("%s: system_space_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
- switch (offset >> 26)
- {
- case 3: // context reg
- if (mem_mask == 0x00ff0000) return m_context<<16;
- return m_context<<24;
-
- case 4: // system enable reg
- return m_system_enable<<24;
-
- case 6: // bus error register
- {
- //printf("sun4c: read buserror %08x, PC=%x (mask %08x)\n", 0x60000000 | (offset << 2), m_maincpu->pc(), mem_mask);
- const uint32_t retval = m_buserr[offset & 0xf];
- m_buserr[offset & 0xf] = 0; // clear on reading
- return retval;
- }
-
- case 8: // (d-)cache tags
- //logerror("sun4: read dcache tags @ %x, PC = %x\n", offset, m_maincpu->pc());
- return m_cachetags[(offset>>3)&0x3fff];
-
- case 9: // (d-)cache data
- //logerror("sun4c: read dcache data @ %x, PC = %x\n", offset, m_maincpu->pc());
- return m_cachedata[offset&0x3fff];
-
- case 0xf: // UART bypass
- //printf("read UART bypass @ %x mask %08x\n", offset<<2, mem_mask);
- switch (offset & 3)
- {
- case 0: if (mem_mask == 0xff000000) return m_scc2->cb_r(space, offset)<<24; else return m_scc2->db_r(space, offset)<<8; break;
- case 1: if (mem_mask == 0xff000000) return m_scc2->ca_r(space, offset)<<24; else return m_scc2->da_r(space, offset)<<8; break;
- }
- return 0xffffffff;
-
- case 0: // IDPROM - TODO: SPARCstation-1 does not have an ID prom and a timeout should occur.
- default:
- logerror("sun4c: ASI 2 space unhandled read @ %x (PC=%x)\n", offset<<2, m_maincpu->pc());
- return 0;
- }
-}
-
-WRITE32_MEMBER( sun4_state::sun4c_system_w )
-{
- //logerror("%s: system_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
- switch (offset >> 26)
- {
- case 3: // context reg
- //printf("%08x to context, mask %08x, offset %x\n", data, mem_mask, offset);
- m_context = data>>24;
- m_context_masked = m_context & m_ctx_mask;
- m_curr_segmap = m_segmap[m_context_masked];
- m_curr_segmap_masked = m_segmap_masked[m_context_masked];
- return;
-
- case 4: // system enable reg
- {
- const uint8_t old_enable = m_system_enable;
- m_system_enable = data>>24;
- m_fetch_bootrom = !(m_system_enable & ENA_NOTBOOT);
-
- if (m_system_enable & ENA_RESET)
- {
- m_reset_timer->adjust(attotime::from_usec(1));
- m_maincpu->set_input_line(SPARC_RESET, ASSERT_LINE);
- logerror("%s: Asserting reset line\n", machine().describe_context());
- }
- //printf("%08x to system enable, mask %08x\n", data, mem_mask);
- if (m_system_enable & ENA_RESET)
- {
- m_system_enable = 0;
- m_maincpu->set_input_line(INPUT_LINE_RESET, ASSERT_LINE);
- m_maincpu->set_input_line(INPUT_LINE_RESET, CLEAR_LINE);
- }
-
- if ((old_enable ^ m_system_enable) & ENA_NOTBOOT)
- {
- //printf("%c", (m_system_enable & ENA_NOTBOOT) ? 'A' : 'B');
- /*if (m_system_enable & ENA_NOTBOOT)
- {
- m_maincpu->space(mb86901_device::AS_START + 9).install_readwrite_handler(0x00000000, 0xffffffff, 0, 0, 0
- , read32_delegate(FUNC(sun4_state::sun4c_insn_data_r<SUPER_INSN>), this)
- , write32_delegate(FUNC(sun4_state::sun4c_insn_data_w<SUPER_INSN>), this));
- m_maincpu->space(AS_PROGRAM).install_readwrite_handler(0x00000000, 0xffffffff, 0, 0, 0
- , read32_delegate(FUNC(sun4_state::sun4c_insn_data_r<SUPER_INSN>), this)
- , write32_delegate(FUNC(sun4_state::sun4c_insn_data_w<SUPER_INSN>), this));
- }
- else
- {
- m_maincpu->space(mb86901_device::AS_START + 9).install_rom(0x00000000, 0x7ffff, 0xfff80000, m_rom_ptr);
- m_maincpu->space(AS_PROGRAM).install_rom(0x00000000, 0x7ffff, 0xfff80000, m_rom_ptr);
- }*/
- }
- return;
- }
-
- case 6: // bus error
- logerror("%08x to bus error @ %x, mask %08x\n", data, offset, mem_mask);
- m_buserr[offset & 0xf] = data;
- return;
-
- case 8: // cache tags
- //logerror("sun4: %08x to cache tags @ %x, PC = %x\n", data, offset, m_maincpu->pc());
- m_cachetags[(offset>>3)&0x3fff] = data & 0x03f8fffc;
- return;
-
- case 9: // cache data
- //logerror("sun4c: %08x to cache data @ %x, PC = %x\n", data, offset, m_maincpu->pc());
- m_cachedata[offset&0x3fff] = data;
- return;
-
- case 0xf: // UART bypass
- //printf("%08x to UART bypass @ %x, mask %08x\n", data, offset<<2, mem_mask);
- switch (offset & 3)
- {
- case 0: if (mem_mask == 0xff000000) m_scc2->cb_w(space, offset, data>>24); else m_scc2->db_w(space, offset, data>>8); break;
- case 1: if (mem_mask == 0xff000000) m_scc2->ca_w(space, offset, data>>24); else { m_scc2->da_w(space, offset, data>>8); printf("%c", data>>8); } break;
- }
- return;
-
- case 0: // IDPROM
- default:
- logerror("sun4c: ASI 2 space unhandled write %x @ %x (mask %08x, PC=%x, shift %x)\n", data, offset<<2, mem_mask, m_maincpu->pc(), offset>>26);
- return;
- }
-}
-
-READ32_MEMBER( sun4_state::sun4c_segment_map_r )
-{
- //logerror("%s: segment_map_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
- //printf("sun4: read segment map @ %x (ctx %d entry %d, mem_mask %08x, PC=%x)\n", offset << 2, m_context_masked, (offset>>16) & 0xfff, mem_mask, m_maincpu->pc());
- if (mem_mask == 0xffff0000)
- return m_curr_segmap[(offset>>16) & 0xfff]<<16;
- else if (mem_mask == 0xff000000)
- return m_curr_segmap[(offset>>16) & 0xfff]<<24;
- else
- logerror("sun4: read segment map w/ unknown mask %08x\n", mem_mask);
- return 0;
-}
-
-WRITE32_MEMBER( sun4_state::sun4c_segment_map_w )
-{
- logerror("segment_map_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
- uint8_t segdata = 0;
- //printf("segment write, mask %08x, PC=%x\n", mem_mask, m_maincpu->pc());
- if (mem_mask == 0xffff0000) segdata = (data >> 16) & 0xff;
- else if (mem_mask == 0xff000000) segdata = (data >> 24) & 0xff;
- else logerror("sun4c: writing segment map with unknown mask %08x, PC=%x\n", mem_mask, m_maincpu->pc());
-
- //printf("sun4c: %08x to segment map @ %x (ctx %d entry %d, mem_mask %08x, PC=%x)\n", segdata, offset << 2, m_context_masked, (offset>>16) & 0xfff, mem_mask, m_maincpu->pc());
- const uint32_t seg = (offset>>16) & 0xfff;
- m_curr_segmap[seg] = segdata;
- m_curr_segmap_masked[seg] = (segdata & m_pmeg_mask) << 6;
-}
-
-READ32_MEMBER( sun4_state::sun4c_page_map_r )
-{
- //logerror("%s: page_map_r: %08x & %08x\n", machine().describe_context(), offset << 2, mem_mask);
- const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f);
- //printf("sun4: read page map @ %x (entry %d, seg %d, PMEG %d, mem_mask %08x, PC=%x)\n", offset << 2, page, (offset >> 16) & 0xfff, m_curr_segmap_masked[(offset >> 16) & 0xfff] >> 6, mem_mask, m_maincpu->pc());
- return m_pagemap[page].to_uint<SUN4C>();
-}
-
-WRITE32_MEMBER( sun4_state::sun4c_page_map_w )
-{
- //logerror("%s: page_map_w: %08x = %08x & %08x\n", machine().describe_context(), offset << 2, data, mem_mask);
- const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 10) & 0x3f);
- //printf("sun4c: %08x to page map @ %x (entry %d, mem_mask %08x, PC=%x)\n", data, offset << 2, page, mem_mask, m_maincpu->pc());
- m_pagemap[page].merge_uint<SUN4C>(data, mem_mask);
- m_page_valid[page] = m_pagemap[page].valid;
-}
-
-template <sun4_state::insn_data_mode MODE>
-READ32_MEMBER( sun4_state::sun4c_insn_data_r )
-{
- // supervisor program fetches in boot state are special
- if (m_fetch_bootrom && MODE == SUPER_INSN)
- {
- return m_rom_ptr[offset & 0x1ffff];
- }
-
- // it's translation time
- const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
- const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f);
-
- if (m_page_valid[entry_index])
- {
- page_entry_t &entry = m_pagemap[entry_index];
- entry.accessed = PM_ACCESSED;
-
- const uint32_t tmp = entry.page | (offset & 0x3ff);
-
- //printf("sun4: read translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint<SUN4C>(), m_maincpu->pc());
-
- switch (entry.type)
- {
- case 0: // type 0 space
- //return m_type0space->read32(space, tmp, mem_mask);
- if (tmp < 0x1000000>>2)
- {
- return m_ram_ptr[tmp];
- }
- else if (tmp >= 0x4000000>>2 && tmp < 0x10000000>>2)
- {
- timeout_r(space, tmp, mem_mask);
- }
- return ~0;
-
- case 1: // type 1 space
- // magic EPROM bypass
- if ((tmp >= (0x6000000>>2)) && (tmp <= (0x6ffffff>>2)))
- {
- return m_rom_ptr[offset & 0x1ffff];
- }
- //printf("Read type 1 @ VA %08x, phys %08x\n", offset<<2, tmp<<2);
- return m_type1space->read32(space, tmp, mem_mask);
-
- default:
- logerror("sun4c: access to memory type not defined in sun4c\n");
- m_maincpu->set_mae();
- m_buserr[0] = 0x20;
- m_buserr[1] = offset << 2;
- return 0;
- }
- }
- else
- {
- if (!machine().side_effects_disabled())
- {
- logerror("sun4c: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint<SUN4C>(), offset <<2, m_maincpu->pc());
- m_maincpu->set_mae();
- m_buserr[0] |= 0x80; // invalid PTE
- m_buserr[0] &= ~0x8000; // read
- m_buserr[1] = offset<<2;
- if (mem_mask != ~0 && mem_mask != 0xffff0000 && mem_mask != 0xff000000)
- {
- if (mem_mask == 0x0000ffff || mem_mask == 0x0000ff00)
- {
- m_buserr[1] |= 2;
- }
- else if (mem_mask == 0x00ff0000)
- {
- m_buserr[1] |= 1;
- }
- else if (mem_mask == 0x000000ff)
- {
- m_buserr[1] |= 3;
- }
- }
- }
- return 0;
- }
-}
-
-template <sun4_state::insn_data_mode MODE>
-WRITE32_MEMBER( sun4_state::sun4c_insn_data_w )
-{
- // it's translation time
- const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
- const uint32_t entry_index = pmeg | ((offset >> 10) & 0x3f);
-
- if (m_page_valid[entry_index])
- {
- page_entry_t &entry = m_pagemap[entry_index];
- if ((!entry.writable) || (entry.supervisor && MODE != SUPER_DATA && MODE != SUPER_INSN))
- {
- logerror("sun4c: write protect MMU error (PC=%x)\n", m_maincpu->pc());
- m_buserr[0] |= 0x8040; // write, protection error
- m_buserr[1] = offset<<2;
- m_maincpu->set_mae();
- return;
- }
-
- entry.accessed = PM_ACCESSED;
- entry.modified = PM_MODIFIED;
-
- const uint32_t tmp = entry.page | (offset & 0x3ff);
-
- //printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, ASI %d, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint<ARCH_4C>(), asi, m_maincpu->pc());
-
- switch (entry.type)
- {
- case 0: // type 0
- //m_type0space->write32(space, tmp, data, mem_mask);
- if (tmp < 0x1000000>>2)
- {
- COMBINE_DATA((m_ram_ptr + tmp));
- }
- else if (tmp >= 0x4000000>>2 && tmp < 0x10000000>>2)
- {
- timeout_w(space, tmp, data, mem_mask);
- }
- return;
-
- case 1: // type 1
- //printf("write device space @ %x\n", tmp<<1);
- m_type1space->write32(space, tmp, data, mem_mask);
- return;
-
- default:
- logerror("sun4c: access to memory type not defined\n");
- m_maincpu->set_mae();
- m_buserr[0] = 0x8020;
- m_buserr[1] = offset << 2;
- return;
- }
- }
- else
- {
- logerror("sun4c: INVALID PTE entry %d %08x accessed! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint<SUN4C>(), data, offset <<2, m_maincpu->pc());
- m_maincpu->set_mae();
- m_buserr[0] |= 0x8080; // write cycle, invalid PTE
- m_buserr[1] = offset<<2;
- if (mem_mask != ~0 && mem_mask != 0xffff0000 && mem_mask != 0xff000000)
- {
- if (mem_mask == 0x0000ffff || mem_mask == 0x0000ff00)
- {
- m_buserr[1] |= 2;
- }
- else if (mem_mask == 0x00ff0000)
- {
- m_buserr[1] |= 1;
- }
- else if (mem_mask == 0x000000ff)
- {
- m_buserr[1] |= 3;
- }
- }
- }
-}
-
-
-// -----------------------------------------------------------------
-
READ32_MEMBER( sun4_state::sun4_system_r )
{
switch (offset >> 26)
@@ -1150,8 +792,8 @@ READ32_MEMBER( sun4_state::sun4_system_r )
//printf("read UART bypass @ %x mask %08x (PC=%x)\n", offset<<2, mem_mask, m_maincpu->pc());
switch (offset & 3)
{
- case 0: if (mem_mask == 0xff000000) return m_scc2->cb_r(space, offset)<<24; else return m_scc2->db_r(space, offset)<<8; break;
- case 1: if (mem_mask == 0xff000000) return m_scc2->ca_r(space, offset)<<24; else return m_scc2->da_r(space, offset)<<8; break;
+ case 0: if (mem_mask == 0xff000000) return m_scc2->cb_r(offset)<<24; else return m_scc2->db_r(offset)<<8; break;
+ case 1: if (mem_mask == 0xff000000) return m_scc2->ca_r(offset)<<24; else return m_scc2->da_r(offset)<<8; break;
}
return 0xffffffff;
@@ -1221,8 +863,8 @@ WRITE32_MEMBER( sun4_state::sun4_system_w )
//printf("%08x to UART bypass @ %x, mask %08x\n", data, offset<<2, mem_mask);
switch (offset & 3)
{
- case 0: if (mem_mask == 0xff000000) m_scc2->cb_w(space, offset, data>>24); else m_scc2->db_w(space, offset, data>>8); break;
- case 1: if (mem_mask == 0xff000000) m_scc2->ca_w(space, offset, data>>24); else { m_scc2->da_w(space, offset, data>>8); printf("%c", data>>8); } break;
+ case 0: if (mem_mask == 0xff000000) m_scc2->cb_w(offset, data>>24); else m_scc2->db_w(offset, data>>8); break;
+ case 1: if (mem_mask == 0xff000000) m_scc2->ca_w(offset, data>>24); else { m_scc2->da_w(offset, data>>8); printf("%c", data>>8); } break;
}
return;
@@ -1262,17 +904,27 @@ READ32_MEMBER( sun4_state::sun4_page_map_r )
{
uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 11) & 0x1f);
//printf("sun4: read page map @ %x (entry %d, seg %d, PMEG %d, mem_mask %08x, PC=%x)\n", offset << 2, page, (offset >> 16) & 0xfff, m_segmap[m_context][(offset >> 16) & 0xfff] & m_pmeg_mask, mem_mask, m_maincpu->pc());
- return m_pagemap[page].to_uint<SUN4>();
+ return m_pagemap[page].to_uint();
}
WRITE32_MEMBER( sun4_state::sun4_page_map_w )
{
const uint32_t page = m_curr_segmap_masked[(offset >> 16) & 0xfff] | ((offset >> 11) & 0x1f);
//printf("sun4: %08x to page map @ %x (entry %d, mem_mask %08x, PC=%x)\n", data, offset << 2, page, mem_mask, m_maincpu->pc());
- m_pagemap[page].merge_uint<SUN4>(data, mem_mask);
+ m_pagemap[page].merge_uint(data, mem_mask);
m_page_valid[page] = m_pagemap[page].valid;
}
+READ32_MEMBER( sun4_state::sun4c_debugger_r )
+{
+ return m_mmu->insn_data_r<sun4c_mmu_device::SUPER_INSN>(offset, mem_mask);
+}
+
+WRITE32_MEMBER( sun4_state::sun4c_debugger_w )
+{
+ m_mmu->insn_data_w<sun4c_mmu_device::SUPER_INSN>(offset, data, mem_mask);
+}
+
template <sun4_state::insn_data_mode MODE>
READ32_MEMBER( sun4_state::sun4_insn_data_r )
{
@@ -1293,7 +945,7 @@ READ32_MEMBER( sun4_state::sun4_insn_data_r )
const uint32_t tmp = entry.page | (offset & 0x7ff);
- //printf("sun4: read translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint<SUN4>(), m_maincpu->pc());
+ //printf("sun4: read translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint(), m_maincpu->pc());
switch (entry.type)
{
@@ -1318,7 +970,7 @@ READ32_MEMBER( sun4_state::sun4_insn_data_r )
{
if (!machine().side_effects_disabled())
{
- logerror("sun4: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint<SUN4>(), offset <<2, m_maincpu->pc());
+ logerror("sun4: INVALID PTE entry %d %08x accessed! vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), offset <<2, m_maincpu->pc());
m_maincpu->set_mae();
m_buserr[0] |= 0x80; // invalid PTE
m_buserr[0] &= ~0x8000; // read
@@ -1356,7 +1008,7 @@ WRITE32_MEMBER( sun4_state::sun4_insn_data_w )
uint32_t tmp = entry.page | (offset & 0x7ff);
- //printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint<SUN4>(), m_maincpu->pc());
+ //printf("sun4: write translated vaddr %08x to phys %08x type %d, PTE %08x, PC=%x\n", offset<<2, tmp<<2, entry.type, entry.to_uint(), m_maincpu->pc());
switch (entry.type)
{
@@ -1376,7 +1028,7 @@ WRITE32_MEMBER( sun4_state::sun4_insn_data_w )
}
else
{
- logerror("sun4: INVALID PTE entry %d %08x accessed! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint<SUN4>(), data, offset <<2, m_maincpu->pc());
+ logerror("sun4: INVALID PTE entry %d %08x accessed! data=%08x vaddr=%x PC=%x\n", entry_index, m_pagemap[entry_index].to_uint(), data, offset <<2, m_maincpu->pc());
//m_maincpu->trap(SPARC_DATA_ACCESS_EXCEPTION);
//m_buserr[0] = 0x8; // invalid PTE
//m_buserr[1] = offset<<2;
@@ -1404,14 +1056,7 @@ void sun4_state::l2p_command(int ref, const std::vector<std::string> &params)
pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
entry_index = pmeg | ((offset >> 11) & 0x1f);
tmp = m_pagemap[entry_index].page | (offset & 0x7ff);
- entry_value = m_pagemap[entry_index].to_uint<SUN4>();
- }
- else if (m_arch == ARCH_SUN4C)
- {
- pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
- entry_index = pmeg | ((offset >> 10) & 0x3f);
- tmp = m_pagemap[entry_index].page | (offset & 0x3ff);
- entry_value = m_pagemap[entry_index].to_uint<SUN4C>();
+ entry_value = m_pagemap[entry_index].to_uint();
}
if (m_page_valid[entry_index])
@@ -1480,44 +1125,9 @@ void sun4_state::sun4_data_map(address_map &map)
map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4_insn_data_r<USER_DATA>), FUNC(sun4_state::sun4_insn_data_w));
}
-void sun4_state::sun4c_system_map(address_map &map)
-{
- map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_system_r), FUNC(sun4_state::sun4c_system_w));
-}
-
-void sun4_state::sun4c_segment_map(address_map &map)
-{
- map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_segment_map_r), FUNC(sun4_state::sun4c_segment_map_w));
-}
-
-void sun4_state::sun4c_page_map(address_map &map)
-{
- map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_page_map_r), FUNC(sun4_state::sun4c_page_map_w));
-}
-
-void sun4_state::sun4c_supervisor_insn_map(address_map &map)
-{
- map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_insn_data_r<SUPER_INSN>), FUNC(sun4_state::sun4c_insn_data_w<SUPER_INSN>));
-}
-
-void sun4_state::sun4c_supervisor_data_map(address_map &map)
-{
- map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_insn_data_r<SUPER_DATA>), FUNC(sun4_state::sun4c_insn_data_w<SUPER_DATA>));
-}
-
-void sun4_state::sun4c_insn_map(address_map &map)
+void sun4_state::sun4c_debugger_map(address_map &map)
{
- map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_insn_data_r<USER_INSN>), FUNC(sun4_state::sun4c_insn_data_w<USER_INSN>));
-}
-
-void sun4_state::sun4c_data_map(address_map &map)
-{
- map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_insn_data_r<USER_DATA>), FUNC(sun4_state::sun4c_insn_data_w<USER_DATA>));
-}
-
-void sun4_state::sun4c_cache_flush_map(address_map &map)
-{
- map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_cache_flush_r), FUNC(sun4_state::sun4c_cache_flush_w));
+ map(0x00000000, 0xffffffff).rw(FUNC(sun4_state::sun4c_debugger_r), FUNC(sun4_state::sun4c_debugger_w));
}
void sun4_state::type0space_map(address_map &map)
@@ -1561,12 +1171,6 @@ INPUT_PORTS_END
void sun4_state::machine_reset()
{
- m_context = 0;
- m_context_masked = 0;
- m_curr_segmap = m_segmap[0];
- m_curr_segmap_masked = m_segmap_masked[0];
- m_system_enable = 0;
- m_fetch_bootrom = true;
m_auxio = 0xc0;
m_irq_reg = 0;
m_scc1_int = m_scc2_int = 0;
@@ -1587,12 +1191,6 @@ void sun4_state::machine_start()
m_ram_size = m_ram->size();
m_ram_size_words = m_ram_size >> 2;
- //m_maincpu->space(mb86901_device::AS_START + 9).install_rom(0x00000, 0x7ffff, 0xfff80000, m_rom_ptr);
- //m_maincpu->space(AS_PROGRAM).install_rom(0x00000, 0x7ffff, 0xfff80000, m_rom_ptr);
- //memory_space().install_ram(start << 8, (start << 8) | 0x00ffU, m_memory);
-
- m_type1_cache = m_type1space->space(0).cache<2, 0, ENDIANNESS_BIG>(); // Not currently used - unsure how to make it work
-
if (machine().debug_flags & DEBUG_FLAG_ENABLED)
{
using namespace std::placeholders;
@@ -1613,21 +1211,6 @@ void sun4_state::machine_start()
m_reset_timer->adjust(attotime::never);
}
-READ32_MEMBER( sun4_state::timeout_r )
-{
- m_buserr[0] = 0x20; // read timeout
- m_buserr[1] = 0x04000000 + (offset << 2);
- m_maincpu->set_mae();
- return ~0;
-}
-
-WRITE32_MEMBER( sun4_state::timeout_w )
-{
- m_buserr[0] = 0x8020; // write timeout
- m_buserr[1] = 0x04000000 + (offset << 2);
- m_maincpu->set_mae();
-}
-
READ32_MEMBER( sun4_state::ram_r )
{
return m_ram_ptr[offset];
@@ -1695,6 +1278,21 @@ WRITE32_MEMBER( sun4_state::ram_w )
COMBINE_DATA(&m_ram_ptr[offset]);
}
+READ32_MEMBER( sun4_state::timeout_r )
+{
+ m_buserr[0] = 0x20; // read timeout
+ m_buserr[1] = 0x04000000 + (offset << 2);
+ m_maincpu->set_mae();
+ return 0;
+}
+
+WRITE32_MEMBER( sun4_state::timeout_w )
+{
+ m_buserr[0] = 0x8020; // write timeout
+ m_buserr[1] = 0x04000000 + (offset << 2);
+ m_maincpu->set_mae();
+}
+
READ8_MEMBER( sun4_state::fdc_r )
{
if (machine().side_effects_disabled())
@@ -1952,8 +1550,6 @@ void sun4_state::dma_transfer_write()
{
//logerror("DMAing from device to RAM\n");
- address_space &space = m_maincpu->space(mb86901_device::AS_START+9);
-
uint8_t pack_cnt = (m_dma[DMA_CTRL] & DMA_PACK_CNT) >> DMA_PACK_CNT_SHIFT;
while (m_dma[DMA_CTRL] & DMA_REQ_PEND)
{
@@ -1970,13 +1566,9 @@ void sun4_state::dma_transfer_write()
{
//logerror("Writing pack register %08x to %08x\n", m_dma_pack_register, m_dma[DMA_ADDR]);
if (m_arch == ARCH_SUN4C)
- {
- sun4c_insn_data_w<SUPER_DATA>(space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0);
- }
- else
- {
- sun4c_insn_data_w<SUPER_DATA>(space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0);
- }
+ m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0);
+ //else - TODO
+ //sun4_insn_data_w(space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, ~0);
pack_cnt = 0;
m_dma_pack_register = 0;
@@ -1992,8 +1584,6 @@ void sun4_state::dma_transfer_read()
{
//logerror("DMAing from RAM to device\n");
- address_space &space = m_maincpu->space(mb86901_device::AS_START+9);
-
bool word_cached = false;
uint32_t current_word = 0;
while (m_dma[DMA_CTRL] & DMA_REQ_PEND)
@@ -2001,13 +1591,9 @@ void sun4_state::dma_transfer_read()
if (!word_cached)
{
if (m_arch == ARCH_SUN4C)
- {
- current_word = sun4c_insn_data_r<SUPER_DATA>(space, m_dma[DMA_ADDR] >> 2, ~0);
- }
- else
- {
- current_word = sun4c_insn_data_r<SUPER_DATA>(space, m_dma[DMA_ADDR] >> 2, ~0);
- }
+ current_word = m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, ~0);
+ //else - TODO
+ //current_word = sun4_insn_data_r<SUPER_DATA>(space, m_dma[DMA_ADDR] >> 2, ~0);
word_cached = true;
//logerror("Current word: %08x\n", current_word);
}
@@ -2029,13 +1615,9 @@ void sun4_state::dma_transfer_read()
void sun4_state::dma_transfer()
{
if (m_dma[DMA_CTRL] & DMA_WRITE)
- {
dma_transfer_write();
- }
else
- {
dma_transfer_read();
- }
if (m_dma[DMA_BYTE_COUNT] == 0 && (m_dma[DMA_CTRL] & DMA_EN_CNT))
{
@@ -2088,7 +1670,10 @@ WRITE32_MEMBER( sun4_state::dma_w )
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));
- sun4c_insn_data_w<SUPER_DATA>(space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index);
+ if (m_arch == ARCH_SUN4C)
+ m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>(m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index);
+ else
+ sun4_insn_data_w(space, m_dma[DMA_ADDR] >> 2, m_dma_pack_register, 0xff << bit_index);
m_dma[DMA_ADDR]++;
}
m_dma_pack_register = 0;
@@ -2159,7 +1744,7 @@ READ32_MEMBER( sun4_state::lance_dma_r )
if (m_arch == ARCH_SUN4)
return sun4_insn_data_r<SUPER_DATA>(space, offset, mem_mask);
else
- return sun4c_insn_data_r<SUPER_DATA>(space, offset, mem_mask);
+ return m_mmu->insn_data_r<sun4c_mmu_device::SUPER_DATA>(offset, mem_mask);
}
WRITE32_MEMBER( sun4_state::lance_dma_w )
@@ -2167,7 +1752,7 @@ WRITE32_MEMBER( sun4_state::lance_dma_w )
if (m_arch == ARCH_SUN4)
sun4_insn_data_w(space, offset, data, mem_mask);
else
- sun4c_insn_data_w<SUPER_DATA>(space, offset, data, mem_mask);
+ m_mmu->insn_data_w<sun4c_mmu_device::SUPER_DATA>(offset, data, mem_mask);
}
WRITE32_MEMBER( sun4_state::buserr_w )
@@ -2214,15 +1799,19 @@ void sun4_state::ncr53c90a(device_t *device)
MACHINE_CONFIG_START(sun4_state::sun4)
/* basic machine hardware */
- MCFG_DEVICE_ADD(m_maincpu, MB86901, 16670000)
+ MCFG_DEVICE_ADD(m_maincpu, MB86901, 16'670'000)
MCFG_SPARC_ADD_ASI_DESC(sun4_asi_desc)
- m_maincpu->set_asi_addrmap(2, &sun4_state::sun4_system_map);
- m_maincpu->set_asi_addrmap(3, &sun4_state::sun4_segment_map);
- m_maincpu->set_asi_addrmap(4, &sun4_state::sun4_page_map);
- m_maincpu->set_asi_addrmap(8, &sun4_state::sun4_insn_map);
- m_maincpu->set_asi_addrmap(9, &sun4_state::sun4_supervisor_insn_map);
- m_maincpu->set_asi_addrmap(10, &sun4_state::sun4_data_map);
- m_maincpu->set_asi_addrmap(11, &sun4_state::sun4_supervisor_data_map);
+ m_maincpu->set_addrmap(0, &sun4_state::sun4c_debugger_map);
+
+ // TODO: MMU for sun4 hardware
+ SUN4C_MMU(config, m_mmu, 25'000'000, 7, 0x7f);
+ m_mmu->type1_r().set(m_type1space, FUNC(address_map_bank_device::read32));
+ m_mmu->type1_w().set(m_type1space, FUNC(address_map_bank_device::write32));
+ m_mmu->set_cpu(m_maincpu);
+ m_mmu->set_ram(m_ram);
+ m_mmu->set_rom("user1");
+ m_mmu->set_scc(m_scc2);
+ m_maincpu->set_mmu(m_mmu);
RAM(config, RAM_TAG).set_default_size("16M").set_default_value(0x00);
@@ -2284,19 +1873,18 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(sun4_state::sun4c)
/* basic machine hardware */
- MCFG_DEVICE_ADD(m_maincpu, MB86901, 16670000)
+ MCFG_DEVICE_ADD(m_maincpu, MB86901, 16'670'000)
MCFG_SPARC_ADD_ASI_DESC(sun4c_asi_desc)
- m_maincpu->set_addrmap(0, &sun4_state::sun4c_supervisor_insn_map);
- m_maincpu->set_asi_addrmap(2, &sun4_state::sun4c_system_map);
- m_maincpu->set_asi_addrmap(3, &sun4_state::sun4c_segment_map);
- m_maincpu->set_asi_addrmap(4, &sun4_state::sun4c_page_map);
- m_maincpu->set_asi_addrmap(8, &sun4_state::sun4c_insn_map);
- m_maincpu->set_asi_addrmap(9, &sun4_state::sun4c_supervisor_insn_map);
- m_maincpu->set_asi_addrmap(10, &sun4_state::sun4c_data_map);
- m_maincpu->set_asi_addrmap(11, &sun4_state::sun4c_supervisor_data_map);
- m_maincpu->set_asi_addrmap(12, &sun4_state::sun4c_cache_flush_map);
- m_maincpu->set_asi_addrmap(13, &sun4_state::sun4c_cache_flush_map);
- m_maincpu->set_asi_addrmap(14, &sun4_state::sun4c_cache_flush_map);
+ m_maincpu->set_addrmap(0, &sun4_state::sun4c_debugger_map);
+
+ SUN4C_MMU(config, m_mmu, 16'670'000, 7, 0x7f);
+ m_mmu->type1_r().set(m_type1space, FUNC(address_map_bank_device::read32));
+ m_mmu->type1_w().set(m_type1space, FUNC(address_map_bank_device::write32));
+ m_mmu->set_cpu(m_maincpu);
+ m_mmu->set_ram(m_ram);
+ m_mmu->set_rom("user1");
+ m_mmu->set_scc(m_scc2);
+ m_maincpu->set_mmu(m_mmu);
RAM(config, RAM_TAG).set_default_size("16M").set_default_value(0x00);
@@ -2355,22 +1943,30 @@ MACHINE_CONFIG_START(sun4_state::sun4c)
MCFG_SLOT_OPTION_MACHINE_CONFIG("ncr53c90a", [this] (device_t *device) { ncr53c90a(device); })
MACHINE_CONFIG_END
-MACHINE_CONFIG_START(sun4_state::sun4_40)
+void sun4_state::sun4_40(machine_config &config)
+{
sun4c(config);
+ m_mmu->set_clock(25'000'000);
+ m_maincpu->set_clock(25'000'000);
+ m_maincpu->set_mmu(m_mmu);
+
m_type1space->set_map(&sun4_state::type1space_sbus_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000);
// SBus
- SBUS(config, m_sbus, 16670000, "maincpu", "type1");
- SBUS_SLOT(config, "slot1", 16'670'000, m_sbus, sbus_cards, nullptr);
- SBUS_SLOT(config, "slot2", 16'670'000, m_sbus, sbus_cards, nullptr);
- SBUS_SLOT(config, "slot3", 16'670'000, m_sbus, sbus_cards, "bwtwo");
-MACHINE_CONFIG_END
+ SBUS(config, m_sbus, 25'000'000, "maincpu", "type1");
+ SBUS_SLOT(config, "slot1", 25'000'000, m_sbus, sbus_cards, nullptr);
+ SBUS_SLOT(config, "slot2", 25'000'000, m_sbus, sbus_cards, nullptr);
+ SBUS_SLOT(config, "slot3", 25'000'000, m_sbus, sbus_cards, "bwtwo");
+}
-MACHINE_CONFIG_START(sun4_state::sun4_60)
+void sun4_state::sun4_60(machine_config &config)
+{
sun4c(config);
+ m_mmu->set_clock(20'000'000);
m_maincpu->set_clock(20'000'000);
+ m_maincpu->set_mmu(m_mmu);
m_type1space->set_map(&sun4_state::type1space_sbus_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000);
@@ -2379,8 +1975,24 @@ MACHINE_CONFIG_START(sun4_state::sun4_60)
SBUS_SLOT(config, "slot1", 20'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, "slot2", 20'000'000, m_sbus, sbus_cards, nullptr);
SBUS_SLOT(config, "slot3", 20'000'000, m_sbus, sbus_cards, nullptr);
-MACHINE_CONFIG_END
+}
+void sun4_state::sun4_75(machine_config &config)
+{
+ sun4c(config);
+
+ m_mmu->set_clock(40'000'000);
+ m_maincpu->set_clock(40'000'000);
+ m_maincpu->set_mmu(m_mmu);
+
+ m_type1space->set_map(&sun4_state::type1space_sbus_map).set_options(ENDIANNESS_BIG, 32, 32, 0x80000000);
+
+ // SBus
+ SBUS(config, m_sbus, 20'000'000, "maincpu", "type1");
+ SBUS_SLOT(config, "slot1", 20'000'000, m_sbus, sbus_cards, nullptr);
+ SBUS_SLOT(config, "slot2", 20'000'000, m_sbus, sbus_cards, nullptr);
+ SBUS_SLOT(config, "slot3", 20'000'000, m_sbus, sbus_cards, nullptr);
+}
/*
Boot PROM
@@ -2628,15 +2240,11 @@ void sun4_state::init_sun4()
void sun4_state::init_sun4c()
{
- m_ctx_mask = 0x7;
- m_pmeg_mask = 0x7f;
m_arch = ARCH_SUN4C;
}
void sun4_state::init_ss2()
{
- m_ctx_mask = 0xf;
- m_pmeg_mask = 0xff;
m_arch = ARCH_SUN4C;
}
@@ -2654,7 +2262,7 @@ COMP( 1991, sun4_50, sun4_300, 0, sun4c, sun4, sun4_state, init_ss2,
COMP( 199?, sun4_20, sun4_300, 0, sun4c, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation SLC (Sun 4/20)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 1989, sun4_60, sun4_300, 0, sun4_60, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 1 (Sun 4/60)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
COMP( 1990, sun4_65, sun4_300, 0, sun4c, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 1+ (Sun 4/65)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
-COMP( 1990, sun4_75, sun4_300, 0, sun4c, sun4, sun4_state, init_ss2, "Sun Microsystems", "SPARCstation 2 (Sun 4/75)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
+COMP( 1990, sun4_75, sun4_300, 0, sun4_75, sun4, sun4_state, init_ss2, "Sun Microsystems", "SPARCstation 2 (Sun 4/75)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
// sun4m (using the SPARC "reference MMU", probably will go to a separate driver)
COMP( 1992, sun_s10, sun4_300, 0, sun4c, sun4, sun4_state, init_sun4c, "Sun Microsystems", "SPARCstation 10 (Sun S10)", MACHINE_NOT_WORKING | MACHINE_NO_SOUND )
diff --git a/src/mame/machine/iteagle_fpga.cpp b/src/mame/machine/iteagle_fpga.cpp
index 7da81e6900b..7ba6967747f 100644
--- a/src/mame/machine/iteagle_fpga.cpp
+++ b/src/mame/machine/iteagle_fpga.cpp
@@ -293,19 +293,19 @@ READ32_MEMBER( iteagle_fpga_device::fpga_r )
m_cpu->eat_cycles(40);
}
if (ACCESSING_BITS_0_7) {
- result |= m_scc1->cb_r(space, offset) << 0;
+ result |= m_scc1->cb_r(offset) << 0;
if (LOG_SERIAL) m_serial0_1.read_control(1);
}
if (ACCESSING_BITS_8_15) {
- result |= m_scc1->ca_r(space, offset) << 8;
+ result |= m_scc1->ca_r(offset) << 8;
if (LOG_SERIAL) m_serial0_1.read_control(0);
}
if (ACCESSING_BITS_16_23) {
- result |= m_scc1->db_r(space, offset) <<16;
+ result |= m_scc1->db_r(offset) <<16;
if (LOG_SERIAL) m_serial0_1.read_data(1);
}
if (ACCESSING_BITS_24_31) {
- result |= m_scc1->da_r(space, offset) << 24;
+ result |= m_scc1->da_r(offset) << 24;
if (LOG_SERIAL) m_serial0_1.read_data(0);
}
if (0 && LOG_FPGA && m_prev_reg != offset)
@@ -390,20 +390,20 @@ WRITE32_MEMBER( iteagle_fpga_device::fpga_w )
break;
case 0x0c/4:
if (ACCESSING_BITS_0_7) {
- m_scc1->cb_w(space, offset, (data >> 0) & 0xff);
+ m_scc1->cb_w(offset, (data >> 0) & 0xff);
if (LOG_SERIAL) m_serial0_1.write_control((data >> 0) & 0xff, 1);
}
if (ACCESSING_BITS_8_15) {
- m_scc1->ca_w(space, offset, (data >> 8) & 0xff);
+ m_scc1->ca_w(offset, (data >> 8) & 0xff);
if (LOG_SERIAL) m_serial0_1.write_control((data >> 8) & 0xff, 0);
}
if (ACCESSING_BITS_16_23) {
// Convert 0xd to 0xa
uint8_t byte = data >> 16;
if (byte==0xd)
- m_scc1->db_w(space, offset, 0xa);
+ m_scc1->db_w(offset, 0xa);
else
- m_scc1->db_w(space, offset, byte);
+ m_scc1->db_w(offset, byte);
if (LOG_SERIAL) {
m_serial0_1.write_data((data >> 16) & 0xff, 1);
if (m_serial0_1.get_tx_str(1).back() == 0xd) {
@@ -414,7 +414,7 @@ WRITE32_MEMBER( iteagle_fpga_device::fpga_w )
}
}
if (ACCESSING_BITS_24_31) {
- m_scc1->da_w(space, offset, (data >> 24) & 0xff);
+ m_scc1->da_w(offset, (data >> 24) & 0xff);
if (LOG_SERIAL) m_serial0_1.write_data((data >> 24) & 0xff, 0);
}
if (1 && LOG_FPGA)