summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2018-09-23 11:51:41 +0200
committer mooglyguy <therealmogminer@gmail.com>2018-09-23 11:53:12 +0200
commit5a48ba08227584b6030b4e1047527ba121b5fd43 (patch)
tree519a14a8537e8ce9217fae3451be2170ed7c6c6b
parentb776b03e5e2a76dbde3623e40fe11fbbef2cca2c (diff)
sun4: More optimizations, nw
-rw-r--r--src/devices/bus/sbus/bwtwo.cpp3
-rw-r--r--src/devices/cpu/sparc/mb86901.cpp1965
-rw-r--r--src/devices/cpu/sparc/sparc.h40
-rw-r--r--src/devices/cpu/sparc/sparc_intf.h3
-rw-r--r--src/devices/cpu/sparc/sparcdefs.h21
-rw-r--r--src/devices/machine/sun4c_mmu.cpp18
-rw-r--r--src/devices/machine/sun4c_mmu.h9
-rw-r--r--src/osd/modules/render/d3d/d3dcomm.h8
-rw-r--r--src/osd/modules/render/drawd3d.cpp14
9 files changed, 1258 insertions, 823 deletions
diff --git a/src/devices/bus/sbus/bwtwo.cpp b/src/devices/bus/sbus/bwtwo.cpp
index 553e040ec1a..e287848675e 100644
--- a/src/devices/bus/sbus/bwtwo.cpp
+++ b/src/devices/bus/sbus/bwtwo.cpp
@@ -72,10 +72,11 @@ void sbus_bwtwo_device::install_device()
uint32_t sbus_bwtwo_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
+ uint8_t *line = &m_vram[0];
+
for (int y = 0; y < 900; y++)
{
uint32_t *scanline = &bitmap.pix32(y);
- uint8_t *line = &m_vram[y * 1152/8];
for (int x = 0; x < 1152/8; x++)
{
memcpy(scanline, m_mono_lut[*line], sizeof(uint32_t) * 8);
diff --git a/src/devices/cpu/sparc/mb86901.cpp b/src/devices/cpu/sparc/mb86901.cpp
index 8ec274535ad..8b0777d847d 100644
--- a/src/devices/cpu/sparc/mb86901.cpp
+++ b/src/devices/cpu/sparc/mb86901.cpp
@@ -286,7 +286,7 @@ void mb86901_device::device_start()
state_add(SPARC_WIM, "WIM", m_wim).formatstr("%08X");
state_add(SPARC_TBR, "TBR", m_tbr).formatstr("%08X");
state_add(SPARC_Y, "Y", m_y).formatstr("%08X");
- state_add(SPARC_ANNUL, "ANNUL", m_annul).formatstr("%01u");
+ state_add(SPARC_ANNUL, "ANNUL", m_no_annul).formatstr("%01u");
state_add(SPARC_ICC, "icc", m_icc).formatstr("%4s");
state_add(SPARC_CWP, "CWP", m_cwp).formatstr("%2d");
char regname[3] = "g0";
@@ -385,7 +385,7 @@ void mb86901_device::device_start()
save_item(NAME(m_et));
save_item(NAME(m_cwp));
save_item(NAME(m_mae));
- save_item(NAME(m_annul));
+ save_item(NAME(m_no_annul));
save_item(NAME(m_hold_bus));
// set our instruction counter
@@ -431,7 +431,7 @@ void mb86901_device::device_reset()
MAE = false;
HOLD_BUS = false;
- m_annul = false;
+ m_no_annul = true;
PC = 0;
nPC = 4;
@@ -444,7 +444,6 @@ void mb86901_device::device_reset()
PSR = PSR_S_MASK | PSR_PS_MASK;
m_s = true;
- m_insn_space = 9;
m_data_space = 11;
for (int i = 0; i < 8; i++)
@@ -517,6 +516,30 @@ void mb86901_device::state_string_export(const device_state_entry &entry, std::s
switch (entry.index())
{
case STATE_GENFLAGS:
+ case SPARC_ANNUL:
+ str = string_format("%01u", m_no_annul ? 0 : 1);
+ break;
+ case SPARC_CWP:
+ str = string_format("%2u", PSR & PSR_CWP_MASK);
+ break;
+ case SPARC_EC:
+ str = string_format("%01u", PSR & PSR_EC_MASK ? 1 : 0);
+ break;
+ case SPARC_EF:
+ str = string_format("%01u", PSR & PSR_EF_MASK ? 1 : 0);
+ break;
+ case SPARC_ET:
+ str = string_format("%01u", PSR & PSR_ET_MASK ? 1 : 0);
+ break;
+ case SPARC_PS:
+ str = string_format("%01u", PSR & PSR_PS_MASK ? 1 : 0);
+ break;
+ case SPARC_S:
+ str = string_format("%01u", PSR & PSR_S_MASK ? 1 : 0);
+ break;
+ case SPARC_PIL:
+ str = string_format("%02u", (PSR & PSR_PIL_MASK) >> PSR_PIL_SHIFT);
+ break;
case SPARC_ICC:
str = string_format("%c%c%c%c", ICC_N_SET ? 'n' : ' ', ICC_Z_SET ? 'z' : ' ', ICC_V_SET ? 'v' : ' ', ICC_C_SET ? 'c' : ' ');
break;
@@ -678,7 +701,7 @@ void mb86901_device::execute_add(uint32_t op)
else if (ADDX || ADDXCC)
result = rs1 + operand2 + ICC_C;
- if (RD != 0)
+ if (RDBITS)
RDREG = result;
if (ADDCC || ADDXCC)
@@ -742,6 +765,8 @@ void mb86901_device::execute_taddcc(uint32_t op)
{
m_trap = 1;
m_tag_overflow = true;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -752,7 +777,7 @@ void mb86901_device::execute_taddcc(uint32_t op)
PSR |= ((BIT31(rs1) && BIT31(operand2)) ||
(!BIT31(result) && (BIT31(rs1) || BIT31(operand2)))) ? PSR_C_MASK : 0;
- if (RD != 0)
+ if (RDBITS)
RDREG = result;
PC = nPC;
@@ -798,7 +823,7 @@ void mb86901_device::execute_sub(uint32_t op)
else if (SUBX || SUBXCC)
result = rs1 - operand2 - ICC_C;
- if (RD != 0)
+ if (RDBITS)
RDREG = result;
if (SUBCC || SUBXCC)
@@ -863,6 +888,8 @@ void mb86901_device::execute_tsubcc(uint32_t op)
{
m_trap = 1;
m_tag_overflow = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -873,7 +900,7 @@ void mb86901_device::execute_tsubcc(uint32_t op)
PSR |= ((!BIT31(rs1) && BIT31(operand2)) ||
(BIT31(result) && (!BIT31(rs1) || BIT31(operand2)))) ? PSR_C_MASK : 0;
- if (RD != 0)
+ if (RDBITS)
RDREG = result;
PC = nPC;
@@ -881,76 +908,111 @@ void mb86901_device::execute_tsubcc(uint32_t op)
}
-//-------------------------------------------------
-// execute_logical - execute a logical-type
-// opcode, and/or/xor/andn/orn/xnor
-//-------------------------------------------------
+/* The SPARC Instruction Manual: Version 8, page 172, "Appendix C - ISP Descriptions - Logical Instructions" (SPARCv8.pdf, pg. 169)
+
+operand2 := if (i = 0) then r[rs2] else sign_extend(simm13);
-void mb86901_device::execute_logical(uint32_t op)
+if ( AND or ANDcc) then result <- r[rs1] and operand2
+if (ANDN or ANDNcc) then result <- r[rs1] and not operand2
+if ( OR or ORcc) then result <- r[rs1] or operand2
+if ( ORN or ORNcc) then result <- r[rs1] or not operand2
+if ( XOR or XORcc) then result <- r[rs1] xor operand2
+if (XNOR or XNORcc) then result <- r[rs1] xor not operand2;
+next;
+
+if (rd != 0) then r[rd] <- result;
+
+if (ANDcccc or ANDNcc or ORcc or ORNcc or XORcc or XNORcc) then (
+ N <- result<31>;
+ Z <- if (result = 0) then 1 else 0;
+ V <- 0
+ C <- 0
+);
+*/
+
+template <mb86901_device::set_cc SETCC>
+void mb86901_device::execute_and(const uint32_t op)
{
- /* The SPARC Instruction Manual: Version 8, page 172, "Appendix C - ISP Descriptions - Logical Instructions" (SPARCv8.pdf, pg. 169)
+ const uint32_t result = RS1REG & (USEIMM ? SIMM13 : RS2REG);
+ if (RDBITS) RDREG = result;
+ if (SETCC)
+ {
+ CLEAR_ICC;
+ if (result & 0x80000000)
+ PSR |= PSR_N_MASK;
+ else if (!result)
+ PSR |= PSR_Z_MASK;
+ }
- operand2 := if (i = 0) then r[rs2] else sign_extend(simm13);
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if ( AND or ANDcc) then result <- r[rs1] and operand2
- if (ANDN or ANDNcc) then result <- r[rs1] and not operand2
- if ( OR or ORcc) then result <- r[rs1] or operand2
- if ( ORN or ORNcc) then result <- r[rs1] or not operand2
- if ( XOR or XORcc) then result <- r[rs1] xor operand2
- if (XNOR or XNORcc) then result <- r[rs1] xor not operand2;
- next;
+template <mb86901_device::set_cc SETCC>
+void mb86901_device::execute_or(const uint32_t op)
+{
+ const uint32_t result = RS1REG | (USEIMM ? SIMM13 : RS2REG);
+ if (RDBITS) RDREG = result;
+ if (SETCC)
+ {
+ CLEAR_ICC;
+ if (result & 0x80000000)
+ PSR |= PSR_N_MASK;
+ else if (!result)
+ PSR |= PSR_Z_MASK;
+ }
- if (rd != 0) then r[rd] <- result;
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if (ANDcccc or ANDNcc or ORcc or ORNcc or XORcc or XNORcc) then (
- N <- result<31>;
- Z <- if (result = 0) then 1 else 0;
- V <- 0
- C <- 0
- );
- */
+template <mb86901_device::set_cc SETCC>
+void mb86901_device::execute_xor(const uint32_t op)
+{
+ const uint32_t result = RS1REG ^ (USEIMM ? SIMM13 : RS2REG);
+ if (RDBITS) RDREG = result;
+ if (SETCC)
+ {
+ CLEAR_ICC;
+ if (result & 0x80000000)
+ PSR |= PSR_N_MASK;
+ else if (!result)
+ PSR |= PSR_Z_MASK;
+ }
- const uint32_t operand2 = USEIMM ? SIMM13 : RS2REG;
- const uint32_t op3 = OP3;
+ PC = nPC;
+ nPC = nPC + 4;
+}
- uint32_t result = 0;
- switch (op3)
+template <mb86901_device::set_cc SETCC>
+void mb86901_device::execute_andn(const uint32_t op)
+{
+ const uint32_t result = RS1REG & ~(USEIMM ? SIMM13 : RS2REG);
+ if (RDBITS) RDREG = result;
+ if (SETCC)
{
- case OP3_AND:
- case OP3_ANDCC:
- result = RS1REG & operand2;
- break;
- case OP3_ANDN:
- case OP3_ANDNCC:
- result = RS1REG & ~operand2;
- break;
- case OP3_OR:
- case OP3_ORCC:
- result = RS1REG | operand2;
- break;
- case OP3_ORN:
- case OP3_ORNCC:
- result = RS1REG | ~operand2;
- break;
- case OP3_XOR:
- case OP3_XORCC:
- result = RS1REG ^ operand2;
- break;
- case OP3_XNOR:
- case OP3_XNORCC:
- result = RS1REG ^ ~operand2;
- break;
+ CLEAR_ICC;
+ if (result & 0x80000000)
+ PSR |= PSR_N_MASK;
+ else if (!result)
+ PSR |= PSR_Z_MASK;
}
- if (RD != 0)
- RDREG = result;
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if (m_alu_setcc[op3])
+template <mb86901_device::set_cc SETCC>
+void mb86901_device::execute_orn(const uint32_t op)
+{
+ const uint32_t result = RS1REG | ~(USEIMM ? SIMM13 : RS2REG);
+ if (RDBITS) RDREG = result;
+ if (SETCC)
{
CLEAR_ICC;
if (result & 0x80000000)
PSR |= PSR_N_MASK;
- else if (result == 0)
+ else if (!result)
PSR |= PSR_Z_MASK;
}
@@ -958,6 +1020,23 @@ void mb86901_device::execute_logical(uint32_t op)
nPC = nPC + 4;
}
+template <mb86901_device::set_cc SETCC>
+void mb86901_device::execute_xnor(const uint32_t op)
+{
+ const uint32_t result = RS1REG ^ ~(USEIMM ? SIMM13 : RS2REG);
+ if (RDBITS) RDREG = result;
+ if (SETCC)
+ {
+ CLEAR_ICC;
+ if (result & 0x80000000)
+ PSR |= PSR_N_MASK;
+ else if (!result)
+ PSR |= PSR_Z_MASK;
+ }
+
+ PC = nPC;
+ nPC = nPC + 4;
+}
//-------------------------------------------------
// execute_shift - execute a shift-type opcode,
@@ -979,12 +1058,15 @@ void mb86901_device::execute_shift(uint32_t op)
*/
uint32_t shift_count = USEIMM ? (SIMM13 & 31) : (RS2REG & 31);
- if (SLL && RD != 0)
- RDREG = RS1REG << shift_count;
- else if (SRL && RD != 0)
- RDREG = uint32_t(RS1REG) >> shift_count;
- else if (SRA && RD != 0)
- RDREG = int32_t(RS1REG) >> shift_count;
+ if (RDBITS)
+ {
+ if (SLL)
+ RDREG = RS1REG << shift_count;
+ else if (SRL)
+ RDREG = uint32_t(RS1REG) >> shift_count;
+ else if (SRA)
+ RDREG = int32_t(RS1REG) >> shift_count;
+ }
PC = nPC;
nPC = nPC + 4;
@@ -1027,7 +1109,7 @@ void mb86901_device::execute_mulscc(uint32_t op)
uint32_t result = operand1 + operand2;
Y = ((RS1REG & 1) ? 0x80000000 : 0) | (Y >> 1);
- if (RD != 0)
+ if (RDBITS)
RDREG = result;
CLEAR_ICC;
@@ -1072,16 +1154,20 @@ void mb86901_device::execute_rdsr(uint32_t op)
{
m_trap = 1;
m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if (m_illegal_instruction_asr[RS1])
{
m_trap = 1;
m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
- if (RD != 0)
+ if (RDBITS)
{
if (RDASR)
{
@@ -1171,12 +1257,16 @@ void mb86901_device::execute_wrsr(uint32_t op)
{
m_trap = 1;
m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if (m_illegal_instruction_asr[RD])
{
m_trap = 1;
m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else
@@ -1192,12 +1282,16 @@ void mb86901_device::execute_wrsr(uint32_t op)
{
m_trap = 1;
m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if ((result & 31) >= NWINDOWS)
{
m_trap = 1;
m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1209,12 +1303,10 @@ void mb86901_device::execute_wrsr(uint32_t op)
m_s = PSR & PSR_S_MASK;
if (m_s)
{
- m_insn_space = 9;
m_data_space = 11;
}
else
{
- m_insn_space = 8;
m_data_space = 10;
}
@@ -1227,6 +1319,8 @@ void mb86901_device::execute_wrsr(uint32_t op)
{
m_trap = 1;
m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1240,6 +1334,8 @@ void mb86901_device::execute_wrsr(uint32_t op)
{
m_trap = 1;
m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1306,6 +1402,8 @@ void mb86901_device::execute_rett(uint32_t op)
{
m_illegal_instruction = 1;
}
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if (IS_USER)
@@ -1354,14 +1452,12 @@ void mb86901_device::execute_rett(uint32_t op)
{
PSR |= PSR_S_MASK;
m_s = true;
- m_insn_space = 9;
m_data_space = 11;
}
else
{
PSR &= ~PSR_S_MASK;
m_s = false;
- m_insn_space = 8;
m_data_space = 10;
}
@@ -1418,6 +1514,8 @@ void mb86901_device::execute_saverestore(uint32_t op)
{
m_trap = 1;
m_window_overflow = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1432,6 +1530,8 @@ void mb86901_device::execute_saverestore(uint32_t op)
{
m_trap = 1;
m_window_underflow = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1442,7 +1542,7 @@ void mb86901_device::execute_saverestore(uint32_t op)
update_gpr_pointers();
- if (RD != 0)
+ if (RDBITS)
RDREG = result;
PC = nPC;
@@ -1476,10 +1576,12 @@ void mb86901_device::execute_jmpl(uint32_t op)
{
m_trap = 1;
m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
}
else
{
- if (RD != 0)
+ if (RDBITS)
RDREG = PC;
PC = nPC;
nPC = jump_address;
@@ -1521,18 +1623,40 @@ inline void mb86901_device::execute_group2(uint32_t op)
break;
case OP3_AND:
+ execute_and<NOCC>(op);
+ break;
case OP3_OR:
+ execute_or<NOCC>(op);
+ break;
case OP3_XOR:
+ execute_xor<NOCC>(op);
+ break;
case OP3_ANDN:
+ execute_andn<NOCC>(op);
+ break;
case OP3_ORN:
+ execute_orn<NOCC>(op);
+ break;
case OP3_XNOR:
+ execute_xnor<NOCC>(op);
+ break;
case OP3_ANDCC:
+ execute_and<USECC>(op);
+ break;
case OP3_ORCC:
+ execute_or<USECC>(op);
+ break;
case OP3_XORCC:
+ execute_xor<USECC>(op);
+ break;
case OP3_ANDNCC:
+ execute_andn<USECC>(op);
+ break;
case OP3_ORNCC:
+ execute_orn<USECC>(op);
+ break;
case OP3_XNORCC:
- execute_logical(op);
+ execute_xnor<USECC>(op);
break;
case OP3_MULSCC:
@@ -1566,6 +1690,8 @@ inline void mb86901_device::execute_group2(uint32_t op)
//printf("fpop @ %08x: %08x\n", PC, op);
m_trap = 1;
m_fp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
}
complete_fp_execution(op);
return;
@@ -1613,6 +1739,8 @@ inline void mb86901_device::execute_group2(uint32_t op)
logerror("fpop @ %08x: %08x\n", PC, op);
m_trap = 1;
m_cp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
#endif
@@ -1620,6 +1748,8 @@ inline void mb86901_device::execute_group2(uint32_t op)
logerror("illegal instruction at %08x: %08x\n", PC, op);
m_trap = 1;
m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
break;
}
}
@@ -1772,12 +1902,16 @@ void mb86901_device::execute_store(uint32_t op)
{
m_trap = 1;
m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if (USEIMM && (STDA || STA || STHA || STBA))
{
m_trap = 1;
m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1797,18 +1931,24 @@ void mb86901_device::execute_store(uint32_t op)
{
m_trap = 1;
m_fp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
if ((STC || STDC || STCSR || STDCQ) && (!(PSR & PSR_EC_MASK) || !m_bp_cp_present))
{
m_trap = 1;
m_cp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
if ((STH || STHA) && ((address & 1) != 0))
{
m_trap = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
m_mem_address_not_aligned = 1;
return;
}
@@ -1816,12 +1956,16 @@ void mb86901_device::execute_store(uint32_t op)
{
m_trap = 1;
m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if ((STD || STDA || STDF || STDFQ || STDC || STDCQ) && ((address & 7) != 0))
{
m_trap = 1;
m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1831,6 +1975,8 @@ void mb86901_device::execute_store(uint32_t op)
m_trap = 1;
m_fp_exception = 1;
m_ftt = m_fpu_sequence_err;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
if (STDCQ)
@@ -1838,6 +1984,8 @@ void mb86901_device::execute_store(uint32_t op)
// assume no coprocessor queue for now
m_trap = 1;
m_cp_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
// { possibly additional implementation-dependent actions }
return;
}
@@ -1846,6 +1994,8 @@ void mb86901_device::execute_store(uint32_t op)
m_trap = 1;
m_fp_exception = 1;
m_ftt = 0xff;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1950,6 +2100,8 @@ void mb86901_device::execute_store(uint32_t op)
{
m_trap = 1;
m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -1982,6 +2134,8 @@ void mb86901_device::execute_store(uint32_t op)
{
m_trap = 1;
m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
}
@@ -1990,761 +2144,925 @@ void mb86901_device::execute_store(uint32_t op)
nPC = nPC + 4;
}
-//-------------------------------------------------
-// execute_load - execute a load-type opcode
-//-------------------------------------------------
+/* The SPARC Instruction Manual: Version 8, page 163, "Appendix C - ISP Descriptions - C.9. Instruction Defintions - Load Instructions" (SPARCv8.pdf, pg. 160)
-void mb86901_device::execute_load(uint32_t op)
-{
- /* The SPARC Instruction Manual: Version 8, page 163, "Appendix C - ISP Descriptions - C.9. Instruction Defintions - Load Instructions" (SPARCv8.pdf, pg. 160)
-
- if (LDD or LD or LDSH or LDUH or LDSB or LDUB or LDDF or LDF or LDFSR or LDDC or LDC or LDCSR) then (
- address <- r[rs1] + (if (i = 0) then r[rs2] else sign_extend(simm13));
- addr_space <- (if (S = 0) then 10 else 11)
- ) else if (LDDA or LDA or LDSHA or LDUHA or LDSBA or LDUBA) then (
- if (S = 0) then (
- trap <- 1;
- privileged_instruction <- 1
- ) else if (i = 1) then (
- trap <- 1;
- illegal_instruction <- 1
- ) else (
- address <- r[rs1] + r[rs2];
- addr_space <- asi
- )
+if (LDD or LD or LDSH or LDUH or LDSB or LDUB or LDDF or LDF or LDFSR or LDDC or LDC or LDCSR) then (
+ address <- r[rs1] + (if (i = 0) then r[rs2] else sign_extend(simm13));
+ addr_space <- (if (S = 0) then 10 else 11)
+) else if (LDDA or LDA or LDSHA or LDUHA or LDSBA or LDUBA) then (
+ if (S = 0) then (
+ trap <- 1;
+ privileged_instruction <- 1
+ ) else if (i = 1) then (
+ trap <- 1;
+ illegal_instruction <- 1
+ ) else (
+ address <- r[rs1] + r[rs2];
+ addr_space <- asi
)
+)
+next;
+if (trap = 0) then (
+ if ( (LDF or LDDF or LDFSR) and ((EF = 0) or (bp_FPU_present = 0)) then (
+ trap <- 1;
+ fp_disabled <- 1
+ ) else if ( (LDC or LDDC or LDCSR) and ((EC = 0) or (bp_CP_present = 0)) then (
+ trap <- 1;
+ cp_disabled <- 1
+ ) else if ( ( (LDD or LDDA or LDDF or LDDC) and (address<2:0> != 0)) or
+ ((LD or LDA or LDF or LDFSR or LDC or LDCSR) and (address<1:0> != 0)) or
+ ((LDSH or LDSHA or LDUH or LDUHA) and address<0> != 0) ) then (
+ trap <- 1;
+ mem_address_not_aligned <- 1
+ ) else if (LDDF and (rd<0> != 0)) then (
+ trap <- 1;
+ fp_exception <- 1;
+ ftt <- invalid_fpr_register
+ ) else if ((LDF or LDDF or LDFSR) and (an FPU sequence error is detected)) then (
+ trap <- 1;
+ fp_exception <- 1;
+ ftt <- sequence_error
+ ) else if ((LDC or LDDC or LDCSR) and (a CP sequence error is detected)) then (
+ trap <- 1;
+ cp_exception <- 1;
+ { possibly additional implementation-dependent actions }
+ )
+);
+next;
+if (trap = 0) then {
+ (data, MAE) <- memory_read(addr_space, address);
next;
- if (trap = 0) then (
- if ( (LDF or LDDF or LDFSR) and ((EF = 0) or (bp_FPU_present = 0)) then (
- trap <- 1;
- fp_disabled <- 1
- ) else if ( (LDC or LDDC or LDCSR) and ((EC = 0) or (bp_CP_present = 0)) then (
- trap <- 1;
- cp_disabled <- 1
- ) else if ( ( (LDD or LDDA or LDDF or LDDC) and (address<2:0> != 0)) or
- ((LD or LDA or LDF or LDFSR or LDC or LDCSR) and (address<1:0> != 0)) or
- ((LDSH or LDSHA or LDUH or LDUHA) and address<0> != 0) ) then (
- trap <- 1;
- mem_address_not_aligned <- 1
- ) else if (LDDF and (rd<0> != 0)) then (
- trap <- 1;
- fp_exception <- 1;
- ftt <- invalid_fpr_register
- ) else if ((LDF or LDDF or LDFSR) and (an FPU sequence error is detected)) then (
- trap <- 1;
- fp_exception <- 1;
- ftt <- sequence_error
- ) else if ((LDC or LDDC or LDCSR) and (a CP sequence error is detected)) then (
- trap <- 1;
- cp_exception <- 1;
- { possibly additional implementation-dependent actions }
- )
- );
- next;
- if (trap = 0) then {
- (data, MAE) <- memory_read(addr_space, address);
- next;
- if (MAE = 1) then (
- trap <- 1;
- data_access_exception <- 1;
- ) else (
- if (LDSB or LDSBA or LDUB or LDUBA) then (
- if (address<1:0> = 0) then byte <- data<31:24>
- else if (address<1:0> = 1) then byte <- data<23:16>
- else if (address<1:0> = 2) then byte <- data<15: 8>
- else if (address<1:0> = 3) then byte <- data< 7: 0>
- next;
- if (LDSB or LDSBA) then
- word0 <- sign_extend_byte(byte)
- else
- word0 <- zero_extend_byte(byte)
- ) else if (LDSH or LDSHA or LDUH or LDUHA) then (
- if (address<1:0> = 0) then halfword <- data<31:16>
- else if (address<1:0> = 2) then halfword <- data<15: 0>
- next;
- if (LDSH or LDSHA) then
- word0 <- sign_extend_halfword(halfword)
- else
- word0 <- zero_extend_halfword(halfword)
- ) else
- word0 <- data
- )
- );
- next;
- if (trap = 0) then (
- if ( (rd != 0) and (LD or LDA or LDSH or LDSHA
- or LDUHA or LDUH or LDSB or LDSBA or LDUB or LDUBA) ) then
- r[rd] <- word0
- else if (LDF) then f[rd] <- word0
- else if (LDC) then { implementation-dependent actions }
- else if (LDFSR) then FSR <- word0
- else if (LDCSR) then CSR <- word0
- else if (LDD or LDDA) then r[rd and 11110] <- word0
- else if (LDDF) then f[rd and 11110] <- word0
- else if (LDDC) then { implementation-dependent actions }
- );
+ if (MAE = 1) then (
+ trap <- 1;
+ data_access_exception <- 1;
+ ) else (
+ if (LDSB or LDSBA or LDUB or LDUBA) then (
+ if (address<1:0> = 0) then byte <- data<31:24>
+ else if (address<1:0> = 1) then byte <- data<23:16>
+ else if (address<1:0> = 2) then byte <- data<15: 8>
+ else if (address<1:0> = 3) then byte <- data< 7: 0>
+ next;
+ if (LDSB or LDSBA) then
+ word0 <- sign_extend_byte(byte)
+ else
+ word0 <- zero_extend_byte(byte)
+ ) else if (LDSH or LDSHA or LDUH or LDUHA) then (
+ if (address<1:0> = 0) then halfword <- data<31:16>
+ else if (address<1:0> = 2) then halfword <- data<15: 0>
+ next;
+ if (LDSH or LDSHA) then
+ word0 <- sign_extend_halfword(halfword)
+ else
+ word0 <- zero_extend_halfword(halfword)
+ ) else
+ word0 <- data
+ )
+);
+next;
+if (trap = 0) then (
+ if ( (rd != 0) and (LD or LDA or LDSH or LDSHA
+ or LDUHA or LDUH or LDSB or LDSBA or LDUB or LDUBA) ) then
+ r[rd] <- word0
+ else if (LDF) then f[rd] <- word0
+ else if (LDC) then { implementation-dependent actions }
+ else if (LDFSR) then FSR <- word0
+ else if (LDCSR) then CSR <- word0
+ else if (LDD or LDDA) then r[rd and 11110] <- word0
+ else if (LDDF) then f[rd and 11110] <- word0
+ else if (LDDC) then { implementation-dependent actions }
+);
+next;
+if (((trap = 0) and (LDD or LDDA or LDDF or LDDC)) then (
+ (word1, MAE) <- memory_read(addr_space, address + 4);
next;
- if (((trap = 0) and (LDD or LDDA or LDDF or LDDC)) then (
- (word1, MAE) <- memory_read(addr_space, address + 4);
- next;
- if (MAE = 1) then ( { MAE = 1 only due to a "non-resumable machine-check error" }
- trap <- 1;
- data_access_exception <- 1 )
- else if (LDD or LDDA) then r[rd or 1] <- word1
- else if (LDDF) then f[rd or 1] <- word1
- else if (LDDC) then { implementation-dependent actions }
- );
- */
+ if (MAE = 1) then ( { MAE = 1 only due to a "non-resumable machine-check error" }
+ trap <- 1;
+ data_access_exception <- 1 )
+ else if (LDD or LDDA) then r[rd or 1] <- word1
+ else if (LDDF) then f[rd or 1] <- word1
+ else if (LDDC) then { implementation-dependent actions }
+);
+*/
+
+inline void mb86901_device::execute_ldd(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+
+ if (address & 7)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ }
+
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+
+ if (MAE)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ if (RDBITS)
+ RDREG = data;
+
+ const uint32_t word1 = m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
+ if (MAE)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ REG(RD | 1) = word1;
+
+ PC = nPC;
+ nPC = nPC + 4;
+}
+
+inline void mb86901_device::execute_ld(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+
+ if (address & 3)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ if (RDBITS)
+ RDREG = data;
+
+ PC = nPC;
+ nPC = nPC + 4;
+}
+
+inline void mb86901_device::execute_ldsh(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+
+ if (address & 1)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask16[address & 2]);
+
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ if (RDBITS)
+ {
+ if ((address & 3) == 0) RDREG = (int32_t)data >> 16;
+ else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 16;
+ }
+
+ PC = nPC;
+ nPC = nPC + 4;
+}
+
+inline void mb86901_device::execute_lduh(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+
+ if (address & 1)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask16[address & 2]);
+
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ if (RDBITS)
+ {
+ if ((address & 3) == 0) RDREG = data >> 16;
+ else if ((address & 3) == 2) RDREG = data & 0xffff;
+ }
+
+ PC = nPC;
+ nPC = nPC + 4;
+}
+
+inline void mb86901_device::execute_ldsb(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+
static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask8[address & 3]);
- switch (OP3)
+ if (m_mae)
{
- case OP3_LDD:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (address & 7)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- }
+ if (RDBITS)
+ {
+ if ((address & 3) == 0) RDREG = (int32_t)data >> 24;
+ else if ((address & 3) == 1) RDREG = ((int32_t)data << 8) >> 24;
+ else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 24;
+ else if ((address & 3) == 3) RDREG = ((int32_t)data << 24) >> 24;
+ }
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if (MAE)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+inline void mb86901_device::execute_ldub(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- if (RD != 0)
- RDREG = data;
+ static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
+ const uint32_t byte_idx = address & 3;
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask8[byte_idx]);
- const uint32_t word1 = m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
- if (MAE)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- REG(RD | 1) = word1;
- break;
- }
- case OP3_LD:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ if (RDBITS)
+ {
+ static const int shifts[4] = { 24, 16, 8, 0 };
+ RDREG = (uint8_t)(data >> shifts[byte_idx]);
+ }
- if (address & 3)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ PC = nPC;
+ nPC = nPC + 4;
+}
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+inline void mb86901_device::execute_lddfpr(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)
+ {
+ m_trap = 1;
+ m_fp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (RD != 0)
- RDREG = data;
- break;
- }
- case OP3_LDSH:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ if (address & 7)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (address & 1)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ if (RD & 1)
+ {
+ m_trap = 1;
+ m_fp_exception = 1;
+ m_ftt = 0xff;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask16[address & 2]);
+ if (m_fpu_sequence_err)
+ {
+ m_trap = 1;
+ m_fp_exception = 1;
+ m_ftt = m_fpu_sequence_err;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
- if (RD != 0)
- {
- if ((address & 3) == 0) RDREG = (int32_t)data >> 16;
- else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 16;
- }
- break;
- }
- case OP3_LDUH:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (address & 1)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ FREG(RD & 0x1e) = data;
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask16[address & 2]);
+ const uint32_t word1 = m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
+ if (MAE)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ FREG(RD | 1) = word1;
- if (RD != 0)
- {
- if ((address & 3) == 0) RDREG = data >> 16;
- else if ((address & 3) == 2) RDREG = data & 0xffff;
- }
- break;
- }
- case OP3_LDSB:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ PC = nPC;
+ nPC = nPC + 4;
+}
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask8[address & 3]);
+inline void mb86901_device::execute_ldfpr(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)
+ {
+ m_trap = 1;
+ m_fp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (RD != 0)
- {
- if ((address & 3) == 0) RDREG = (int32_t)data >> 24;
- else if ((address & 3) == 1) RDREG = ((int32_t)data << 8) >> 24;
- else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 24;
- else if ((address & 3) == 3) RDREG = ((int32_t)data << 24) >> 24;
- }
- break;
- }
- case OP3_LDUB:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ if (address & 3)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, mask8[address & 3]);
+ if (m_fpu_sequence_err)
+ {
+ m_trap = 1;
+ m_fp_exception = 1;
+ m_ftt = m_fpu_sequence_err;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
- if (RD != 0)
- {
- if ((address & 3) == 0) RDREG = data >> 24;
- else if ((address & 3) == 1) RDREG = (data >> 16) & 0xff;
- else if ((address & 3) == 2) RDREG = (data >> 8) & 0xff;
- else if ((address & 3) == 3) RDREG = data & 0xff;
- }
- break;
- }
- case OP3_LDDFPR:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)
- {
- m_trap = 1;
- m_fp_disabled = 1;
- return;
- }
+ FDREG = data;
- if (address & 7)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if (RD & 1)
- {
- m_trap = 1;
- m_fp_exception = 1;
- m_ftt = 0xff;
- return;
- }
+inline void mb86901_device::execute_ldfsr(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- if (m_fpu_sequence_err)
- {
- m_trap = 1;
- m_fp_exception = 1;
- m_ftt = m_fpu_sequence_err;
- return;
- }
+ if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)
+ {
+ m_trap = 1;
+ m_fp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ if (address & 3)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (m_fpu_sequence_err)
+ {
+ m_trap = 1;
+ m_fp_exception = 1;
+ m_ftt = m_fpu_sequence_err;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- FREG(RD & 0x1e) = data;
+ const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
- const uint32_t word1 = m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
- if (MAE)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- FREG(RD | 1) = word1;
- break;
- }
- case OP3_LDFPR:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ FSR = data;
- if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)
- {
- m_trap = 1;
- m_fp_disabled = 1;
- return;
- }
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if (address & 3)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+inline void mb86901_device::execute_lddcpr(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- if (m_fpu_sequence_err)
- {
- m_trap = 1;
- m_fp_exception = 1;
- m_ftt = m_fpu_sequence_err;
- return;
- }
+ if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
+ {
+ m_trap = 1;
+ m_cp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ if (address & 7)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ if (m_cp_sequence_err)
+ {
+ m_trap = 1;
+ m_cp_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ // possibly additional implementation-dependent actions
+ return;
+ }
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ if (MAE)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- FDREG = data;
- break;
- }
- case OP3_LDFSR:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ // implementation-dependent actions
- if (!(PSR & PSR_EF_MASK) || m_bp_fpu_present == 0)
- {
- m_trap = 1;
- m_fp_disabled = 1;
- return;
- }
+ m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
+ if (MAE)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (address & 3)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ // implementation-dependent actions
- if (m_fpu_sequence_err)
- {
- m_trap = 1;
- m_fp_exception = 1;
- m_ftt = m_fpu_sequence_err;
- return;
- }
+ PC = nPC;
+ nPC = nPC + 4;
+}
- const uint32_t data = m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+inline void mb86901_device::execute_ldcpr(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
+ {
+ m_trap = 1;
+ m_cp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- FSR = data;
- break;
- }
- case OP3_LDDCPR:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ if (address & 3)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
- {
- m_trap = 1;
- m_cp_disabled = 1;
- return;
- }
+ if (m_cp_sequence_err)
+ {
+ m_trap = 1;
+ m_cp_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ // possibly additional implementation-dependent actions
+ return;
+ }
- if (address & 7)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
- if (m_cp_sequence_err)
- {
- m_trap = 1;
- m_cp_exception = 1;
- // possibly additional implementation-dependent actions
- return;
- }
+ if (MAE)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
- if (MAE)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ // implementation-dependent actions
- // implementation-dependent actions
+ PC = nPC;
+ nPC = nPC + 4;
+}
- m_mmu->read_asi(m_data_space, (address + 4) >> 2, 0xffffffff);
- if (MAE)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+inline void mb86901_device::execute_ldcsr(uint32_t op)
+{
+ const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
- // implementation-dependent actions
- break;
- }
- case OP3_LDCPR:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
+ {
+ m_trap = 1;
+ m_cp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
- {
- m_trap = 1;
- m_cp_disabled = 1;
- return;
- }
+ if (address & 3)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (address & 3)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ if (m_cp_sequence_err)
+ {
+ m_trap = 1;
+ m_cp_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ // possibly additional implementation-dependent actions
+ return;
+ }
- if (m_cp_sequence_err)
- {
- m_trap = 1;
- m_cp_exception = 1;
- // possibly additional implementation-dependent actions
- return;
- }
+ m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
- m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ if (MAE)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (MAE)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ // implementation-dependent actions
- // implementation-dependent actions
- break;
- }
- case OP3_LDCSR:
- {
- const uint32_t address = RS1REG + (USEIMM ? SIMM13 : RS2REG);
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if (!(PSR & PSR_EC_MASK) || !m_bp_cp_present)
- {
- m_trap = 1;
- m_cp_disabled = 1;
- return;
- }
+inline void mb86901_device::execute_ldda(uint32_t op)
+{
+ if (IS_USER)
+ {
+ m_trap = 1;
+ m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+ else if (USEIMM)
+ {
+ m_trap = 1;
+ m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (address & 3)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ const uint32_t address = RS1REG + RS2REG;
+ const uint32_t addr_space = ASI;
- if (m_cp_sequence_err)
- {
- m_trap = 1;
- m_cp_exception = 1;
- // possibly additional implementation-dependent actions
- return;
- }
+ if (address & 7)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- m_mmu->read_asi(m_data_space, address >> 2, 0xffffffff);
+ const uint32_t data = m_mmu->read_asi(addr_space, address >> 2, 0xffffffff);
- if (MAE)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- // implementation-dependent actions
- break;
- }
- case OP3_LDDA:
- {
- if (IS_USER)
- {
- m_trap = 1;
- m_privileged_instruction = 1;
- return;
- }
- else if (USEIMM)
- {
- m_trap = 1;
- m_illegal_instruction = 1;
- return;
- }
+ if (RDBITS)
+ RDREG = data;
- const uint32_t address = RS1REG + RS2REG;
- const uint32_t addr_space = ASI;
+ uint32_t word1 = m_mmu->read_asi(addr_space, (address + 4) >> 2, 0xffffffff);
+ if (MAE)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (address & 7)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ REG(RD | 1) = word1;
- const uint32_t data = m_mmu->read_asi(addr_space, address >> 2, 0xffffffff);
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+inline void mb86901_device::execute_lda(uint32_t op)
+{
+ if (IS_USER)
+ {
+ m_trap = 1;
+ m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+ else if (USEIMM)
+ {
+ m_trap = 1;
+ m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (RD != 0)
- RDREG = data;
+ const uint32_t address = RS1REG + RS2REG;
- uint32_t word1 = m_mmu->read_asi(addr_space, (address + 4) >> 2, 0xffffffff);
- if (MAE)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (address & 3)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- REG(RD | 1) = word1;
- break;
- }
- case OP3_LDA:
- {
- if (IS_USER)
- {
- m_trap = 1;
- m_privileged_instruction = 1;
- return;
- }
- else if (USEIMM)
- {
- m_trap = 1;
- m_illegal_instruction = 1;
- return;
- }
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, 0xffffffff);
- const uint32_t address = RS1REG + RS2REG;
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (address & 3)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ if (RDBITS)
+ RDREG = data;
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, 0xffffffff);
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+inline void mb86901_device::execute_ldsha(uint32_t op)
+{
+ if (IS_USER)
+ {
+ m_trap = 1;
+ m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+ else if (USEIMM)
+ {
+ m_trap = 1;
+ m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (RD != 0)
- RDREG = data;
- break;
- }
- case OP3_LDSHA:
- {
- if (IS_USER)
- {
- m_trap = 1;
- m_privileged_instruction = 1;
- return;
- }
- else if (USEIMM)
- {
- m_trap = 1;
- m_illegal_instruction = 1;
- return;
- }
+ const uint32_t address = RS1REG + RS2REG;
- const uint32_t address = RS1REG + RS2REG;
+ if (address & 1)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (address & 1)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+ static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask16[address & 2]);
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask16[address & 2]);
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (RDBITS)
+ {
+ if ((address & 3) == 0) RDREG = (int32_t)data >> 16;
+ else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 16;
+ }
- if (RD != 0)
- {
- if ((address & 3) == 0) RDREG = (int32_t)data >> 16;
- else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 16;
- }
- break;
- }
- case OP3_LDUHA:
- {
- if (IS_USER)
- {
- m_trap = 1;
- m_privileged_instruction = 1;
- return;
- }
- else if (USEIMM)
- {
- m_trap = 1;
- m_illegal_instruction = 1;
- return;
- }
+ PC = nPC;
+ nPC = nPC + 4;
+}
- const uint32_t address = RS1REG + RS2REG;
- if (address & 1)
- {
- m_trap = 1;
- m_mem_address_not_aligned = 1;
- return;
- }
+inline void mb86901_device::execute_lduha(uint32_t op)
+{
+ if (IS_USER)
+ {
+ m_trap = 1;
+ m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+ else if (USEIMM)
+ {
+ m_trap = 1;
+ m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask16[address & 2]);
+ const uint32_t address = RS1REG + RS2REG;
+ if (address & 1)
+ {
+ m_trap = 1;
+ m_mem_address_not_aligned = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ static const uint32_t mask16[4] = { 0xffff0000, 0x00000000, 0x0000ffff, 0x00000000 };
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask16[address & 2]);
- if (RD != 0)
- {
- if ((address & 3) == 0) RDREG = data >> 16;
- else if ((address & 3) == 2) RDREG = data & 0xffff;
- }
- break;
- }
- case OP3_LDSBA:
- {
- if (IS_USER)
- {
- m_trap = 1;
- m_privileged_instruction = 1;
- return;
- }
- else if (USEIMM)
- {
- m_trap = 1;
- m_illegal_instruction = 1;
- return;
- }
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- const uint32_t address = RS1REG + RS2REG;
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask8[address & 3]);
+ if (RDBITS)
+ {
+ if ((address & 3) == 0) RDREG = data >> 16;
+ else if ((address & 3) == 2) RDREG = data & 0xffff;
+ }
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ PC = nPC;
+ nPC = nPC + 4;
+}
- if (RD != 0)
- {
- if ((address & 3) == 0) RDREG = (int32_t)data >> 24;
- else if ((address & 3) == 1) RDREG = ((int32_t)data << 8) >> 24;
- else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 24;
- else if ((address & 3) == 3) RDREG = ((int32_t)data << 24) >> 24;
- }
- break;
- }
- case OP3_LDUBA:
- {
- if (IS_USER)
- {
- m_trap = 1;
- m_privileged_instruction = 1;
- return;
- }
- else if (USEIMM)
- {
- m_trap = 1;
- m_illegal_instruction = 1;
- return;
- }
+inline void mb86901_device::execute_ldsba(uint32_t op)
+{
+ if (IS_USER)
+ {
+ m_trap = 1;
+ m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+ else if (USEIMM)
+ {
+ m_trap = 1;
+ m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- const uint32_t address = RS1REG + RS2REG;
- const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask8[address & 3]);
+ static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
+ const uint32_t address = RS1REG + RS2REG;
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask8[address & 3]);
- if (m_mae)
- {
- m_trap = 1;
- m_data_access_exception = 1;
- return;
- }
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
- if (RD != 0)
- {
- if ((address & 3) == 0) RDREG = data >> 24;
- else if ((address & 3) == 1) RDREG = (data >> 16) & 0xff;
- else if ((address & 3) == 2) RDREG = (data >> 8) & 0xff;
- else if ((address & 3) == 3) RDREG = data & 0xff;
- }
- break;
- }
- default:
- break;
+ if (RDBITS)
+ {
+ if ((address & 3) == 0) RDREG = (int32_t)data >> 24;
+ else if ((address & 3) == 1) RDREG = ((int32_t)data << 8) >> 24;
+ else if ((address & 3) == 2) RDREG = ((int32_t)data << 16) >> 24;
+ else if ((address & 3) == 3) RDREG = ((int32_t)data << 24) >> 24;
+ }
+
+ PC = nPC;
+ nPC = nPC + 4;
+}
+
+inline void mb86901_device::execute_lduba(uint32_t op)
+{
+ if (IS_USER)
+ {
+ m_trap = 1;
+ m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+ else if (USEIMM)
+ {
+ m_trap = 1;
+ m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ static const uint32_t mask8[4] = { 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff };
+ const uint32_t address = RS1REG + RS2REG;
+ const uint32_t data = m_mmu->read_asi(ASI, address >> 2, mask8[address & 3]);
+
+ if (m_mae)
+ {
+ m_trap = 1;
+ m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+
+ if (RDBITS)
+ {
+ if ((address & 3) == 0) RDREG = data >> 24;
+ else if ((address & 3) == 1) RDREG = (data >> 16) & 0xff;
+ else if ((address & 3) == 2) RDREG = (data >> 8) & 0xff;
+ else if ((address & 3) == 3) RDREG = data & 0xff;
}
PC = nPC;
@@ -2831,12 +3149,16 @@ void mb86901_device::execute_ldstub(uint32_t op)
{
m_trap = 1;
m_privileged_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else if (USEIMM)
{
m_trap = 1;
m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
else
@@ -2864,6 +3186,8 @@ void mb86901_device::execute_ldstub(uint32_t op)
{
m_trap = 1;
m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -2875,6 +3199,8 @@ void mb86901_device::execute_ldstub(uint32_t op)
{
m_trap = 1;
m_data_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
@@ -2895,7 +3221,7 @@ void mb86901_device::execute_ldstub(uint32_t op)
{
word = data & 0xff;
}
- if (RD != 0)
+ if (RDBITS)
RDREG = word;
PC = nPC;
@@ -2924,24 +3250,58 @@ inline void mb86901_device::execute_group3(uint32_t op)
switch (OP3)
{
case OP3_LD:
+ execute_ld(op);
+ break;
case OP3_LDUB:
+ execute_ldub(op);
+ break;
case OP3_LDUH:
+ execute_lduh(op);
+ break;
case OP3_LDD:
+ execute_ldd(op);
+ break;
case OP3_LDSB:
+ execute_ldsb(op);
+ break;
case OP3_LDSH:
+ execute_ldsh(op);
+ break;
case OP3_LDA:
+ execute_lda(op);
+ break;
case OP3_LDUBA:
+ execute_lduba(op);
+ break;
case OP3_LDUHA:
+ execute_lduha(op);
+ break;
case OP3_LDDA:
+ execute_ldda(op);
+ break;
case OP3_LDSBA:
+ execute_ldsba(op);
+ break;
case OP3_LDSHA:
+ execute_ldsha(op);
+ break;
case OP3_LDFPR:
+ execute_ldfpr(op);
+ break;
case OP3_LDFSR:
+ execute_ldfsr(op);
+ break;
case OP3_LDDFPR:
+ execute_lddfpr(op);
+ break;
case OP3_LDCPR:
+ execute_ldcpr(op);
+ break;
case OP3_LDCSR:
+ execute_ldcsr(op);
+ break;
case OP3_LDDCPR:
- execute_load(op);
+ execute_lddcpr(op);
break;
case OP3_ST:
@@ -2979,6 +3339,8 @@ inline void mb86901_device::execute_group3(uint32_t op)
logerror("illegal instruction at %08x: %08x\n", PC, op);
m_trap = 1;
m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
break;
}
@@ -2996,28 +3358,39 @@ inline void mb86901_device::execute_group3(uint32_t op)
bool mb86901_device::evaluate_condition(uint32_t op)
{
- bool take = false;
- bool n = ICC_N_SET;
- bool z = ICC_Z_SET;
- bool v = ICC_V_SET;
- bool c = ICC_C_SET;
-
- switch(COND & 7) // COND & 8
- { // 0 8
- case 0: take = false; break; // bn ba
- case 1: take = z; break; // bz bne
- case 2: take = z | (n ^ z); break; // ble bg
- case 3: take = n ^ v; break; // bl bge
- case 4: take = c | z; break; // bleu bgu
- case 5: take = c; break; // bcs bcc
- case 6: take = n; break; // bneg bpos
- case 7: take = v; break; // bvs bvc
+ // COND & 8
+ // 0 8
+ // bn ba
+ // bz bne
+ // ble bg
+ // bl bge
+ // bleu bgu
+ // bcs bcc
+ // bneg bpos
+ // bvs bvc
+
+ switch(COND)
+ {
+ case 0: return false;
+ case 1: return ICC_Z_SET;
+ case 2: return ICC_Z_SET || (ICC_N != ICC_Z);
+ case 3: return (ICC_N != ICC_V);
+ case 4: return ICC_C_SET || ICC_Z_SET;
+ case 5: return ICC_C_SET;
+ case 6: return ICC_N_SET;
+ case 7: return ICC_V_SET;
+
+ case 8: return true;
+ case 9: return ICC_Z_CLEAR;
+ case 10: return ICC_Z_CLEAR && ICC_N_CLEAR;
+ case 11: return (ICC_N == ICC_V);
+ case 12: return ICC_C_CLEAR && ICC_Z_CLEAR;
+ case 13: return ICC_C_CLEAR;
+ case 14: return ICC_N_CLEAR;
+ case 15: return ICC_V_CLEAR;
}
- if (COND & 8)
- take = !take;
-
- return take;
+ return false;
}
@@ -3066,13 +3439,13 @@ void mb86901_device::execute_bicc(uint32_t op)
{
nPC = pc + DISP22;
if (COND == COND_BA && ANNUL)
- m_annul = 1;
+ m_no_annul = false;
}
else
{
nPC = nPC + 4;
if (ANNUL)
- m_annul = 1;
+ m_no_annul = false;
}
}
@@ -3129,6 +3502,8 @@ void mb86901_device::execute_ticc(uint32_t op)
m_trap = 1;
m_trap_instruction = 1;
m_ticc_trap_type = trap_number & 0x7f;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
}
else
{
@@ -3330,7 +3705,6 @@ void mb86901_device::execute_trap()
PSR |= PSR_S_MASK;
m_s = true;
- m_insn_space = 9;
m_data_space = 11;
int cwp = PSR & PSR_CWP_MASK;
@@ -3341,7 +3715,7 @@ void mb86901_device::execute_trap()
update_gpr_pointers();
- if (m_annul == 0)
+ if (m_no_annul)
{
REG(17) = PC;
REG(18) = nPC;
@@ -3350,7 +3724,7 @@ void mb86901_device::execute_trap()
{
REG(17) = nPC;
REG(18) = nPC + 4;
- m_annul = 0;
+ m_no_annul = true;
}
if (!m_reset_trap)
@@ -3426,6 +3800,8 @@ inline void mb86901_device::dispatch_instruction(uint32_t op)
logerror("fbfcc at %08x: %08x\n", PC, op);
m_trap = 1;
m_fp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
break;
@@ -3436,6 +3812,8 @@ inline void mb86901_device::dispatch_instruction(uint32_t op)
logerror("cbccc @ %08x: %08x\n", PC, op);
m_trap = 1;
m_cp_disabled = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
return;
@@ -3444,6 +3822,8 @@ inline void mb86901_device::dispatch_instruction(uint32_t op)
logerror("illegal instruction at %08x: %08x\n", PC, op);
m_trap = 1;
m_illegal_instruction = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
return;
}
break;
@@ -3537,29 +3917,10 @@ inline void mb86901_device::execute_step()
)
)
*/
- if (m_bp_reset_in)
- {
- m_execute_mode = 0;
- m_error_mode = 0;
- m_reset_mode = 1;
- m_stashed_icount = m_icount;
- m_icount = 0;
- return;
- }
- else if (m_et && (m_bp_irl == 15 || m_bp_irl > m_pil))
- {
- m_trap = 1;
- m_interrupt_level = m_bp_irl;
- }
-
- if (m_trap)
- {
- execute_trap();
- }
// write-state-register delay not yet implemented
- const uint32_t op = m_mmu->read_asi(m_insn_space, PC >> 2, 0xffffffff);
+ const uint32_t op = m_mmu->fetch_insn(m_s, PC >> 2);
#if LOG_FCODES
//if (m_log_fcodes)
@@ -3568,23 +3929,23 @@ inline void mb86901_device::execute_step()
}
#endif
- if (MAE && !m_annul)
+ if (m_no_annul)
{
- m_trap = 1;
- m_instruction_access_exception = 1;
+ if (MAE)
+ {
+ m_trap = 1;
+ m_instruction_access_exception = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+ dispatch_instruction(op);
}
else
{
- if (!m_annul)
- {
- dispatch_instruction(op);
- }
- else
- {
- m_annul = 0;
- PC = nPC;
- nPC = nPC + 4;
- }
+ m_no_annul = true;
+ PC = nPC;
+ nPC = nPC + 4;
}
}
@@ -3695,8 +4056,28 @@ void mb86901_device::execute_run()
{
bool debug = machine().debug_flags & DEBUG_FLAG_ENABLED;
+ if (m_bp_reset_in)
+ {
+ m_execute_mode = 0;
+ m_error_mode = 0;
+ m_reset_mode = 1;
+ m_stashed_icount = m_icount;
+ m_icount = 0;
+ return;
+ }
+ else if (m_et && (m_bp_irl == 15 || m_bp_irl > m_pil))
+ {
+ m_trap = 1;
+ m_interrupt_level = m_bp_irl;
+ }
+
do
{
+ if (m_trap)
+ {
+ execute_trap();
+ }
+
if (debug)
{
if (m_reset_mode)
diff --git a/src/devices/cpu/sparc/sparc.h b/src/devices/cpu/sparc/sparc.h
index 14edcd19d01..1a3351c57fe 100644
--- a/src/devices/cpu/sparc/sparc.h
+++ b/src/devices/cpu/sparc/sparc.h
@@ -54,7 +54,7 @@ public:
uint8_t get_asi() { return 0; }
uint32_t pc() { return m_pc; }
- void set_mae() override { m_mae = 1; }
+ void set_mae() override { m_mae = true; }
void add_asi_desc(std::function<void (sparc_disassembler *)> f) { m_asi_desc_adder = f; }
@@ -71,7 +71,6 @@ protected:
void execute_taddcc(uint32_t op);
void execute_sub(uint32_t op);
void execute_tsubcc(uint32_t op);
- void execute_logical(uint32_t op);
void execute_shift(uint32_t op);
void execute_mulscc(uint32_t op);
void execute_rdsr(uint32_t op);
@@ -85,7 +84,25 @@ protected:
#endif
inline void execute_group2(uint32_t op);
- void execute_load(uint32_t op);
+ inline void execute_ldd(uint32_t op);
+ inline void execute_ld(uint32_t op);
+ inline void execute_ldsh(uint32_t op);
+ inline void execute_lduh(uint32_t op);
+ inline void execute_ldsb(uint32_t op);
+ inline void execute_ldub(uint32_t op);
+ inline void execute_lddfpr(uint32_t op);
+ inline void execute_ldfpr(uint32_t op);
+ inline void execute_ldfsr(uint32_t op);
+ inline void execute_lddcpr(uint32_t op);
+ inline void execute_ldcpr(uint32_t op);
+ inline void execute_ldcsr(uint32_t op);
+ inline void execute_ldda(uint32_t op);
+ inline void execute_lda(uint32_t op);
+ inline void execute_ldsha(uint32_t op);
+ inline void execute_lduha(uint32_t op);
+ inline void execute_ldsba(uint32_t op);
+ inline void execute_lduba(uint32_t op);
+
void execute_store(uint32_t op);
void execute_ldstub(uint32_t op);
#if SPARCV8
@@ -93,8 +110,21 @@ protected:
#endif
inline void execute_group3(uint32_t op);
+ enum set_cc
+ {
+ NOCC = 0,
+ USECC
+ };
+
+ template <set_cc SETCC> void execute_and(const uint32_t op);
+ template <set_cc SETCC> void execute_or(const uint32_t op);
+ template <set_cc SETCC> void execute_xor(const uint32_t op);
+ template <set_cc SETCC> void execute_andn(const uint32_t op);
+ template <set_cc SETCC> void execute_orn(const uint32_t op);
+ template <set_cc SETCC> void execute_xnor(const uint32_t op);
+
bool evaluate_condition(uint32_t op);
- void execute_bicc(uint32_t op);
+ inline void execute_bicc(uint32_t op);
void execute_ticc(uint32_t op);
void select_trap();
void execute_trap();
@@ -216,7 +246,7 @@ protected:
bool m_privileged_asr[32];
bool m_illegal_instruction_asr[32];
bool m_mae;
- bool m_annul;
+ bool m_no_annul;
bool m_hold_bus;
int m_icount;
int m_stashed_icount;
diff --git a/src/devices/cpu/sparc/sparc_intf.h b/src/devices/cpu/sparc/sparc_intf.h
index 5e904b4f04f..b1fad3ad9a9 100644
--- a/src/devices/cpu/sparc/sparc_intf.h
+++ b/src/devices/cpu/sparc/sparc_intf.h
@@ -22,9 +22,10 @@ class sparc_mmu_interface
{
public:
virtual ~sparc_mmu_interface() { }
- virtual void set_host(sparc_mmu_host_interface *host) = 0;
+ virtual uint32_t fetch_insn(const bool supervisor, const uint32_t offset) = 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;
+ virtual void set_host(sparc_mmu_host_interface *host) = 0;
};
#endif // MAME_CPU_SPARC_SPARC_INTF_H
diff --git a/src/devices/cpu/sparc/sparcdefs.h b/src/devices/cpu/sparc/sparcdefs.h
index 385392feacb..38227f4c668 100644
--- a/src/devices/cpu/sparc/sparcdefs.h
+++ b/src/devices/cpu/sparc/sparcdefs.h
@@ -29,9 +29,13 @@
#define PSR_RES_MASK 0x000fc000
#define PSR_ICC_MASK 0x00f00000
#define PSR_N_MASK 0x00800000
+#define PSR_N_SHIFT 23
#define PSR_Z_MASK 0x00400000
+#define PSR_Z_SHIFT 22
#define PSR_V_MASK 0x00200000
+#define PSR_V_SHIFT 21
#define PSR_C_MASK 0x00100000
+#define PSR_C_SHIFT 20
#define PSR_VER_SHIFT 24
#define PSR_VER_MASK 0x0f000000
#define PSR_VER 0
@@ -41,25 +45,25 @@
#define PSR_ZERO_MASK (PSR_IMPL_MASK | PSR_VER_MASK | PSR_RES_MASK)
#define ICC_N_SET (m_psr & PSR_N_MASK)
-#define ICC_N (ICC_N_SET ? 1 : 0)
+#define ICC_N (ICC_N_SET >> PSR_N_SHIFT)
#define ICC_N_CLEAR (!ICC_N_SET)
#define SET_ICC_N_FLAG do { m_psr |= PSR_N_MASK; } while(0)
#define CLEAR_ICC_N_FLAG do { m_psr &= ~PSR_N_MASK; } while(0)
#define ICC_Z_SET (m_psr & PSR_Z_MASK)
-#define ICC_Z (ICC_Z_SET ? 1 : 0)
+#define ICC_Z (ICC_Z_SET >> PSR_Z_SHIFT)
#define ICC_Z_CLEAR (!ICC_Z_SET)
#define SET_ICC_Z_FLAG do { m_psr |= PSR_Z_MASK; } while(0)
#define CLEAR_ICC_Z_FLAG do { m_psr &= ~PSR_Z_MASK; } while(0)
#define ICC_V_SET (m_psr & PSR_V_MASK)
-#define ICC_V (ICC_V_SET ? 1 : 0)
+#define ICC_V (ICC_V_SET >> PSR_V_SHIFT)
#define ICC_V_CLEAR (!ICC_V_SET)
#define SET_ICC_V_FLAG do { m_psr |= PSR_V_MASK; } while(0)
#define CLEAR_ICC_V_FLAG do { m_psr &= ~PSR_V_MASK; } while(0)
#define ICC_C_SET (m_psr & PSR_C_MASK)
-#define ICC_C (ICC_C_SET ? 1 : 0)
+#define ICC_C (ICC_C_SET >> PSR_C_SHIFT)
#define ICC_C_CLEAR (!ICC_C_SET)
#define SET_ICC_C_FLAG do { m_psr |= PSR_C_MASK; } while(0)
#define CLEAR_ICC_C_FLAG do { m_psr &= ~PSR_C_MASK; } while(0)
@@ -106,23 +110,24 @@
#define SHCNT64 (op & 63)
#define IAMODE (op & 0x7)
#define USEIMM (op & (1 << 13))
-#define USEEXT ((op >> 12) & 1)
+#define USEEXT (op & (1 << 12))
#define COND ((op >> 25) & 15)
#define RCOND ((op >> 10) & 7)
#define MOVCOND ((op >> 14) & 15)
-#define PRED ((op >> 19) & 1)
-#define ANNUL ((op >> 29) & 1)
+#define PRED (op & (1 << 19))
+#define ANNUL (op & (1 << 29))
#define BRCC ((op >> 20) & 3)
#define MOVCC (((op >> 11) & 3) | ((op >> 16) & 4))
#define OPFCC ((op >> 11) & 7)
#define TCCCC ((op >> 11) & 3)
-#define ASI ((op >> 5) & 255)
+#define ASI (uint8_t)(op >> 5)
#define MMASK (op & 15)
#define CMASK ((op >> 4) & 7)
#define RD ((op >> 25) & 31)
+#define RDBITS (op & 0x3e000000)
#define RS1 ((op >> 14) & 31)
#define RS2 (op & 31)
diff --git a/src/devices/machine/sun4c_mmu.cpp b/src/devices/machine/sun4c_mmu.cpp
index b33e6a65cf9..eabc5c073b4 100644
--- a/src/devices/machine/sun4c_mmu.cpp
+++ b/src/devices/machine/sun4c_mmu.cpp
@@ -75,6 +75,14 @@ void sun4c_mmu_device::device_timer(emu_timer &timer, device_timer_id id, int pa
}
}
+uint32_t sun4c_mmu_device::fetch_insn(const bool supervisor, const uint32_t offset)
+{
+ if (supervisor)
+ return insn_data_r<SUPER_INSN>(offset, 0xffffffff);
+ else
+ return insn_data_r<USER_INSN>(offset, 0xffffffff);
+}
+
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);
@@ -341,11 +349,11 @@ template uint32_t sun4c_mmu_device::insn_data_r<sun4c_mmu_device::SUPER_DATA>(co
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];
- }
+ // supervisor program fetches in boot state are special
+ if (MODE == SUPER_INSN && m_fetch_bootrom)
+ {
+ return m_rom_ptr[offset & 0x1ffff];
+ }
// it's translation time
const uint32_t pmeg = m_curr_segmap_masked[(offset >> 16) & 0xfff];
diff --git a/src/devices/machine/sun4c_mmu.h b/src/devices/machine/sun4c_mmu.h
index 305bb010966..b31d7fcc56c 100644
--- a/src/devices/machine/sun4c_mmu.h
+++ b/src/devices/machine/sun4c_mmu.h
@@ -32,6 +32,9 @@ public:
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)); }
+ auto type1_r() { return m_type1_r.bind(); }
+ auto type1_w() { return m_type1_w.bind(); }
+
enum insn_data_mode
{
USER_INSN,
@@ -43,13 +46,11 @@ public:
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 fetch_insn(const bool supervisor, const uint32_t offset) override;
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; }
+ void set_host(sparc_mmu_host_interface *host) override { m_host = host; }
protected:
static const device_timer_id TIMER_RESET = 0;
diff --git a/src/osd/modules/render/d3d/d3dcomm.h b/src/osd/modules/render/d3d/d3dcomm.h
index 38b93adb7ac..95dcac48ca7 100644
--- a/src/osd/modules/render/d3d/d3dcomm.h
+++ b/src/osd/modules/render/d3d/d3dcomm.h
@@ -143,6 +143,14 @@ private:
void compute_size(int texwidth, int texheight);
void compute_size_subroutine(int texwidth, int texheight, int* p_width, int* p_height);
+ inline void copyline_palette16(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xborderpix);
+ inline void copyline_palettea16(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xborderpix);
+ inline void copyline_rgb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette, int xborderpix);
+ inline void copyline_argb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette, int xborderpix);
+ inline void copyline_yuy16_to_yuy2(uint16_t *dst, const uint16_t *src, int width, const rgb_t *palette);
+ inline void copyline_yuy16_to_uyvy(uint16_t *dst, const uint16_t *src, int width, const rgb_t *palette);
+ inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette);
+
d3d_texture_manager * m_texture_manager; // texture manager pointer
renderer_d3d9 * m_renderer; // renderer pointer
diff --git a/src/osd/modules/render/drawd3d.cpp b/src/osd/modules/render/drawd3d.cpp
index 5b359458f76..e5dd8547c9b 100644
--- a/src/osd/modules/render/drawd3d.cpp
+++ b/src/osd/modules/render/drawd3d.cpp
@@ -2214,7 +2214,7 @@ void texture_info::compute_size(int texwidth, int texheight)
// copyline_palette16
//============================================================
-static inline void copyline_palette16(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xborderpix)
+inline void texture_info::copyline_palette16(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xborderpix)
{
if (xborderpix)
*dst++ = 0xff000000 | palette[*src];
@@ -2229,7 +2229,7 @@ static inline void copyline_palette16(uint32_t *dst, const uint16_t *src, int wi
// copyline_palettea16
//============================================================
-static inline void copyline_palettea16(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xborderpix)
+inline void texture_info::copyline_palettea16(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette, int xborderpix)
{
if (xborderpix)
*dst++ = palette[*src];
@@ -2244,7 +2244,7 @@ static inline void copyline_palettea16(uint32_t *dst, const uint16_t *src, int w
// copyline_rgb32
//============================================================
-static inline void copyline_rgb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette, int xborderpix)
+inline void texture_info::copyline_rgb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette, int xborderpix)
{
if (palette != nullptr)
{
@@ -2280,7 +2280,7 @@ static inline void copyline_rgb32(uint32_t *dst, const uint32_t *src, int width,
// copyline_argb32
//============================================================
-static inline void copyline_argb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette, int xborderpix)
+inline void texture_info::copyline_argb32(uint32_t *dst, const uint32_t *src, int width, const rgb_t *palette, int xborderpix)
{
if (palette != nullptr)
{
@@ -2317,7 +2317,7 @@ static inline void copyline_argb32(uint32_t *dst, const uint32_t *src, int width
// copyline_yuy16_to_yuy2
//============================================================
-static inline void copyline_yuy16_to_yuy2(uint16_t *dst, const uint16_t *src, int width, const rgb_t *palette)
+inline void texture_info::copyline_yuy16_to_yuy2(uint16_t *dst, const uint16_t *src, int width, const rgb_t *palette)
{
assert(width % 2 == 0);
@@ -2348,7 +2348,7 @@ static inline void copyline_yuy16_to_yuy2(uint16_t *dst, const uint16_t *src, in
// copyline_yuy16_to_uyvy
//============================================================
-static inline void copyline_yuy16_to_uyvy(uint16_t *dst, const uint16_t *src, int width, const rgb_t *palette)
+inline void texture_info::copyline_yuy16_to_uyvy(uint16_t *dst, const uint16_t *src, int width, const rgb_t *palette)
{
assert(width % 2 == 0);
@@ -2375,7 +2375,7 @@ static inline void copyline_yuy16_to_uyvy(uint16_t *dst, const uint16_t *src, in
// copyline_yuy16_to_argb
//============================================================
-static inline void copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette)
+inline void texture_info::copyline_yuy16_to_argb(uint32_t *dst, const uint16_t *src, int width, const rgb_t *palette)
{
assert(width % 2 == 0);