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

📄 decoder.h

📁 DOSBox emulates a full x86 pc with sound and dos. Its main use is to run old dosgames on platforms w
💻 H
📖 第 1 页 / 共 5 页
字号:
		cache_addb(0xe8);		cache_addd(((Bit32u)&mem_writed_checked_x86) - (Bit32u)cache.pos-4);		cache_addw(0xc483);		// add esp,8		cache_addb(0x08);		cache_addw(0x012c);		// sub al,1		cache_addb(0x5a);		// pop edx		// Restore registers to be used again		x86gen.regs[X86_REG_EAX]->notusable=false;		x86gen.regs[X86_REG_ECX]->notusable=false;		dyn_check_bool_exception_ne();		gen_fill_jump(jmp_loc);	} else {		gen_protectflags();		gen_call_function((void *)&mem_writew_checked_x86,"%Ddr%Dd",addr,val);		dyn_check_bool_exception_al();	}}#endifstatic void dyn_push_unchecked(DynReg * dynreg) {	gen_protectflags();	gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2));	gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask);	gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask);	gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK));	gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS));	if (decode.big_op) {		gen_call_function((void *)&mem_writed,"%Drd%Dd",DREG(STACK),dynreg);	} else {		//Can just push the whole 32-bit word as operand		gen_call_function((void *)&mem_writew,"%Drd%Dd",DREG(STACK),dynreg);	}}static void dyn_push(DynReg * dynreg) {	gen_protectflags();	gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?(-4):(-2));	gen_dop_word(DOP_MOV,true,DREG(NEWESP),DREG(ESP));	gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask);	gen_dop_word_var(DOP_AND,true,DREG(NEWESP),&cpu.stack.notmask);	gen_dop_word(DOP_OR,true,DREG(NEWESP),DREG(STACK));	gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS));	if (decode.big_op) {		gen_call_function((void *)&mem_writed_checked_x86,"%Drd%Dd",DREG(STACK),dynreg);	} else {		//Can just push the whole 32-bit word as operand		gen_call_function((void *)&mem_writew_checked_x86,"%Drd%Dd",DREG(STACK),dynreg);	}	dyn_check_bool_exception_al();	/* everything was ok, change register now */	gen_dop_word(DOP_MOV,true,DREG(ESP),DREG(NEWESP));	gen_releasereg(DREG(NEWESP));}static void dyn_pop(DynReg * dynreg,bool checked=true) {	gen_protectflags();	gen_dop_word(DOP_MOV,true,DREG(STACK),DREG(ESP));	gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask);	gen_dop_word(DOP_ADD,true,DREG(STACK),DREG(SS));	if (checked) {		if (decode.big_op) {			gen_call_function((void *)&mem_readd_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata);		} else {			gen_call_function((void *)&mem_readw_checked_x86,"%Drd%Id",DREG(STACK),&core_dyn.readdata);		}		dyn_check_bool_exception_al();		gen_mov_host(&core_dyn.readdata,dynreg,decode.big_op?4:2);	} else {		if (decode.big_op) {			gen_call_function((void *)&mem_readd,"%Rd%Drd",dynreg,DREG(STACK));		} else {			gen_call_function((void *)&mem_readw,"%Rw%Drd",dynreg,DREG(STACK));		}	}	if (dynreg!=DREG(ESP)) {		gen_lea(DREG(STACK),DREG(ESP),0,0,decode.big_op?4:2);		gen_dop_word_var(DOP_AND,true,DREG(STACK),&cpu.stack.mask);		gen_dop_word_var(DOP_AND,true,DREG(ESP),&cpu.stack.notmask);		gen_dop_word(DOP_OR,true,DREG(ESP),DREG(STACK));	}}static void INLINE dyn_get_modrm(void) {	decode.modrm.val=decode_fetchb();	decode.modrm.mod=(decode.modrm.val >> 6) & 3;	decode.modrm.reg=(decode.modrm.val >> 3) & 7;	decode.modrm.rm=(decode.modrm.val & 7);}static void dyn_fill_ea(bool addseg=true, DynReg * reg_ea=DREG(EA)) {	DynReg * segbase;	if (!decode.big_addr) {		Bits imm;		switch (decode.modrm.mod) {		case 0:imm=0;break;		case 1:imm=(Bit8s)decode_fetchb();break;		case 2:imm=(Bit16s)decode_fetchw();break;		}		DynReg * extend_src=reg_ea;		switch (decode.modrm.rm) {		case 0:/* BX+SI */			gen_lea(reg_ea,DREG(EBX),DREG(ESI),0,imm);			segbase=DREG(DS);			break;		case 1:/* BX+DI */			gen_lea(reg_ea,DREG(EBX),DREG(EDI),0,imm);			segbase=DREG(DS);			break;		case 2:/* BP+SI */			gen_lea(reg_ea,DREG(EBP),DREG(ESI),0,imm);			segbase=DREG(SS);			break;		case 3:/* BP+DI */			gen_lea(reg_ea,DREG(EBP),DREG(EDI),0,imm);			segbase=DREG(SS);			break;		case 4:/* SI */			if (imm) gen_lea(reg_ea,DREG(ESI),0,0,imm);			else extend_src=DREG(ESI);			segbase=DREG(DS);			break;		case 5:/* DI */			if (imm) gen_lea(reg_ea,DREG(EDI),0,0,imm);			else extend_src=DREG(EDI);			segbase=DREG(DS);			break;		case 6:/* imm/BP */			if (!decode.modrm.mod) {				imm=decode_fetchw();                gen_dop_word_imm(DOP_MOV,true,reg_ea,imm);				segbase=DREG(DS);				goto skip_extend_word;			} else {				gen_lea(reg_ea,DREG(EBP),0,0,imm);				segbase=DREG(SS);			}			break;		case 7: /* BX */			if (imm) gen_lea(reg_ea,DREG(EBX),0,0,imm);			else extend_src=DREG(EBX);			segbase=DREG(DS);			break;		}		gen_extend_word(false,reg_ea,extend_src);skip_extend_word:		if (addseg) {			gen_lea(reg_ea,reg_ea,decode.segprefix ? decode.segprefix : segbase,0,0);		}	} else {		Bits imm=0;		DynReg * base=0;DynReg * scaled=0;Bitu scale=0;		switch (decode.modrm.rm) {		case 0:base=DREG(EAX);segbase=DREG(DS);break;		case 1:base=DREG(ECX);segbase=DREG(DS);break;		case 2:base=DREG(EDX);segbase=DREG(DS);break;		case 3:base=DREG(EBX);segbase=DREG(DS);break;		case 4:	/* SIB */			{				Bitu sib=decode_fetchb();				static DynReg * scaledtable[8]={					DREG(EAX),DREG(ECX),DREG(EDX),DREG(EBX),							0,DREG(EBP),DREG(ESI),DREG(EDI),				};				scaled=scaledtable[(sib >> 3) &7];				scale=(sib >> 6);				switch (sib & 7) {				case 0:base=DREG(EAX);segbase=DREG(DS);break;				case 1:base=DREG(ECX);segbase=DREG(DS);break;				case 2:base=DREG(EDX);segbase=DREG(DS);break;				case 3:base=DREG(EBX);segbase=DREG(DS);break;				case 4:base=DREG(ESP);segbase=DREG(SS);break;				case 5:					if (decode.modrm.mod) {						base=DREG(EBP);segbase=DREG(SS);					} else {						segbase=DREG(DS);						Bitu val;						if (decode_fetchd_imm(val)) {							gen_mov_host((void*)val,DREG(EA),4);							if (!addseg) {								gen_lea(reg_ea,DREG(EA),scaled,scale,0);							} else {								DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase;								gen_lea(DREG(EA),DREG(EA),scaled,scale,0);								gen_lea(reg_ea,DREG(EA),*seg,0,0);							}							return;						}						imm=(Bit32s)val;					}					break;				case 6:base=DREG(ESI);segbase=DREG(DS);break;				case 7:base=DREG(EDI);segbase=DREG(DS);break;				}			}				break;	/* SIB Break */		case 5:			if (decode.modrm.mod) {				base=DREG(EBP);segbase=DREG(SS);			} else {				imm=(Bit32s)decode_fetchd();segbase=DREG(DS);			}			break;		case 6:base=DREG(ESI);segbase=DREG(DS);break;		case 7:base=DREG(EDI);segbase=DREG(DS);break;		}		switch (decode.modrm.mod) {		case 1:imm=(Bit8s)decode_fetchb();break;		case 2: {			Bitu val;			if (decode_fetchd_imm(val)) {				gen_mov_host((void*)val,DREG(EA),4);				if (!addseg) {					gen_lea(DREG(EA),DREG(EA),scaled,scale,0);					gen_lea(reg_ea,DREG(EA),base,0,0);				} else {					DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase;					if (!base) {						gen_lea(DREG(EA),DREG(EA),scaled,scale,0);						gen_lea(reg_ea,DREG(EA),*seg,0,0);					} else if (!scaled) {						gen_lea(DREG(EA),DREG(EA),*seg,0,0);						gen_lea(reg_ea,DREG(EA),base,0,0);					} else {						gen_lea(DREG(EA),DREG(EA),scaled,scale,0);						gen_lea(DREG(EA),DREG(EA),base,0,0);						gen_lea(reg_ea,DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0);					}				}				return;			}						imm=(Bit32s)val;			break;			}		}		if (!addseg) {			gen_lea(reg_ea,base,scaled,scale,imm);		} else {			DynReg** seg = decode.segprefix ? &decode.segprefix : &segbase;			if (!base) gen_lea(reg_ea,*seg,scaled,scale,imm);			else if (!scaled) gen_lea(reg_ea,base,*seg,0,imm);			else {				gen_lea(DREG(EA),base,scaled,scale,imm);				gen_lea(reg_ea,DREG(EA),decode.segprefix ? decode.segprefix : segbase,0,0);			}		}	}}static void dyn_dop_word_imm(DualOps op,bool dword,DynReg * dr1) {	Bitu val;	if (dword) {		if (decode_fetchd_imm(val)) {			gen_dop_word_imm_mem(op,true,dr1,(void*)val);			return;		}	} else {		if (decode_fetchw_imm(val)) {			gen_dop_word_imm_mem(op,false,dr1,(void*)val);			return;		}	}	gen_dop_word_imm(op,dword,dr1,val);}static void dyn_dop_byte_imm(DualOps op,DynReg * dr1,Bit8u di1) {	Bitu val;	if (decode_fetchb_imm(val)) {		gen_dop_byte_imm_mem(op,dr1,di1,(void*)val);	} else {		gen_dop_byte_imm(op,dr1,di1,(Bit8u)val);	}}#include "helpers.h"#include "string.h"static void dyn_dop_ebgb(DualOps op) {	dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];	if (decode.modrm.mod<3) {		dyn_fill_ea();		if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true);		dyn_read_byte(DREG(EA),DREG(TMPB),false);		if (op<=DOP_TEST) {			if (op==DOP_ADC || op==DOP_SBB) gen_needcarry();			else set_skipflags(false);		}		gen_dop_byte(op,DREG(TMPB),0,rm_reg,decode.modrm.reg&4);		if (op!=DOP_CMP) dyn_write_byte_release(DREG(EA),DREG(TMPB),false);		else gen_releasereg(DREG(EA));		gen_releasereg(DREG(TMPB));	} else {		if (op<=DOP_TEST) {			if (op==DOP_ADC || op==DOP_SBB) gen_needcarry();			else gen_discardflags();		}		gen_dop_byte(op,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,decode.modrm.reg&4);	}}static void dyn_dop_gbeb(DualOps op) {	dyn_get_modrm();DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];	if (decode.modrm.mod<3) {		dyn_fill_ea();		if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true);		dyn_read_byte_release(DREG(EA),DREG(TMPB),false);		if (op<=DOP_TEST) {			if (op==DOP_ADC || op==DOP_SBB) gen_needcarry();			else set_skipflags(false);		}		gen_dop_byte(op,rm_reg,decode.modrm.reg&4,DREG(TMPB),0);		gen_releasereg(DREG(TMPB));	} else {		if (op<=DOP_TEST) {			if (op==DOP_ADC || op==DOP_SBB) gen_needcarry();			else gen_discardflags();		}		gen_dop_byte(op,rm_reg,decode.modrm.reg&4,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4);	}}static void dyn_mov_ebib(void) {	dyn_get_modrm();	if (decode.modrm.mod<3) {		dyn_fill_ea();		gen_call_write(DREG(EA),decode_fetchb(),1);		dyn_check_bool_exception_al();	} else {		gen_dop_byte_imm(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,decode_fetchb());	}}static void dyn_mov_ebgb(void) {	dyn_get_modrm();	DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4;	if (decode.modrm.mod<3) {		dyn_fill_ea();		dyn_write_byte_release(DREG(EA),rm_reg,rm_regi);	} else {		gen_dop_byte(DOP_MOV,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4,rm_reg,rm_regi);	}}static void dyn_mov_gbeb(void) {	dyn_get_modrm();	DynReg * rm_reg=&DynRegs[decode.modrm.reg&3];Bitu rm_regi=decode.modrm.reg&4;	if (decode.modrm.mod<3) {		dyn_fill_ea();		dyn_read_byte_release(DREG(EA),rm_reg,rm_regi);	} else {		gen_dop_byte(DOP_MOV,rm_reg,rm_regi,&DynRegs[decode.modrm.rm&3],decode.modrm.rm&4);	}}static void dyn_dop_evgv(DualOps op) {	dyn_get_modrm();	DynReg * rm_reg=&DynRegs[decode.modrm.reg];	if (decode.modrm.mod<3) {		dyn_fill_ea();		if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true);		dyn_read_word(DREG(EA),DREG(TMPW),decode.big_op);		if (op<=DOP_TEST) {			if (op==DOP_ADC || op==DOP_SBB) gen_needcarry();			else set_skipflags(false);		}		gen_dop_word(op,decode.big_op,DREG(TMPW),rm_reg);		if (op!=DOP_CMP) dyn_write_word_release(DREG(EA),DREG(TMPW),decode.big_op);		else gen_releasereg(DREG(EA));		gen_releasereg(DREG(TMPW));	} else {		if (op<=DOP_TEST) {			if (op==DOP_ADC || op==DOP_SBB) gen_needcarry();			else gen_discardflags();		}		gen_dop_word(op,decode.big_op,&DynRegs[decode.modrm.rm],rm_reg);	}}static void dyn_imul_gvev(Bitu immsize) {	dyn_get_modrm();DynReg * src;	DynReg * rm_reg=&DynRegs[decode.modrm.reg];	if (decode.modrm.mod<3) {		dyn_fill_ea();dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op);		src=DREG(TMPW);	} else {		src=&DynRegs[decode.modrm.rm];	}	gen_needflags();	switch (immsize) {	case 0:gen_imul_word(decode.big_op,rm_reg,src);break;	case 1:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit8s)decode_fetchb());break;	case 2:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit16s)decode_fetchw());break;	case 4:gen_imul_word_imm(decode.big_op,rm_reg,src,(Bit32s)decode_fetchd());break;	}	gen_releasereg(DREG(TMPW));}static void dyn_dop_gvev(DualOps op) {	dyn_get_modrm();	DynReg * rm_reg=&DynRegs[decode.modrm.reg];	if (decode.modrm.mod<3) {		dyn_fill_ea();		if ((op<=DOP_TEST) && (op!=DOP_ADC && op!=DOP_SBB)) set_skipflags(true);		dyn_read_word_release(DREG(EA),DREG(TMPW),decode.big_op);		if (op<=DOP_TEST) {			if (op==DOP_ADC || op==DOP_SBB) gen_needcarry();			else set_skipflags(false);		}		gen_dop_word(op,decode.big_op,rm_reg,DREG(TMPW));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -