From d1fad49c88c0e1e3753409062175029e901117aa Mon Sep 17 00:00:00 2001 From: Nigel Barnes Date: Sat, 25 Mar 2023 12:24:07 +0000 Subject: cpu/nec: Implemented bitfield instructions INS and EXT. --- src/devices/cpu/nec/necinstr.hxx | 47 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/src/devices/cpu/nec/necinstr.hxx b/src/devices/cpu/nec/necinstr.hxx index 43c00cec6d9..6854642a6d8 100644 --- a/src/devices/cpu/nec/necinstr.hxx +++ b/src/devices/cpu/nec/necinstr.hxx @@ -43,8 +43,51 @@ OP( 0x0f, i_pre_nec ) { uint32_t ModRM, tmp, tmp2; case 0x26 : CMP4S; CLKS(7,7,2); break; case 0x28 : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp <<= 4; tmp |= Breg(AL) & 0xf; Breg(AL) = (Breg(AL) & 0xf0) | ((tmp>>8)&0xf); tmp &= 0xff; PutbackRMByte(ModRM,tmp); CLKM(13,13,9,28,28,15); break; case 0x2a : ModRM = fetch(); tmp = GetRMByte(ModRM); tmp2 = (Breg(AL) & 0xf)<<4; Breg(AL) = (Breg(AL) & 0xf0) | (tmp&0xf); tmp = tmp2 | (tmp>>4); PutbackRMByte(ModRM,tmp); CLKM(17,17,13,32,32,19); break; - case 0x31 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield INS\n",PC()); break; - case 0x33 : ModRM = fetch(); ModRM=0; logerror("%06x: Unimplemented bitfield EXT\n",PC()); break; + case 0x31 : // INS reg1,reg2 + ModRM = fetch(); + tmp = GetRMByte(0xc0 | (ModRM & 7)) & 0x0f; + tmp2 = (GetRMByte(0xc0 |(ModRM >> 3) & 7) & 0x0f) + 1; + PutMemW(DS1, Wreg(IY), (GetMemW(DS1, Wreg(IY)) & ~(((1 << tmp2) - 1) << tmp)) | ((Wreg(AW) & ((1 << tmp2) - 1)) << tmp)); + if (tmp + tmp2 > 15) { + Wreg(IY) += 2; + PutMemW(DS1, Wreg(IY), (GetMemW(DS1, Wreg(IY)) & ~((1 << (tmp2 - (16 - tmp))) - 1)) | ((Wreg(AW) >> (16 - tmp)) & ((1 << (tmp2 - (16 - tmp))) - 1))); + } + PutRMByte(ModRM, (tmp + tmp2) & 0x0f); + // When and how many extra cycles are taken is not documented: + // V20: 35-113 cycles + // V30: 35-133 cycles, odd addresses + // V30: 31-117 cycles, even addresses + // V33: 39-77 cycles, odd addresses + // V33: 37-69 cycles, even addresses + if (Wreg(IY) & 1) { + CLKS(113, 113, 77); + } else { + CLKS(113, 117, 69); + } + break; + case 0x33 : // EXT reg1,reg2 + ModRM = fetch(); + tmp = GetRMByte(0xc0 | (ModRM & 7)) & 0x0f; + tmp2 = (GetRMByte(0xc0 |(ModRM >> 3) & 7) & 0x0f) + 1; + Wreg(AW) = GetMemW(DS0, Wreg(IX)) >> tmp; + if (tmp + tmp2 > 15) { + Wreg(IX) += 2; + Wreg(AW) |= GetMemW(DS0, Wreg(IX)) << (16 - tmp); + } + Wreg(AW) &= ((1 << tmp2) - 1); + PutRMByte(ModRM, (tmp + tmp2) & 0x0f); + // When and how many extra cycles are taken is not documented: + // V20: 34-59 cycles + // V30: 34-59 cycles, odd addresses + // V30: 26-55 cycles, even addresses + // V33: 33-63 cycles, odd addresses + // V33: 29-61 cycles, even addresses + if (Wreg(IX) & 1) { + CLKS(59, 59, 63); + } else { + CLKS(59, 55, 62); + } + break; case 0x39 : // INS reg,imm4 ModRM = fetch(); tmp = GetRMByte(ModRM) & 0x0f; -- cgit v1.2.3