📄 i86.c
字号:
/****************************************************************************
* real mode i286 emulator v1.4 by Fabrice Frances *
* (initial work based on David Hedley's pcemu) *
****************************************************************************/
#include <stdio.h>
#include "host.h"
#include "I86.h"
#include "I86intrf.h"
#include "memory.h"
/***************************************************************************/
/* cpu state */
/***************************************************************************/
static i86basicregs regs; /* ASG 971222 */
int i86_ICount;
#define cycle_count i86_ICount
static unsigned ip; /* instruction pointer register */
static unsigned sregs[4]; /* four segment registers */
static unsigned base[4]; /* and their base addresses */
static unsigned prefix_base; /* base address of the latest prefix segment */
static char seg_prefix; /* prefix segment indicator */
static BYTE TF, IF, DF; /* 0 or 1 valued flags */
static int AuxVal, OverVal, SignVal, ZeroVal, CarryVal, ParityVal; /* 0 or non-0 valued flags */
int int86_pending; /* The interrupt number of a pending external interrupt pending */
/* NMI is number 2. For INTR interrupts, the level is caught on the bus during an INTA cycle */
/* ASG 971222 static unsigned char *Memory; * fetching goes directly to memory instead of going through MAME's cpu_readmem() */
/***************************************************************************/
/* ASG 971222 static int cycle_count, cycles_per_run; */
#include "instr.h"
#include "ea.h"
#include "modrm.h"
static UINT8 parity_table[256];
/***************************************************************************/
/* ASG 971222 void I86_Reset(unsigned char *mem,int cycles)*/
void i86_Reset (void)
{
unsigned int i,j,c;
BREGS reg_name[8]={ AL, CL, DL, BL, AH, CH, DH, BH };
/* ASG 971222 cycles_per_run=cycles;*/
int86_pending=0;
for (i = 0; i < 4; i++) sregs[i] = 0;
sregs[CS]=0xFFFF;
base[CS] = SegBase(CS);
base[DS] = SegBase(DS);
base[ES] = SegBase(ES);
base[SS] = SegBase(SS);
for (i=0; i < 8; i++) regs.w[i] = 0;
ip = 0;
/* ASG 971222 Memory=mem;*/
for (i = 0;i < 256; i++)
{
for (j = i, c = 0; j > 0; j >>= 1)
if (j & 1) c++;
parity_table[i] = !(c & 1);
}
TF = IF = DF = 0;
SignVal=CarryVal=AuxVal=OverVal=0;
ZeroVal=ParityVal=1;
for (i = 0; i < 256; i++)
{
Mod_RM.reg.b[i] = reg_name[(i & 0x38) >> 3];
Mod_RM.reg.w[i] = (WREGS) ( (i & 0x38) >> 3) ;
}
for (i = 0xc0; i < 0x100; i++)
{
Mod_RM.RM.w[i] = (WREGS)( i & 7 );
Mod_RM.RM.b[i] = (BREGS)reg_name[i & 7];
}
}
static void I86_interrupt(unsigned int_num)
{
unsigned dest_seg, dest_off;
i_pushf();
dest_off = ReadWord(int_num*4);
dest_seg = ReadWord(int_num*4+2);
PUSH(sregs[CS]);
PUSH(ip);
ip = (WORD)dest_off;
sregs[CS] = (WORD)dest_seg;
base[CS] = SegBase(CS);
TF = IF = 0;
}
void trap(void)
{
instruction[FETCH]();
I86_interrupt(1);
}
static void external_int(void)
{
I86_interrupt(int86_pending);
int86_pending = 0;
}
/****************************************************************************/
static void i_add_br8(void) /* Opcode 0x00 */
{
DEF_br8(dst,src);
cycle_count-=3;
ADDB(dst,src);
PutbackRMByte(ModRM,dst);
}
static void i_add_wr16(void) /* Opcode 0x01 */
{
DEF_wr16(dst,src);
cycle_count-=3;
ADDW(dst,src);
PutbackRMWord(ModRM,dst);
}
static void i_add_r8b(void) /* Opcode 0x02 */
{
DEF_r8b(dst,src);
cycle_count-=3;
ADDB(dst,src);
RegByte(ModRM)=dst;
}
static void i_add_r16w(void) /* Opcode 0x03 */
{
DEF_r16w(dst,src);
cycle_count-=3;
ADDW(dst,src);
RegWord(ModRM)=dst;
}
static void i_add_ald8(void) /* Opcode 0x04 */
{
DEF_ald8(dst,src);
cycle_count-=4;
ADDB(dst,src);
regs.b[AL]=dst;
}
static void i_add_axd16(void) /* Opcode 0x05 */
{
DEF_axd16(dst,src);
cycle_count-=4;
ADDW(dst,src);
regs.w[AX]=dst;
}
static void i_push_es(void) /* Opcode 0x06 */
{
cycle_count-=3;
PUSH(sregs[ES]);
}
static void i_pop_es(void) /* Opcode 0x07 */
{
POP(sregs[ES]);
base[ES] = SegBase(ES);
cycle_count-=2;
}
static void i_or_br8(void) /* Opcode 0x08 */
{
DEF_br8(dst,src);
cycle_count-=3;
ORB(dst,src);
PutbackRMByte(ModRM,dst);
}
static void i_or_wr16(void) /* Opcode 0x09 */
{
DEF_wr16(dst,src);
cycle_count-=3;
ORW(dst,src);
PutbackRMWord(ModRM,dst);
}
static void i_or_r8b(void) /* Opcode 0x0a */
{
DEF_r8b(dst,src);
cycle_count-=3;
ORB(dst,src);
RegByte(ModRM)=dst;
}
static void i_or_r16w(void) /* Opcode 0x0b */
{
DEF_r16w(dst,src);
cycle_count-=3;
ORW(dst,src);
RegWord(ModRM)=dst;
}
static void i_or_ald8(void) /* Opcode 0x0c */
{
DEF_ald8(dst,src);
cycle_count-=4;
ORB(dst,src);
regs.b[AL]=dst;
}
static void i_or_axd16(void) /* Opcode 0x0d */
{
DEF_axd16(dst,src);
cycle_count-=4;
ORW(dst,src);
regs.w[AX]=dst;
}
static void i_push_cs(void) /* Opcode 0x0e */
{
cycle_count-=3;
PUSH(sregs[CS]);
}
/* Opcode 0x0f invalid */
static void i_adc_br8(void) /* Opcode 0x10 */
{
DEF_br8(dst,src);
cycle_count-=3;
src+=CF;
ADDB(dst,src);
PutbackRMByte(ModRM,dst);
}
static void i_adc_wr16(void) /* Opcode 0x11 */
{
DEF_wr16(dst,src);
cycle_count-=3;
src+=CF;
ADDW(dst,src);
PutbackRMWord(ModRM,dst);
}
static void i_adc_r8b(void) /* Opcode 0x12 */
{
DEF_r8b(dst,src);
cycle_count-=3;
src+=CF;
ADDB(dst,src);
RegByte(ModRM)=dst;
}
static void i_adc_r16w(void) /* Opcode 0x13 */
{
DEF_r16w(dst,src);
cycle_count-=3;
src+=CF;
ADDW(dst,src);
RegWord(ModRM)=dst;
}
static void i_adc_ald8(void) /* Opcode 0x14 */
{
DEF_ald8(dst,src);
cycle_count-=4;
src+=CF;
ADDB(dst,src);
regs.b[AL] = dst;
}
static void i_adc_axd16(void) /* Opcode 0x15 */
{
DEF_axd16(dst,src);
cycle_count-=4;
src+=CF;
ADDW(dst,src);
regs.w[AX]=dst;
}
static void i_push_ss(void) /* Opcode 0x16 */
{
cycle_count-=3;
PUSH(sregs[SS]);
}
static void i_pop_ss(void) /* Opcode 0x17 */
{
cycle_count-=2;
POP(sregs[SS]);
base[SS] = SegBase(SS);
instruction[FETCH](); /* no interrupt before next instruction */
}
static void i_sbb_br8(void) /* Opcode 0x18 */
{
DEF_br8(dst,src);
cycle_count-=3;
src+=CF;
SUBB(dst,src);
PutbackRMByte(ModRM,dst);
}
static void i_sbb_wr16(void) /* Opcode 0x19 */
{
DEF_wr16(dst,src);
cycle_count-=3;
src+=CF;
SUBW(dst,src);
PutbackRMWord(ModRM,dst);
}
static void i_sbb_r8b(void) /* Opcode 0x1a */
{
DEF_r8b(dst,src);
cycle_count-=3;
src+=CF;
SUBB(dst,src);
RegByte(ModRM)=dst;
}
static void i_sbb_r16w(void) /* Opcode 0x1b */
{
DEF_r16w(dst,src);
cycle_count-=3;
src+=CF;
SUBW(dst,src);
RegWord(ModRM)= dst;
}
static void i_sbb_ald8(void) /* Opcode 0x1c */
{
DEF_ald8(dst,src);
cycle_count-=4;
src+=CF;
SUBB(dst,src);
regs.b[AL] = dst;
}
static void i_sbb_axd16(void) /* Opcode 0x1d */
{
DEF_axd16(dst,src);
cycle_count-=4;
src+=CF;
SUBW(dst,src);
regs.w[AX]=dst;
}
static void i_push_ds(void) /* Opcode 0x1e */
{
cycle_count-=3;
PUSH(sregs[DS]);
}
static void i_pop_ds(void) /* Opcode 0x1f */
{
POP(sregs[DS]);
base[DS] = SegBase(DS);
cycle_count-=2;
}
static void i_and_br8(void) /* Opcode 0x20 */
{
DEF_br8(dst,src);
cycle_count-=3;
ANDB(dst,src);
PutbackRMByte(ModRM,dst);
}
static void i_and_wr16(void) /* Opcode 0x21 */
{
DEF_wr16(dst,src);
cycle_count-=3;
ANDW(dst,src);
PutbackRMWord(ModRM,dst);
}
static void i_and_r8b(void) /* Opcode 0x22 */
{
DEF_r8b(dst,src);
cycle_count-=3;
ANDB(dst,src);
RegByte(ModRM)=dst;
}
static void i_and_r16w(void) /* Opcode 0x23 */
{
DEF_r16w(dst,src);
cycle_count-=3;
ANDW(dst,src);
RegWord(ModRM)=dst;
}
static void i_and_ald8(void) /* Opcode 0x24 */
{
DEF_ald8(dst,src);
cycle_count-=4;
ANDB(dst,src);
regs.b[AL] = dst;
}
static void i_and_axd16(void) /* Opcode 0x25 */
{
DEF_axd16(dst,src);
cycle_count-=4;
ANDW(dst,src);
regs.w[AX]=dst;
}
static void i_es(void) /* Opcode 0x26 */
{
seg_prefix=TRUE;
prefix_base=base[ES];
cycle_count-=2;
instruction[FETCH]();
}
static void i_daa(void) /* Opcode 0x27 */
{
if (AF || ((regs.b[AL] & 0xf) > 9))
{
int tmp;
regs.b[AL] = tmp = regs.b[AL] + 6;
AuxVal = 1;
CarryVal |= tmp & 0x100;
}
if (CF || (regs.b[AL] > 0x9f))
{
regs.b[AL] += 0x60;
CarryVal = 1;
}
SetSZPF_Byte(regs.b[AL]);
cycle_count-=4;
}
static void i_sub_br8(void) /* Opcode 0x28 */
{
DEF_br8(dst,src);
cycle_count-=3;
SUBB(dst,src);
PutbackRMByte(ModRM,dst);
}
static void i_sub_wr16(void) /* Opcode 0x29 */
{
DEF_wr16(dst,src);
cycle_count-=3;
SUBW(dst,src);
PutbackRMWord(ModRM,dst);
}
static void i_sub_r8b(void) /* Opcode 0x2a */
{
DEF_r8b(dst,src);
cycle_count-=3;
SUBB(dst,src);
RegByte(ModRM)=dst;
}
static void i_sub_r16w(void) /* Opcode 0x2b */
{
DEF_r16w(dst,src);
cycle_count-=3;
SUBW(dst,src);
RegWord(ModRM)=dst;
}
static void i_sub_ald8(void) /* Opcode 0x2c */
{
DEF_ald8(dst,src);
cycle_count-=4;
SUBB(dst,src);
regs.b[AL] = dst;
}
static void i_sub_axd16(void) /* Opcode 0x2d */
{
DEF_axd16(dst,src);
cycle_count-=4;
SUBW(dst,src);
regs.w[AX]=dst;
}
static void i_cs(void) /* Opcode 0x2e */
{
seg_prefix=TRUE;
prefix_base=base[CS];
cycle_count-=2;
instruction[FETCH]();
}
static void i_das(void) /* Opcode 0x2f */
{
if (AF || ((regs.b[AL] & 0xf) > 9))
{
int tmp;
regs.b[AL] = tmp = regs.b[AL] - 6;
AuxVal = 1;
CarryVal |= tmp & 0x100;
}
if (CF || (regs.b[AL] > 0x9f))
{
regs.b[AL] -= 0x60;
CarryVal = 1;
}
SetSZPF_Byte(regs.b[AL]);
cycle_count-=4;
}
static void i_xor_br8(void) /* Opcode 0x30 */
{
DEF_br8(dst,src);
cycle_count-=3;
XORB(dst,src);
PutbackRMByte(ModRM,dst);
}
static void i_xor_wr16(void) /* Opcode 0x31 */
{
DEF_wr16(dst,src);
cycle_count-=3;
XORW(dst,src);
PutbackRMWord(ModRM,dst);
}
static void i_xor_r8b(void) /* Opcode 0x32 */
{
DEF_r8b(dst,src);
cycle_count-=3;
XORB(dst,src);
RegByte(ModRM)=dst;
}
static void i_xor_r16w(void) /* Opcode 0x33 */
{
DEF_r16w(dst,src);
cycle_count-=3;
XORW(dst,src);
RegWord(ModRM)=dst;
}
static void i_xor_ald8(void) /* Opcode 0x34 */
{
DEF_ald8(dst,src);
cycle_count-=4;
XORB(dst,src);
regs.b[AL] = dst;
}
static void i_xor_axd16(void) /* Opcode 0x35 */
{
DEF_axd16(dst,src);
cycle_count-=4;
XORW(dst,src);
regs.w[AX]=dst;
}
static void i_ss(void) /* Opcode 0x36 */
{
seg_prefix=TRUE;
prefix_base=base[SS];
cycle_count-=2;
instruction[FETCH]();
}
static void i_aaa(void) /* Opcode 0x37 */
{
if (AF || ((regs.b[AL] & 0xf) > 9))
{
regs.b[AL] += 6;
regs.b[AH] += 1;
AuxVal = 1;
CarryVal = 1;
}
else {
AuxVal = 0;
CarryVal = 0;
}
regs.b[AL] &= 0x0F;
cycle_count-=8;
}
static void i_cmp_br8(void) /* Opcode 0x38 */
{
DEF_br8(dst,src);
cycle_count-=3;
SUBB(dst,src);
}
static void i_cmp_wr16(void) /* Opcode 0x39 */
{
DEF_wr16(dst,src);
cycle_count-=3;
SUBW(dst,src);
}
static void i_cmp_r8b(void) /* Opcode 0x3a */
{
DEF_r8b(dst,src);
cycle_count-=3;
SUBB(dst,src);
}
static void i_cmp_r16w(void) /* Opcode 0x3b */
{
DEF_r16w(dst,src);
cycle_count-=3;
SUBW(dst,src);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -