📄 i86.c
字号:
cycle_count-=9;
for (; count > 0; count--)
i_lodsw();
regs.w[CX]=count;
break;
case 0xae: /* REP(N)E SCASB */
cycle_count-=9;
for (ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
i_scasb();
regs.w[CX]=count;
break;
case 0xaf: /* REP(N)E SCASW */
cycle_count-=9;
for (ZeroVal = !flagval; (ZF == flagval) && (count > 0); count--)
i_scasw();
regs.w[CX]=count;
break;
default:
instruction[next]();
}
}
static void i_repne(void) /* Opcode 0xf2 */
{
rep(0);
}
static void i_repe(void) /* Opcode 0xf3 */
{
rep(1);
}
static void i_hlt(void) /* Opcode 0xf4 */
{
cycle_count=0;
}
static void i_cmc(void) /* Opcode 0xf5 */
{
cycle_count-=2;
CarryVal = !CF;
}
static void i_f6pre(void)
{
/* Opcode 0xf6 */
unsigned ModRM = FETCH;
unsigned tmp = (unsigned)GetRMByte(ModRM);
unsigned tmp2;
switch (ModRM & 0x38)
{
case 0x00: /* TEST Eb, data8 */
case 0x08: /* ??? */
cycle_count-=5;
tmp &= FETCH;
CarryVal = OverVal = AuxVal = 0;
SetSZPF_Byte(tmp);
break;
case 0x10: /* NOT Eb */
cycle_count-=3;
PutbackRMByte(ModRM,~tmp);
break;
case 0x18: /* NEG Eb */
cycle_count-=3;
tmp2=0;
SUBB(tmp2,tmp);
PutbackRMByte(ModRM,tmp2);
break;
case 0x20: /* MUL AL, Eb */
cycle_count-=77;
{
UINT16 result;
tmp2 = regs.b[AL];
SetSF((INT8)tmp2);
SetPF(tmp2);
result = (UINT16)tmp2*tmp;
regs.w[AX]=(WORD)result;
SetZF(regs.w[AX]);
CarryVal = OverVal = (regs.b[AH] != 0);
}
break;
case 0x28: /* IMUL AL, Eb */
cycle_count-=80;
{
INT16 result;
tmp2 = (unsigned)regs.b[AL];
SetSF((INT8)tmp2);
SetPF(tmp2);
result = (INT16)((INT8)tmp2)*(INT16)((INT8)tmp);
regs.w[AX]=(WORD)result;
SetZF(regs.w[AX]);
CarryVal = OverVal = (result >> 7 != 0) && (result >> 7 != -1);
}
break;
case 0x30: /* DIV AL, Ew */
cycle_count-=90;
{
UINT16 result;
result = regs.w[AX];
if (tmp)
{
if ((result / tmp) > 0xff)
{
I86_interrupt(0);
break;
}
else
{
regs.b[AH] = result % tmp;
regs.b[AL] = result / tmp;
}
}
else
{
I86_interrupt(0);
break;
}
}
break;
case 0x38: /* IDIV AL, Ew */
cycle_count-=106;
{
INT16 result;
result = regs.w[AX];
if (tmp)
{
tmp2 = result % (INT16)((INT8)tmp);
if ((result /= (INT16)((INT8)tmp)) > 0xff)
{
I86_interrupt(0);
break;
}
else
{
regs.b[AL] = result;
regs.b[AH] = tmp2;
}
}
else
{
I86_interrupt(0);
break;
}
}
break;
}
}
static void i_f7pre(void)
{
/* Opcode 0xf7 */
unsigned ModRM = FETCH;
unsigned tmp = GetRMWord(ModRM);
unsigned tmp2;
switch (ModRM & 0x38)
{
case 0x00: /* TEST Ew, data16 */
case 0x08: /* ??? */
cycle_count-=3;
tmp2 = FETCH;
tmp2 += FETCH << 8;
tmp &= tmp2;
CarryVal = OverVal = AuxVal = 0;
SetSZPF_Word(tmp);
break;
case 0x10: /* NOT Ew */
cycle_count-=3;
tmp = ~tmp;
PutbackRMWord(ModRM,tmp);
break;
case 0x18: /* NEG Ew */
cycle_count-=3;
tmp2 = 0;
SUBW(tmp2,tmp);
PutbackRMWord(ModRM,tmp2);
break;
case 0x20: /* MUL AX, Ew */
cycle_count-=129;
{
UINT32 result;
tmp2 = regs.w[AX];
SetSF((INT16)tmp2);
SetPF(tmp2);
result = (UINT32)tmp2*tmp;
regs.w[AX]=(WORD)result;
result >>= 16;
regs.w[DX]=result;
SetZF(regs.w[AX] | regs.w[DX]);
CarryVal = OverVal = (regs.w[DX] != 0);
}
break;
case 0x28: /* IMUL AX, Ew */
cycle_count-=150;
{
INT32 result;
tmp2 = regs.w[AX];
SetSF((INT16)tmp2);
SetPF(tmp2);
result = (INT32)((INT16)tmp2)*(INT32)((INT16)tmp);
CarryVal = OverVal = (result >> 15 != 0) && (result >> 15 != -1);
regs.w[AX]=(WORD)result;
result = (WORD)(result >> 16);
regs.w[DX]=result;
SetZF(regs.w[AX] | regs.w[DX]);
}
break;
case 0x30: /* DIV AX, Ew */
cycle_count-=158;
{
UINT32 result;
result = (regs.w[DX] << 16) + regs.w[AX];
if (tmp)
{
tmp2 = result % tmp;
if ((result / tmp) > 0xffff)
{
I86_interrupt(0);
break;
}
else
{
regs.w[DX]=tmp2;
result /= tmp;
regs.w[AX]=result;
}
}
else
{
I86_interrupt(0);
break;
}
}
break;
case 0x38: /* IDIV AX, Ew */
cycle_count-=180;
{
INT32 result;
result = (regs.w[DX] << 16) + regs.w[AX];
if (tmp)
{
tmp2 = result % (INT32)((INT16)tmp);
if ((result /= (INT32)((INT16)tmp)) > 0xffff)
{
I86_interrupt(0);
break;
}
else
{
regs.w[AX]=result;
regs.w[DX]=tmp2;
}
}
else
{
I86_interrupt(0);
break;
}
}
break;
}
}
static void i_clc(void) /* Opcode 0xf8 */
{
cycle_count-=2;
CarryVal = 0;
}
static void i_stc(void) /* Opcode 0xf9 */
{
cycle_count-=2;
CarryVal = 1;
}
static void i_cli(void) /* Opcode 0xfa */
{
cycle_count-=2;
IF = 0;
}
static void i_sti(void) /* Opcode 0xfb */
{
cycle_count-=2;
IF = 1;
}
static void i_cld(void) /* Opcode 0xfc */
{
cycle_count-=2;
DF = 0;
}
static void i_std(void) /* Opcode 0xfd */
{
cycle_count-=2;
DF = 1;
}
static void i_fepre(void) /* Opcode 0xfe */
{
unsigned ModRM = FETCH;
unsigned tmp = GetRMByte(ModRM);
unsigned tmp1;
cycle_count-=3; /* 2 if dest is in memory */
if ((ModRM & 0x38) == 0) /* INC eb */
{
tmp1 = tmp+1;
SetOFB_Add(tmp1,tmp,1);
}
else /* DEC eb */
{
tmp1 = tmp-1;
SetOFB_Sub(tmp1,1,tmp);
}
SetAF(tmp1,tmp,1);
SetSZPF_Byte(tmp1);
PutbackRMByte(ModRM,(BYTE)tmp1);
}
static void i_ffpre(void) /* Opcode 0xff */
{
unsigned ModRM = FETCH;
unsigned tmp;
unsigned tmp1;
switch(ModRM & 0x38)
{
case 0x00: /* INC ew */
cycle_count-=3; /* 2 if dest is in memory */
tmp = GetRMWord(ModRM);
tmp1 = tmp+1;
SetOFW_Add(tmp1,tmp,1);
SetAF(tmp1,tmp,1);
SetSZPF_Word(tmp1);
PutbackRMWord(ModRM,(WORD)tmp1);
break;
case 0x08: /* DEC ew */
cycle_count-=3; /* 2 if dest is in memory */
tmp = GetRMWord(ModRM);
tmp1 = tmp-1;
SetOFW_Sub(tmp1,1,tmp);
SetAF(tmp1,tmp,1);
SetSZPF_Word(tmp1);
PutbackRMWord(ModRM,(WORD)tmp1);
break;
case 0x10: /* CALL ew */
cycle_count-=9; /* 8 if dest is in memory */
tmp = GetRMWord(ModRM);
PUSH(ip);
ip = (WORD)tmp;
break;
case 0x18: /* CALL FAR ea */
cycle_count-=11;
PUSH(sregs[CS]);
PUSH(ip);
ip = GetRMWord(ModRM);
sregs[CS] = GetnextRMWord;
base[CS] = SegBase(CS);
break;
case 0x20: /* JMP ea */
cycle_count-=11; /* 8 if address in memory */
ip = GetRMWord(ModRM);
break;
case 0x28: /* JMP FAR ea */
cycle_count-=4;
ip = GetRMWord(ModRM);
sregs[CS] = GetnextRMWord;
base[CS] = SegBase(CS);
break;
case 0x30: /* PUSH ea */
cycle_count-=3;
tmp = GetRMWord(ModRM);
PUSH(tmp);
break;
}
}
static void i_invalid(void)
{
/* makes the cpu loops forever until user resets it */
ip--;
cycle_count-=10;
}
/* ASG 971222 -- added these interface functions */
void i86_SetRegs(i86_Regs *Regs)
{
regs = Regs->regs;
ip = Regs->ip;
ExpandFlags(Regs->flags);
sregs[CS] = Regs->sregs[CS];
sregs[DS] = Regs->sregs[DS];
sregs[ES] = Regs->sregs[ES];
sregs[SS] = Regs->sregs[SS];
int86_pending = Regs->pending_interrupts;
base[CS] = SegBase(CS);
base[DS] = SegBase(DS);
base[ES] = SegBase(ES);
base[SS] = SegBase(SS);
}
void i86_GetRegs(i86_Regs *Regs)
{
Regs->regs = regs;
Regs->ip = ip;
Regs->flags = CompressFlags();
Regs->sregs[CS] = sregs[CS];
Regs->sregs[DS] = sregs[DS];
Regs->sregs[ES] = sregs[ES];
Regs->sregs[SS] = sregs[SS];
Regs->pending_interrupts = int86_pending;
}
unsigned i86_GetPC(void)
{
return ip;
}
void i86_Cause_Interrupt(int type)
{
int86_pending = type;
}
void i86_Clear_Pending_Interrupts(void)
{
int86_pending = 0;
}
int i86_Execute(int cycles)
{
/* ASG 971222 if (int86_pending) external_int();*/
cycle_count=cycles;/* ASG 971222 cycles_per_run;*/
while(cycle_count>0)
{
if (int86_pending) external_int(); /* ASG 971222 */
seg_prefix=FALSE;
#if defined(BIGCASE) && !defined(RS6000)
/* Some compilers cannot handle large case statements */
switch(FETCH)
{
case 0x00: i_add_br8(); break;
case 0x01: i_add_wr16(); break;
case 0x02: i_add_r8b(); break;
case 0x03: i_add_r16w(); break;
case 0x04: i_add_ald8(); break;
case 0x05: i_add_axd16(); break;
case 0x06: i_push_es(); break;
case 0x07: i_pop_es(); break;
case 0x08: i_or_br8(); break;
case 0x09: i_or_wr16(); break;
case 0x0a: i_or_r8b(); break;
case 0x0b: i_or_r16w(); break;
case 0x0c: i_or_ald8(); break;
case 0x0d: i_or_axd16(); break;
case 0x0e: i_push_cs(); break;
case 0x0f: i_invalid(); break;
case 0x10: i_adc_br8(); break;
case 0x11: i_adc_wr16(); break;
case 0x12: i_adc_r8b(); break;
case 0x13: i_adc_r16w(); break;
case 0x14: i_adc_ald8(); break;
case 0x15: i_adc_axd16(); break;
case 0x16: i_push_ss(); break;
case 0x17: i_pop_ss(); break;
case 0x18: i_sbb_br8(); break;
case 0x19: i_sbb_wr16(); break;
case 0x1a: i_sbb_r8b(); break;
case 0x1b: i_sbb_r16w(); break;
case 0x1c: i_sbb_ald8(); break;
case 0x1d: i_sbb_axd16(); break;
case 0x1e: i_push_ds(); break;
case 0x1f: i_pop_ds(); break;
case 0x20: i_and_br8(); break;
case 0x21: i_and_wr16(); break;
case 0x22: i_and_r8b(); break;
case 0x23: i_and_r16w(); break;
case 0x24: i_and_ald8(); break;
case 0x25: i_and_axd16(); break;
case 0x26: i_es(); break;
case 0x27: i_daa(); break;
case 0x28: i_sub_br8(); break;
case 0x29: i_sub_wr16(); break;
case 0x2a: i_sub_r8b(); break;
case 0x2b: i_sub_r16w(); break;
case 0x2c: i_sub_ald8(); break;
case 0x2d: i_sub_axd16(); break;
case 0x2e: i_cs(); break;
case 0x2f: i_das(); break;
case 0x30: i_xor_br8(); break;
case 0x31: i_xor_wr16(); break;
case 0x32: i_xor_r8b(); break;
case 0x33: i_xor_r16w(); break;
case 0x34: i_xor_ald8(); break;
case 0x35: i_xor_axd16(); break;
case 0x36: i_ss(); break;
case 0x37: i_aaa(); break;
case 0x38: i_cmp_br8(); break;
case 0x39: i_cmp_wr16(); break;
case 0x3a: i_cmp_r8b(); break;
case 0x3b: i_cmp_r16w(); break;
case 0x3c: i_cmp_ald8(); break;
case 0x3d: i_cmp_axd16(); break;
case 0x3e: i_ds(); break;
case 0x3f: i_aas(); break;
case 0x40: i_inc_ax(); break;
case 0x41: i_inc_cx(); break;
case 0x42: i_inc_dx(); break;
case 0x43: i_inc_bx(); break;
case 0x44: i_inc_sp(); break;
case 0x45: i_inc_bp(); break;
case 0x46: i_inc_si(); break;
case 0x47: i_inc_di(); break;
case 0x48: i_dec_ax(); break;
case 0x49: i_dec_cx(); break;
case 0x4a: i_dec_dx(); break;
case 0x4b: i_dec_bx(); break;
case 0x4c: i_dec_sp(); break;
case 0x4d: i_dec_bp(); break;
case 0x4e: i_dec_si(); break;
case 0x4f: i_dec_di(); break;
case 0x50: i_push_ax(); break;
case 0x51: i_push_cx(); break;
case 0x52: i_push_dx(); break;
case 0x53: i_push_bx(); break;
case 0x54: i_push_sp(); break;
case 0x55: i_push_bp(); break;
case 0x56: i_push_si(); break;
case 0x57: i_push_di(); break;
case 0x58: i_pop_ax(); break;
case 0x59: i_pop_cx(); break;
case 0x5a: i_pop_dx(); break;
case 0x5b: i_pop_bx(); break;
case 0x5c: i_pop_sp(); break;
case 0x5d: i_pop_bp(); break;
case 0x5e: i_pop_si(); break;
case 0x5f: i_pop_di(); break;
case 0x60: i_pusha(); break;
case 0x61: i_popa(); break;
case 0x62: i_bound(); break;
case 0x63: i_invalid(); break;
case 0x64: i_invalid(); break;
case 0x65: i_invalid(); break;
case 0x66: i_invalid(); break;
case 0x67: i_invalid(); break;
case 0x68: i_push_d16(); break;
case 0x69: i_imul_d16(); break;
case 0x6a: i_push_d8(); break;
case 0x6b: i_imul_d8(); break;
case 0x6c: i_insb(); break;
case 0x6d: i_insw(); break;
case 0x6e: i_outsb(); break;
case 0x6f: i_outsw(); break;
case 0x70: i_jo(); break;
case 0x71: i_jno(); break;
case 0x72: i_jb(); break;
case 0x73: i_jnb(); break;
case 0x74: i_jz(); break;
case 0x75: i_jnz(); break;
case 0x76: i_jbe(); break;
case 0x77: i_jnbe(); break;
case 0x78: i_js(); break;
case 0x79: i_jns(); break;
cas
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -