diff --git a/src/emu/cpu/arcompact/arcompact_execute.c b/src/emu/cpu/arcompact/arcompact_execute.c index 93bccbe7cd1..38695ee1396 100644 --- a/src/emu/cpu/arcompact/arcompact_execute.c +++ b/src/emu/cpu/arcompact/arcompact_execute.c @@ -135,8 +135,7 @@ int arcompact_device::check_condition(UINT8 condition) { case 0x00: return 1; // AL case 0x01: return CONDITION_EQ; - - case 0x02: fatalerror("unhandled condition check %s", conditions[condition]); return -1; + case 0x02: return !CONDITION_EQ; // NE case 0x03: fatalerror("unhandled condition check %s", conditions[condition]); return -1; case 0x04: fatalerror("unhandled condition check %s", conditions[condition]); return -1; case 0x05: fatalerror("unhandled condition check %s", conditions[condition]); return -1; @@ -1144,8 +1143,34 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle1e_03(OPS_16) ARCOMPACT_RETTYPE arcompact_device::arcompact_handle00_00(OPS_32) { int size = 4; + + COMMON32_GET_CONDITION + + if (!check_condition(condition)) + return m_pc + (size>>0); + // Branch Conditionally - arcompact_log("unimplemented Bcc %08x", op); + // 0000 0sss ssss sss0 SSSS SSSS SSNQ QQQQ + INT32 address = (op & 0x07fe0000) >> 17; + address |= ((op & 0x0000ffc0) >> 6) << 10; + if (address & 0x80000) address = -0x80000 + (address & 0x7ffff); + int n = (op & 0x00000020) >> 5; op &= ~0x00000020; + + UINT32 realaddress = PC_ALIGNED32 + (address * 2); + + if (n) + { + m_delayactive = 1; + m_delayjump = realaddress; + m_delaylinks = 0; // don't link + } + else + { + // m_regs[REG_BLINK] = m_pc + (size >> 0); // don't link + return realaddress; + } + + return m_pc + (size>>0); } @@ -2219,47 +2244,6 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_04(OPS_32) { return a ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_05(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "SEXB"); } // SEXB ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_06(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "SEXW"); } // SEXW -// EXTB -ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_07_p00(OPS_32) // note 'b' destination for 04_2f_07_xx group -{ - SETUP_HANDLE04_2f_0x_P00; - - m_regs[breg] = c & 0x000000ff; - if (F) - { - arcompact_fatal("arcompact_handle04_2f_08_p00 (EXTW) (F set)\n"); // not yet supported - } - - return m_pc + (size >> 0); -} - -ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_07_p01(OPS_32) -{ - int size = 4; - arcompact_fatal("arcompact_handle04_2f_07_p01 (EXTB)\n"); - return m_pc + (size >> 0); -} - -ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_07_p10(OPS_32) -{ - int size = 4; - arcompact_fatal("illegal 04_2f_07_p10 (EXTB)\n"); // illegal mode because 'S' bits have already been used for opcode select - return m_pc + (size >> 0); -} - -ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_07_p11_m0(OPS_32) -{ - int size = 4; - arcompact_fatal("arcompact_handle04_2f_07_p11_m0 (EXTB)\n"); // illegal mode because 'Q' bits have already been used for opcode select - return m_pc + (size >> 0); -} - -ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_07_p11_m1(OPS_32) -{ - int size = 4; - arcompact_fatal("arcompact_handle04_2f_07_p11_m1 (EXTB)\n"); // illegal mode because 'Q' bits have already been used for opcode select - return m_pc + (size >> 0); -} // EXTW b <- c or EXTW b <- limm or EXTW limm <- c (no result) or EXTW limm, limm (invalid?) ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_08_p00(OPS_32) // note 'b' destination for 04_2f_08_xx group diff --git a/src/emu/cpu/arcompact/arcompact_make.py b/src/emu/cpu/arcompact/arcompact_make.py index 54ce75b842a..0cd5904845e 100644 --- a/src/emu/cpu/arcompact/arcompact_make.py +++ b/src/emu/cpu/arcompact/arcompact_make.py @@ -32,7 +32,7 @@ def EmitGroup04_Flaghandler(f,funcname, opname, flagcondition, flaghandler): flaghandler(f, funcname, opname) print >>f, " }" -def EmitGroup04(f,funcname, opname, opexecute, ignore_a, breg_is_dst_only, flagcondition, flaghandler): +def EmitGroup04(f,funcname, opname, opexecute, opwrite, opwrite_alt, ignore_a, breg_is_dst_only, flagcondition, flaghandler): # the mode 0x00 handler print >>f, "ARCOMPACT_RETTYPE arcompact_device::arcompact_handle%s_p00(OPS_32)" % (funcname) print >>f, "{" @@ -53,7 +53,9 @@ def EmitGroup04(f,funcname, opname, opexecute, ignore_a, breg_is_dst_only, flagc print >>f, " COMMON32_GET_areg;" elif ignore_a == 1: print >>f, " //COMMON32_GET_areg; // areg is reserved / not used" - + elif ignore_a == 2: + print >>f, " //COMMON32_GET_areg; // areg bits already used as opcode select" + print >>f, " " print >>f, " UINT32 c;" @@ -89,6 +91,7 @@ def EmitGroup04(f,funcname, opname, opexecute, ignore_a, breg_is_dst_only, flagc print >>f, " /* todo: is the limm, limm syntax valid? (it's pointless.) */" print >>f, " /* todo: if areg = LIMM then there is no result (but since that register can never be read, I guess it doesn't matter if we store it there anyway?) */" print >>f, " %s" % (opexecute) + print >>f, " %s" % (opwrite) print >>f, " " EmitGroup04_Flaghandler(f,funcname,opname,flagcondition,flaghandler) print >>f, " return m_pc + (size >> 0);" @@ -116,6 +119,8 @@ def EmitGroup04(f,funcname, opname, opexecute, ignore_a, breg_is_dst_only, flagc print >>f, " COMMON32_GET_areg;" elif ignore_a == 1: print >>f, " //COMMON32_GET_areg; // areg is reserved / not used" + elif ignore_a == 2: + print >>f, " //COMMON32_GET_areg; // areg bits already used as opcode select" print >>f, " " @@ -141,6 +146,7 @@ def EmitGroup04(f,funcname, opname, opexecute, ignore_a, breg_is_dst_only, flagc print >>f, " " print >>f, " /* todo: if areg = LIMM then there is no result (but since that register can never be read, I guess it doesn't matter if we store it there anyway?) */" print >>f, " %s" % (opexecute) + print >>f, " %s" % (opwrite) print >>f, " " EmitGroup04_Flaghandler(f,funcname,opname,flagcondition,flaghandler) print >>f, " return m_pc + (size >> 0);" @@ -149,73 +155,91 @@ def EmitGroup04(f,funcname, opname, opexecute, ignore_a, breg_is_dst_only, flagc print >>f, "" # the mode 0x10 handler print >>f, "ARCOMPACT_RETTYPE arcompact_device::arcompact_handle%s_p10(OPS_32)" % (funcname) - print >>f, "{" - print >>f, " int size = 4;" - - if breg_is_dst_only == 0: - print >>f, " UINT32 limm = 0;" - - print >>f, "/* int got_limm = 0; */" - print >>f, " " - print >>f, " COMMON32_GET_breg;" - - if flagcondition == -1: - print >>f, " COMMON32_GET_F;" - - print >>f, " COMMON32_GET_s12;" - - if ignore_a == 0: - print >>f, " COMMON32_GET_areg;" - elif ignore_a == 1: - print >>f, " //COMMON32_GET_areg; // areg is reserved / not used" - - print >>f, " " - print >>f, " UINT32 c;" - if breg_is_dst_only == 0: - print >>f, " UINT32 b;" + if ignore_a == 2: + print >>f, "{" + print >>f, " int size = 4;" + print >>f, " arcompact_fatal(\"illegal arcompact_handle%s_p10 (ares bits already used as opcode select, can't be used as s12) (%s)\\n\");" % (funcname, opname) + print >>f, " return m_pc + (size >> 0);" + print >>f, "}" + else: + print >>f, "{" + print >>f, " int size = 4;" + if breg_is_dst_only == 0: + print >>f, " UINT32 limm = 0;" + + print >>f, "/* int got_limm = 0; */" print >>f, " " - print >>f, " /* is having b as LIMM valid here? LIMM vs. fixed u6 value makes no sense */" - print >>f, " if (breg == LIMM_REG)" - print >>f, " {" - print >>f, " GET_LIMM_32;" - print >>f, " size = 8;" - print >>f, "/* got_limm = 1; */" - print >>f, " b = limm;" - print >>f, " }" - print >>f, " else" - print >>f, " {" - print >>f, " b = m_regs[breg];" - print >>f, " }" + print >>f, " COMMON32_GET_breg;" - print >>f, " " - print >>f, " c = (UINT32)S;" - print >>f, " " - print >>f, " /* todo: if areg = LIMM then there is no result (but since that register can never be read, I guess it doesn't matter if we store it there anyway?) */" - print >>f, " %s" % (opexecute) - print >>f, " " - EmitGroup04_Flaghandler(f,funcname,opname,flagcondition,flaghandler) - print >>f, " return m_pc + (size >> 0);" - print >>f, "}" - print >>f, "" - print >>f, "" + if flagcondition == -1: + print >>f, " COMMON32_GET_F;" + + print >>f, " COMMON32_GET_s12;" + + # areg can't be used here, it's used for s12 bits + + print >>f, " " + print >>f, " UINT32 c;" + if breg_is_dst_only == 0: + print >>f, " UINT32 b;" + print >>f, " " + print >>f, " /* is having b as LIMM valid here? LIMM vs. fixed u6 value makes no sense */" + print >>f, " if (breg == LIMM_REG)" + print >>f, " {" + print >>f, " GET_LIMM_32;" + print >>f, " size = 8;" + print >>f, "/* got_limm = 1; */" + print >>f, " b = limm;" + print >>f, " }" + print >>f, " else" + print >>f, " {" + print >>f, " b = m_regs[breg];" + print >>f, " }" + + print >>f, " " + print >>f, " c = (UINT32)S;" + print >>f, " " + print >>f, " /* todo: if areg = LIMM then there is no result (but since that register can never be read, I guess it doesn't matter if we store it there anyway?) */" + print >>f, " %s" % (opexecute) + print >>f, " %s" % (opwrite_alt) + print >>f, " " + EmitGroup04_Flaghandler(f,funcname,opname,flagcondition,flaghandler) + print >>f, " return m_pc + (size >> 0);" + print >>f, "}" + print >>f, "" + print >>f, "" # the mode 0x11 m0 handler print >>f, "ARCOMPACT_RETTYPE arcompact_device::arcompact_handle%s_p11_m0(OPS_32)" % (funcname) - print >>f, "{" - print >>f, " int size = 4;" - print >>f, " arcompact_fatal(\"arcompact_handle%s_p11_m0 (%s)\\n\");" % (funcname, opname) - print >>f, " return m_pc + (size >> 0);" - print >>f, "}" - print >>f, "" - print >>f, "" + if ignore_a == 2: + print >>f, "{" + print >>f, " int size = 4;" + print >>f, " arcompact_fatal(\"illegal arcompact_handle%s_p11_m0 (ares bits already used as opcode select, can't be used as Q condition) (%s)\\n\");" % (funcname, opname) + print >>f, " return m_pc + (size >> 0);" + print >>f, "}" + else: + print >>f, "{" + print >>f, " int size = 4;" + print >>f, " arcompact_fatal(\"arcompact_handle%s_p11_m0 (%s)\\n\");" % (funcname, opname) + print >>f, " return m_pc + (size >> 0);" + print >>f, "}" + print >>f, "" + print >>f, "" # the mode 0x11 m1 handler print >>f, "ARCOMPACT_RETTYPE arcompact_device::arcompact_handle%s_p11_m1(OPS_32)" % (funcname) - print >>f, "{" - print >>f, " int size = 4;" - print >>f, " arcompact_fatal(\"arcompact_handle%s_p11_m1 (%s)\\n\");" % (funcname, opname) - print >>f, " return m_pc + (size >> 0);" - print >>f, "}" - print >>f, "" - print >>f, "" + if ignore_a == 2: + print >>f, "{" + print >>f, " int size = 4;" + print >>f, " arcompact_fatal(\"illegal arcompact_handle%s_p11_m1 (ares bits already used as opcode select, can't be used as Q condition) (%s)\\n\");" % (funcname, opname) + print >>f, " return m_pc + (size >> 0);" + print >>f, "}" + else: + print >>f, "{" + print >>f, " int size = 4;" + print >>f, " arcompact_fatal(\"arcompact_handle%s_p11_m1 (%s)\\n\");" % (funcname, opname) + print >>f, " return m_pc + (size >> 0);" + print >>f, "}" + print >>f, "" + print >>f, "" # xxx_S b, b, u5 format opcodes def EmitGroup17(f,funcname, opname, opexecute): @@ -244,25 +268,29 @@ except Exception, err: sys.exit(1) -EmitGroup04(f, "04_00", "ADD", "UINT32 result = b + c; m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "04_00", "ADD", "UINT32 result = b + c;", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "04_02", "SUB", "UINT32 result = b - c; m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "04_02", "SUB", "UINT32 result = b - c;", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "04_04", "AND", "UINT32 result = b & c; m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "04_05", "OR", "UINT32 result = b | c; m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "04_06", "BIC", "UINT32 result = b & (~c); m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "04_07", "XOR", "UINT32 result = b ^ c; m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "04_04", "AND", "UINT32 result = b & c;", "if (areg != LIMM_REG) { m_regs[areg] = result; }", "if (breg != LIMM_REG) { m_regs[breg] = result; }", 0,0, -1, EmitGroup04_Handle_NZ_Flags ) +EmitGroup04(f, "04_05", "OR", "UINT32 result = b | c;", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "04_06", "BIC", "UINT32 result = b & (~c);", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "04_07", "XOR", "UINT32 result = b ^ c;", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "04_0a", "MOV", "UINT32 result = c; m_regs[breg] = result;", 1,1, -1, EmitGroup04_Handle_NZ_Flags ) +EmitGroup04(f, "04_0a", "MOV", "UINT32 result = c;", "m_regs[breg] = result;", "m_regs[breg] = result;", 1,1, -1, EmitGroup04_Handle_NZ_Flags ) # special case, result always goes to breg -EmitGroup04(f, "04_0f", "BSET", "UINT32 result = b | (1 << (c & 0x1f)); m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "04_0f", "BSET", "UINT32 result = b | (1 << (c & 0x1f));", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "04_15", "ADD2", "UINT32 result = b + (c << 2); m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "04_16", "ADD3", "UINT32 result = b + (c << 3); m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "04_15", "ADD2", "UINT32 result = b + (c << 2);", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "04_16", "ADD3", "UINT32 result = b + (c << 3);", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "05_00", "ASL", "UINT32 result = b << (c&0x1f); m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) -EmitGroup04(f, "05_01", "LSR", "UINT32 result = b >> (c&0x1f); m_regs[areg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "05_00", "ASL", "UINT32 result = b << (c&0x1f);", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) +EmitGroup04(f, "05_01", "LSR", "UINT32 result = b >> (c&0x1f);", "m_regs[areg] = result;", "m_regs[breg] = result;", 0,0, -1, EmitGroup04_unsupported_Flags ) + +# the 04_2f subgroup uses the same encoding, but the areg is already used as sub-opcode select, so any modes relying on areg bits for other reasons (sign, condition) (modes 10, 11m0, 11m1) are illegal. the destination is also breg not areg +EmitGroup04(f, "04_2f_07", "EXTB", "UINT32 result = c & 0x000000ff;", "m_regs[breg] = result;","", 2,1, -1, EmitGroup04_unsupported_Flags ) # no alt handler (invalid path) + # xxx_S b, b, u5 format opcodes EmitGroup17(f, "17_00", "ASL_S", "m_regs[breg] = m_regs[breg] << (u&0x1f);" ) diff --git a/src/emu/cpu/arcompact/arcompactdasm_ops.c b/src/emu/cpu/arcompact/arcompactdasm_ops.c index b630a28a152..20e413b7b60 100644 --- a/src/emu/cpu/arcompact/arcompactdasm_ops.c +++ b/src/emu/cpu/arcompact/arcompactdasm_ops.c @@ -129,7 +129,7 @@ int arcompact_handle00_00_dasm(DASM_OPS_32) // 0000 0sss ssss sss0 SSSS SSSS SSNQ QQQQ INT32 address = (op & 0x07fe0000) >> 17; address |= ((op & 0x0000ffc0) >> 6) << 10; - if (address & 0x800000) address = -0x800000 + (address & 0x7fffff); + if (address & 0x80000) address = -0x80000 + (address & 0x7ffff); int n = (op & 0x00000020) >> 5; op &= ~0x00000020; COMMON32_GET_CONDITION