diff options
-rw-r--r-- | src/devices/cpu/ns32000/ns32000.cpp | 385 | ||||
-rw-r--r-- | src/devices/cpu/ns32000/ns32000.h | 1 |
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> |