⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i86.c

📁 这个是延伸mame的在wince平台下的游戏模拟器的代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	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 + -