summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2020-09-09 17:04:12 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2020-09-09 17:04:12 +0700
commitb4aaaa7fd39dcbfa6e26a78c965f7df8836275d2 (patch)
tree653f25991979ae7bc5df1868a2a08c15bbf28f8d
parentbcb54484af93872eab5f3f3ac6713b751ecfea91 (diff)
ns32000: fix shift/rotate instruction decoding bug
-rw-r--r--src/devices/cpu/ns32000/ns32000.cpp19
-rw-r--r--src/devices/cpu/ns32000/ns32000.h2
2 files changed, 11 insertions, 10 deletions
diff --git a/src/devices/cpu/ns32000/ns32000.cpp b/src/devices/cpu/ns32000/ns32000.cpp
index e43a68c75d9..41743521755 100644
--- a/src/devices/cpu/ns32000/ns32000.cpp
+++ b/src/devices/cpu/ns32000/ns32000.cpp
@@ -214,7 +214,7 @@ s32 ns32000_device::displacement(unsigned &bytes)
return disp;
}
-void ns32000_device::decode(addr_mode *mode, unsigned size, unsigned &bytes)
+void ns32000_device::decode(addr_mode *mode, unsigned imm_size, unsigned &bytes)
{
bool scaled[] = { false, false };
@@ -272,11 +272,11 @@ void ns32000_device::decode(addr_mode *mode, unsigned size, unsigned &bytes)
break;
case 0x14:
// immediate
- switch (size)
+ switch (imm_size)
{
- case 0: mode[i].base = space(0).read_byte(m_pc + bytes); bytes += 1; break;
- case 1: mode[i].base = swapendian_int16(space(0).read_word_unaligned(m_pc + bytes)); bytes += 2; break;
- case 3: mode[i].base = swapendian_int32(space(0).read_dword_unaligned(m_pc + bytes)); bytes += 4; break;
+ case SIZE_B: mode[i].base = space(0).read_byte(m_pc + bytes); bytes += 1; break;
+ case SIZE_W: mode[i].base = swapendian_int16(space(0).read_word_unaligned(m_pc + bytes)); bytes += 2; break;
+ case SIZE_D: mode[i].base = swapendian_int32(space(0).read_dword_unaligned(m_pc + bytes)); bytes += 4; break;
}
mode[i].type = IMM;
break;
@@ -1258,8 +1258,8 @@ void ns32000_device::execute_run()
{
mode[1].rmw();
- u32 const src1 = gen_read(mode[0], size);
- u32 const src2 = gen_read(mode[1], size);
+ u32 const src1 = gen_read(mode[0], size) & size_mask[size];
+ u32 const src2 = gen_read(mode[1], size) & size_mask[size];
u32 const dest = src2 - src1 - (m_psr & PSR_C);
flags(src1, src2, dest, size, true);
@@ -1483,7 +1483,8 @@ void ns32000_device::execute_run()
addr_mode mode[] = { addr_mode((opword >> 11) & 31), addr_mode((opword >> 6) & 31) };
unsigned const size = opword & 3;
- decode(mode, size, bytes);
+ // byte-size immediates for ROT, ASH and LSH
+ decode(mode, ((opword >> 2) & 10) ? size : SIZE_B, bytes);
switch ((opword >> 2) & 15)
{
@@ -1643,7 +1644,7 @@ void ns32000_device::execute_run()
// gen,gen
// read.i,write.i
{
- u32 const src = gen_read(mode[0], size) & size_mask[size];
+ u32 const src = gen_read(mode[0], size);
gen_write(mode[1], size, src ^ 1U);
}
diff --git a/src/devices/cpu/ns32000/ns32000.h b/src/devices/cpu/ns32000/ns32000.h
index a6356189aa3..dea909cdc68 100644
--- a/src/devices/cpu/ns32000/ns32000.h
+++ b/src/devices/cpu/ns32000/ns32000.h
@@ -67,7 +67,7 @@ private:
// instruction decoding helpers
s32 displacement(unsigned &bytes);
- void decode(addr_mode *mode, unsigned size, unsigned &bytes);
+ void decode(addr_mode *mode, unsigned imm_size, unsigned &bytes);
// operand read/write helpers
u32 ea(addr_mode const mode);