mirror of
https://github.com/holub/mame
synced 2025-10-06 17:08:28 +03:00
e132x, looked at subs opcode, nw.
This commit is contained in:
parent
b47c845eda
commit
edf05a30a5
@ -1721,143 +1721,11 @@ offs_t hyperstone_device::disasm_disassemble(std::ostream &stream, offs_t pc, co
|
||||
|
||||
/* Opcodes */
|
||||
|
||||
void hyperstone_device::hyperstone_subs(regs_decode &decode)
|
||||
{
|
||||
if (SRC_IS_SR)
|
||||
SREG = GET_C;
|
||||
|
||||
int64_t tmp = (int64_t)((int32_t)(DREG)) - (int64_t)((int32_t)(SREG));
|
||||
|
||||
//#ifdef SETCARRYS
|
||||
// CHECK_C(tmp);
|
||||
//#endif
|
||||
|
||||
CHECK_VSUB(SREG,DREG,tmp);
|
||||
|
||||
int32_t res = (int32_t)(DREG) - (int32_t)(SREG);
|
||||
|
||||
SET_DREG(res);
|
||||
|
||||
SET_Z(res == 0 ? 1 : 0);
|
||||
SET_N(SIGN_BIT(res));
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
|
||||
if (SR & V_MASK)
|
||||
{
|
||||
uint32_t addr = get_trap_addr(TRAPNO_RANGE_ERROR);
|
||||
execute_exception(addr);
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_sardi()
|
||||
{
|
||||
check_delay_PC();
|
||||
|
||||
const uint32_t dst_code = (DST_CODE + GET_FP) % 64;
|
||||
const uint32_t dstf_code = (DST_CODE + GET_FP + 1) % 64;
|
||||
|
||||
uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]);
|
||||
|
||||
SR &= ~(C_MASK | Z_MASK | N_MASK);
|
||||
|
||||
const uint32_t n = N_VALUE;
|
||||
if (n)
|
||||
{
|
||||
SR |= (val >> (n - 1)) & 1;
|
||||
|
||||
const uint64_t sign_bit = val >> 63;
|
||||
val >>= n;
|
||||
|
||||
if (sign_bit)
|
||||
{
|
||||
val |= 0xffffffff00000000U << (32 - n);
|
||||
}
|
||||
}
|
||||
|
||||
m_local_regs[dst_code] = (uint32_t)(val >> 32);
|
||||
m_local_regs[dstf_code] = (uint32_t)val;
|
||||
|
||||
if (val == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(m_local_regs[dst_code]);
|
||||
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_shld()
|
||||
{
|
||||
check_delay_PC();
|
||||
|
||||
uint32_t src_code = (SRC_CODE + GET_FP) % 64;
|
||||
uint32_t dst_code = (DST_CODE + GET_FP) % 64;
|
||||
uint32_t dstf_code = (DST_CODE + GET_FP + 1) % 64;
|
||||
|
||||
// result undefined if Ls denotes the same register as Ld or Ldf
|
||||
if (src_code == dst_code || src_code == dstf_code)
|
||||
{
|
||||
DEBUG_PRINTF(("Denoted same registers in hyperstone_shld. PC = %08X\n", PC));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t n = m_local_regs[src_code % 64] & 0x1f;
|
||||
uint32_t high_order = m_local_regs[dst_code]; /* registers offset by frame pointer */
|
||||
uint32_t low_order = m_local_regs[dstf_code];
|
||||
|
||||
uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
|
||||
|
||||
uint64_t val = concat_64(high_order, low_order);
|
||||
SET_C( (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0);
|
||||
uint32_t tmp = high_order << n;
|
||||
|
||||
if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)))
|
||||
SET_V(1);
|
||||
else
|
||||
SR &= ~V_MASK;
|
||||
|
||||
val <<= n;
|
||||
|
||||
m_local_regs[dst_code] = extract_64hi(val);
|
||||
m_local_regs[dstf_code] = extract_64lo(val);
|
||||
|
||||
SET_Z(val == 0 ? 1 : 0);
|
||||
SET_N(SIGN_BIT(high_order));
|
||||
}
|
||||
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_shl()
|
||||
{
|
||||
check_delay_PC();
|
||||
|
||||
uint32_t src_code = SRC_CODE + GET_FP;
|
||||
uint32_t dst_code = DST_CODE + GET_FP;
|
||||
|
||||
uint32_t n = m_local_regs[src_code % 64] & 0x1f;
|
||||
uint32_t base = m_local_regs[dst_code % 64]; /* registers offset by frame pointer */
|
||||
uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
|
||||
SET_C( (n)?(((base<<(n-1))&0x80000000)?1:0):0);
|
||||
uint32_t ret = base << n;
|
||||
|
||||
if (((base & mask) && (!(ret & 0x80000000))) || (((base & mask) ^ mask) && (ret & 0x80000000)))
|
||||
SET_V(1);
|
||||
else
|
||||
SR &= ~V_MASK;
|
||||
|
||||
m_local_regs[dst_code % 64] = ret;
|
||||
SET_Z(ret == 0 ? 1 : 0);
|
||||
SET_N(SIGN_BIT(ret));
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_trap()
|
||||
{
|
||||
check_delay_PC();
|
||||
|
||||
const uint8_t trapno = (m_op & 0xfc) >> 2;
|
||||
|
||||
const uint32_t addr = get_trap_addr(trapno);
|
||||
const uint8_t code = ((m_op & 0x300) >> 6) | (m_op & 0x03);
|
||||
|
||||
@ -2079,10 +1947,10 @@ void hyperstone_device::execute_run()
|
||||
case 0x49: hyperstone_sub_global_local(); break;
|
||||
case 0x4a: hyperstone_sub_local_global(); break;
|
||||
case 0x4b: hyperstone_sub_local_local(); break;
|
||||
case 0x4c: op4c(); break;
|
||||
case 0x4d: op4d(); break;
|
||||
case 0x4e: op4e(); break;
|
||||
case 0x4f: op4f(); break;
|
||||
case 0x4c: hyperstone_subs_global_global(); break;
|
||||
case 0x4d: hyperstone_subs_global_local(); break;
|
||||
case 0x4e: hyperstone_subs_local_global(); break;
|
||||
case 0x4f: hyperstone_subs_local_local(); break;
|
||||
case 0x50: hyperstone_addc_global_global(); break;
|
||||
case 0x51: hyperstone_addc_global_local(); break;
|
||||
case 0x52: hyperstone_addc_local_global(); break;
|
||||
|
@ -281,7 +281,10 @@ private:
|
||||
void hyperstone_sub_global_local();
|
||||
void hyperstone_sub_local_global();
|
||||
void hyperstone_sub_local_local();
|
||||
void hyperstone_subs(regs_decode &decode);
|
||||
void hyperstone_subs_global_global();
|
||||
void hyperstone_subs_global_local();
|
||||
void hyperstone_subs_local_global();
|
||||
void hyperstone_subs_local_local();
|
||||
void hyperstone_addc_global_global();
|
||||
void hyperstone_addc_global_local();
|
||||
void hyperstone_addc_local_global();
|
||||
@ -465,8 +468,6 @@ private:
|
||||
bool generate_opcode(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
#endif
|
||||
|
||||
void op4c(); void op4d(); void op4e(); void op4f(); // subs
|
||||
|
||||
#if 0
|
||||
void generate_op00(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op01(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
void generate_op02(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc); void generate_op03(drcuml_block *block, compiler_state *compiler, const opcode_desc *desc);
|
||||
|
@ -2078,72 +2078,119 @@ void hyperstone_device::hyperstone_sub_local_local()
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
void hyperstone_device::op4c()
|
||||
void hyperstone_device::hyperstone_subs_global_global()
|
||||
{
|
||||
regs_decode decode;
|
||||
check_delay_PC();
|
||||
decode.src = SRC_CODE;
|
||||
decode.dst = DST_CODE;
|
||||
const uint32_t src_code = SRC_CODE;
|
||||
const uint32_t dst_code = DST_CODE;
|
||||
const int32_t sreg = (src_code == SR_REGISTER) ? (SR & C_MASK) : (int32_t)m_global_regs[dst_code];
|
||||
const int32_t dreg = (int32_t)m_global_regs[dst_code];
|
||||
const int64_t tmp = (int64_t)dreg - (int64_t)sreg;
|
||||
|
||||
decode.src_is_local = 0;
|
||||
SREG = m_global_regs[decode.src];
|
||||
SR &= ~(V_MASK | Z_MASK | N_MASK);
|
||||
|
||||
decode.dst_is_local = 0;
|
||||
DREG = m_global_regs[decode.dst];
|
||||
//#ifdef SETCARRYS
|
||||
// CHECK_C(tmp);
|
||||
//#endif
|
||||
|
||||
hyperstone_subs(decode);
|
||||
printf("0x4c, subs global,global\n");
|
||||
SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
|
||||
|
||||
const int32_t res = dreg - sreg;
|
||||
set_global_register(dst_code, res);
|
||||
|
||||
if (res == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(res);
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
|
||||
if (SR & V_MASK)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
}
|
||||
|
||||
void hyperstone_device::op4d()
|
||||
void hyperstone_device::hyperstone_subs_global_local()
|
||||
{
|
||||
regs_decode decode;
|
||||
check_delay_PC();
|
||||
decode.src = SRC_CODE;
|
||||
decode.dst = DST_CODE;
|
||||
const uint32_t dst_code = DST_CODE;
|
||||
const int32_t sreg = (int32_t)m_local_regs[(SRC_CODE + GET_FP) & 0x3f];
|
||||
const int32_t dreg = (int32_t)m_global_regs[dst_code];
|
||||
const int64_t tmp = (int64_t)dreg - (int64_t)sreg;
|
||||
|
||||
decode.src_is_local = 1;
|
||||
SREG = m_local_regs[(decode.src + GET_FP) & 0x3f];
|
||||
SR &= ~(V_MASK | Z_MASK | N_MASK);
|
||||
|
||||
decode.dst_is_local = 0;
|
||||
DREG = m_global_regs[decode.dst];
|
||||
//#ifdef SETCARRYS
|
||||
// CHECK_C(tmp);
|
||||
//#endif
|
||||
|
||||
hyperstone_subs(decode);
|
||||
printf("0x4d, subs global,local\n");
|
||||
SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
|
||||
|
||||
const int32_t res = dreg - sreg;
|
||||
set_global_register(dst_code, res);
|
||||
|
||||
if (res == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(res);
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
|
||||
if (SR & V_MASK)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
}
|
||||
|
||||
void hyperstone_device::op4e()
|
||||
void hyperstone_device::hyperstone_subs_local_global()
|
||||
{
|
||||
regs_decode decode;
|
||||
check_delay_PC();
|
||||
decode.src = SRC_CODE;
|
||||
decode.dst = DST_CODE;
|
||||
const uint32_t src_code = SRC_CODE;
|
||||
const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f;
|
||||
const int32_t sreg = (src_code == SR_REGISTER) ? (SR & C_MASK) : (int32_t)m_global_regs[dst_code];
|
||||
const int32_t dreg = (int32_t)m_local_regs[dst_code];
|
||||
const int64_t tmp = (int64_t)dreg - (int64_t)sreg;
|
||||
|
||||
decode.src_is_local = 0;
|
||||
SREG = m_global_regs[decode.src];
|
||||
SR &= ~(V_MASK | Z_MASK | N_MASK);
|
||||
|
||||
decode.dst_is_local = 1;
|
||||
DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f];
|
||||
//#ifdef SETCARRYS
|
||||
// CHECK_C(tmp);
|
||||
//#endif
|
||||
|
||||
hyperstone_subs(decode);
|
||||
printf("0x4e, subs local,global\n");
|
||||
SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
|
||||
|
||||
const int32_t res = dreg - sreg;
|
||||
m_local_regs[dst_code] = res;
|
||||
|
||||
if (res == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(res);
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
|
||||
if (SR & V_MASK)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
}
|
||||
|
||||
void hyperstone_device::op4f()
|
||||
void hyperstone_device::hyperstone_subs_local_local()
|
||||
{
|
||||
regs_decode decode;
|
||||
check_delay_PC();
|
||||
decode.src = SRC_CODE;
|
||||
decode.dst = DST_CODE;
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
const int32_t sreg = (int32_t)m_local_regs[(SRC_CODE + fp) & 0x3f];
|
||||
const int32_t dreg = (int32_t)m_local_regs[dst_code];
|
||||
const int64_t tmp = (int64_t)dreg - (int64_t)sreg;
|
||||
|
||||
decode.src_is_local = 1;
|
||||
SREG = m_local_regs[(decode.src + GET_FP) & 0x3f];
|
||||
SR &= ~(V_MASK | Z_MASK | N_MASK);
|
||||
|
||||
decode.dst_is_local = 1;
|
||||
DREG = m_local_regs[(decode.dst + GET_FP) & 0x3f]; /* registers offset by frame pointer */
|
||||
//#ifdef SETCARRYS
|
||||
// CHECK_C(tmp);
|
||||
//#endif
|
||||
|
||||
hyperstone_subs(decode);
|
||||
printf("0x4f, subs local,local\n");
|
||||
SR |= ((tmp ^ dreg) & (dreg ^ sreg) & 0x80000000) >> 28;
|
||||
|
||||
const int32_t res = dreg - sreg;
|
||||
m_local_regs[dst_code] = res;
|
||||
|
||||
if (res == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(res);
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
|
||||
if (SR & V_MASK)
|
||||
execute_exception(get_trap_addr(TRAPNO_RANGE_ERROR));
|
||||
}
|
||||
|
||||
|
||||
@ -3512,6 +3559,41 @@ void hyperstone_device::hyperstone_shr()
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_sardi()
|
||||
{
|
||||
check_delay_PC();
|
||||
|
||||
const uint32_t dst_code = (DST_CODE + GET_FP) % 64;
|
||||
const uint32_t dstf_code = (DST_CODE + GET_FP + 1) % 64;
|
||||
|
||||
uint64_t val = concat_64(m_local_regs[dst_code], m_local_regs[dstf_code]);
|
||||
|
||||
SR &= ~(C_MASK | Z_MASK | N_MASK);
|
||||
|
||||
const uint32_t n = N_VALUE;
|
||||
if (n)
|
||||
{
|
||||
SR |= (val >> (n - 1)) & 1;
|
||||
|
||||
const uint64_t sign_bit = val >> 63;
|
||||
val >>= n;
|
||||
|
||||
if (sign_bit)
|
||||
{
|
||||
val |= 0xffffffff00000000U << (32 - n);
|
||||
}
|
||||
}
|
||||
|
||||
m_local_regs[dst_code] = (uint32_t)(val >> 32);
|
||||
m_local_regs[dstf_code] = (uint32_t)val;
|
||||
|
||||
if (val == 0)
|
||||
SR |= Z_MASK;
|
||||
SR |= SIGN_TO_N(m_local_regs[dst_code]);
|
||||
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_sard()
|
||||
{
|
||||
check_delay_PC();
|
||||
@ -3629,6 +3711,73 @@ void hyperstone_device::hyperstone_shldi()
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_shld()
|
||||
{
|
||||
check_delay_PC();
|
||||
|
||||
uint32_t src_code = (SRC_CODE + GET_FP) % 64;
|
||||
uint32_t dst_code = (DST_CODE + GET_FP) % 64;
|
||||
uint32_t dstf_code = (DST_CODE + GET_FP + 1) % 64;
|
||||
|
||||
// result undefined if Ls denotes the same register as Ld or Ldf
|
||||
if (src_code == dst_code || src_code == dstf_code)
|
||||
{
|
||||
DEBUG_PRINTF(("Denoted same registers in hyperstone_shld. PC = %08X\n", PC));
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t n = m_local_regs[src_code % 64] & 0x1f;
|
||||
uint32_t high_order = m_local_regs[dst_code]; /* registers offset by frame pointer */
|
||||
uint32_t low_order = m_local_regs[dstf_code];
|
||||
|
||||
uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
|
||||
|
||||
uint64_t val = concat_64(high_order, low_order);
|
||||
SET_C( (n)?(((val<<(n-1))&0x8000000000000000U)?1:0):0);
|
||||
uint32_t tmp = high_order << n;
|
||||
|
||||
if (((high_order & mask) && (!(tmp & 0x80000000))) || (((high_order & mask) ^ mask) && (tmp & 0x80000000)))
|
||||
SET_V(1);
|
||||
else
|
||||
SR &= ~V_MASK;
|
||||
|
||||
val <<= n;
|
||||
|
||||
m_local_regs[dst_code] = extract_64hi(val);
|
||||
m_local_regs[dstf_code] = extract_64lo(val);
|
||||
|
||||
SET_Z(val == 0 ? 1 : 0);
|
||||
SET_N(SIGN_BIT(high_order));
|
||||
}
|
||||
|
||||
m_icount -= m_clock_cycles_2;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_shl()
|
||||
{
|
||||
check_delay_PC();
|
||||
|
||||
uint32_t src_code = SRC_CODE + GET_FP;
|
||||
uint32_t dst_code = DST_CODE + GET_FP;
|
||||
|
||||
uint32_t n = m_local_regs[src_code % 64] & 0x1f;
|
||||
uint32_t base = m_local_regs[dst_code % 64]; /* registers offset by frame pointer */
|
||||
uint64_t mask = ((((uint64_t)1) << (32 - n)) - 1) ^ 0xffffffff;
|
||||
SET_C( (n)?(((base<<(n-1))&0x80000000)?1:0):0);
|
||||
uint32_t ret = base << n;
|
||||
|
||||
if (((base & mask) && (!(ret & 0x80000000))) || (((base & mask) ^ mask) && (ret & 0x80000000)))
|
||||
SET_V(1);
|
||||
else
|
||||
SR &= ~V_MASK;
|
||||
|
||||
m_local_regs[dst_code % 64] = ret;
|
||||
SET_Z(ret == 0 ? 1 : 0);
|
||||
SET_N(SIGN_BIT(ret));
|
||||
|
||||
m_icount -= m_clock_cycles_1;
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_testlz()
|
||||
{
|
||||
check_delay_PC();
|
||||
|
Loading…
Reference in New Issue
Block a user