summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/score/score.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/score/score.cpp')
-rw-r--r--src/devices/cpu/score/score.cpp128
1 files changed, 65 insertions, 63 deletions
diff --git a/src/devices/cpu/score/score.cpp b/src/devices/cpu/score/score.cpp
index f541c27a0fe..14565f23488 100644
--- a/src/devices/cpu/score/score.cpp
+++ b/src/devices/cpu/score/score.cpp
@@ -14,7 +14,6 @@
******************************************************************************/
#include "emu.h"
-#include "debugger.h"
#include "score.h"
#include "scoredsm.h"
@@ -222,7 +221,6 @@ void score7_cpu_device::execute_set_input(int inputnum, int state)
{
if (state)
{
- standard_irq_callback(inputnum);
if (inputnum > 0 && inputnum < 64)
m_pending_interrupt |= 1ULL << inputnum;
}
@@ -273,13 +271,6 @@ bool score7_cpu_device::check_condition(uint8_t bc)
return false;
}
-int32_t score7_cpu_device::sign_extend(uint32_t data, uint8_t len)
-{
- data &= (1ULL << len) - 1;
- uint32_t sign = 1 << (len - 1);
- return (data ^ sign) - sign;
-}
-
uint32_t score7_cpu_device::fetch()
{
return m_cache.read_dword(m_pc & ~3);
@@ -324,7 +315,7 @@ void score7_cpu_device::check_irq()
if (m_pending_interrupt & (1ULL << i))
{
m_pending_interrupt &= ~(1ULL << i);
- standard_irq_callback(i);
+ standard_irq_callback(i, m_pc);
gen_exception(EXCEPTION_INTERRUPT, i);
return;
}
@@ -561,31 +552,34 @@ void score7_cpu_device::op_specialform()
}
break;
case 0x18: // sll
- m_gpr[rd] = m_gpr[ra] << (m_gpr[rb] & 0x1f);
+ r = m_gpr[ra] << (m_gpr[rb] & 0x1f);
if (cu)
{
- CHECK_Z(m_gpr[rd]);
- CHECK_N(m_gpr[rd]);
+ CHECK_Z(r);
+ CHECK_N(r);
SET_C(BIT(m_gpr[ra], 32 - (m_gpr[rb] & 0x1f)));
}
+ m_gpr[rd] = r;
break;
case 0x1a: // srl
- m_gpr[rd] = m_gpr[ra] >> (m_gpr[rb] & 0x1f);
+ r = m_gpr[ra] >> (m_gpr[rb] & 0x1f);
if (cu)
{
- CHECK_Z(m_gpr[rd]);
- CHECK_N(m_gpr[rd]);
+ CHECK_Z(r);
+ CHECK_N(r);
SET_C(BIT(m_gpr[ra], (m_gpr[rb] & 0x1f) - 1));
}
+ m_gpr[rd] = r;
break;
case 0x1b: // sra
- m_gpr[rd] = sign_extend(m_gpr[ra] >> (m_gpr[rb] & 0x1f), 32 - (m_gpr[rb] & 0x1f));
+ r = util::sext(m_gpr[ra] >> (m_gpr[rb] & 0x1f), 32 - (m_gpr[rb] & 0x1f));
if (cu)
{
- CHECK_Z(m_gpr[rd]);
- CHECK_N(m_gpr[rd]);
+ CHECK_Z(r);
+ CHECK_N(r);
SET_C(BIT(m_gpr[ra], (m_gpr[rb] & 0x1f) - 1));
}
+ m_gpr[rd] = r;
break;
case 0x1c: // ror
unemulated_op("ror");
@@ -601,18 +595,14 @@ void score7_cpu_device::op_specialform()
break;
case 0x20: // mul
{
- int64_t a = (int32_t)m_gpr[ra];
- int64_t b = (int32_t)m_gpr[rb];
- uint64_t d = a * b;
+ uint64_t d = mul_32x32(m_gpr[ra], m_gpr[rb]);
REG_CEL = d & 0xffffffff;
REG_CEH = (d >> 32) & 0xffffffff;
break;
}
case 0x21: // mulu
{
- uint64_t a = (uint32_t)m_gpr[ra];
- uint64_t b = (uint32_t)m_gpr[rb];
- uint64_t d = a * b;
+ uint64_t d = mulu_32x32(m_gpr[ra], m_gpr[rb]);
REG_CEL = d & 0xffffffff;
REG_CEH = (d >> 32) & 0xffffffff;
break;
@@ -662,10 +652,14 @@ void score7_cpu_device::op_specialform()
case 0x28: // mfsr
if (rb < 3)
m_gpr[rd] = m_sr[rb];
+ else
+ logerror("%s: mfsr accessing sr%d (PC=0x%08x)\n", tag(), rb, m_ppc);
break;
case 0x29: // mtsr
if (rb < 3)
m_sr[rb] = m_gpr[ra];
+ else
+ logerror("%s: mtsr accessing sr%d (PC=0x%08x)\n", tag(), rb, m_ppc);
break;
case 0x2a: // t
SET_T(check_condition(rb));
@@ -676,7 +670,7 @@ void score7_cpu_device::op_specialform()
break;
case 0x2c: // extsb
case 0x2d: // extsh
- m_gpr[rd] = sign_extend(m_gpr[ra], (GET_S_FUNC6(m_op) & 1) ? 16 : 8);
+ m_gpr[rd] = util::sext(m_gpr[ra], (GET_S_FUNC6(m_op) & 1) ? 16 : 8);
if (cu)
{
CHECK_N(m_gpr[rd]);
@@ -711,31 +705,34 @@ void score7_cpu_device::op_specialform()
unemulated_op("sce");
break;
case 0x38: // slli
- m_gpr[rd] = m_gpr[ra] << rb;
+ r = m_gpr[ra] << rb;
if (cu)
{
- CHECK_Z(m_gpr[rd]);
- CHECK_N(m_gpr[rd]);
+ CHECK_Z(r);
+ CHECK_N(r);
SET_C(BIT(m_gpr[ra], 32 - rb));
}
+ m_gpr[rd] = r;
break;
case 0x3a: // srli
- m_gpr[rd] = m_gpr[ra] >> rb;
+ r = m_gpr[ra] >> rb;
if (cu)
{
- CHECK_Z(m_gpr[rd]);
- CHECK_N(m_gpr[rd]);
+ CHECK_Z(r);
+ CHECK_N(r);
SET_C(BIT(m_gpr[ra], rb - 1));
}
+ m_gpr[rd] = r;
break;
case 0x3b: // srai
- m_gpr[rd] = sign_extend(m_gpr[ra] >> rb, 32 - rb);
+ r = util::sext(m_gpr[ra] >> rb, 32 - rb);
if (cu)
{
- CHECK_Z(m_gpr[rd]);
- CHECK_N(m_gpr[rd]);
+ CHECK_Z(r);
+ CHECK_N(r);
SET_C(BIT(m_gpr[ra], rb - 1));
}
+ m_gpr[rd] = r;
break;
case 0x3c: // rori
unemulated_op("rori");
@@ -758,7 +755,7 @@ void score7_cpu_device::op_iform1()
{
uint8_t rd = GET_I_RD(m_op);
uint32_t imm16 = GET_I_IMM16(m_op);
- int32_t simm16 = sign_extend(imm16, 16);
+ int32_t simm16 = util::sext(imm16, 16);
uint8_t cu = GET_I_CU(m_op);
uint32_t r;
@@ -823,7 +820,7 @@ void score7_cpu_device::op_rixform1()
uint8_t rd = GET_RIX_RD(m_op);
// pre-increment
- m_gpr[ra] += sign_extend(GET_RIX_IMM12(m_op), 12);
+ m_gpr[ra] += util::sext(GET_RIX_IMM12(m_op), 12);
switch(GET_RIX_FUNC3(m_op))
{
@@ -831,13 +828,13 @@ void score7_cpu_device::op_rixform1()
m_gpr[rd] = read_dword(m_gpr[ra]);
break;
case 1: // lh
- m_gpr[rd] = sign_extend(read_word(m_gpr[ra]), 16);
+ m_gpr[rd] = util::sext(read_word(m_gpr[ra]), 16);
break;
case 2: // lhu
m_gpr[rd] = read_word(m_gpr[ra]);
break;
case 3: // lb
- m_gpr[rd] = sign_extend(read_byte(m_gpr[ra]), 8);
+ m_gpr[rd] = util::sext(read_byte(m_gpr[ra]), 8);
break;
case 4: // sw
write_dword(m_gpr[ra], m_gpr[rd]);
@@ -858,7 +855,7 @@ void score7_cpu_device::op_branch()
{
if (check_condition_branch(GET_BC_BC(m_op)))
{
- int32_t disp = sign_extend(GET_BC_DISP19(m_op), 19) << 1;
+ int32_t disp = util::sext(GET_BC_DISP19(m_op), 19) << 1;
if (GET_BC_LK(m_op))
REG_LNK = m_pc;
@@ -962,13 +959,13 @@ void score7_cpu_device::op_rixform2()
m_gpr[rd] = read_dword(m_gpr[ra]);
break;
case 1: // lh
- m_gpr[rd] = sign_extend(read_word(m_gpr[ra]), 16);
+ m_gpr[rd] = util::sext(read_word(m_gpr[ra]), 16);
break;
case 2: // lhu
m_gpr[rd] = read_word(m_gpr[ra]);
break;
case 3: // lb
- m_gpr[rd] = sign_extend(read_byte(m_gpr[ra]), 8);
+ m_gpr[rd] = util::sext(read_byte(m_gpr[ra]), 8);
break;
case 4: // sw
write_dword(m_gpr[ra], m_gpr[rd]);
@@ -985,14 +982,14 @@ void score7_cpu_device::op_rixform2()
}
// post-increment
- m_gpr[ra] += sign_extend(GET_RIX_IMM12(m_op), 12);
+ m_gpr[ra] += util::sext(GET_RIX_IMM12(m_op), 12);
}
void score7_cpu_device::op_addri()
{
uint8_t ra = GET_RI_RA(m_op);
uint8_t rd = GET_RI_RD(m_op);
- int32_t simm14 = sign_extend(GET_RI_IMM14(m_op), 14);
+ int32_t simm14 = util::sext(GET_RI_IMM14(m_op), 14);
uint8_t cu = GET_RI_CU(m_op);
uint32_t r = m_gpr[ra] + simm14;
@@ -1040,7 +1037,7 @@ void score7_cpu_device::op_lw()
{
uint8_t rd = GET_LS_RD(m_op);
uint8_t ra = GET_LS_RA(m_op);
- int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
+ int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15);
m_gpr[rd] = read_dword(m_gpr[ra] + simm15);
}
@@ -1049,16 +1046,16 @@ void score7_cpu_device::op_lh()
{
uint8_t rd = GET_LS_RD(m_op);
uint8_t ra = GET_LS_RA(m_op);
- int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
+ int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15);
- m_gpr[rd] = sign_extend(read_word(m_gpr[ra] + simm15), 16);
+ m_gpr[rd] = util::sext(read_word(m_gpr[ra] + simm15), 16);
}
void score7_cpu_device::op_lhu()
{
uint8_t rd = GET_LS_RD(m_op);
uint8_t ra = GET_LS_RA(m_op);
- int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
+ int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15);
m_gpr[rd] = read_word(m_gpr[ra] + simm15);
}
@@ -1067,16 +1064,16 @@ void score7_cpu_device::op_lb()
{
uint8_t rd = GET_LS_RD(m_op);
uint8_t ra = GET_LS_RA(m_op);
- int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
+ int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15);
- m_gpr[rd] = sign_extend(read_byte(m_gpr[ra] + simm15), 8);
+ m_gpr[rd] = util::sext(read_byte(m_gpr[ra] + simm15), 8);
}
void score7_cpu_device::op_sw()
{
uint8_t rd = GET_LS_RD(m_op);
uint8_t ra = GET_LS_RA(m_op);
- int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
+ int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15);
write_dword(m_gpr[ra] + simm15, m_gpr[rd]);
}
@@ -1085,7 +1082,7 @@ void score7_cpu_device::op_sh()
{
uint8_t rd = GET_LS_RD(m_op);
uint8_t ra = GET_LS_RA(m_op);
- int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
+ int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15);
write_word(m_gpr[ra] + simm15, m_gpr[rd] & 0xffff);
}
@@ -1094,7 +1091,7 @@ void score7_cpu_device::op_lbu()
{
uint8_t rd = GET_LS_RD(m_op);
uint8_t ra = GET_LS_RA(m_op);
- int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
+ int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15);
m_gpr[rd] = read_byte(m_gpr[ra] + simm15);
}
@@ -1103,7 +1100,7 @@ void score7_cpu_device::op_sb()
{
uint8_t rd = GET_LS_RD(m_op);
uint8_t ra = GET_LS_RA(m_op);
- int32_t simm15 = sign_extend(GET_LS_IMM15(m_op), 15);
+ int32_t simm15 = util::sext(GET_LS_IMM15(m_op), 15);
write_byte(m_gpr[ra] + simm15, m_gpr[rd] & 0xff);
}
@@ -1158,7 +1155,7 @@ void score7_cpu_device::op_rform1()
m_gpr[rd] = m_gpr[rd] >> (m_gpr[ra] & 0x1f);
break;
case 0x0b: // sra!
- m_gpr[rd] = sign_extend(m_gpr[rd] >> (m_gpr[ra] & 0x1f), 32 - (m_gpr[ra] & 0x1f));
+ m_gpr[rd] = util::sext(m_gpr[rd] >> (m_gpr[ra] & 0x1f), 32 - (m_gpr[ra] & 0x1f));
break;
case 0x0c: // brl!
if (check_condition_branch(rd))
@@ -1197,11 +1194,12 @@ void score7_cpu_device::op_rform2()
m_gpr[rd] = r;
break;
case 0x02: // neg!
- m_gpr[rd] = 0 - m_gpr[ra];
- CHECK_Z(m_gpr[rd]);
- CHECK_N(m_gpr[rd]);
- CHECK_V_SUB(0, m_gpr[ra], m_gpr[rd]);
+ r = 0 - m_gpr[ra];
+ CHECK_Z(r);
+ CHECK_N(r);
+ CHECK_V_SUB(0, m_gpr[ra], r);
CHECK_C_SUB(0, m_gpr[ra]);
+ m_gpr[rd] = r;
break;
case 0x03: // cmp!
r = m_gpr[rd] - m_gpr[ra];
@@ -1234,7 +1232,7 @@ void score7_cpu_device::op_rform2()
m_gpr[rd] = read_dword(m_gpr[ra]);
break;
case 0x09: // lh!
- m_gpr[rd] = sign_extend(read_word(m_gpr[ra]), 16);
+ m_gpr[rd] = util::sext(read_word(m_gpr[ra]), 16);
break;
case 0x0a: // pop!
m_gpr[GET_P_RDG(m_op)] = read_dword(m_gpr[GET_P_RAG(m_op)]);
@@ -1270,7 +1268,7 @@ void score7_cpu_device::op_jform()
void score7_cpu_device::op_branch16()
{
if(check_condition_branch(GET_BX_EC(m_op)))
- m_pc = m_ppc + (sign_extend(GET_BX_DISP8(m_op), 8) << 1);
+ m_pc = m_ppc + (util::sext(GET_BX_DISP8(m_op), 8) << 1);
}
void score7_cpu_device::op_ldiu()
@@ -1291,9 +1289,12 @@ void score7_cpu_device::op_iform1a()
else
m_gpr[rd] += 1 << (imm5 & 0xf);
- // condition flags are invalid after this instruction
+ // according to the datasheet, the flags are undefined after this instruction, but xmen expects the Z flag to be valid.
+ CHECK_Z(m_gpr[rd]);
+ CHECK_N(m_gpr[rd]);
break;
case 0x01: // slli!
+ SET_C(BIT(m_gpr[rd], 32 - imm5));
m_gpr[rd] <<= imm5;
CHECK_Z(m_gpr[rd]);
CHECK_N(m_gpr[rd]);
@@ -1302,6 +1303,7 @@ void score7_cpu_device::op_iform1a()
unemulated_op("sdbbp!");
break;
case 0x03: // srli!
+ SET_C(BIT(m_gpr[rd], imm5 - 1));
m_gpr[rd] >>= imm5;
CHECK_Z(m_gpr[rd]);
CHECK_N(m_gpr[rd]);
@@ -1341,7 +1343,7 @@ void score7_cpu_device::op_iform1b()
m_gpr[rd] = read_dword(REG_BP + (imm5<<2));
break;
case 0x01: // lhp!
- m_gpr[rd] = sign_extend(read_word(REG_BP + (imm5<<1)), 16);
+ m_gpr[rd] = util::sext(read_word(REG_BP + (imm5<<1)), 16);
break;
case 0x03: // lbup!
m_gpr[rd] = read_byte(REG_BP + imm5);