mirror of
https://github.com/holub/mame
synced 2025-05-10 16:21:42 +03:00
arcompact - start to add the hardware loop support (nw)
This commit is contained in:
parent
6216b82a84
commit
3b35928395
@ -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;
|
||||
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)");
|
||||
|
Loading…
Reference in New Issue
Block a user