summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/nec/necinstr.hxx
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/nec/necinstr.hxx')
-rw-r--r--src/devices/cpu/nec/necinstr.hxx98
1 files changed, 93 insertions, 5 deletions
diff --git a/src/devices/cpu/nec/necinstr.hxx b/src/devices/cpu/nec/necinstr.hxx
index f1209d675a9..11abacbedb0 100644
--- a/src/devices/cpu/nec/necinstr.hxx
+++ b/src/devices/cpu/nec/necinstr.hxx
@@ -43,11 +43,99 @@ 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;
+ tmp2 = (fetch() & 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: 75-103 cycles
+ // V30: 75-103 cycles, odd addresses
+ // V30: 67-87 cycles, even addresses
+ // V33: 39-77 cycles, odd addresses
+ // V33: 37-69 cycles, even addresses
+ if (Wreg(IY) & 1) {
+ CLKS(103, 103, 77);
+ } else {
+ CLKS(103, 87, 69);
+ }
+ break;
+ case 0x3b : // EXT reg,imm4
+ ModRM = fetch();
+ tmp = GetRMByte(ModRM) & 0x0f;
+ tmp2 = (fetch() & 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: 25-52 cycles
+ // V30: 25-52 cycles, odd addresses
+ // V30: 21-44 cycles, even addresses
+ // V33: 33-63 cycles, odd addresses
+ // V33: 29-61 cycles, even addresses
+ if (Wreg(IX) & 1) {
+ CLKS(52, 52, 63);
+ } else {
+ CLKS(52, 44, 62);
+ }
+ break;
case 0xe0 : BRKXA(true); CLK(12); break;
case 0xf0 : BRKXA(false); CLK(12); break;
- case 0xff : ModRM = fetch(); ModRM=0; logerror("%06x: unimplemented BRKEM (break to 8080 emulation mode)\n",PC()); break;
+ case 0xff : BRKEM; CLK(50); break;
default: logerror("%06x: Unknown V20 instruction\n",PC()); break;
}
}
@@ -334,7 +422,7 @@ OP( 0x8c, i_mov_wsreg ) { GetModRM;
default: logerror("%06x: MOV Sreg - Invalid register\n",PC());
}
}
-OP( 0x8d, i_lea ) { uint16_t ModRM = fetch(); (void)(this->*s_GetEA[ModRM])(); RegWord(ModRM)=m_EO; CLKS(4,4,2); }
+OP( 0x8d, i_lea ) { uint16_t ModRM = fetch(); if (ModRM >= 0xc0) logerror("LDEA invalid mode %Xh\n", ModRM); else { (void)(this->*s_GetEA[ModRM])(); RegWord(ModRM)=m_EO; } CLKS(4,4,2); }
OP( 0x8e, i_mov_sregw ) { uint16_t src; GetModRM; src = GetRMWord(ModRM); CLKR(15,15,7,15,11,5,2,m_EA);
switch (ModRM & 0x38) {
case 0x00: Sreg(DS1) = src; break; /* mov es,ew */
@@ -610,7 +698,7 @@ OP( 0xf3, i_repe ) { uint32_t next = fetchop(); uint16_t c = Wreg(CW);
}
m_seg_prefix=false;
}
-OP( 0xf4, i_hlt ) { logerror("%06x: HALT\n",PC()); m_halted=1; m_icount=0; }
+OP( 0xf4, i_hlt ) { m_halted=1; m_icount=0; }
OP( 0xf5, i_cmc ) { m_CarryVal = !CF; CLK(2); }
OP( 0xf6, i_f6pre ) { uint32_t tmp; uint32_t uresult,uresult2; int32_t result,result2;
GetModRM; tmp = GetRMByte(ModRM);