summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--src/emu/cpu/arcompact/arcompact.c17
-rw-r--r--src/emu/cpu/arcompact/arcompact.h8
-rw-r--r--src/emu/cpu/arcompact/arcompact_common.h1
-rw-r--r--src/emu/cpu/arcompact/arcompact_execute.c115
-rw-r--r--src/emu/cpu/arcompact/arcompact_make.py14
-rw-r--r--src/emu/cpu/arcompact/arcompactdasm_ops.c2
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)");