mirror of
https://github.com/holub/mame
synced 2025-04-09 18:17:44 +03:00
-cpu/e132xs: Miscellaneous fixes/optimisation:
* Fixed behaviour of delayed branches, trace exceptions, and saved PC
calculation for error exceptions in delay slots for the interpreter.
All instructions in delay slots, branching instructions that can raise
exceptions and tracing shoud now (mis)behave properly for the
interpreter, including things the manual says you shouldn't do.
* Fixed and optimised flag updates for left shifts for the recompiler.
* Optimised ROL instruction for the recompiler and made flag calculation
equivalent to the interpreter both with and without the "Missioncraft
flags" compile-time option.
* Only block interrupts for one instruction following a delayed branch.
* Optimised the SOFTWARE instruction a little for the recompiler.
* Added more SDRAM configuration logging and cleaned up code a bit.
-cpu/drcbearm64.cpp: Apply the change from 7efe37938f
to OR and
XOR instructions as well, and fix some cases where a 32-bit logical
operation would fail to clear the upper bits of a register.
-cpu/drcbex64.cpp: Avoid more conditional branches on conditional MOV.
This commit is contained in:
parent
9349b16a17
commit
436431d99b
@ -4091,6 +4091,7 @@ void drcbe_arm64::op_and(a64::Assembler &a, const uml::instruction &inst)
|
||||
}
|
||||
|
||||
const a64::Gp dst = dstp.select_register(TEMP_REG3, inst.size());
|
||||
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
||||
|
||||
if (src1p.is_immediate_value(0) || src2p.is_immediate_value(0))
|
||||
{
|
||||
@ -4108,21 +4109,33 @@ void drcbe_arm64::op_and(a64::Assembler &a, const uml::instruction &inst)
|
||||
}
|
||||
else if (src2p.is_immediate() && is_valid_immediate_mask(src2p.immediate(), inst.size()))
|
||||
{
|
||||
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
|
||||
a.emit(opcode, dst, src1, src2p.immediate());
|
||||
}
|
||||
else if ((inst.size() == 8) && src2p.is_immediate() && is_valid_immediate_mask(src2p.immediate(), 4) && (!inst.flags() || !BIT(src2p.immediate(), 31)))
|
||||
{
|
||||
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
|
||||
a.emit(opcode, dst.w(), src1.w(), src2p.immediate());
|
||||
}
|
||||
else if (src2p.is_immediate_value(util::make_bitmask<uint64_t>(inst.size() * 8)) || (src1p == src2p))
|
||||
{
|
||||
if ((dstp == src1p) && !inst.flags())
|
||||
{
|
||||
if ((inst.size() == 8) || (dstp.is_memory() && !dstp.is_cold_register()))
|
||||
return;
|
||||
}
|
||||
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
|
||||
if ((dst.id() != src1.id()) || ((inst.size() == 4) && (dstp == src1p) && dstp.is_int_register()))
|
||||
a.emit(opcode, dst, src1, src1);
|
||||
else if (inst.flags())
|
||||
a.tst(dst, dst);
|
||||
}
|
||||
else
|
||||
{
|
||||
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
||||
const a64::Gp src2 = src2p.select_register(TEMP_REG1, inst.size());
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
mov_reg_param(a, inst.size(), src2, src2p);
|
||||
@ -4194,35 +4207,45 @@ void drcbe_arm64::op_or(a64::Assembler &a, const uml::instruction &inst)
|
||||
be_parameter src1p(*this, inst.param(1), PTYPE_MRI);
|
||||
be_parameter src2p(*this, inst.param(2), PTYPE_MRI);
|
||||
|
||||
const a64::Gp src1 = src1p.select_register(TEMP_REG1, inst.size());
|
||||
const a64::Gp src2 = src2p.select_register(TEMP_REG2, inst.size());
|
||||
if (src1p.is_immediate() || (dstp.is_int_register() && (dstp == src2p)))
|
||||
{
|
||||
using std::swap;
|
||||
swap(src1p, src2p);
|
||||
}
|
||||
|
||||
const a64::Gp dst = dstp.select_register(TEMP_REG3, inst.size());
|
||||
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
||||
|
||||
if (src1p.is_immediate() && src2p.is_immediate())
|
||||
{
|
||||
get_imm_relative(a, dst, src1p.immediate() | src2p.immediate());
|
||||
}
|
||||
else if (src2p.is_immediate() && is_valid_immediate_mask(src2p.immediate(), inst.size()))
|
||||
else if (src2p.is_immediate_value(util::make_bitmask<uint64_t>(inst.size() * 8)))
|
||||
{
|
||||
a.mov(dst, src2p.immediate());
|
||||
}
|
||||
else if (src2p.is_immediate_value(0) || (src1p == src2p))
|
||||
{
|
||||
if ((dstp == src1p) && !inst.flags())
|
||||
{
|
||||
if ((inst.size() == 8) || (dstp.is_memory() && !dstp.is_cold_register()))
|
||||
return;
|
||||
}
|
||||
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
|
||||
if ((dst.id() != src1.id()) || ((inst.size() == 4) && (dstp == src1p) && dstp.is_int_register()))
|
||||
a.mov(dst, src1);
|
||||
}
|
||||
else if (src2p.is_immediate() && is_valid_immediate(src2p.immediate(), 12))
|
||||
{
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
|
||||
if (src2p.is_immediate_value(0))
|
||||
{
|
||||
if (dst.id() != src1.id())
|
||||
a.mov(dst, src1);
|
||||
}
|
||||
else if (is_valid_immediate(src2p.immediate(), 12))
|
||||
{
|
||||
a.orr(dst, src1, src2p.immediate());
|
||||
}
|
||||
else
|
||||
{
|
||||
a.mov(SCRATCH_REG1, src2p.immediate());
|
||||
a.orr(dst, src1, select_register(SCRATCH_REG1, inst.size()));
|
||||
}
|
||||
a.orr(dst, src1, src2p.immediate());
|
||||
}
|
||||
else
|
||||
{
|
||||
const a64::Gp src2 = src2p.select_register(TEMP_REG1, inst.size());
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
mov_reg_param(a, inst.size(), src2, src2p);
|
||||
|
||||
@ -4248,30 +4271,51 @@ void drcbe_arm64::op_xor(a64::Assembler &a, const uml::instruction &inst)
|
||||
be_parameter src1p(*this, inst.param(1), PTYPE_MRI);
|
||||
be_parameter src2p(*this, inst.param(2), PTYPE_MRI);
|
||||
|
||||
const a64::Gp src1 = src1p.select_register(TEMP_REG1, inst.size());
|
||||
const a64::Gp src2 = src2p.select_register(TEMP_REG2, inst.size());
|
||||
if (src1p.is_immediate() || (dstp.is_int_register() && (dstp == src2p)))
|
||||
{
|
||||
using std::swap;
|
||||
swap(src1p, src2p);
|
||||
}
|
||||
|
||||
const a64::Gp dst = dstp.select_register(TEMP_REG3, inst.size());
|
||||
const a64::Gp src1 = src1p.select_register(dst, inst.size());
|
||||
|
||||
if (src1p.is_immediate() && src2p.is_immediate())
|
||||
{
|
||||
get_imm_relative(a, dst, src1p.immediate() ^ src2p.immediate());
|
||||
}
|
||||
else if (src2p.is_immediate() && is_valid_immediate_mask(src2p.immediate(), inst.size()))
|
||||
else if (src2p.is_immediate_value(0))
|
||||
{
|
||||
if ((dstp == src1p) && !inst.flags())
|
||||
{
|
||||
if ((inst.size() == 8) || (dstp.is_memory() && !dstp.is_cold_register()))
|
||||
return;
|
||||
}
|
||||
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
|
||||
if ((dst.id() != src1.id()) || ((inst.size() == 4) && (dstp == src1p) && dstp.is_int_register()))
|
||||
a.mov(dst, src1);
|
||||
}
|
||||
else if (src2p.is_immediate_value(util::make_bitmask<uint64_t>(inst.size() * 8)))
|
||||
{
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
|
||||
if (src2p.is_immediate_value(0))
|
||||
{
|
||||
if (dst.id() != src1.id())
|
||||
a.mov(dst, src1);
|
||||
}
|
||||
else
|
||||
{
|
||||
a.eor(dst, src1, src2p.immediate());
|
||||
}
|
||||
a.mvn(dst, src1);
|
||||
}
|
||||
else (src2p.is_immediate() && is_valid_immediate_mask(src2p.immediate()))
|
||||
{
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
|
||||
a.eor(dst, src1, src2p.immediate());
|
||||
}
|
||||
else if (src1p == src2p)
|
||||
{
|
||||
a.mov(dst, select_register(a64::xzr, inst.size()));
|
||||
}
|
||||
else
|
||||
{
|
||||
const a64::Gp src2 = src2p.select_register(TEMP_REG1, inst.size());
|
||||
mov_reg_param(a, inst.size(), src1, src1p);
|
||||
mov_reg_param(a, inst.size(), src2, src2p);
|
||||
|
||||
|
@ -3661,26 +3661,28 @@ void drcbe_x64::op_mov(Assembler &a, const instruction &inst)
|
||||
|
||||
// add a conditional branch unless a conditional move is possible
|
||||
Label skip;
|
||||
if (inst.condition() != uml::COND_ALWAYS && !(dstp.is_int_register() && !srcp.is_immediate()))
|
||||
const bool need_skip = (inst.condition() != uml::COND_ALWAYS) && !dstp.is_int_register();
|
||||
if (need_skip)
|
||||
{
|
||||
skip = a.newLabel();
|
||||
a.short_().j(X86_NOT_CONDITION(inst.condition()), skip);
|
||||
}
|
||||
|
||||
// register to memory
|
||||
if (dstp.is_memory() && srcp.is_int_register())
|
||||
{
|
||||
// register to memory
|
||||
Gp const src = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, srcp.ireg());
|
||||
|
||||
a.mov(MABS(dstp.memory()), src);
|
||||
}
|
||||
// immediate to memory
|
||||
else if (dstp.is_memory() && srcp.is_immediate() && short_immediate(srcp.immediate()))
|
||||
{
|
||||
// immediate to memory
|
||||
a.mov(MABS(dstp.memory(), inst.size()), s32(srcp.immediate()));
|
||||
|
||||
// conditional memory to register
|
||||
}
|
||||
else if (dstp.is_int_register() && srcp.is_memory())
|
||||
{
|
||||
// conditional memory to register
|
||||
Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg());
|
||||
|
||||
if (inst.condition() != uml::COND_ALWAYS)
|
||||
@ -3688,30 +3690,41 @@ void drcbe_x64::op_mov(Assembler &a, const instruction &inst)
|
||||
else
|
||||
a.mov(dst, MABS(srcp.memory()));
|
||||
}
|
||||
|
||||
// conditional register to register
|
||||
else if (dstp.is_int_register() && srcp.is_int_register())
|
||||
else if (dstp.is_int_register())
|
||||
{
|
||||
Gp const src = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, srcp.ireg());
|
||||
// conditional register to register
|
||||
Gp const dst = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, dstp.ireg());
|
||||
|
||||
if (inst.condition() != uml::COND_ALWAYS)
|
||||
a.cmov(X86_CONDITION(inst.condition()), dst, src);
|
||||
{
|
||||
if (srcp.is_int_register())
|
||||
{
|
||||
Gp const src = Gp::fromTypeAndId((inst.size() == 4) ? RegType::kX86_Gpd : RegType::kX86_Gpq, srcp.ireg());
|
||||
a.cmov(X86_CONDITION(inst.condition()), dst, src);
|
||||
}
|
||||
else
|
||||
{
|
||||
Gp const src = (inst.size() == 4) ? Gp(eax) : Gp(rax);
|
||||
mov_reg_param(a, src, srcp, true);
|
||||
a.cmov(X86_CONDITION(inst.condition()), dst, src);
|
||||
}
|
||||
}
|
||||
else
|
||||
a.mov(dst, src);
|
||||
{
|
||||
mov_reg_param(a, dst, srcp, true);
|
||||
}
|
||||
}
|
||||
|
||||
// general case
|
||||
else
|
||||
{
|
||||
Gp dstreg = (inst.size() == 4) ? dstp.select_register(eax) : dstp.select_register(rax);
|
||||
// general case
|
||||
Gp const dstreg = (inst.size() == 4) ? dstp.select_register(eax) : dstp.select_register(rax);
|
||||
|
||||
mov_reg_param(a, dstreg, srcp, true);
|
||||
mov_param_reg(a, dstp, dstreg);
|
||||
}
|
||||
|
||||
// resolve the jump
|
||||
if (inst.condition() != uml::COND_ALWAYS && !(dstp.is_int_register() && !srcp.is_immediate()))
|
||||
if (need_skip)
|
||||
a.bind(skip);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
TODO:
|
||||
- All instructions should clear the H flag (not just MOV/MOVI)
|
||||
- Fix behaviour of branches in delay slots
|
||||
- Fix behaviour of branches in delay slots for recompiler
|
||||
- Many wrong cycle counts
|
||||
- Prevent reading write-only BCR, TPR, FCR and MCR
|
||||
- IRAM selection should happen before EA calculation
|
||||
@ -40,7 +40,7 @@
|
||||
- Should a zero bit shift clear C or leave it unchanged?
|
||||
- What actually happens on trying to load to PC, SR, G14 or G15?
|
||||
- Verify register wrapping with sregf/dregf on hardware
|
||||
- Tracing doesn't work properly
|
||||
- Tracing doesn't work properly for the recompiler
|
||||
DRC does not generate trace exceptions on branch or return
|
||||
|
||||
*********************************************************************/
|
||||
@ -453,7 +453,7 @@ void hyperstone_device::update_memory_control()
|
||||
const uint32_t val = m_core->global_regs[MCR_REGISTER];
|
||||
|
||||
static char const *const entrymap[8] = { "MEM0", "MEM1", "MEM2", "IRAM", "reserved", "reserved", "reserved", "MEM3" };
|
||||
LOG("%s: Set MCR = 0x%08x entry map in %s\n",
|
||||
LOG("%s: Set MCR = 0x%08x, entry map in %s\n",
|
||||
machine().describe_context(),
|
||||
val,
|
||||
entrymap[BIT(val, 12, 3)]);
|
||||
@ -472,7 +472,7 @@ void hyperstone_device::update_memory_control()
|
||||
static char const *const dramtype[4] = { "S", "S", "EDO ", "fast page " };
|
||||
LOG("MEM0 %s %sDRAM, hold time %s, parity %s\n",
|
||||
size[BIT(val, 0, 2)], // MEM0 bus size
|
||||
dramtype[bitswap<2>(val, 15, 22)], // MEM0 DRAM type
|
||||
dramtype[bitswap<2>(val, 22, 15)], // MEM0 DRAM type
|
||||
BIT(val, 8) ? "1 cycle" : "0 cycles", // MEM0 bus hold
|
||||
BIT(val, 28) ? "disabled" : "enabled", // MEM0 parity
|
||||
BIT(val, 15) ? "strobe" : "enable"); // MEM0 byte mode
|
||||
@ -493,6 +493,13 @@ void hyperstone_device::update_memory_control()
|
||||
BIT(val, 11) ? "disabled" : "enabled", // MEM3 bus hold break
|
||||
BIT(val, 31) ? "disabled" : "enabled"); // MEM3 parity
|
||||
|
||||
// install SDRAM mode and control handlers if appropriate
|
||||
if (!BIT(val, 21) && !BIT(val, 22))
|
||||
{
|
||||
m_program->unmap_read(0x20000000, 0x3fffffff);
|
||||
m_program->install_write_handler(0x20000000, 0x2fffffff, emu::rw_delegate(*this, FUNC(hyperstone_device::sdram_mode_w)));
|
||||
m_program->install_write_handler(0x30000000, 0x3fffffff, emu::rw_delegate(*this, FUNC(hyperstone_device::sdram_control_w)));
|
||||
}
|
||||
|
||||
// bits 14..12 EntryTableMap
|
||||
const int which = (val & 0x7000) >> 12;
|
||||
@ -500,6 +507,24 @@ void hyperstone_device::update_memory_control()
|
||||
m_core->trap_entry = s_trap_entries[which];
|
||||
}
|
||||
|
||||
void hyperstone_device::sdram_mode_w(offs_t offset, uint32_t data)
|
||||
{
|
||||
// writes to mode register of the connected SDRAM
|
||||
LOG("%s: set SDRAM mode = 0x%07x\n", machine().describe_context(), offset);
|
||||
}
|
||||
|
||||
void hyperstone_device::sdram_control_w(offs_t offset, uint32_t data)
|
||||
{
|
||||
const uint32_t val = offset << 2;
|
||||
LOG("%s: set SDCR = 0x%08x\n", machine().describe_context(), val);
|
||||
LOG("MEM0 SDRAM bank bits 0x%08x, second SDRAM chip select CS#1 %s, A%u selects CS#0/CS#1, CAS latency %s, SDCLK CPU clock%s\n",
|
||||
BIT(val, 12, 9) << 20,
|
||||
BIT(val, 11) ? "disabled" : "enabled",
|
||||
BIT(val, 8, 3) + 21,
|
||||
BIT(val, 6) ? "2 clock cycles" : "1 clock cycle",
|
||||
BIT(val, 3) ? " / 2" : "");
|
||||
}
|
||||
|
||||
TIMER_CALLBACK_MEMBER( hyperstone_device::timer_callback )
|
||||
{
|
||||
int update = param;
|
||||
@ -671,26 +696,27 @@ void hyperstone_device::set_global_register(uint8_t code, uint32_t val)
|
||||
|
||||
constexpr uint32_t WRITE_ONLY_REGMASK = (1 << BCR_REGISTER) | (1 << TPR_REGISTER) | (1 << FCR_REGISTER) | (1 << MCR_REGISTER);
|
||||
|
||||
#define check_delay_PC() \
|
||||
do \
|
||||
{ \
|
||||
/* if PC is used in a delay instruction, the delayed PC should be used */ \
|
||||
if (m_core->delay_slot) \
|
||||
{ \
|
||||
using std::swap; \
|
||||
swap(PC, m_core->delay_pc); \
|
||||
m_core->delay_slot = 0; \
|
||||
m_core->delay_slot_taken = 1; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
m_core->delay_slot_taken = 0; \
|
||||
} \
|
||||
} while (0)
|
||||
inline ATTR_FORCE_INLINE void hyperstone_device::check_delay_pc()
|
||||
{
|
||||
// if PC is used in a delay instruction, the delayed PC should be used
|
||||
if (!m_core->delay_slot)
|
||||
{
|
||||
m_core->delay_slot_taken = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
using std::swap;
|
||||
swap(PC, m_core->delay_pc);
|
||||
m_core->delay_slot = 0;
|
||||
m_core->delay_slot_taken = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::ignore_immediate_s()
|
||||
{
|
||||
static const uint32_t lengths[16] = { 1<<19, 3<<19, 2<<19, 2<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19, 1<<19 };
|
||||
static const uint32_t lengths[16] = {
|
||||
1 << ILC_SHIFT, 3 << ILC_SHIFT, 2 << ILC_SHIFT, 2 << ILC_SHIFT, 1 << ILC_SHIFT, 1 << ILC_SHIFT, 1 << ILC_SHIFT, 1 << ILC_SHIFT,
|
||||
1 << ILC_SHIFT, 1 << ILC_SHIFT, 1 << ILC_SHIFT, 1 << ILC_SHIFT, 1 << ILC_SHIFT, 1 << ILC_SHIFT, 1 << ILC_SHIFT, 1 << ILC_SHIFT };
|
||||
static const uint32_t offsets[16] = { 0, 4, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
const uint8_t nybble = m_op & 0x0f;
|
||||
m_instruction_length = lengths[nybble];
|
||||
@ -706,21 +732,21 @@ uint32_t hyperstone_device::decode_immediate_s()
|
||||
return 16;
|
||||
case 1:
|
||||
{
|
||||
m_instruction_length = (3<<19);
|
||||
m_instruction_length = 3 << ILC_SHIFT;
|
||||
uint32_t extra_u = (m_pr16(PC) << 16) | m_pr16(PC + 2);
|
||||
PC += 4;
|
||||
return extra_u;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
m_instruction_length = (2<<19);
|
||||
m_instruction_length = 2 << ILC_SHIFT;
|
||||
uint32_t extra_u = m_pr16(PC);
|
||||
PC += 2;
|
||||
return extra_u;
|
||||
}
|
||||
case 3:
|
||||
{
|
||||
m_instruction_length = (2<<19);
|
||||
m_instruction_length = 2 << ILC_SHIFT;
|
||||
uint32_t extra_u = 0xffff0000 | m_pr16(PC);
|
||||
PC += 2;
|
||||
return extra_u;
|
||||
@ -741,7 +767,7 @@ uint32_t hyperstone_device::decode_const()
|
||||
const uint16_t imm_2 = m_pr16(PC);
|
||||
|
||||
PC += 2;
|
||||
m_instruction_length = (3<<19);
|
||||
m_instruction_length = 3 << ILC_SHIFT;
|
||||
|
||||
uint32_t imm = imm_2;
|
||||
imm |= ((imm_1 & 0x3fff) << 16);
|
||||
@ -752,7 +778,7 @@ uint32_t hyperstone_device::decode_const()
|
||||
}
|
||||
else
|
||||
{
|
||||
m_instruction_length = (2<<19);
|
||||
m_instruction_length = 2 << ILC_SHIFT;
|
||||
|
||||
uint32_t imm = imm_1 & 0x3fff;
|
||||
|
||||
@ -769,7 +795,7 @@ int32_t hyperstone_device::decode_pcrel()
|
||||
uint16_t next = m_pr16(PC);
|
||||
|
||||
PC += 2;
|
||||
m_instruction_length = (2<<19);
|
||||
m_instruction_length = 2 << ILC_SHIFT;
|
||||
|
||||
int32_t offset = (OP & 0x7f) << 16;
|
||||
offset |= (next & 0xfffe);
|
||||
@ -790,26 +816,15 @@ int32_t hyperstone_device::decode_pcrel()
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::ignore_pcrel()
|
||||
inline void hyperstone_device::ignore_pcrel()
|
||||
{
|
||||
if (m_op & 0x80)
|
||||
{
|
||||
PC += 2;
|
||||
m_instruction_length = (2<<19);
|
||||
m_instruction_length = 2 << ILC_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_br()
|
||||
{
|
||||
const int32_t offset = decode_pcrel();
|
||||
check_delay_PC();
|
||||
|
||||
PC += offset;
|
||||
SR &= ~M_MASK;
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_2;
|
||||
}
|
||||
|
||||
void hyperstone_device::execute_trap(uint8_t trapno)
|
||||
{
|
||||
debugger_exception_hook(int(unsigned(trapno)));
|
||||
@ -864,7 +879,7 @@ void hyperstone_device::execute_exception(uint8_t trapno)
|
||||
if (!m_core->delay_slot_taken)
|
||||
SET_ILC(m_instruction_length);
|
||||
else
|
||||
PC = m_core->delay_pc;
|
||||
PC = m_core->delay_pc - (m_instruction_length >> ILC_SHIFT);
|
||||
|
||||
// RET does not automatically set P
|
||||
if (((m_op & 0xfef0) != 0x0400) || !(m_op & 0x010e))
|
||||
@ -888,14 +903,14 @@ void hyperstone_device::execute_exception(uint8_t trapno)
|
||||
|
||||
void hyperstone_device::execute_software()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SRC_CODE;
|
||||
const uint32_t sreg = m_core->local_regs[(src_code + fp) & 0x3f];
|
||||
const uint32_t sregf = m_core->local_regs[(src_code + 1 + fp) & 0x3f];
|
||||
|
||||
SET_ILC(1<<19);
|
||||
SET_ILC(1 << ILC_SHIFT);
|
||||
|
||||
const uint32_t addr = get_emu_code_addr((m_op & 0xff00) >> 8);
|
||||
const uint8_t reg = fp + GET_FL;
|
||||
@ -943,7 +958,7 @@ void hyperstone_device::execute_software()
|
||||
#define IO2_LINE_STATE (ISR & 0x20)
|
||||
#define IO3_LINE_STATE (ISR & 0x40)
|
||||
|
||||
template <hyperstone_device::is_timer TIMER>
|
||||
template <hyperstone_device::is_timer Timer>
|
||||
void hyperstone_device::check_interrupts()
|
||||
{
|
||||
// Interrupt-Lock flag isn't set
|
||||
@ -951,7 +966,7 @@ void hyperstone_device::check_interrupts()
|
||||
return;
|
||||
|
||||
// quick exit if nothing
|
||||
if (TIMER == NO_TIMER && (ISR & 0x7f) == 0)
|
||||
if (Timer == NO_TIMER && (ISR & 0x7f) == 0)
|
||||
return;
|
||||
|
||||
// IO3 is priority 5; state is in bit 6 of ISR; FCR bit 10 enables input and FCR bit 8 inhibits interrupt
|
||||
@ -963,7 +978,7 @@ void hyperstone_device::check_interrupts()
|
||||
}
|
||||
|
||||
// timer int might be priority 6 if FCR bits 20-21 == 3; FCR bit 23 inhibits interrupt
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00300000)
|
||||
if (Timer && (FCR & 0x00b00000) == 0x00300000)
|
||||
{
|
||||
m_core->timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
@ -979,7 +994,7 @@ void hyperstone_device::check_interrupts()
|
||||
}
|
||||
|
||||
// timer int might be priority 8 if FCR bits 20-21 == 2; FCR bit 23 inhibits interrupt
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00200000)
|
||||
if (Timer && (FCR & 0x00b00000) == 0x00200000)
|
||||
{
|
||||
m_core->timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
@ -995,7 +1010,7 @@ void hyperstone_device::check_interrupts()
|
||||
}
|
||||
|
||||
// timer int might be priority 10 if FCR bits 20-21 == 1; FCR bit 23 inhibits interrupt
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00100000)
|
||||
if (Timer && (FCR & 0x00b00000) == 0x00100000)
|
||||
{
|
||||
m_core->timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
@ -1011,7 +1026,7 @@ void hyperstone_device::check_interrupts()
|
||||
}
|
||||
|
||||
// timer int might be priority 12 if FCR bits 20-21 == 0; FCR bit 23 inhibits interrupt
|
||||
if (TIMER && (FCR & 0x00b00000) == 0x00000000)
|
||||
if (Timer && (FCR & 0x00b00000) == 0x00000000)
|
||||
{
|
||||
m_core->timer_int_pending = 0;
|
||||
execute_int(get_trap_addr(TRAPNO_TIMER));
|
||||
@ -1323,8 +1338,10 @@ void hyperstone_device::device_reset()
|
||||
|
||||
m_core->trap_entry = s_trap_entries[E132XS_ENTRY_MEM3]; // default entry point @ MEM3
|
||||
|
||||
set_global_register(BCR_REGISTER, ~uint32_t(0));
|
||||
set_global_register(MCR_REGISTER, ~uint32_t(0));
|
||||
m_core->global_regs[BCR_REGISTER] = ~uint32_t(0);
|
||||
m_core->global_regs[MCR_REGISTER] = ~uint32_t(0);
|
||||
update_bus_control();
|
||||
update_memory_control();
|
||||
set_global_register(FCR_REGISTER, ~uint32_t(0));
|
||||
set_global_register(TPR_REGISTER, 0xc000000);
|
||||
|
||||
@ -1337,7 +1354,7 @@ void hyperstone_device::device_reset()
|
||||
SET_T(0);
|
||||
SET_L(1);
|
||||
SET_S(1);
|
||||
SET_ILC(1<<19);
|
||||
SET_ILC(1 << ILC_SHIFT);
|
||||
|
||||
set_local_register(0, (PC & 0xfffffffe) | GET_S);
|
||||
set_local_register(1, SR);
|
||||
@ -1492,7 +1509,7 @@ void hyperstone_device::hyperstone_trap()
|
||||
false, false, false, false, true, false, true, false, true, false, true, false, true, false, true, false
|
||||
};
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint8_t trapno = (m_op & 0xfc) >> 2;
|
||||
const uint8_t code = ((m_op & 0x300) >> 6) | (m_op & 0x03);
|
||||
@ -1910,7 +1927,10 @@ void hyperstone_device::execute_run()
|
||||
}
|
||||
|
||||
if (GET_T && GET_P && !m_core->delay_slot) /* Not in a Delayed Branch instructions */
|
||||
{
|
||||
m_core->delay_slot_taken = 0;
|
||||
execute_exception(TRAPNO_TRACE_EXCEPTION);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -261,6 +261,9 @@ protected:
|
||||
void update_bus_control();
|
||||
void update_memory_control();
|
||||
|
||||
void sdram_mode_w(offs_t offset, uint32_t data);
|
||||
void sdram_control_w(offs_t offset, uint32_t data);
|
||||
|
||||
void e116_16k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e116_4k_iram_map(address_map &map) ATTR_COLD;
|
||||
void e116_8k_iram_map(address_map &map) ATTR_COLD;
|
||||
@ -299,7 +302,7 @@ protected:
|
||||
|
||||
private:
|
||||
// internal functions
|
||||
template <hyperstone_device::is_timer TIMER> void check_interrupts();
|
||||
template <hyperstone_device::is_timer Timer> void check_interrupts();
|
||||
|
||||
void set_global_register(uint8_t code, uint32_t val);
|
||||
void set_local_register(uint8_t code, uint32_t val);
|
||||
@ -315,6 +318,7 @@ private:
|
||||
|
||||
TIMER_CALLBACK_MEMBER(timer_callback);
|
||||
|
||||
void check_delay_pc();
|
||||
uint32_t decode_const();
|
||||
uint32_t decode_immediate_s();
|
||||
void ignore_immediate_s();
|
||||
|
@ -733,39 +733,27 @@ void hyperstone_device::generate_software(drcuml_block &block, compiler_state &c
|
||||
|
||||
const uint16_t op = desc->opptr.w[0];
|
||||
|
||||
const uint32_t num = op >> 8;
|
||||
const uint32_t src_code = op & 0xf;
|
||||
const uint32_t srcf_code = src_code + 1;
|
||||
const uint32_t dst_code = (op & 0xf0) >> 4;
|
||||
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f); // I3 = FP
|
||||
UML_MOV(block, I2, DRC_SR);
|
||||
UML_ROLAND(block, I3, I2, 32 - FP_SHIFT, 0x7f); // I3 = FP
|
||||
|
||||
UML_ADD(block, I2, I3, src_code);
|
||||
UML_AND(block, I4, I2, 0x3f);
|
||||
UML_LOAD(block, I0, (void *)m_core->local_regs, I4, SIZE_DWORD, SCALE_x4); // I0 = sreg
|
||||
UML_ADD(block, I2, I3, srcf_code);
|
||||
UML_AND(block, I4, I2, 0x3f);
|
||||
UML_LOAD(block, I1, (void *)m_core->local_regs, I4, SIZE_DWORD, SCALE_x4); // I1 = sregf
|
||||
UML_ADD(block, I1, I3, src_code);
|
||||
UML_AND(block, I1, I1, 0x3f);
|
||||
UML_LOAD(block, I0, (void *)m_core->local_regs, I1, SIZE_DWORD, SCALE_x4); // I0 = sreg
|
||||
UML_ADD(block, I1, I1, 1);
|
||||
UML_AND(block, I1, I1, 0x3f);
|
||||
UML_LOAD(block, I1, (void *)m_core->local_regs, I1, SIZE_DWORD, SCALE_x4); // I1 = sregf
|
||||
|
||||
UML_ROLINS(block, DRC_SR, 1, ILC_SHIFT, ILC_MASK);
|
||||
UML_AND(block, I2, I2, ~ILC_MASK);
|
||||
UML_OR(block, I2, I2, 1 << ILC_SHIFT);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
uint32_t num = op >> 8;
|
||||
int mem3 = compiler.next_label();
|
||||
int have_code_addr = compiler.next_label();
|
||||
UML_MOV(block, I4, mem(&m_core->trap_entry));
|
||||
UML_CMP(block, I4, 0xffffff00);
|
||||
UML_JMPc(block, uml::COND_E, mem3);
|
||||
UML_OR(block, I5, I4, (0x10c | ((0xcf - num) << 4)));
|
||||
UML_JMP(block, have_code_addr);
|
||||
|
||||
UML_LABEL(block, mem3);
|
||||
UML_SUB(block, I5, I4, 0x100);
|
||||
UML_OR(block, I5, I5, ((num & 0xf) << 4)); // I5 = addr
|
||||
|
||||
UML_LABEL(block, have_code_addr);
|
||||
|
||||
UML_ROLAND(block, I2, DRC_SR, 32 - FL_SHIFT, 0xf);
|
||||
UML_MOVc(block, uml::COND_Z, I2, 16);
|
||||
UML_ADD(block, I4, I2, I3); // I4 = reg
|
||||
UML_ROLAND(block, I4, I2, 32 - FL_SHIFT, 0xf);
|
||||
UML_MOVc(block, uml::COND_Z, I4, 16);
|
||||
UML_ADD(block, I4, I4, I3); // I4 = reg
|
||||
|
||||
UML_AND(block, I2, mem(&SP), 0xffffff00);
|
||||
UML_ADD(block, I6, I2, 0x100); // I6 = (SP & ~0xff) + 0x100
|
||||
@ -776,31 +764,44 @@ void hyperstone_device::generate_software(drcuml_block &block, compiler_state &c
|
||||
|
||||
UML_AND(block, I2, I4, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, I6, SIZE_DWORD, SCALE_x4); // m_core->local_regs[(reg + 0) & 0x3f] = stack_of_dst;
|
||||
UML_ADD(block, I6, I2, 1);
|
||||
UML_AND(block, I2, I6, 0x3f);
|
||||
UML_ADD(block, I2, I2, 1);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, I0, SIZE_DWORD, SCALE_x4); // m_core->local_regs[(reg + 1) & 0x3f] = sreg;
|
||||
UML_ADD(block, I6, I2, 1);
|
||||
UML_AND(block, I2, I6, 0x3f);
|
||||
UML_ADD(block, I2, I2, 1);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, I1, SIZE_DWORD, SCALE_x4); // m_core->local_regs[(reg + 2) & 0x3f] = sregf;
|
||||
|
||||
UML_AND(block, I0, DRC_PC, ~uint32_t(1));
|
||||
UML_ROLINS(block, I0, DRC_SR, 32 - S_SHIFT, 1);
|
||||
UML_ADD(block, I6, I2, 1);
|
||||
UML_AND(block, I2, I6, 0x3f);
|
||||
UML_ADD(block, I2, I2, 1);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, I0, SIZE_DWORD, SCALE_x4); // m_core->local_regs[(reg + 3) & 0x3f] = (PC & ~1) | GET_S;
|
||||
|
||||
UML_ADD(block, I6, I2, 1);
|
||||
UML_AND(block, I2, I6, 0x3f);
|
||||
UML_ADD(block, I2, I2, 1);
|
||||
UML_AND(block, I2, I2, 0x3f);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I2, DRC_SR, SIZE_DWORD, SCALE_x4); // m_core->local_regs[(reg + 4) & 0x3f] = oldSR;
|
||||
|
||||
UML_MOV(block, DRC_PC, I5); // PC = addr
|
||||
const int mem3 = compiler.next_label();
|
||||
const int have_code_addr = compiler.next_label();
|
||||
UML_MOV(block, I1, mem(&m_core->trap_entry));
|
||||
UML_CMP(block, I1, 0xffffff00);
|
||||
UML_JMPc(block, uml::COND_E, mem3);
|
||||
UML_OR(block, I1, I1, (0x10c | ((0xcf - num) << 4)));
|
||||
UML_JMP(block, have_code_addr);
|
||||
|
||||
UML_LABEL(block, mem3);
|
||||
UML_SUB(block, I1, I1, 0x100);
|
||||
UML_OR(block, I1, I1, ((num & 0xf) << 4));
|
||||
|
||||
UML_LABEL(block, have_code_addr);
|
||||
UML_MOV(block, DRC_PC, I1); // PC = addr
|
||||
|
||||
UML_MOV(block, I0, DRC_SR);
|
||||
UML_ROLINS(block, I0, (6 << FL_SHIFT) | L_MASK, 0, FL_MASK | T_MASK | L_MASK | M_MASK); // FL = 6, T = 0, L = 1, M = 0
|
||||
UML_ROLINS(block, I0, I4, FP_SHIFT, FP_MASK); // SET_FP(reg)
|
||||
UML_MOV(block, DRC_SR, I0);
|
||||
|
||||
generate_branch(block, compiler, compiler.mode() & 0x1, uml::I5, desc); // T cleared - only keep S in bit zero of mode
|
||||
generate_branch(block, compiler, compiler.mode() & 0x1, uml::I1, desc); // T cleared - only keep S in bit zero of mode
|
||||
}
|
||||
|
||||
|
||||
@ -2412,7 +2413,7 @@ void hyperstone_device::generate_shldi(drcuml_block &block, compiler_state &comp
|
||||
generate_load_operand(block, compiler, LOCAL, dst_code, uml::I1, uml::I4);
|
||||
generate_load_operand(block, compiler, LOCAL, dst_code + 1, uml::I0, uml::I5);
|
||||
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK));
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK | V_MASK));
|
||||
if (n)
|
||||
UML_SHR(block, I3, I1, 32 - n);
|
||||
|
||||
@ -2472,7 +2473,7 @@ void hyperstone_device::generate_shld(drcuml_block &block, compiler_state &compi
|
||||
generate_load_operand(block, compiler, LOCAL, src_code, uml::I1, uml::I3);
|
||||
|
||||
const int no_shift = compiler.next_label();
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK));
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK | V_MASK));
|
||||
UML_AND(block, I1, I1, 0x1f);
|
||||
UML_JMPc(block, uml::COND_Z, no_shift);
|
||||
UML_SUB(block, I3, 64, I1);
|
||||
@ -2516,33 +2517,37 @@ void hyperstone_device::generate_shl(drcuml_block &block, compiler_state &compil
|
||||
UML_MOV(block, I2, DRC_SR);
|
||||
UML_ROLAND(block, I3, I2, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
generate_load_operand(block, compiler, LOCAL, src_code, uml::I1, uml::I1);
|
||||
generate_load_operand(block, compiler, LOCAL, dst_code, uml::I0, uml::I3);
|
||||
if (dst_code != src_code)
|
||||
{
|
||||
generate_load_operand(block, compiler, LOCAL, src_code, uml::I1, uml::I1);
|
||||
generate_load_operand(block, compiler, LOCAL, dst_code, uml::I0, uml::I3);
|
||||
UML_AND(block, I1, I1, 0x1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_load_operand(block, compiler, LOCAL, dst_code, uml::I0, uml::I3);
|
||||
UML_AND(block, I1, I0, 0x1f);
|
||||
}
|
||||
|
||||
const int no_shift = compiler.next_label();
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK));
|
||||
UML_AND(block, I1, I1, 0x1f);
|
||||
UML_JMPc(block, uml::COND_Z, no_shift);
|
||||
UML_SUB(block, I5, 32, I1);
|
||||
UML_SHR(block, I4, I0, I5);
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK | V_MASK));
|
||||
|
||||
UML_SUB(block, I4, 32, I1);
|
||||
UML_SHR(block, I5, ~uint32_t(0), I4);
|
||||
UML_SHR(block, I4, I0, I4);
|
||||
UML_TEST(block, I1, 0xffffffff);
|
||||
UML_MOVc(block, uml::COND_Z, I4, 0);
|
||||
UML_MOVc(block, uml::COND_Z, I5, 0);
|
||||
UML_ROLINS(block, I2, I4, C_SHIFT, C_MASK);
|
||||
UML_LABEL(block, no_shift);
|
||||
|
||||
UML_SHL(block, I0, I0, I1);
|
||||
|
||||
const int no_overflow = compiler.next_label();
|
||||
UML_TEST(block, I1, ~uint32_t(0));
|
||||
UML_JMPc(block, uml::COND_Z, no_overflow);
|
||||
UML_SHR(block, I1, ~uint32_t(0), I5);
|
||||
UML_TEST(block, I0, ~uint32_t(0));
|
||||
UML_MOVc(block, uml::COND_NS, I1, 0);
|
||||
UML_CMP(block, I4, I1);
|
||||
UML_JMPc(block, uml::COND_E, no_overflow);
|
||||
UML_OR(block, I2, I2, V_MASK);
|
||||
UML_LABEL(block, no_overflow);
|
||||
|
||||
UML_TEST(block, I0, ~uint32_t(0));
|
||||
UML_MOVc(block, uml::COND_NS, I5, 0);
|
||||
generate_update_nz(block, compiler, uml::I2);
|
||||
|
||||
UML_XOR(block, I4, I4, I5);
|
||||
UML_MOV(block, I1, V_MASK);
|
||||
UML_MOVc(block, uml::COND_Z, I1, 0);
|
||||
UML_OR(block, I2, I2, I1);
|
||||
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
UML_STORE(block, (void *)m_core->local_regs, I3, I0, SIZE_DWORD, SCALE_x4);
|
||||
@ -2564,25 +2569,27 @@ void hyperstone_device::generate_shli(drcuml_block &block, compiler_state &compi
|
||||
|
||||
generate_load_operand(block, compiler, DstGlobal, dst_code, uml::I0, uml::I3);
|
||||
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK));
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK | V_MASK));
|
||||
if (n)
|
||||
{
|
||||
UML_SHR(block, I4, I0, 32 - n);
|
||||
UML_MOV(block, I5, util::make_bitmask<uint32_t>(n));
|
||||
UML_ROLAND(block, I1, I4, C_SHIFT, C_MASK);
|
||||
UML_OR(block, I2, I2, I1);
|
||||
}
|
||||
|
||||
UML_SHL(block, I0, I0, n);
|
||||
if (n)
|
||||
{
|
||||
UML_MOVc(block, uml::COND_NS, I5, 0);
|
||||
}
|
||||
generate_update_nz(block, compiler, uml::I2);
|
||||
|
||||
if (n)
|
||||
{
|
||||
UML_TEST(block, I0, ~uint32_t(0));
|
||||
UML_MOV(block, I1, util::make_bitmask<uint32_t>(n));
|
||||
UML_MOVc(block, uml::COND_NS, I1, 0);
|
||||
UML_CMP(block, I4, I1);
|
||||
UML_XOR(block, I4, I4, I5);
|
||||
UML_MOV(block, I1, V_MASK);
|
||||
UML_MOVc(block, uml::COND_E, I1, 0);
|
||||
UML_MOVc(block, uml::COND_Z, I1, 0);
|
||||
UML_OR(block, I2, I2, I1);
|
||||
}
|
||||
|
||||
@ -2618,49 +2625,50 @@ void hyperstone_device::generate_rol(drcuml_block &block, compiler_state &compil
|
||||
const uint32_t dst_code = (op & 0xf0) >> 4;
|
||||
const uint32_t src_code = op & 0xf;
|
||||
|
||||
UML_ROLAND(block, I3, DRC_SR, 32 - FP_SHIFT, 0x7f);
|
||||
UML_MOV(block, I2, DRC_SR);
|
||||
UML_ROLAND(block, I3, I2, 32 - FP_SHIFT, 0x7f);
|
||||
|
||||
UML_ADD(block, I2, I3, dst_code);
|
||||
UML_AND(block, I4, I2, 0x3f);
|
||||
UML_LOAD(block, I0, (void *)m_core->local_regs, I4, SIZE_DWORD, SCALE_x4); // I0 = dreg
|
||||
if (dst_code != src_code)
|
||||
{
|
||||
generate_load_operand(block, compiler, LOCAL, src_code, uml::I1, uml::I1);
|
||||
generate_load_operand(block, compiler, LOCAL, dst_code, uml::I0, uml::I3);
|
||||
UML_AND(block, I1, I1, 0x1f);
|
||||
}
|
||||
else
|
||||
{
|
||||
generate_load_operand(block, compiler, LOCAL, dst_code, uml::I0, uml::I3);
|
||||
UML_AND(block, I1, I0, 0x1f);
|
||||
}
|
||||
|
||||
UML_ADD(block, I2, I3, src_code);
|
||||
UML_AND(block, I1, I2, 0x3f);
|
||||
UML_LOAD(block, I5, (void *)m_core->local_regs, I1, SIZE_DWORD, SCALE_x4);
|
||||
UML_AND(block, I1, I5, 0x1f); // I1 = sreg & 0x1f
|
||||
#ifdef MISSIONCRAFT_FLAGS
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK | V_MASK));
|
||||
|
||||
int no_shift = compiler.next_label();
|
||||
UML_CMP(block, I1, 0);
|
||||
UML_JMPc(block, uml::COND_E, no_shift);
|
||||
UML_ROL(block, I2, I0, I1);
|
||||
UML_LABEL(block, no_shift);
|
||||
UML_SUB(block, I4, 32, I1);
|
||||
UML_SHR(block, I4, ~uint32_t(0), I4);
|
||||
UML_TEST(block, I1, 0xffffffff);
|
||||
UML_MOVc(block, uml::COND_Z, I4, 0);
|
||||
UML_MOV(block, I5, I4);
|
||||
#else
|
||||
UML_AND(block, I2, I2, ~(C_MASK | Z_MASK | N_MASK));
|
||||
#endif
|
||||
|
||||
UML_DSHR(block, I5, 0xffffffff00000000ULL, I1);
|
||||
UML_AND(block, I3, I0, I5);
|
||||
UML_ROL(block, I0, I0, I1);
|
||||
#ifdef MISSIONCRAFT_FLAGS
|
||||
UML_MOVc(block, uml::COND_NS, I4, 0);
|
||||
#endif
|
||||
generate_update_nz(block, compiler, uml::I2);
|
||||
|
||||
UML_MOV(block, I6, 0);
|
||||
#ifdef MISSIONCRAFT_FLAGS
|
||||
UML_AND(block, I1, I5, I0);
|
||||
UML_XOR(block, I4, I4, I1);
|
||||
UML_MOV(block, I1, V_MASK);
|
||||
UML_MOVc(block, uml::COND_Z, I1, 0);
|
||||
UML_OR(block, I2, I2, I1);
|
||||
#endif
|
||||
|
||||
int no_hi_bit = compiler.next_label();
|
||||
UML_TEST(block, I0, 0x80000000);
|
||||
UML_JMPc(block, uml::COND_Z, no_hi_bit);
|
||||
UML_MOV(block, DRC_SR, I2);
|
||||
|
||||
UML_XOR(block, I3, I3, I5);
|
||||
|
||||
int done_shift = compiler.next_label();
|
||||
UML_LABEL(block, no_hi_bit);
|
||||
UML_TEST(block, I3, ~0);
|
||||
UML_JMPc(block, uml::COND_Z, done_shift);
|
||||
UML_OR(block, I6, I6, V_MASK);
|
||||
|
||||
UML_LABEL(block, done_shift);
|
||||
UML_TEST(block, I2, ~uint32_t(0));
|
||||
UML_SETc(block, uml::COND_Z, I5);
|
||||
UML_SHL(block, I5, I5, Z_SHIFT);
|
||||
UML_ROLINS(block, I5, I2, N_SHIFT + 1, N_MASK);
|
||||
|
||||
UML_OR(block, I5, I5, I6);
|
||||
UML_ROLINS(block, DRC_SR, I5, 0, (V_MASK | N_MASK | Z_MASK | C_MASK));
|
||||
UML_STORE(block, (void *)m_core->local_regs, I4, I2, SIZE_DWORD, SCALE_x4);
|
||||
UML_STORE(block, (void *)m_core->local_regs, I3, I0, SIZE_DWORD, SCALE_x4);
|
||||
}
|
||||
|
||||
|
||||
@ -3857,7 +3865,7 @@ void hyperstone_device::generate_dbr(drcuml_block &block, compiler_state &compil
|
||||
UML_ADD(block, I0, DRC_PC, target);
|
||||
UML_MOV(block, mem(&m_core->delay_slot), 1);
|
||||
UML_MOV(block, mem(&m_core->delay_pc), I0);
|
||||
UML_MOV(block, mem(&m_core->intblock), 3);
|
||||
UML_MOV(block, mem(&m_core->intblock), 2);
|
||||
|
||||
auto const *delayslot = desc->delay.first();
|
||||
if (delayslot)
|
||||
@ -3869,7 +3877,7 @@ void hyperstone_device::generate_dbr(drcuml_block &block, compiler_state &compil
|
||||
|
||||
generate_update_cycles(block);
|
||||
|
||||
UML_MOV(block, mem(&m_core->intblock), 2);
|
||||
UML_MOV(block, mem(&m_core->intblock), 1);
|
||||
|
||||
#if E132XS_LOG_DRC_REGS
|
||||
UML_CALLC(block, &c_funcs::dump_registers, this);
|
||||
|
@ -28,7 +28,7 @@ void hyperstone_device::set_double_word(uint8_t dst_code, uint8_t dstf_code, uin
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_chk()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -52,7 +52,7 @@ void hyperstone_device::hyperstone_chk()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_movd()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -134,7 +134,7 @@ void hyperstone_device::hyperstone_movd()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal, hyperstone_device::sign_mode SIGNED>
|
||||
void hyperstone_device::hyperstone_divsu()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + fp) & 0x3f);
|
||||
@ -194,7 +194,7 @@ void hyperstone_device::hyperstone_xm()
|
||||
m_instruction_length = (2<<19);
|
||||
}
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -224,7 +224,7 @@ template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank Src
|
||||
void hyperstone_device::hyperstone_mask()
|
||||
{
|
||||
const uint32_t extra_u = decode_const();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
const uint32_t dreg = (SrcGlobal ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f]) & extra_u;
|
||||
|
||||
if (dreg == 0)
|
||||
@ -244,7 +244,7 @@ template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank Src
|
||||
void hyperstone_device::hyperstone_sum()
|
||||
{
|
||||
const uint32_t extra_u = decode_const();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
const uint32_t sreg = SrcGlobal ? ((src_code == SR_REGISTER) ? GET_C : m_core->global_regs[src_code]) : m_core->local_regs[src_code];
|
||||
@ -275,7 +275,7 @@ void hyperstone_device::hyperstone_sums()
|
||||
{
|
||||
const int32_t extra_s = decode_const();
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -311,7 +311,7 @@ void hyperstone_device::hyperstone_sums()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_cmp()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -341,7 +341,7 @@ void hyperstone_device::hyperstone_mov()
|
||||
{
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const bool h = (SR & H_MASK) != 0;
|
||||
SR &= ~H_MASK;
|
||||
@ -378,7 +378,7 @@ void hyperstone_device::hyperstone_mov()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_add()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -417,7 +417,7 @@ void hyperstone_device::hyperstone_add()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_adds()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -456,7 +456,7 @@ void hyperstone_device::hyperstone_adds()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_cmpb()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -476,7 +476,7 @@ void hyperstone_device::hyperstone_cmpb()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_andn()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
const uint32_t sreg = SrcGlobal ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f];
|
||||
@ -498,7 +498,7 @@ void hyperstone_device::hyperstone_andn()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_or()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
const uint32_t sreg = SrcGlobal ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f];
|
||||
@ -520,7 +520,7 @@ void hyperstone_device::hyperstone_or()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_xor()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
const uint32_t sreg = SrcGlobal ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f];
|
||||
@ -544,7 +544,7 @@ void hyperstone_device::hyperstone_xor()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_subc()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -579,7 +579,7 @@ void hyperstone_device::hyperstone_subc()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_not()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dreg = ~(SrcGlobal ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f]);
|
||||
|
||||
@ -599,7 +599,7 @@ void hyperstone_device::hyperstone_not()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_sub()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -638,7 +638,7 @@ void hyperstone_device::hyperstone_sub()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_subs()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -674,7 +674,7 @@ void hyperstone_device::hyperstone_subs()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_addc()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -719,7 +719,7 @@ void hyperstone_device::hyperstone_addc()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_and()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
const uint32_t sreg = SrcGlobal ? m_core->global_regs[SRC_CODE] : m_core->local_regs[(SRC_CODE + GET_FP) & 0x3f];
|
||||
@ -741,7 +741,7 @@ void hyperstone_device::hyperstone_and()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_neg()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -770,7 +770,7 @@ void hyperstone_device::hyperstone_neg()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_negs()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -813,7 +813,7 @@ void hyperstone_device::hyperstone_cmpi()
|
||||
if (ImmLong)
|
||||
imm = decode_immediate_s();
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
if (!ImmLong)
|
||||
imm = m_op & 0x0f;
|
||||
@ -844,7 +844,7 @@ void hyperstone_device::hyperstone_movi()
|
||||
uint32_t imm;
|
||||
if (ImmLong)
|
||||
imm = decode_immediate_s();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
if (!ImmLong)
|
||||
imm = m_op & 0x0f;
|
||||
@ -887,7 +887,7 @@ void hyperstone_device::hyperstone_addi()
|
||||
uint32_t imm;
|
||||
if (ImmLong)
|
||||
imm = decode_immediate_s();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
uint32_t dreg = (DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code];
|
||||
@ -929,7 +929,7 @@ template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::imm_size Imm
|
||||
void hyperstone_device::hyperstone_addsi()
|
||||
{
|
||||
if (!ImmLong)
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
const int32_t dreg = (DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code];
|
||||
@ -940,7 +940,7 @@ void hyperstone_device::hyperstone_addsi()
|
||||
if (ImmLong)
|
||||
{
|
||||
imm = decode_immediate_s();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -952,7 +952,7 @@ void hyperstone_device::hyperstone_addsi()
|
||||
if (ImmLong)
|
||||
{
|
||||
ignore_immediate_s();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
}
|
||||
imm = SR & (((SR & Z_MASK) ? 0 : 1) | (dreg & 0x01));
|
||||
}
|
||||
@ -989,7 +989,7 @@ template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::imm_size Imm
|
||||
void hyperstone_device::hyperstone_cmpbi()
|
||||
{
|
||||
if (!ImmLong)
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dreg = DstGlobal ? m_core->global_regs[DST_CODE] : m_core->local_regs[(DST_CODE + GET_FP) & 0x3f];
|
||||
|
||||
@ -1002,7 +1002,7 @@ void hyperstone_device::hyperstone_cmpbi()
|
||||
if (ImmLong)
|
||||
{
|
||||
ignore_immediate_s();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
}
|
||||
imm = 0x7fffffff; // bit 31 = 0, others = 1
|
||||
}
|
||||
@ -1011,7 +1011,7 @@ void hyperstone_device::hyperstone_cmpbi()
|
||||
if (ImmLong)
|
||||
{
|
||||
imm = decode_immediate_s();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1029,7 +1029,7 @@ void hyperstone_device::hyperstone_cmpbi()
|
||||
if (ImmLong)
|
||||
{
|
||||
ignore_immediate_s();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
}
|
||||
if ((dreg & 0xff000000) == 0 || (dreg & 0x00ff0000) == 0 || (dreg & 0x0000ff00) == 0 || (dreg & 0x000000ff) == 0)
|
||||
SR |= Z_MASK;
|
||||
@ -1047,7 +1047,7 @@ void hyperstone_device::hyperstone_andni()
|
||||
if (ImmLong)
|
||||
imm = decode_immediate_s();
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
if (N_OP_MASK == 0x10f)
|
||||
imm = 0x7fffffff; // bit 31 = 0, others = 1
|
||||
@ -1089,7 +1089,7 @@ void hyperstone_device::hyperstone_ori()
|
||||
if (ImmLong)
|
||||
imm = decode_immediate_s();
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
if (!ImmLong)
|
||||
imm = m_op & 0x0f;
|
||||
@ -1127,7 +1127,7 @@ void hyperstone_device::hyperstone_xori()
|
||||
if (ImmLong)
|
||||
imm = decode_immediate_s();
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
if (!ImmLong)
|
||||
imm = m_op & 0x0f;
|
||||
@ -1162,7 +1162,7 @@ void hyperstone_device::hyperstone_xori()
|
||||
template <hyperstone_device::shift_type HiN>
|
||||
void hyperstone_device::hyperstone_shrdi()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f;
|
||||
const uint32_t dstf_code = (dst_code + 1) & 0x3f;
|
||||
@ -1191,7 +1191,7 @@ void hyperstone_device::hyperstone_shrdi()
|
||||
|
||||
void hyperstone_device::hyperstone_shrd()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = (SRC_CODE + fp) & 0x3f;
|
||||
@ -1227,7 +1227,7 @@ void hyperstone_device::hyperstone_shrd()
|
||||
|
||||
void hyperstone_device::hyperstone_shr()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
@ -1253,7 +1253,7 @@ void hyperstone_device::hyperstone_shr()
|
||||
template <hyperstone_device::shift_type HiN>
|
||||
void hyperstone_device::hyperstone_sardi()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = (DST_CODE + GET_FP) & 0x3f;
|
||||
const uint32_t dstf_code = (dst_code + 1) & 0x3f;
|
||||
@ -1285,7 +1285,7 @@ void hyperstone_device::hyperstone_sardi()
|
||||
|
||||
void hyperstone_device::hyperstone_sard()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = (SRC_CODE + fp) & 0x3f;
|
||||
@ -1327,7 +1327,7 @@ void hyperstone_device::hyperstone_sard()
|
||||
|
||||
void hyperstone_device::hyperstone_sar()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
@ -1361,7 +1361,7 @@ void hyperstone_device::hyperstone_sar()
|
||||
template <hyperstone_device::shift_type HiN>
|
||||
void hyperstone_device::hyperstone_shldi()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t code = DST_CODE;
|
||||
@ -1396,7 +1396,7 @@ void hyperstone_device::hyperstone_shldi()
|
||||
|
||||
void hyperstone_device::hyperstone_shld()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t d_code = DST_CODE;
|
||||
@ -1441,7 +1441,7 @@ void hyperstone_device::hyperstone_shld()
|
||||
|
||||
void hyperstone_device::hyperstone_shl()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
uint32_t src_code = SRC_CODE + fp;
|
||||
@ -1470,7 +1470,7 @@ void hyperstone_device::hyperstone_shl()
|
||||
|
||||
void hyperstone_device::hyperstone_testlz()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t sreg = m_core->local_regs[(SRC_CODE + fp) & 0x3f];
|
||||
@ -1483,7 +1483,7 @@ void hyperstone_device::hyperstone_testlz()
|
||||
|
||||
void hyperstone_device::hyperstone_rol()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
@ -1545,7 +1545,7 @@ void hyperstone_device::hyperstone_ldxx1()
|
||||
extra_s |= 0xfffff000;
|
||||
}
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -1670,7 +1670,7 @@ void hyperstone_device::hyperstone_ldxx2()
|
||||
extra_s |= 0xfffff000;
|
||||
}
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : (SRC_CODE + fp) & 0x3f;
|
||||
@ -1833,7 +1833,7 @@ void hyperstone_device::hyperstone_stxx1()
|
||||
extra_s |= 0xfffff000;
|
||||
}
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -1931,7 +1931,7 @@ void hyperstone_device::hyperstone_stxx2()
|
||||
extra_s |= 0xfffff000;
|
||||
}
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2030,7 +2030,7 @@ void hyperstone_device::hyperstone_stxx2()
|
||||
template <hyperstone_device::shift_type HiN, hyperstone_device::reg_bank DstGlobal>
|
||||
void hyperstone_device::hyperstone_shri()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
uint32_t val = (DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code];
|
||||
@ -2058,7 +2058,7 @@ void hyperstone_device::hyperstone_shri()
|
||||
template <hyperstone_device::shift_type HiN, hyperstone_device::reg_bank DstGlobal>
|
||||
void hyperstone_device::hyperstone_sari()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
|
||||
@ -2094,7 +2094,7 @@ void hyperstone_device::hyperstone_sari()
|
||||
template <hyperstone_device::shift_type HiN, hyperstone_device::reg_bank DstGlobal>
|
||||
void hyperstone_device::hyperstone_shli()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
uint32_t val = (DstGlobal ? m_core->global_regs : m_core->local_regs)[dst_code];
|
||||
@ -2128,7 +2128,7 @@ void hyperstone_device::hyperstone_shli()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal, hyperstone_device::sign_mode SIGNED>
|
||||
void hyperstone_device::hyperstone_mulsu()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2162,7 +2162,7 @@ void hyperstone_device::hyperstone_mulsu()
|
||||
template <hyperstone_device::shift_type HiN, hyperstone_device::reg_bank DstGlobal>
|
||||
void hyperstone_device::hyperstone_set()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t dst_code = DstGlobal ? DST_CODE : ((DST_CODE + GET_FP) & 0x3f);
|
||||
const uint32_t n = LO_N_VALUE;
|
||||
@ -2222,7 +2222,7 @@ void hyperstone_device::hyperstone_set()
|
||||
template <hyperstone_device::reg_bank DstGlobal, hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_mul()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2256,7 +2256,7 @@ void hyperstone_device::hyperstone_extend()
|
||||
m_instruction_length = (2<<19);
|
||||
const uint32_t func = m_pr16(PC);
|
||||
PC += 2;
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
//TODO: add locks, overflow error and other things
|
||||
const uint32_t fp = GET_FP;
|
||||
@ -2371,7 +2371,7 @@ void hyperstone_device::hyperstone_extend()
|
||||
template <hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_ldwr()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t dreg = m_core->local_regs[(DST_CODE + fp) & 0x3f];
|
||||
@ -2392,7 +2392,7 @@ void hyperstone_device::hyperstone_ldwr()
|
||||
template <hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_lddr()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2421,7 +2421,7 @@ void hyperstone_device::hyperstone_lddr()
|
||||
template <hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_ldwp()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t dst_code = (DST_CODE + fp) & 0x3f;
|
||||
@ -2455,7 +2455,7 @@ void hyperstone_device::hyperstone_ldwp()
|
||||
template <hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_lddp()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2493,7 +2493,7 @@ void hyperstone_device::hyperstone_lddp()
|
||||
template <hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_stwr()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2514,7 +2514,7 @@ void hyperstone_device::hyperstone_stwr()
|
||||
template <hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_stdr()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2538,7 +2538,7 @@ void hyperstone_device::hyperstone_stdr()
|
||||
template <hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_stwp()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2562,7 +2562,7 @@ void hyperstone_device::hyperstone_stwp()
|
||||
template <hyperstone_device::reg_bank SrcGlobal>
|
||||
void hyperstone_device::hyperstone_stdp()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint32_t fp = GET_FP;
|
||||
const uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2592,40 +2592,44 @@ template <hyperstone_device::branch_condition Condition, hyperstone_device::cond
|
||||
void hyperstone_device::hyperstone_db()
|
||||
{
|
||||
static const uint32_t condition_masks[6] = { V_MASK, Z_MASK, C_MASK, C_MASK | Z_MASK, N_MASK, N_MASK | Z_MASK };
|
||||
if (CondSet)
|
||||
const bool taken = CondSet ? (SR & condition_masks[Condition]) : !(SR & condition_masks[Condition]);
|
||||
if (!m_core->delay_slot)
|
||||
{
|
||||
if (SR & condition_masks[Condition])
|
||||
m_core->delay_slot_taken = 0;
|
||||
if (taken)
|
||||
{
|
||||
const int32_t offset = decode_pcrel();
|
||||
check_delay_PC();
|
||||
m_core->delay_slot = 1;
|
||||
m_core->delay_pc = PC + offset;
|
||||
m_core->intblock = 3;
|
||||
m_core->intblock = 2;
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
ignore_pcrel();
|
||||
check_delay_PC();
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (SR & condition_masks[Condition])
|
||||
m_core->delay_slot = 0;
|
||||
m_core->delay_slot_taken = 1;
|
||||
if (taken)
|
||||
{
|
||||
ignore_pcrel();
|
||||
check_delay_PC();
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
const int32_t offset = decode_pcrel();
|
||||
PC = m_core->delay_pc + offset;
|
||||
SR &= ~M_MASK;
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
const int32_t offset = decode_pcrel();
|
||||
check_delay_PC();
|
||||
m_core->delay_slot = 1;
|
||||
m_core->delay_pc = PC + offset;
|
||||
m_core->intblock = 3;
|
||||
m_core->icount -= m_core->clock_cycles_2;
|
||||
ignore_pcrel();
|
||||
PC = m_core->delay_pc;
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2633,18 +2637,30 @@ void hyperstone_device::hyperstone_db()
|
||||
void hyperstone_device::hyperstone_dbr()
|
||||
{
|
||||
const int32_t offset = decode_pcrel();
|
||||
check_delay_PC();
|
||||
if (!m_core->delay_slot)
|
||||
{
|
||||
m_core->delay_pc = PC + offset;
|
||||
m_core->delay_slot = 1;
|
||||
m_core->delay_slot_taken = 0;
|
||||
m_core->intblock = 2;
|
||||
|
||||
m_core->delay_slot = 1;
|
||||
m_core->delay_pc = PC + offset;
|
||||
m_core->intblock = 3;
|
||||
m_core->icount -= m_core->clock_cycles_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_core->delay_slot = 0;
|
||||
m_core->delay_slot_taken = 1;
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_2;
|
||||
PC = m_core->delay_pc + offset;
|
||||
SR &= ~M_MASK;
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_2;
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_frame()
|
||||
{
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
const uint8_t realfp = GET_FP - SRC_CODE;
|
||||
const uint8_t dst_code = DST_CODE;
|
||||
@ -2708,7 +2724,7 @@ void hyperstone_device::hyperstone_call()
|
||||
extra_s |= 0xffffc000;
|
||||
}
|
||||
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
|
||||
uint32_t fp = GET_FP;
|
||||
uint32_t src_code = SrcGlobal ? SRC_CODE : ((SRC_CODE + fp) & 0x3f);
|
||||
@ -2750,7 +2766,7 @@ void hyperstone_device::hyperstone_b()
|
||||
else
|
||||
{
|
||||
ignore_pcrel();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
}
|
||||
}
|
||||
@ -2759,7 +2775,7 @@ void hyperstone_device::hyperstone_b()
|
||||
if (SR & condition_masks[Condition])
|
||||
{
|
||||
ignore_pcrel();
|
||||
check_delay_PC();
|
||||
check_delay_pc();
|
||||
m_core->icount -= m_core->clock_cycles_1;
|
||||
}
|
||||
else
|
||||
@ -2768,3 +2784,14 @@ void hyperstone_device::hyperstone_b()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void hyperstone_device::hyperstone_br()
|
||||
{
|
||||
const int32_t offset = decode_pcrel();
|
||||
check_delay_pc();
|
||||
|
||||
PC += offset;
|
||||
SR &= ~M_MASK;
|
||||
|
||||
m_core->icount -= m_core->clock_cycles_2;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user