diff options
author | 2014-12-26 23:42:10 +0000 | |
---|---|---|
committer | 2014-12-26 23:42:10 +0000 | |
commit | 3b359283955547bc8cae7fe3cd85cc4b03ba299d (patch) | |
tree | a4674ed3080ecd842a555d16167369a453ef7dea | |
parent | 6216b82a849ad3d1342de8da069a5267407fb8c3 (diff) |
arcompact - start to add the hardware loop support (nw)
-rw-r--r-- | src/emu/cpu/arcompact/arcompact.c | 17 | ||||
-rw-r--r-- | src/emu/cpu/arcompact/arcompact.h | 8 | ||||
-rw-r--r-- | src/emu/cpu/arcompact/arcompact_common.h | 1 | ||||
-rw-r--r-- | src/emu/cpu/arcompact/arcompact_execute.c | 115 | ||||
-rw-r--r-- | src/emu/cpu/arcompact/arcompact_make.py | 14 | ||||
-rw-r--r-- | src/emu/cpu/arcompact/arcompactdasm_ops.c | 2 |
6 files changed, 80 insertions, 77 deletions
diff --git a/src/emu/cpu/arcompact/arcompact.c b/src/emu/cpu/arcompact/arcompact.c index f586bf23af3..735a9ecd893 100644 --- a/src/emu/cpu/arcompact/arcompact.c +++ b/src/emu/cpu/arcompact/arcompact.c @@ -63,6 +63,8 @@ void arcompact_device::device_start() state_add( 0, "PC", m_debugger_temp).callimport().callexport().formatstr("%08X"); state_add( 0x10, "STATUS32", m_debugger_temp).callimport().callexport().formatstr("%08X"); + state_add( 0x11, "LP_START", m_debugger_temp).callimport().callexport().formatstr("%08X"); + state_add( 0x12, "LP_END", m_debugger_temp).callimport().callexport().formatstr("%08X"); state_add(STATE_GENPC, "GENPC", m_debugger_temp).callexport().noshow(); @@ -88,6 +90,12 @@ void arcompact_device::state_export(const device_state_entry &entry) case 0x10: m_debugger_temp = m_status32; break; + case 0x11: + m_debugger_temp = m_LP_START; + break; + case 0x12: + m_debugger_temp = m_LP_END; + break; case STATE_GENPC: m_debugger_temp = m_pc; @@ -116,6 +124,12 @@ void arcompact_device::state_import(const device_state_entry &entry) case 0x10: m_status32 = m_debugger_temp; break; + case 0x11: + m_LP_START = m_debugger_temp; + break; + case 0x12: + m_LP_END = m_debugger_temp; + break; default: if ((index >= 0x100) && (index < 0x140)) @@ -137,6 +151,9 @@ void arcompact_device::device_reset() m_regs[i] = 0; m_status32 = 0; + m_LP_START = 0; + m_LP_END = 0; + } /*****************************************************************************/ diff --git a/src/emu/cpu/arcompact/arcompact.h b/src/emu/cpu/arcompact/arcompact.h index 3e5fdb677d6..94e3f77a6ff 100644 --- a/src/emu/cpu/arcompact/arcompact.h +++ b/src/emu/cpu/arcompact/arcompact.h @@ -186,7 +186,7 @@ protected: ARCOMPACT_RETTYPE arcompact_handle04_2b(OPS_32); ARCOMPACT_RETTYPE arcompact_handle04_2f_00(OPS_32); ARCOMPACT_RETTYPE arcompact_handle04_2f_01(OPS_32); - ARCOMPACT_RETTYPE arcompact_handle04_2f_02(OPS_32); +// ARCOMPACT_RETTYPE arcompact_handle04_2f_02(OPS_32); ARCOMPACT_RETTYPE arcompact_handle04_2f_03(OPS_32); ARCOMPACT_RETTYPE arcompact_handle04_2f_04(OPS_32); ARCOMPACT_RETTYPE arcompact_handle04_2f_05(OPS_32); @@ -778,6 +778,7 @@ protected: ARCOMPACT_HANDLER04_TYPE_PM(04_16); ARCOMPACT_HANDLER04_TYPE_PM(04_20); + ARCOMPACT_HANDLER04_TYPE_PM(04_2f_02); ARCOMPACT_HANDLER04_TYPE_PM(04_2f_07); ARCOMPACT_HANDLER04_TYPE_PM(04_2f_08); @@ -815,6 +816,10 @@ private: // f e d c| b a 9 8| 7 6 5 4| 3 2 1 0 // - - - L| Z N C V| U DE AE A2|A1 E2 E1 H UINT32 m_status32; + + UINT32 m_LP_START; + UINT32 m_LP_END; + }; #define V_OVERFLOW_FLAG (0x00000100) @@ -845,6 +850,7 @@ private: // Condition 0x0c (LE) #define CONDITION_LE ((STATUS32_CHECK_Z) || (STATUS32_CHECK_N && !STATUS32_CHECK_V) || (!STATUS32_CHECK_N && STATUS32_CHECK_V)) // Z or (N and /V) or (/N and V) #define CONDITION_EQ (STATUS32_CHECK_Z) +#define CONDITION_CS (STATUS32_CHECK_C) extern const device_type ARCA5; diff --git a/src/emu/cpu/arcompact/arcompact_common.h b/src/emu/cpu/arcompact/arcompact_common.h index f6d8c922a12..9eca6c2a182 100644 --- a/src/emu/cpu/arcompact/arcompact_common.h +++ b/src/emu/cpu/arcompact/arcompact_common.h @@ -19,3 +19,4 @@ extern const char *opcodes_04[0x40]; #define REG_SP (0x1c) // r28 #define REG_ILINK1 (0x1d) // r29 #define REG_ILINK2 (0x1e) // r30 +#define REG_LP_COUNT (0x3c) // r60 diff --git a/src/emu/cpu/arcompact/arcompact_execute.c b/src/emu/cpu/arcompact/arcompact_execute.c index 38695ee1396..855f3d8647c 100644 --- a/src/emu/cpu/arcompact/arcompact_execute.c +++ b/src/emu/cpu/arcompact/arcompact_execute.c @@ -36,6 +36,17 @@ void arcompact_device::execute_run() m_pc = get_insruction(op); } + // hardware loops + if (m_pc == m_LP_END) + { + if (m_regs[REG_LP_COUNT] != 1) + { + m_pc = m_LP_START; + } + m_regs[REG_LP_COUNT]--; + + } + m_icount--; } @@ -138,7 +149,7 @@ int arcompact_device::check_condition(UINT8 condition) 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; + case 0x05: return CONDITION_CS; // CS (Carry Set / Lower than) case 0x06: fatalerror("unhandled condition check %s", conditions[condition]); return -1; case 0x07: fatalerror("unhandled condition check %s", conditions[condition]); return -1; case 0x08: fatalerror("unhandled condition check %s", conditions[condition]); return -1; @@ -2054,23 +2065,46 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_23(OPS_32) ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_28(OPS_32) // LPcc (loop setup) { int size = 4; - +// COMMON32_GET_breg; // breg is reserved COMMON32_GET_p; - + if (p == 0x00) { + arcompact_fatal("<illegal LPcc, p = 0x00)"); } else if (p == 0x01) { + arcompact_fatal("<illegal LPcc, p = 0x01)"); } else if (p == 0x02) // Loop unconditional - { + { // 0010 0RRR 1010 1000 0RRR ssss ssSS SSSS + COMMON32_GET_s12 + if (S & 0x800) S = -0x800 + (S&0x7ff); + + arcompact_fatal("Lp unconditional not supported %d", S); } else if (p == 0x03) // Loop conditional - { + { // 0010 0RRR 1110 1000 0RRR uuuu uu1Q QQQQ + COMMON32_GET_u6 + COMMON32_GET_CONDITION + //arcompact_fatal("Lp conditional %s not supported %d", conditions[condition], u); + + // if the loop condition fails then just jump to after the end of the loop, don't set any registers + if (!check_condition(condition)) + { + UINT32 realoffset = PC_ALIGNED32 + (u * 2); + return realoffset; + } + else + { + // otherwise set up the loop positions + m_LP_START = m_pc + (size >> 0); + m_LP_END = PC_ALIGNED32 + (u * 2); + return m_pc + (size>>0); + } + } - arcompact_log("unimplemented LPcc %08x", op); return m_pc + (size>>0); } @@ -2211,83 +2245,16 @@ ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_helper(OPS_32, const c } -#define SETUP_HANDLE04_2f_0x_P00 \ - int size = 4; \ - UINT32 limm = 0; \ - \ - COMMON32_GET_breg; \ - COMMON32_GET_F; \ - COMMON32_GET_creg; \ - \ - UINT32 c; \ - \ - if (creg == LIMM_REG) \ - { \ - GET_LIMM_32; \ - size = 8; \ - c = limm; \ - } \ - else \ - { \ - c = m_regs[creg]; \ - } \ - /* todo: is the limm, limm syntax valid? (it's pointless.) */ \ - /* todo: if breg = 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?) */ \ - - ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_00(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "ASL"); } // ASL ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_01(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "ASR"); } // ASR -ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_02(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "LSR"); } // LSR + ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_03(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "ROR"); } // ROR ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_04(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "RCC"); } // RCC 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 -// 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 -{ - SETUP_HANDLE04_2f_0x_P00; - - m_regs[breg] = c & 0x0000ffff; - 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_08_p01(OPS_32) -{ - int size = 4; - arcompact_fatal("arcompact_handle04_2f_08_p01 (EXTW)\n"); - return m_pc + (size >> 0); -} - -ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_08_p10(OPS_32) -{ - int size = 4; - arcompact_fatal("illegal 04_2f_08_p10 (EXTW)\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_08_p11_m0(OPS_32) -{ - int size = 4; - arcompact_fatal("arcompact_handle04_2f_08_p11_m0 (EXTW)\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_08_p11_m1(OPS_32) -{ - int size = 4; - arcompact_fatal("arcompact_handle04_2f_08_p11_m1 (EXTW)\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_09(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "ABS"); } // ABS ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_0a(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "NOT"); } // NOT ARCOMPACT_RETTYPE arcompact_device::arcompact_handle04_2f_0b(OPS_32) { return arcompact_handle04_2f_helper(PARAMS, "RCL"); } // RLC diff --git a/src/emu/cpu/arcompact/arcompact_make.py b/src/emu/cpu/arcompact/arcompact_make.py index 0cd5904845e..d7a3987ba24 100644 --- a/src/emu/cpu/arcompact/arcompact_make.py +++ b/src/emu/cpu/arcompact/arcompact_make.py @@ -9,6 +9,16 @@ def EmitGroup04_Handle_NZ_Flags(f, funcname, opname): print >>f, " if (result == 0x00000000) { STATUS32_SET_Z; }" print >>f, " else { STATUS32_CLEAR_Z; }" +def EmitGroup04_Handle_NZC_LSR1_Flags(f, funcname, opname): + print >>f, " if (result & 0x80000000) { STATUS32_SET_N; }" + print >>f, " else { STATUS32_CLEAR_N; }" + print >>f, " if (result == 0x00000000) { STATUS32_SET_Z; }" + print >>f, " else { STATUS32_CLEAR_Z; }" + print >>f, " if (c == 0x00000001) { STATUS32_SET_C; }" + print >>f, " else { STATUS32_CLEAR_C; }" + + + def EmitGroup04_no_Flags(f, funcname, opname): print >>f, " // no flag changes" @@ -289,7 +299,9 @@ EmitGroup04(f, "05_00", "ASL", "UINT32 result = b << (c&0x1f);", "m_regs[areg] = 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) +EmitGroup04(f, "04_2f_02", "LSR1", "UINT32 result = c >> 1;", "m_regs[breg] = result;","", 2,1, -1, EmitGroup04_Handle_NZC_LSR1_Flags ) # no alt handler (invalid path) +EmitGroup04(f, "04_2f_07", "EXTB", "UINT32 result = c & 0x000000ff;", "m_regs[breg] = result;","", 2,1, -1, EmitGroup04_unsupported_Flags ) # ^ +EmitGroup04(f, "04_2f_08", "EXTW", "UINT32 result = c & 0x0000ffff;", "m_regs[breg] = result;","", 2,1, -1, EmitGroup04_unsupported_Flags ) # ^ # xxx_S b, b, u5 format opcodes diff --git a/src/emu/cpu/arcompact/arcompactdasm_ops.c b/src/emu/cpu/arcompact/arcompactdasm_ops.c index 20e413b7b60..4cdf09a37a0 100644 --- a/src/emu/cpu/arcompact/arcompactdasm_ops.c +++ b/src/emu/cpu/arcompact/arcompactdasm_ops.c @@ -887,7 +887,7 @@ int arcompact_handle04_28_dasm(DASM_OPS_32) // LPcc (loop setup) { // 0010 0RRR 1110 1000 0RRR uuuu uu1Q QQQQ COMMON32_GET_u6 COMMON32_GET_CONDITION - output += sprintf(output, "LP<%s> (start %08x, end %08x)", conditions[condition], pc + 4, pc + u*2); + output += sprintf(output, "LP<%s> (start %08x, end %08x)", conditions[condition], pc + 4, PC_ALIGNED32 + u*2); int unused = (op & 0x00000020)>>5; if (unused==0) output += sprintf(output, "(unused bit not set)"); |