diff options
Diffstat (limited to 'src/emu/cpu/i86/instrv30.c')
-rw-r--r-- | src/emu/cpu/i86/instrv30.c | 1311 |
1 files changed, 1311 insertions, 0 deletions
diff --git a/src/emu/cpu/i86/instrv30.c b/src/emu/cpu/i86/instrv30.c new file mode 100644 index 00000000000..39272760f8f --- /dev/null +++ b/src/emu/cpu/i86/instrv30.c @@ -0,0 +1,1311 @@ +static void PREFIXV30(_0fpre) (void) /* Opcode 0x0f */ +{ + unsigned Opcode = FETCH; + unsigned ModRM; + unsigned tmp; + unsigned tmp2; + + switch (Opcode) + { + case 0x10: /* 0F 10 47 30 - TEST1 [bx+30h],cl */ + ModRM = FETCH; + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 3; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 12; /* my source says 14 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = I.regs.b[CL] & 0x7; + I.ZeroVal = tmp & bytes[tmp2] ? 1 : 0; +/* SetZF(tmp & (1<<tmp2)); */ + break; + + case 0x11: /* 0F 11 47 30 - TEST1 [bx+30h],cl */ + ModRM = FETCH; + /* tmp = GetRMWord(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.w[Mod_RM.RM.w[ModRM]]; + nec_ICount -= 3; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadWord(EA); + nec_ICount = old - 12; /* my source says 14 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = I.regs.b[CL] & 0xF; + I.ZeroVal = tmp & bytes[tmp2] ? 1 : 0; +/* SetZF(tmp & (1<<tmp2)); */ + break; + + case 0x12: /* 0F 12 [mod:000:r/m] - CLR1 reg/m8,cl */ + ModRM = FETCH; + /* need the long if due to correct cycles OB[19.07.99] */ + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 5; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 14; /* my source says 14 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = I.regs.b[CL] & 0x7; /* hey its a Byte so &07 NOT &0f */ + tmp &= ~(bytes[tmp2]); + PutbackRMByte(ModRM, tmp); + break; + + case 0x13: /* 0F 13 [mod:000:r/m] - CLR1 reg/m16,cl */ + ModRM = FETCH; + /* tmp = GetRMWord(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.w[Mod_RM.RM.w[ModRM]]; + nec_ICount -= 5; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadWord(EA); + nec_ICount = old - 14; /* my source says 14 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = I.regs.b[CL] & 0xF; /* this time its a word */ + tmp &= ~(bytes[tmp2]); + PutbackRMWord(ModRM, tmp); + break; + + case 0x14: /* 0F 14 47 30 - SET1 [bx+30h],cl */ + ModRM = FETCH; + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 4; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 13; + } + tmp2 = I.regs.b[CL] & 0x7; + tmp |= (bytes[tmp2]); + PutbackRMByte(ModRM, tmp); + break; + + case 0x15: /* 0F 15 C6 - SET1 si,cl */ + ModRM = FETCH; + /* tmp = GetRMWord(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.w[Mod_RM.RM.w[ModRM]]; + nec_ICount -= 4; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadWord(EA); + nec_ICount = old - 13; + } + tmp2 = I.regs.b[CL] & 0xF; + tmp |= (bytes[tmp2]); + PutbackRMWord(ModRM, tmp); + break; + + case 0x16: /* 0F 16 C6 - NOT1 si,cl */ + ModRM = FETCH; + /* need the long if due to correct cycles OB[19.07.99] */ + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 4; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 18; /* my source says 18 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = I.regs.b[CL] & 0x7; /* hey its a Byte so &07 NOT &0f */ + if (tmp & bytes[tmp2]) + tmp &= ~(bytes[tmp2]); + else + tmp |= (bytes[tmp2]); + PutbackRMByte(ModRM, tmp); + break; + + case 0x17: /* 0F 17 C6 - NOT1 si,cl */ + ModRM = FETCH; + /* tmp = GetRMWord(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.w[Mod_RM.RM.w[ModRM]]; + nec_ICount -= 4; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadWord(EA); + nec_ICount = old - 18; /* my source says 14 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = I.regs.b[CL] & 0xF; /* this time its a word */ + if (tmp & bytes[tmp2]) + tmp &= ~(bytes[tmp2]); + else + tmp |= (bytes[tmp2]); + PutbackRMWord(ModRM, tmp); + break; + + case 0x18: /* 0F 18 XX - TEST1 [bx+30h],07 */ + ModRM = FETCH; + /* tmp = GetRMByte(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 4; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 13; /* my source says 15 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = FETCH; + tmp2 &= 0xF; + I.ZeroVal = tmp & (bytes[tmp2]) ? 1 : 0; +/* SetZF(tmp & (1<<tmp2)); */ + break; + + case 0x19: /* 0F 19 XX - TEST1 [bx+30h],07 */ + ModRM = FETCH; + /* tmp = GetRMWord(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.w[Mod_RM.RM.w[ModRM]]; + nec_ICount -= 4; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadWord(EA); + nec_ICount = old - 13; /* my source says 14 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = FETCH; + tmp2 &= 0xf; + I.ZeroVal = tmp & (bytes[tmp2]) ? 1 : 0; +/* SetZF(tmp & (1<<tmp2)); */ + break; + + case 0x1a: /* 0F 1A 06 - CLR1 si,cl */ + ModRM = FETCH; + /* tmp = GetRMByte(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 6; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 15; /* my source says 15 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = FETCH; + tmp2 &= 0x7; + tmp &= ~(bytes[tmp2]); + PutbackRMByte(ModRM, tmp); + break; + + case 0x1B: /* 0F 1B 06 - CLR1 si,cl */ + ModRM = FETCH; + /* tmp = GetRMWord(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.w[Mod_RM.RM.w[ModRM]]; + nec_ICount -= 6; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadWord(EA); + nec_ICount = old - 15; /* my source says 15 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = FETCH; + tmp2 &= 0xF; + tmp &= ~(bytes[tmp2]); + PutbackRMWord(ModRM, tmp); + break; + + case 0x1C: /* 0F 1C 47 30 - SET1 [bx+30h],cl */ + ModRM = FETCH; + /* tmp = GetRMByte(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 5; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 14; /* my source says 15 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = FETCH; + tmp2 &= 0x7; + tmp |= (bytes[tmp2]); + PutbackRMByte(ModRM, tmp); + break; + + case 0x1D: /* 0F 1D C6 - SET1 si,cl */ + /* logerror("PC=%06x : Set1 ",activecpu_get_pc()-2); */ + ModRM = FETCH; + if (ModRM >= 0xc0) + { + tmp = I.regs.w[Mod_RM.RM.w[ModRM]]; + nec_ICount -= 5; + /* logerror("reg=%04x ->",tmp); */ + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); /* calculate EA */ + tmp = ReadWord(EA); /* read from EA */ + nec_ICount = old - 14; + /* logerror("[%04x]=%04x ->",EA,tmp); */ + } + tmp2 = FETCH; + tmp2 &= 0xF; + tmp |= (bytes[tmp2]); + /* logerror("%04x",tmp); */ + PutbackRMWord(ModRM, tmp); + break; + + case 0x1e: /* 0F 1e C6 - NOT1 si,07 */ + ModRM = FETCH; + /* tmp = GetRMByte(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 5; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 19; + } + tmp2 = FETCH; + tmp2 &= 0x7; + if (tmp & bytes[tmp2]) + tmp &= ~(bytes[tmp2]); + else + tmp |= (bytes[tmp2]); + PutbackRMByte(ModRM, tmp); + break; + + case 0x1f: /* 0F 1f C6 - NOT1 si,07 */ + ModRM = FETCH; + //tmp = GetRMWord(ModRM); + if (ModRM >= 0xc0) + { + tmp = I.regs.w[Mod_RM.RM.w[ModRM]]; + nec_ICount -= 5; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadWord(EA); + nec_ICount = old - 19; /* my source says 15 cycles everytime and not + * ModRM-dependent like GetEA[] does..hmmm */ + } + tmp2 = FETCH; + tmp2 &= 0xF; + if (tmp & bytes[tmp2]) + tmp &= ~(bytes[tmp2]); + else + tmp |= (bytes[tmp2]); + PutbackRMWord(ModRM, tmp); + break; + + case 0x20: /* 0F 20 59 - add4s */ + { + /* length in words ! */ + int count = (I.regs.b[CL] + 1) / 2; + int i; + unsigned di = I.regs.w[DI]; + unsigned si = I.regs.w[SI]; + + I.ZeroVal = 1; + I.CarryVal = 0; /* NOT ADC */ + for (i = 0; i < count; i++) + { + int v1, v2; + int result; + + tmp = GetMemB(DS, si); + tmp2 = GetMemB(ES, di); + + v1 = (tmp >> 4) * 10 + (tmp & 0xf); + v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf); + result = v1 + v2 + I.CarryVal; + I.CarryVal = result > 99 ? 1 : 0; + result = result % 100; + v1 = ((result / 10) << 4) | (result % 10); + PutMemB(ES, di, v1); + if (v1) + I.ZeroVal = 0; + si++; + di++; + } + I.OverVal = I.CarryVal; + nec_ICount -= 7 + 19 * count; /* 7+19n, n #operand words */ + } + break; + + case 0x22: /* 0F 22 59 - sub4s */ + { + int count = (I.regs.b[CL] + 1) / 2; + int i; + unsigned di = I.regs.w[DI]; + unsigned si = I.regs.w[SI]; + + I.ZeroVal = 1; + I.CarryVal = 0; /* NOT ADC */ + for (i = 0; i < count; i++) + { + int v1, v2; + int result; + + tmp = GetMemB(ES, di); + tmp2 = GetMemB(DS, si); + + v1 = (tmp >> 4) * 10 + (tmp & 0xf); + v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf); + if (v1 < (v2 + I.CarryVal)) + { + v1 += 100; + result = v1 - (v2 + I.CarryVal); + I.CarryVal = 1; + } + else + { + result = v1 - (v2 + I.CarryVal); + I.CarryVal = 0; + } + v1 = ((result / 10) << 4) | (result % 10); + PutMemB(ES, di, v1); + if (v1) + I.ZeroVal = 0; + si++; + di++; + } + I.OverVal = I.CarryVal; + nec_ICount -= 7 + 19 * count; + } + break; + + case 0x25: + /* + * ----------O-MOVSPA--------------------------------- + * OPCODE MOVSPA - Move Stack Pointer After Bank Switched + * + * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard + * Type of Instruction: System + * + * Instruction: MOVSPA + * + * Description: This instruction transfer both SS and SP of the old register + * bank to new register bank after the bank has been switched by + * interrupt or BRKCS instruction. + * + * Flags Affected: None + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form: MOVSPA + * COP (Code of Operation) : 0Fh 25h + * + * Clocks: 16 + */ + logerror("PC=%06x : MOVSPA\n", activecpu_get_pc() - 2); + nec_ICount -= 16; + break; + case 0x26: /* 0F 22 59 - cmp4s */ + { + int count = (I.regs.b[CL] + 1) / 2; + int i; + unsigned di = I.regs.w[DI]; + unsigned si = I.regs.w[SI]; + + I.ZeroVal = 1; + I.CarryVal = 0; /* NOT ADC */ + for (i = 0; i < count; i++) + { + int v1, v2; + int result; + + tmp = GetMemB(ES, di); + tmp2 = GetMemB(DS, si); + + v1 = (tmp >> 4) * 10 + (tmp & 0xf); + v2 = (tmp2 >> 4) * 10 + (tmp2 & 0xf); + if (v1 < (v2 + I.CarryVal)) + { + v1 += 100; + result = v1 - (v2 + I.CarryVal); + I.CarryVal = 1; + } + else + { + result = v1 - (v2 + I.CarryVal); + I.CarryVal = 0; + } + v1 = ((result / 10) << 4) | (result % 10); +/* PutMemB(ES, di,v1); */ /* no store, only compare */ + if (v1) + I.ZeroVal = 0; + si++; + di++; + } + I.OverVal = I.CarryVal; + nec_ICount -= 7 + 19 * (I.regs.b[CL] + 1); // 7+19n, n #operand bytes + } + break; + case 0x28: /* 0F 28 C7 - ROL4 bh */ + ModRM = FETCH; + /* tmp = GetRMByte(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 25; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 28; + } + tmp <<= 4; + tmp |= I.regs.b[AL] & 0xF; + I.regs.b[AL] = (I.regs.b[AL] & 0xF0) | ((tmp >> 8) & 0xF); + tmp &= 0xff; + PutbackRMByte(ModRM, tmp); + break; + + /* Is this a REAL instruction?? */ + case 0x29: /* 0F 29 C7 - ROL4 bx */ + + ModRM = FETCH; + /* + * if (ModRM >= 0xc0) + * { + * tmp=I.regs.w[Mod_RM.RM.w[ModRM]]; + * nec_ICount-=29; + * } + * else + * { + * int old=nec_ICount; + * (*GetEA[ModRM])(); + * tmp=ReadWord(EA); + * nec_ICount=old-33; + * } + * tmp <<= 4; + * tmp |= I.regs.b[AL] & 0xF; + * I.regs.b[AL] = (I.regs.b[AL] & 0xF0) | ((tmp>>8)&0xF); + * tmp &= 0xffff; + * PutbackRMWord(ModRM,tmp); + */ + logerror("PC=%06x : ROL4 %02x\n", activecpu_get_pc() - 3, ModRM); + break; + + case 0x2A: /* 0F 2a c2 - ROR4 bh */ + ModRM = FETCH; + /* tmp = GetRMByte(ModRM); */ + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + nec_ICount -= 29; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + nec_ICount = old - 33; + } + tmp2 = (I.regs.b[AL] & 0xF) << 4; + I.regs.b[AL] = (I.regs.b[AL] & 0xF0) | (tmp & 0xF); + tmp = tmp2 | (tmp >> 4); + PutbackRMByte(ModRM, tmp); + break; + + case 0x2B: // 0F 2b c2 - ROR4 bx + ModRM = FETCH; + /* + * /* tmp = GetRMWord(ModRM); + * if (ModRM >= 0xc0) + * { + * tmp=I.regs.w[Mod_RM.RM.w[ModRM]]; + * nec_ICount-=29; + * } + * else { + * int old=nec_ICount; + * (*GetEA[ModRM])(); + * tmp=ReadWord(EA); + * nec_ICount=old-33; + * } + * tmp2 = (I.regs.b[AL] & 0xF)<<4; + * I.regs.b[AL] = (I.regs.b[AL] & 0xF0) | (tmp&0xF); + * tmp = tmp2 | (tmp>>4); + * PutbackRMWord(ModRM,tmp); + */ + logerror("PC=%06x : ROR4 %02x\n", activecpu_get_pc() - 3, ModRM); + break; + + case 0x2D: /* 0Fh 2Dh <1111 1RRR> */ + /* OPCODE BRKCS - Break with Contex Switch + * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard + * Description: + * + * Perform a High-Speed Software Interrupt with contex-switch to + * register bank indicated by the lower 3-bits of 'bank'. + * + * Info: NEC V25/V35/V25 Plus/V35 Plus Bank System + * + * This Chips have 8 32bytes register banks, which placed in + * Internal chip RAM by addresses: + * xxE00h..xxE1Fh Bank 0 + * xxE20h..xxE3Fh Bank 1 + * ......... + * xxEC0h..xxEDFh Bank 6 + * xxEE0h..xxEFFh Bank 7 + * xxF00h..xxFFFh Special Functions Register + * Where xx is Value of IDB register. + * IBD is Byte Register contained Internal data area base + * IBD addresses is FFFFFh and xxFFFh where xx is data in IBD. + * + * Format of Bank: + * +0 Reserved + * +2 Vector PC + * +4 Save PSW + * +6 Save PC + * +8 DS0 ;DS + * +A SS ;SS + * +C PS ;CS + * +E DS1 ;ES + * +10 IY ;DI + * +11 IX ;SI + * +14 BP ;BP + * +16 SP ;SP + * +18 BW ;BX + * +1A DW ;DX + * +1C CW ;CX + * +1E AW ;AX + * + * Format of V25 etc. PSW (FLAGS): + * Bit Description + * 15 1 + * 14 RB2 \ + * 13 RB1 > Current Bank Number + * 12 RB0 / + * 11 V ;OF + * 10 IYR ;DF + * 9 IE ;IF + * 8 BRK ;TF + * 7 S ;SF + * 6 Z ;ZF + * 5 F1 General Purpose user flag #1 (accessed by Flag Special Function Register) + * 4 AC ;AF + * 3 F0 General purpose user flag #0 (accessed by Flag Special Function Register) + * 2 P ;PF + * 1 BRKI I/O Trap Enable Flag + * 0 CY ;CF + * + * Flags Affected: None + */ + ModRM = FETCH; + logerror("PC=%06x : BRKCS %02x\n", activecpu_get_pc() - 3, ModRM); + nec_ICount -= 15; /* checked ! */ + break; + + case 0x31: /* 0F 31 [mod:reg:r/m] - INS reg8,reg8 or INS reg8,imm4 */ + ModRM = FETCH; + logerror("PC=%06x : INS ", activecpu_get_pc() - 2); + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + logerror("ModRM=%04x \n", ModRM); + nec_ICount -= 29; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + logerror("ModRM=%04x Byte=%04x\n", EA, tmp); + nec_ICount = old - 33; + } + + /* more to come + * bfl=tmp2 & 0xf; /* bit field length + * bfs=tmp & 0xf; /* bit field start (bit offset in DS:SI) + * I.regs.b[AH] =0; /* AH =0 + */ + + /* 2do: the rest is silence....yet + * ----------O-INS------------------------------------ + * OPCODE INS - Insert Bit String + * + * CPU: NEC/Sony all V-series + * Type of Instruction: User + * + * Instruction: INS start,len + * + * Description: + * + * BitField [ BASE = ES:DI + * START BIT OFFSET = start + * LENGTH = len + * ] <- AX [ bits= (len-1)..0] + * + * Note: di and start automatically UPDATE + * Note: Alternative Name of this instruction is NECINS + * + * Flags Affected: None + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form : INS reg8,reg8 + * COP (Code of Operation) : 0FH 31H PostByte + */ + + /* nec_ICount-=31; */ /* 31 -117 clocks ....*/ + break; + + case 0x33: /* 0F 33 [mod:reg:r/m] - EXT reg8,reg8 or EXT reg8,imm4 */ + ModRM = FETCH; + logerror("PC=%06x : EXT ", activecpu_get_pc() - 2); + if (ModRM >= 0xc0) + { + tmp = I.regs.b[Mod_RM.RM.b[ModRM]]; + logerror("ModRM=%04x \n", ModRM); + nec_ICount -= 29; + } + else + { + int old = nec_ICount; + + (*GetEA[ModRM]) (); + tmp = ReadByte(EA); + logerror("ModRM=%04x Byte=%04x\n", EA, tmp); + nec_ICount = old - 33; + } + /* 2do: the rest is silence....yet + /* + * bfl=tmp2 & 0xf; /* bit field length + * bfs=tmp & 0xf; /* bit field start (bit offset in DS:SI) + * I.regs.b[AH] =0; /* AH =0 + */ + + /* + * + * ----------O-EXT------------------------------------ + * OPCODE EXT - Extract Bit Field + * + * CPU: NEC/Sony all V-series + * Type of Instruction: User + * + * Instruction: EXT start,len + * + * Description: + * + * AX <- BitField [ + * BASE = DS:SI + * START BIT OFFSET = start + * LENGTH = len + * ]; + * + * Note: si and start automatically UPDATE + * + * Flags Affected: None + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form : EXT reg8,reg8 + * COP (Code of Operation) : 0FH 33H PostByte + * + * Clocks: EXT reg8,reg8 + * NEC V20: 26-55 + */ + + /* NEC_ICount-=26; */ /* 26 -55 clocks ....*/ + break; + + case 0x91: + /* + * ----------O-RETRBI--------------------------------- + * OPCODE RETRBI - Return from Register Bank Context + * Switch Interrupt. + * + * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard + * Type of Instruction: System + * + * Instruction: RETRBI + * + * Description: + * + * PC <- Save PC; + * PSW <- Save PSW; + * + * Flags Affected: All + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form: RETRBI + * COP (Code of Operation) : 0Fh 91h + * + * Clocks: 12 + */ + logerror("PC=%06x : RETRBI\n", activecpu_get_pc() - 2); + nec_ICount -= 12; + break; + + case 0x94: + /* + * ----------O-TSKSW---------------------------------- + * OPCODE TSKSW - Task Switch + * + * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard + * Type of Instruction: System + * + * Instruction: TSKSW reg16 + * + * Description: Perform a High-Speed task switch to the register bank indicated + * by lower 3 bits of reg16. The PC and PSW are saved in the old + * banks. PC and PSW save Registers and the new PC and PSW values + * are retrived from the new register bank's save area. + * + * Note: See BRKCS instruction for more Info about banks. + * + * Flags Affected: All + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form: TSCSW reg16 + * COP (Code of Operation) : 0Fh 94h <1111 1RRR> + * + * Clocks: 11 + */ + ModRM = FETCH; + + logerror("PC=%06x : TSCSW %02x\n", activecpu_get_pc() - 3, ModRM); + nec_ICount -= 11; + break; + + case 0x95: + /* + * ----------O-MOVSPB--------------------------------- + * OPCODE MOVSPB - Move Stack Pointer Before Bamk Switching + * + * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard + * Type of Instruction: System + * + * Instruction: MOVSPB Number_of_bank + * + * Description: The MOVSPB instruction transfers the current SP and SS before + * the bank switching to new register bank. + * + * Note: New Register Bank Number indicated by lower 3bit of Number_of_ + * _bank. + * + * Note: See BRKCS instruction for more info about banks. + * + * Flags Affected: None + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form: MOVSPB reg16 + * COP (Code of Operation) : 0Fh 95h <1111 1RRR> + * + * Clocks: 11 + */ + ModRM = FETCH; + logerror("PC=%06x : MOVSPB %02x\n", activecpu_get_pc() - 3, ModRM); + nec_ICount -= 11; + break; + + case 0xbe: + /* + * ----------O-STOP----------------------------------- + * OPCODE STOP - Stop CPU + * + * CPU: NEC V25,V35,V25 Plus,V35 Plus,V25 Software Guard + * Type of Instruction: System + * + * Instruction: STOP + * + * Description: + * PowerDown instruction, Stop Oscillator, + * Halt CPU. + * + * Flags Affected: None + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form: STOP + * COP (Code of Operation) : 0Fh BEh + * + * Clocks: N/A + */ + logerror("PC=%06x : STOP\n", activecpu_get_pc() - 2); + nec_ICount -= 2; /* of course this is crap */ + break; + + case 0xe0: + /* + * ----------O-BRKXA---------------------------------- + * OPCODE BRKXA - Break to Expansion Address + * + * CPU: NEC V33/V53 only + * Type of Instruction: System + * + * Instruction: BRKXA int_vector + * + * Description: + * [sp-1,sp-2] <- PSW ; PSW EQU FLAGS + * [sp-3,sp-4] <- PS ; PS EQU CS + * [sp-5,sp-6] <- PC ; PC EQU IP + * SP <- SP -6 + * IE <- 0 + * BRK <- 0 + * MD <- 0 + * PC <- [int_vector*4 +0,+1] + * PS <- [int_vector*4 +2,+3] + * Enter Expansion Address Mode. + * + * Note: In NEC V53 Memory Space dividing into 1024 16K pages. + * The programming model is Same as in Normal mode. + * + * Mechanism is: + * 20 bit Logical Address: 19..14 Page Num 13..0 Offset + * + * page Num convertin by internal table to 23..14 Page Base + * tHE pHYIXCAL ADDRESS is both Base and Offset. + * + * Address Expansion Registers: + * logical Address A19..A14 I/O Address + * 0 FF00h + * 1 FF02h + * ... ... + * 63 FF7Eh + * + * Register XAM aliased with port # FF80h indicated current mode + * of operation. + * Format of XAM register (READ ONLY): + * 15..1 reserved + * 0 XA Flag, if=1 then in XA mode. + * + * Format of V53 PSW: + * 15..12 1 + * 11 V + * 10 IYR + * 9 IE + * 8 BRK + * 7 S + * 6 Z + * 5 0 + * 4 AC + * 3 0 + * 2 P + * 1 1 + * 0 CY + * + * Flags Affected: None + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form: BRKXA imm8 + * COP (Code of Operation) : 0Fh E0h imm8 + */ + + ModRM = FETCH; + logerror("PC=%06x : BRKXA %02x\n", activecpu_get_pc() - 3, ModRM); + nec_ICount -= 12; + break; + + case 0xf0: + /* + * ----------O-RETXA---------------------------------- + * OPCODE RETXA - Return from Expansion Address + * + * CPU: NEC V33/V53 only + * Type of Instruction: System + * + * Instruction: RETXA int_vector + * + * Description: + * [sp-1,sp-2] <- PSW ; PSW EQU FLAGS + * [sp-3,sp-4] <- PS ; PS EQU CS + * [sp-5,sp-6] <- PC ; PC EQU IP + * SP <- SP -6 + * IE <- 0 + * BRK <- 0 + * MD <- 0 + * PC <- [int_vector*4 +0,+1] + * PS <- [int_vector*4 +2,+3] + * Disable EA mode. + * + * Flags Affected: None + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form: RETXA imm8 + * COP (Code of Operation) : 0Fh F0h imm8 + * + * Clocks: 12 + */ + ModRM = FETCH; + logerror("PC=%06x : RETXA %02x\n", activecpu_get_pc() - 3, ModRM); + nec_ICount -= 12; + break; + + case 0xff: /* 0F ff imm8 - BRKEM */ + /* + * OPCODE BRKEM - Break for Emulation + * + * CPU: NEC/Sony V20/V30/V40/V50 + * Description: + * + * PUSH FLAGS + * PUSH CS + * PUSH IP + * MOV CS,0:[intnum*4+2] + * MOV IP,0:[intnum*4] + * MD <- 0; // Enable 8080 emulation + * + * Note: + * BRKEM instruction do software interrupt and then New CS,IP loaded + * it switch to 8080 mode i.e. CPU will execute 8080 code. + * Mapping Table of Registers in 8080 Mode + * 8080 Md. A B C D E H L SP PC F + * native. AL CH CL DH DL BH BL BP IP FLAGS(low) + * For Return of 8080 mode use CALLN instruction. + * Note: I.e. 8080 addressing only 64KB then "Real Address" is CS*16+PC + * + * Flags Affected: MD + */ + ModRM = FETCH; + nec_ICount -= 38; + logerror("PC=%06x : BRKEM %02x\n", activecpu_get_pc() - 3, ModRM); + PREFIXV30(_interrupt) (ModRM, 1); + break; + } +} + +static void PREFIXV30(_brkn) (void) /* Opcode 0x63 BRKN - Break to Native Mode */ +{ + /* + * CPU: NEC (V25/V35) Software Guard only + * Instruction: BRKN int_vector + * + * Description: + * [sp-1,sp-2] <- PSW ; PSW EQU FLAGS + * [sp-3,sp-4] <- PS ; PS EQU CS + * [sp-5,sp-6] <- PC ; PC EQU IP + * SP <- SP -6 + * IE <- 0 + * BRK <- 0 + * MD <- 1 + * PC <- [int_vector*4 +0,+1] + * PS <- [int_vector*4 +2,+3] + * + * Note: The BRKN instruction switches operations in Native Mode + * from Security Mode via Interrupt call. In Normal Mode + * Instruction executed as mPD70320/70322 (V25) operation mode. + * + * Flags Affected: None + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form: BRKN imm8 + * COP (Code of Operation) : 63h imm8 + * + * Clocks: 56+10T [44+10T] + */ + /* nec_ICount-=56; */ + unsigned int_vector; + + int_vector = FETCH; + logerror("PC=%06x : BRKN %02x\n", activecpu_get_pc() - 2, int_vector); +} + +static void PREFIXV30(repc) (int flagval) +{ + /* Handles repc- and repnc- prefixes. flagval is the value of ZF + * for the loop to continue for CMPS and SCAS instructions. + */ + + unsigned next = FETCHOP; + unsigned count = I.regs.w[CX]; + + switch (next) + { + case 0x26: /* ES: */ + seg_prefix = TRUE; + prefix_base = I.base[ES]; + nec_ICount -= 2; + PREFIXV30(repc) (flagval); + break; + case 0x2e: /* CS: */ + seg_prefix = TRUE; + prefix_base = I.base[CS]; + nec_ICount -= 2; + PREFIXV30(repc) (flagval); + break; + case 0x36: /* SS: */ + seg_prefix = TRUE; + prefix_base = I.base[SS]; + nec_ICount -= 2; + PREFIXV30(repc) (flagval); + break; + case 0x3e: /* DS: */ + seg_prefix = TRUE; + prefix_base = I.base[DS]; + nec_ICount -= 2; + PREFIXV30(repc) (flagval); + break; + case 0x6c: /* REP INSB */ + nec_ICount -= 9 - count; + for (; (CF == flagval) && (count > 0); count--) + PREFIX186(_insb) (); + I.regs.w[CX] = count; + break; + case 0x6d: /* REP INSW */ + nec_ICount -= 9 - count; + for (; (CF == flagval) && (count > 0); count--) + PREFIX186(_insw) (); + I.regs.w[CX] = count; + break; + case 0x6e: /* REP OUTSB */ + nec_ICount -= 9 - count; + for (; (CF == flagval) && (count > 0); count--) + PREFIX186(_outsb) (); + I.regs.w[CX] = count; + break; + case 0x6f: /* REP OUTSW */ + nec_ICount -= 9 - count; + for (; (CF == flagval) && (count > 0); count--) + PREFIX186(_outsw) (); + I.regs.w[CX] = count; + break; + case 0xa4: /* REP MOVSB */ + nec_ICount -= 9 - count; + for (; (CF == flagval) && (count > 0); count--) + PREFIX86(_movsb) (); + I.regs.w[CX] = count; + break; + case 0xa5: /* REP MOVSW */ + nec_ICount -= 9 - count; + for (; (CF == flagval) && (count > 0); count--) + PREFIX86(_movsw) (); + I.regs.w[CX] = count; + break; + case 0xa6: /* REP(N)E CMPSB */ + nec_ICount -= 9; + for (I.ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) + PREFIX86(_cmpsb) (); + I.regs.w[CX] = count; + break; + case 0xa7: /* REP(N)E CMPSW */ + nec_ICount -= 9; + for (I.ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) + PREFIX86(_cmpsw) (); + I.regs.w[CX] = count; + break; + case 0xaa: /* REP STOSB */ + nec_ICount -= 9 - count; + for (; (CF == flagval) && (count > 0); count--) + PREFIX86(_stosb) (); + I.regs.w[CX] = count; + break; + case 0xab: /* REP STOSW */ + nec_ICount -= 9 - count; + for (; (CF == flagval) && (count > 0); count--) + PREFIX86(_stosw) (); + I.regs.w[CX] = count; + break; + case 0xac: /* REP LODSB */ + nec_ICount -= 9; + for (; (CF == flagval) && (count > 0); count--) + PREFIX86(_lodsb) (); + I.regs.w[CX] = count; + break; + case 0xad: /* REP LODSW */ + nec_ICount -= 9; + for (; (CF == flagval) && (count > 0); count--) + PREFIX86(_lodsw) (); + I.regs.w[CX] = count; + break; + case 0xae: /* REP(N)E SCASB */ + nec_ICount -= 9; + for (I.ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) + PREFIX86(_scasb) (); + I.regs.w[CX] = count; + break; + case 0xaf: /* REP(N)E SCASW */ + nec_ICount -= 9; + for (I.ZeroVal = !flagval; (ZF == flagval) && (CF == flagval) && (count > 0); count--) + PREFIX86(_scasw) (); + I.regs.w[CX] = count; + break; + default: + PREFIXV30(_instruction)[next] (); + } +} + +static void PREFIXV30(_repnc) (void) /* Opcode 0x64 */ +{ + PREFIXV30(repc) (0); +} + +static void PREFIXV30(_repc) (void) /* Opcode 0x65 */ +{ + PREFIXV30(repc) (1); +} + +static void PREFIXV30(_setalc) (void) /* Opcode 0xd6 */ +{ + /* + * ----------O-SETALC--------------------------------- + * OPCODE SETALC - Set AL to Carry Flag + * + * CPU: Intel 8086 and all its clones and upward + * compatibility chips. + * Type of Instruction: User + * + * Instruction: SETALC + * + * Description: + * + * IF (CF=0) THEN AL:=0 ELSE AL:=FFH; + * + * Flags Affected: None + * + * CPU mode: RM,PM,VM,SMM + * + * Physical Form: SETALC + * COP (Code of Operation): D6H + * Clocks: 80286 : n/a [3] + * 80386 : n/a [3] + * Cx486SLC : n/a [2] + * i486 : n/a [3] + * Pentium : n/a [3] + * Note: n/a is Time that Intel etc not say. + * [3] is real time it executed. + * + */ + I.regs.b[AL] = (CF) ? 0xff : 0x00; + nec_ICount -= 3; // V30 + logerror("PC=%06x : SETALC\n", activecpu_get_pc() - 1); +} + +#if 0 +static void PREFIXV30(_brks) (void) /* Opcode 0xf1 - Break to Security Mode */ +{ + /* + * CPU: NEC (V25/V35) Software Guard only + * Instruction: BRKS int_vector + * + * Description: + * [sp-1,sp-2] <- PSW ; PSW EQU FLAGS + * [sp-3,sp-4] <- PS ; PS EQU CS + * [sp-5,sp-6] <- PC ; PC EQU IP + * SP <- SP -6 + * IE <- 0 + * BRK <- 0 + * MD <- 0 + * PC <- [int_vector*4 +0,+1] + * PS <- [int_vector*4 +2,+3] + * + * Note: The BRKS instruction switches operations in Security Mode + * via Interrupt call. In Security Mode the fetched operation + * code is executed after conversion in accordance with build-in + * translation table + * + * Flags Affected: None + * + * CPU mode: RM + * + * +++++++++++++++++++++++ + * Physical Form: BRKS imm8 + * Clocks: 56+10T [44+10T] + */ + unsigned int_vector; + + int_vector = FETCH; + logerror("PC=%06x : BRKS %02x\n", activecpu_get_pc() - 2, int_vector); +} +#endif |