summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2020-10-07 19:30:15 +0700
committer Patrick Mackinlay <pmackinlay@hotmail.com>2020-10-07 19:30:15 +0700
commit088cf0ad1995d29546d434f607015f141debf588 (patch)
treede71ff6579b1aae4cf65d4d49b045efc97cc8405
parent4fb2dfeb6926f8c8a244915cfafde799e4495bc5 (diff)
ns32000: many bug fixes
* fixed many instruction bugs * implemented cmpm instruction * reworked pc increment to better support prefetch * tightened up decoding
-rw-r--r--src/devices/cpu/ns32000/ns32000.cpp385
-rw-r--r--src/devices/cpu/ns32000/ns32000.h1
2 files changed, 186 insertions, 200 deletions
diff --git a/src/devices/cpu/ns32000/ns32000.cpp b/src/devices/cpu/ns32000/ns32000.cpp
index 6a95afc0146..1680955a7ac 100644
--- a/src/devices/cpu/ns32000/ns32000.cpp
+++ b/src/devices/cpu/ns32000/ns32000.cpp
@@ -358,10 +358,7 @@ template <int Width> u64 ns32000_device<Width>::gen_read(addr_mode mode)
break;
case REG:
- if (mode.size == SIZE_Q)
- data = (u64(m_r[mode.gen ^ 1]) << 32) | m_r[mode.gen ^ 0];
- else
- data = m_r[mode.gen] & size_mask[mode.size];
+ data = m_r[mode.gen] & size_mask[mode.size];
break;
case TOS:
@@ -412,13 +409,7 @@ template <int Width> void ns32000_device<Width>::gen_write(addr_mode mode, u64 d
switch (mode.type)
{
case REG:
- if (mode.size == SIZE_Q)
- {
- m_r[mode.gen ^ 0] = u32(data);
- m_r[mode.gen ^ 1] = data >> 32;
- }
- else
- m_r[mode.gen] = (m_r[mode.gen] & ~size_mask[mode.size]) | (data & size_mask[mode.size]);
+ m_r[mode.gen] = (m_r[mode.gen] & ~size_mask[mode.size]) | (data & size_mask[mode.size]);
break;
case TOS:
@@ -538,6 +529,7 @@ template <int Width> void ns32000_device<Width>::interrupt(unsigned const vector
m_pc = space(0).read_dword_unaligned(m_mod + 8) + u16(descriptor >> 16);
// TODO: flush queue
+ m_sequential = false;
}
template <int Width> void ns32000_device<Width>::execute_run()
@@ -594,6 +586,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
u8 const opbyte = space(0).read_byte(m_pc);
unsigned bytes = 1;
+ m_sequential = true;
if ((opbyte & 15) == 10)
{
@@ -603,9 +596,10 @@ template <int Width> void ns32000_device<Width>::execute_run()
s32 const dst = displacement(bytes);
if (condition(opbyte >> 4))
+ {
m_pc += dst;
- else
- m_pc += bytes;
+ m_sequential = false;
+ }
}
else if ((opbyte & 15) == 2)
{
@@ -622,6 +616,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
space(0).write_dword_unaligned(SP, m_pc + bytes);
m_pc += dst;
+ m_sequential = false;
}
break;
case 0x1:
@@ -634,6 +629,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
SP += 4 + constant;
m_pc = addr;
+ m_sequential = false;
}
break;
case 0x2:
@@ -653,6 +649,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
m_mod = u16(descriptor);
m_sb = space(0).read_dword_unaligned(m_mod + 0);
m_pc = space(0).read_dword_unaligned(m_mod + 8) + u16(descriptor >> 16);
+ m_sequential = false;
}
break;
case 0x3:
@@ -668,6 +665,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
m_sb = space(0).read_dword_unaligned(m_mod + 0);
SP += constant;
+ m_sequential = false;
}
break;
case 0x4:
@@ -688,6 +686,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
m_sb = space(0).read_dword_unaligned(m_mod);
SP += constant;
+ m_sequential = false;
}
else
interrupt(ILL, m_pc);
@@ -708,6 +707,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
sp += 2;
m_sb = space(0).read_dword_unaligned(m_mod);
+ m_sequential = false;
}
else
interrupt(ILL, m_pc);
@@ -727,7 +727,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
}
}
}
- m_pc += bytes;
break;
case 0x7:
// RESTORE reglist
@@ -744,7 +743,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
}
}
}
- m_pc += bytes;
break;
case 0x8:
// ENTER reglist,constant
@@ -767,7 +765,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
}
}
}
- m_pc += bytes;
break;
case 0x9:
// EXIT reglist
@@ -787,16 +784,13 @@ template <int Width> void ns32000_device<Width>::execute_run()
m_fp = space(0).read_dword_unaligned(SP);
SP += 4;
}
- m_pc += bytes;
break;
case 0xa:
// NOP
- m_pc += bytes;
break;
case 0xb:
// WAIT
m_wait = true;
- m_pc += bytes;
break;
case 0xc:
// DIA
@@ -806,8 +800,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
// FLAG
if (m_psr & PSR_F)
interrupt(FLG, m_pc);
- else
- m_pc += bytes;
break;
case 0xe:
// SVC
@@ -849,7 +841,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[0], dst);
}
- m_pc += bytes;
break;
case 1:
// CMPQi src1,src2
@@ -859,7 +850,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[0].read_i(size);
decode(mode, bytes);
- u32 const src1 = s32(quick << 28) >> 28;
+ u32 const src1 = (s32(quick << 28) >> 28) & size_mask[size];
u32 const src2 = gen_read(mode[0]);
m_psr &= ~(PSR_N | PSR_Z | PSR_L);
@@ -877,7 +868,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
|| ((size == SIZE_B && u8(src1) > u8(src2)))))
m_psr |= PSR_L;
}
- m_pc += bytes;
break;
case 2:
// SPRi procreg,dst
@@ -891,41 +881,30 @@ template <int Width> void ns32000_device<Width>::execute_run()
case 0x0: // US
// TODO: user stack pointer?
gen_write(mode[0], m_sp1);
- m_pc += bytes;
break;
case 0x8: // FP
gen_write(mode[0], m_fp);
- m_pc += bytes;
break;
case 0x9: // SP
gen_write(mode[0], SP);
- m_pc += bytes;
break;
case 0xa: // SB
gen_write(mode[0], m_sb);
- m_pc += bytes;
break;
case 0xd: // PSR
if (!(m_psr & PSR_U))
- {
gen_write(mode[0], m_psr);
- m_pc += bytes;
- }
else
interrupt(ILL, m_pc);
break;
case 0xe: // INTBASE
if (!(m_psr & PSR_U))
- {
gen_write(mode[0], m_intbase);
- m_pc += bytes;
- }
else
interrupt(ILL, m_pc);
break;
case 0xf: // MOD
gen_write(mode[0], m_mod);
- m_pc += bytes;
break;
}
break;
@@ -937,7 +916,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
decode(mode, bytes);
gen_write(mode[0], condition(quick));
- m_pc += bytes;
break;
case 4:
// ACBi inc,index,dst
@@ -955,9 +933,10 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[0], index);
if (index & size_mask[size])
+ {
m_pc += dst;
- else
- m_pc += bytes;
+ m_sequential = false;
+ }
}
break;
case 5:
@@ -968,7 +947,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
decode(mode, bytes);
gen_write(mode[0], s32(quick << 28) >> 28);
- m_pc += bytes;
break;
case 6:
// LPRi procreg,src
@@ -979,22 +957,17 @@ template <int Width> void ns32000_device<Width>::execute_run()
switch (quick)
{
- case 0x0: // US
- // TODO: user stack pointer?
- m_sp1 = gen_read(mode[0]);
- m_pc += bytes;
+ case 0x0: // UPSR
+ m_psr = (m_psr & 0xff00) | u8(gen_read(mode[0]));
break;
case 0x8: // FP
m_fp = gen_read(mode[0]);
- m_pc += bytes;
break;
case 0x9: // SP
SP = gen_read(mode[0]);
- m_pc += bytes;
break;
case 0xa: // SB
m_sb = gen_read(mode[0]);
- m_pc += bytes;
break;
case 0xd: // PSR
if (!(m_psr & PSR_U))
@@ -1005,24 +978,21 @@ template <int Width> void ns32000_device<Width>::execute_run()
m_psr = (m_psr & 0xff00) | u8(src);
else
m_psr = src;
-
- m_pc += bytes;
}
else
interrupt(ILL, m_pc);
break;
case 0xe: // INTBASE
if (!(m_psr & PSR_U))
- {
m_intbase = gen_read(mode[0]);
- m_pc += bytes;
- }
else
interrupt(ILL, m_pc);
break;
case 0xf: // MOD
m_mod = gen_read(mode[0]);
- m_pc += bytes;
+ break;
+ default:
+ interrupt(UND, m_pc);
break;
}
break;
@@ -1034,37 +1004,40 @@ template <int Width> void ns32000_device<Width>::execute_run()
// CXPD desc
// gen
// addr
+ if (size == SIZE_D)
{
mode[0].addr();
decode(mode, bytes);
- u32 const desc = gen_read(mode[0]);
+ u32 const descriptor = gen_read(mode[0]);
SP -= 4;
space(0).write_dword_unaligned(SP, m_mod);
SP -= 4;
space(0).write_dword_unaligned(SP, m_pc + bytes);
- m_mod = u16(desc);
+ m_mod = u16(descriptor);
m_sb = space(0).read_dword_unaligned(m_mod + 0);
- m_pc = u16(desc >> 16) + space(0).read_dword_unaligned(m_mod + 8);
+ m_pc = space(0).read_dword_unaligned(m_mod + 8) + u16(descriptor >> 16);
+ m_sequential = false;
}
+ else
+ interrupt(UND, m_pc);
break;
case 0x2:
// BICPSRi src
// gen
// read.[BW]
- mode[0].read_i(size);
- decode(mode, bytes);
-
- if (size < SIZE_D)
+ if (size == SIZE_B || size == SIZE_W)
{
+ mode[0].read_i(size);
+ decode(mode, bytes);
+
if (size == SIZE_B || !(m_psr & PSR_U))
{
u16 const src = gen_read(mode[0]);
m_psr &= ~src;
- m_pc += bytes;
}
else
interrupt(ILL, m_pc);
@@ -1076,27 +1049,31 @@ template <int Width> void ns32000_device<Width>::execute_run()
// JUMP dst
// gen
// addr
- mode[0].addr();
- decode(mode, bytes);
+ if (size == SIZE_D)
+ {
+ mode[0].addr();
+ decode(mode, bytes);
- // FIXME: size != 3?
- m_pc = ea(mode[0]);
+ m_pc = ea(mode[0]);
+ m_sequential = false;
+ }
+ else
+ interrupt(UND, m_pc);
break;
case 0x6:
// BISPSRi src
// gen
// read.[BW]
- mode[0].read_i(size);
- decode(mode, bytes);
-
- if (size < SIZE_D)
+ if (size == SIZE_B || size == SIZE_W)
{
+ mode[0].read_i(size);
+ decode(mode, bytes);
+
if (size == SIZE_B || !(m_psr & PSR_U))
{
u16 const src = gen_read(mode[0]);
m_psr |= src;
- m_pc += bytes;
}
else
interrupt(ILL, m_pc);
@@ -1116,12 +1093,12 @@ template <int Width> void ns32000_device<Width>::execute_run()
SP -= src;
}
- m_pc += bytes;
break;
case 0xc:
// JSR dst
// gen
// addr
+ if (size == SIZE_D)
{
mode[0].addr();
decode(mode, bytes);
@@ -1130,7 +1107,10 @@ template <int Width> void ns32000_device<Width>::execute_run()
space(0).write_dword_unaligned(SP, m_pc + bytes);
m_pc = ea(mode[0]);
+ m_sequential = false;
}
+ else
+ interrupt(UND, m_pc);
break;
case 0xe:
// CASEi src
@@ -1143,6 +1123,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
s32 const src = gen_read_sx(mode[0]);
m_pc += src;
+ m_sequential = false;
}
break;
@@ -1181,7 +1162,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0x1:
// CMPi src1,src2
@@ -1210,7 +1190,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
|| ((size == SIZE_B && u8(src1) > u8(src2)))))
m_psr |= PSR_L;
}
- m_pc += bytes;
break;
case 0x2:
// BICi src,dst
@@ -1226,7 +1205,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst & ~src);
}
- m_pc += bytes;
break;
case 0x4:
// ADDCi src,dst
@@ -1245,7 +1223,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0x5:
// MOVi src,dst
@@ -1260,7 +1237,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], src);
}
- m_pc += bytes;
break;
case 0x6:
// ORi src,dst
@@ -1276,7 +1252,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], src | dst);
}
- m_pc += bytes;
break;
case 0x8:
// SUBi src,dst
@@ -1295,18 +1270,21 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0x9:
// ADDR src,dst
// gen,gen
// addr,write.D
- mode[0].addr();
- mode[1].write_i(SIZE_D);
- decode(mode, bytes);
+ if (size == SIZE_D)
+ {
+ mode[0].addr();
+ mode[1].write_i(size);
+ decode(mode, bytes);
- gen_write(mode[1], ea(mode[0]));
- m_pc += bytes;
+ gen_write(mode[1], ea(mode[0]));
+ }
+ else
+ interrupt(UND, m_pc);
break;
case 0xa:
// ANDi src,dst
@@ -1322,7 +1300,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], src & dst);
}
- m_pc += bytes;
break;
case 0xc:
// SUBCi src,dst
@@ -1341,7 +1318,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0xd:
// TBITi offset,base
@@ -1371,7 +1347,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
m_psr &= ~PSR_F;
}
}
- m_pc += bytes;
break;
case 0xe:
// XORi src,dst
@@ -1387,7 +1362,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], src ^ dst);
}
- m_pc += bytes;
break;
}
}
@@ -1448,7 +1422,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
m_r[0]--;
}
- m_pc += bytes;
break;
case 1:
// CMPSi options
@@ -1505,16 +1478,12 @@ template <int Width> void ns32000_device<Width>::execute_run()
m_r[0]--;
}
- m_pc += bytes;
break;
case 2:
// SETCFG cfglist
// short
if (!(m_psr & PSR_U))
- {
m_cfg = (opword >> 7) & 15;
- m_pc += bytes;
- }
else
interrupt(ILL, m_pc);
break;
@@ -1545,7 +1514,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
m_r[0]--;
}
- m_pc += bytes;
break;
default:
interrupt(UND, m_pc);
@@ -1577,11 +1545,10 @@ template <int Width> void ns32000_device<Width>::execute_run()
u32 const src = gen_read(mode[1]);
unsigned const limit = (size + 1) * 8 - 1;
- u32 const dst = ((src << (count & limit)) & size_mask[size]) | ((src & size_mask[size]) >> (limit - (count & limit)));
+ u32 const dst = ((src << (count & limit)) & size_mask[size]) | ((src & size_mask[size]) >> (limit - (count & limit) + 1));
gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0x1:
// ASHi count,dst
@@ -1599,7 +1566,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0x2:
// CBITi offset,base
@@ -1638,7 +1604,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
space(0).write_byte(byte_ea, byte & ~(1U << (offset & 7)));
}
}
- m_pc += bytes;
break;
case 0x4:
interrupt(UND, m_pc);
@@ -1659,7 +1624,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0x6:
// SBITi offset,base
@@ -1695,10 +1659,9 @@ template <int Width> void ns32000_device<Width>::execute_run()
else
m_psr &= ~PSR_F;
- space(0).write_byte(byte_ea, byte | ~(1U << (offset & 7)));
+ space(0).write_byte(byte_ea, byte | (1U << (offset & 7)));
}
}
- m_pc += bytes;
break;
case 0x8:
// NEGi src,dst
@@ -1727,7 +1690,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], src);
}
}
- m_pc += bytes;
break;
case 0x9:
// NOTi src,dst
@@ -1742,7 +1704,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], src ^ 1U);
}
- m_pc += bytes;
break;
case 0xa:
interrupt(UND, m_pc);
@@ -1764,18 +1725,15 @@ template <int Width> void ns32000_device<Width>::execute_run()
s32 const src = gen_read_sx(mode[0]);
- s32 const dst = std::abs(src);
-
m_psr &= ~PSR_F;
- if (BIT(dst, ((size + 1) * 8 - 1)))
+ if (src == s32(0x80000000) >> (32 - (size + 1) * 8))
{
m_psr |= PSR_F;
gen_write(mode[1], src);
}
else
- gen_write(mode[1], dst);
+ gen_write(mode[1], std::abs(src));
}
- m_pc += bytes;
break;
case 0xd:
// COMi src,dst
@@ -1790,7 +1748,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], ~src);
}
- m_pc += bytes;
break;
case 0xe:
// IBITi offset,base
@@ -1825,7 +1782,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
space(0).write_byte(byte_ea, byte ^ (1U << (offset & 7)));
}
}
- m_pc += bytes;
break;
case 0xf:
// ADDPi src,dst
@@ -1858,10 +1814,10 @@ template <int Width> void ns32000_device<Width>::execute_run()
u32 block1 = ea(mode[0]);
u32 block2 = ea(mode[1]);
- s32 length = displacement(bytes);
+ unsigned const num = displacement(bytes) / (size + 1) + 1;
// TODO: aligned/unaligned transfers?
- for (unsigned num = 0; num * (size + 1) < length; num++)
+ for (unsigned i = 0; i < num; i++)
{
switch (size)
{
@@ -1877,13 +1833,63 @@ template <int Width> void ns32000_device<Width>::execute_run()
block2 += (size + 1);
}
}
- m_pc += bytes;
break;
case 0x1:
// CMPMi block1,block2,length
// gen,gen,disp
// addr,addr
- fatalerror("unimplemented: cmpm (%s)\n", machine().describe_context());
+ {
+ mode[0].addr();
+ mode[1].addr();
+ decode(mode, bytes);
+
+ u32 block1 = ea(mode[0]);
+ u32 block2 = ea(mode[1]);
+ unsigned const num = displacement(bytes) / (size + 1) + 1;
+
+ m_psr |= PSR_Z;
+ m_psr &= ~(PSR_N | PSR_L);
+
+ // TODO: aligned/unaligned transfers?
+ for (unsigned i = 0; i < num; i++)
+ {
+ s32 int1 = 0;
+ s32 int2 = 0;
+
+ switch (size)
+ {
+ case SIZE_B:
+ int1 = s8(space(0).read_byte(block1));
+ int2 = s8(space(0).read_byte(block2));
+ break;
+ case SIZE_W:
+ int1 = s16(space(0).read_word_unaligned(block1));
+ int2 = s16(space(0).read_word_unaligned(block2));
+ break;
+ case SIZE_D:
+ int1 = s32(space(0).read_dword_unaligned(block1));
+ int2 = s32(space(0).read_dword_unaligned(block2));
+ break;
+ default:
+ // can't happen
+ break;
+ }
+
+ if (int1 != int2)
+ {
+ m_psr &= ~PSR_Z;
+ if (int1 > int2)
+ m_psr |= PSR_N;
+ if (u32(int1) > u32(int2))
+ m_psr |= PSR_L;
+
+ break;
+ }
+
+ block1 += (size + 1);
+ block2 += (size + 1);
+ }
+ }
break;
case 0x2:
// INSSi src,base,offset,length
@@ -1903,7 +1909,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], (base & ~mask) | ((src << offset) & mask));
}
- m_pc += bytes;
break;
case 0x3:
// EXTSi base,dst,offset,length
@@ -1923,12 +1928,12 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0x4:
// MOVXBW src,dst
// gen,gen
// read.B,write.W
+ if (size == SIZE_B)
{
mode[0].read_i(size);
mode[1].write_i(SIZE_W);
@@ -1939,12 +1944,14 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
+ else
+ interrupt(UND, m_pc);
break;
case 0x5:
// MOVZBW src,dst
// gen,gen
// read.B,write.W
+ if (size == SIZE_B)
{
mode[0].read_i(size);
mode[1].write_i(SIZE_W);
@@ -1955,12 +1962,14 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
+ else
+ interrupt(UND, m_pc);
break;
case 0x6:
// MOVZiD src,dst
// gen,gen
// read.[BW],write.D
+ if (size == SIZE_B || size == SIZE_W)
{
mode[0].read_i(size);
mode[1].write_i(SIZE_D);
@@ -1970,12 +1979,14 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], src);
}
- m_pc += bytes;
+ else
+ interrupt(UND, m_pc);
break;
case 0x7:
// MOVXiD src,dst
// gen,gen
// read.[BW],write.D
+ if (size == SIZE_B || size == SIZE_W)
{
mode[0].read_i(size);
mode[1].write_i(SIZE_D);
@@ -1986,7 +1997,8 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
+ else
+ interrupt(UND, m_pc);
break;
case 0x8:
// MULi src,dst
@@ -2004,7 +2016,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0x9:
// MEIi src,dst
@@ -2012,7 +2023,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
// read.i,rmw.2i
{
mode[0].read_i(size);
- mode[1].rmw_i(size_code(size * 2 + 1));
+ mode[1].rmw_i(size);
decode(mode, bytes);
u32 const src1 = gen_read(mode[0]);
@@ -2020,9 +2031,15 @@ template <int Width> void ns32000_device<Width>::execute_run()
u64 const dst = mulu_32x32(src1, src2);
- gen_write(mode[1], dst);
+ mode[1].rmw_i(size_code(size * 2 + 1));
+ if (mode[1].type == REG)
+ {
+ m_r[mode[1].gen ^ 0] = (m_r[mode[1].gen ^ 0] & ~size_mask[size]) | ((dst >> 0) & size_mask[size]);
+ m_r[mode[1].gen ^ 1] = (m_r[mode[1].gen ^ 1] & ~size_mask[size]) | ((dst >> ((size + 1) * 8)) & size_mask[size]);
+ }
+ else
+ gen_write(mode[1], dst);
}
- m_pc += bytes;
break;
case 0xa:
interrupt(UND, m_pc);
@@ -2039,7 +2056,9 @@ template <int Width> void ns32000_device<Width>::execute_run()
u32 const src1 = gen_read(mode[0]);
if (src1)
{
- u64 const src2 = gen_read(mode[1]);
+ u64 const src2 = (mode[1].type == REG) ?
+ (u64(m_r[mode[1].gen ^ 1] & size_mask[size]) << ((size + 1) * 8)) | (m_r[mode[1].gen ^ 0] & size_mask[size]) :
+ gen_read(mode[1]);
u32 const quotient = src2 / src1;
u32 const remainder = src2 % src1;
@@ -2051,8 +2070,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
}
else
gen_write(mode[1], (u64(quotient) << ((size + 1) * 8)) | remainder);
-
- m_pc += bytes;
}
else
{
@@ -2081,7 +2098,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
s32 const dst = src2 / src1;
gen_write(mode[1], dst);
- m_pc += bytes;
}
else
{
@@ -2110,7 +2126,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
s32 const dst = src2 % src1;
gen_write(mode[1], dst);
- m_pc += bytes;
}
else
{
@@ -2131,15 +2146,14 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].rmw_i(size);
decode(mode, bytes);
- u32 const src1 = gen_read_sx(mode[0]);
+ s32 const src1 = gen_read_sx(mode[0]);
if (src1)
{
- u32 const src2 = gen_read_sx(mode[1]);
+ s32 const src2 = gen_read_sx(mode[1]);
s32 const dst = (src1 + (src2 % src1)) % src1;
gen_write(mode[1], dst);
- m_pc += bytes;
}
else
{
@@ -2172,8 +2186,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], quotient - 1);
else
gen_write(mode[1], quotient);
-
- m_pc += bytes;
}
else
{
@@ -2234,8 +2246,8 @@ template <int Width> void ns32000_device<Width>::execute_run()
// CVTP offset,base,dst
// reg,gen,gen
// addr,write.D
+ if (size == SIZE_D)
{
- // TODO: size != SIZE_D?
mode[0].addr();
mode[1].write_i(size);
decode(mode, bytes);
@@ -2245,6 +2257,8 @@ template <int Width> void ns32000_device<Width>::execute_run()
gen_write(mode[1], base * 8 + offset);
}
+ else
+ interrupt(UND, m_pc);
break;
case 2:
// INSi offset,src,base,length
@@ -2269,7 +2283,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
}
else
{
- u32 const base_ea = ea(mode[0]) + (offset >> 3);
+ u32 const base_ea = ea(mode[1]) + (offset >> 3);
u32 const base = space(0).read_dword_unaligned(base_ea);
u32 const mask = ((1U << length) - 1) << (offset & 7);
@@ -2295,9 +2309,18 @@ template <int Width> void ns32000_device<Width>::execute_run()
s32 upper = 0;
switch (size)
{
- case SIZE_B: lower = s8(space(0).read_byte(bounds + 0)); upper = s8(space(0).read_byte(bounds + 1)); break;
- case SIZE_W: lower = s16(space(0).read_word_unaligned(bounds + 0)); upper = s16(space(0).read_word_unaligned(bounds + 2)); break;
- case SIZE_D: lower = s32(space(0).read_dword_unaligned(bounds + 0)); upper = s32(space(0).read_dword_unaligned(bounds + 4)); break;
+ case SIZE_B:
+ upper = s8(space(0).read_byte(bounds + 0));
+ lower = s8(space(0).read_byte(bounds + 1));
+ break;
+ case SIZE_W:
+ upper = s16(space(0).read_word_unaligned(bounds + 0));
+ lower = s16(space(0).read_word_unaligned(bounds + 2));
+ break;
+ case SIZE_D:
+ upper = s32(space(0).read_dword_unaligned(bounds + 0));
+ lower = s32(space(0).read_dword_unaligned(bounds + 4));
+ break;
default:
// can't happen
break;
@@ -2350,7 +2373,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
else
offset++;
- gen_write(mode[1], offset & limit);
+ gen_write(mode[1], offset & (limit - 1));
}
break;
case 6:
@@ -2367,7 +2390,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
break;
}
}
- m_pc += bytes;
break;
case 0x3e:
// format 9: xxxx xyyy yyoo ofii 0011 1110
@@ -2396,9 +2418,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 1:
@@ -2408,9 +2428,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[0].read_i(size);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 2:
@@ -2421,9 +2439,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 3:
@@ -2434,9 +2450,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 4:
@@ -2447,9 +2461,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_i(size);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 5:
@@ -2460,9 +2472,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_i(size);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 6:
@@ -2472,9 +2482,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[0].write_i(size);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[1], mode[0]))
interrupt(FPU, m_pc);
break;
case 7:
@@ -2485,9 +2493,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_i(size);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
}
@@ -2524,9 +2530,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].rmw_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 0x1:
@@ -2537,9 +2541,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 0x2:
@@ -2556,8 +2558,6 @@ template <int Width> void ns32000_device<Width>::execute_run()
{
m_psr &= ~(PSR_N | PSR_Z | PSR_L);
m_psr |= status & (ns32000_slave_interface::SLAVE_N | ns32000_slave_interface::SLAVE_Z | ns32000_slave_interface::SLAVE_L);
-
- m_pc += bytes;
}
else
interrupt(FPU, m_pc);
@@ -2570,9 +2570,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].read_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 0x4:
@@ -2583,9 +2581,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].rmw_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 0x5:
@@ -2596,9 +2592,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 0x8:
@@ -2609,9 +2603,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].rmw_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 0x9:
@@ -2621,9 +2613,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 0xc:
@@ -2634,9 +2624,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].rmw_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
case 0xd:
@@ -2647,9 +2635,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
mode[1].write_f(size_f);
decode(mode, bytes);
- if (!slave(mode[0], mode[1]))
- m_pc += bytes;
- else
+ if (slave(mode[0], mode[1]))
interrupt(FPU, m_pc);
break;
}
@@ -2684,8 +2670,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
// addr
mode[0].addr();
decode(mode, bytes);
-
- m_pc += bytes;
+ logerror("rdval (%s)\n", machine().describe_context());
break;
case 1:
// WRVAL loc
@@ -2693,8 +2678,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
// addr
mode[0].addr();
decode(mode, bytes);
-
- m_pc += bytes;
+ logerror("wrval (%s)\n", machine().describe_context());
break;
case 2:
// LMR mmureg,src
@@ -2702,8 +2686,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
// read.D
mode[0].read_i(size);
decode(mode, bytes);
-
- m_pc += bytes;
+ logerror("lmr (%s)\n", machine().describe_context());
break;
case 3:
// SMR mmureg,dst
@@ -2711,8 +2694,7 @@ template <int Width> void ns32000_device<Width>::execute_run()
// write.D
mode[0].write_i(size);
decode(mode, bytes);
-
- m_pc += bytes;
+ logerror("smr (%s)\n", machine().describe_context());
break;
default:
interrupt(UND, m_pc);
@@ -2746,6 +2728,9 @@ template <int Width> void ns32000_device<Width>::execute_run()
break;
}
+ if (m_sequential)
+ m_pc += bytes;
+
// trace trap
if (m_psr & PSR_P)
interrupt(TRC, m_pc);
diff --git a/src/devices/cpu/ns32000/ns32000.h b/src/devices/cpu/ns32000/ns32000.h
index f76325b65fb..f5254fa068d 100644
--- a/src/devices/cpu/ns32000/ns32000.h
+++ b/src/devices/cpu/ns32000/ns32000.h
@@ -142,6 +142,7 @@ private:
bool m_nmi_line;
bool m_int_line;
bool m_wait;
+ bool m_sequential;
};
class ns32008_device : public ns32000_device<0>