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

📄 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 页
字号:
	dyn_pop(DREG(EBP),false);	gen_releasereg(DREG(TMPW));}static void dyn_segprefix(SegNames seg) {	if (GCC_UNLIKELY((Bitu)(decode.segprefix))) IllegalOption("dyn_segprefix");	decode.segprefix=&DynRegs[G_ES+seg];}static void dyn_closeblock(void) {	//Shouldn't create empty block normally but let's do it like this	gen_protectflags();	dyn_fill_blocks();	cache_closeblock();}static void dyn_normal_exit(BlockReturn code) {	gen_protectflags();	dyn_reduce_cycles();	dyn_set_eip_last();	dyn_save_critical_regs();	gen_return(code);	dyn_closeblock();}static void dyn_exit_link(Bits eip_change) {	gen_protectflags();	gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),(decode.code-decode.code_start)+eip_change);	dyn_reduce_cycles();	dyn_save_critical_regs();	gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start));	dyn_closeblock();}static void dyn_branched_exit(BranchTypes btype,Bit32s eip_add) {	Bitu eip_base=decode.code-decode.code_start; 	gen_needflags(); 	gen_protectflags();	dyn_save_noncritical_regs();	gen_releasereg(DREG(FLAGS));	gen_releasereg(DREG(EIP));	gen_preloadreg(DREG(CYCLES));	gen_preloadreg(DREG(EIP));	DynReg save_cycles,save_eip;	dyn_saveregister(DREG(CYCLES),&save_cycles);	dyn_saveregister(DREG(EIP),&save_eip);	Bit8u * data=gen_create_branch(btype); 	/* Branch not taken */	dyn_reduce_cycles(); 	gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base);	gen_releasereg(DREG(CYCLES)); 	gen_releasereg(DREG(EIP)); 	gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start)); 	gen_fill_branch(data); 	/* Branch taken */	dyn_restoreregister(&save_cycles,DREG(CYCLES));	dyn_restoreregister(&save_eip,DREG(EIP));	dyn_reduce_cycles(); 	gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(EIP),eip_base+eip_add);	gen_releasereg(DREG(CYCLES)); 	gen_releasereg(DREG(EIP)); 	gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start)); 	dyn_closeblock();}enum LoopTypes {	LOOP_NONE,LOOP_NE,LOOP_E,LOOP_JCXZ};static void dyn_loop(LoopTypes type) {	dyn_reduce_cycles();	Bits eip_add=(Bit8s)decode_fetchb();	Bitu eip_base=decode.code-decode.code_start;	Bit8u * branch1=0;Bit8u * branch2=0;	dyn_save_critical_regs();	switch (type) {	case LOOP_E:		gen_needflags();		branch1=gen_create_branch(BR_NZ);		break;	case LOOP_NE:		gen_needflags();		branch1=gen_create_branch(BR_Z);		break;	}	gen_protectflags();	switch (type) {	case LOOP_E:	case LOOP_NE:	case LOOP_NONE:		gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX));		gen_releasereg(DREG(ECX));		branch2=gen_create_branch(BR_Z);		break;	case LOOP_JCXZ:		gen_dop_word(DOP_OR,decode.big_addr,DREG(ECX),DREG(ECX));		gen_releasereg(DREG(ECX));		branch2=gen_create_branch(BR_NZ);		break;	}	gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base+eip_add);	gen_releasereg(DREG(EIP));	gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start));	if (branch1) {		gen_fill_branch(branch1);		gen_sop_word(SOP_DEC,decode.big_addr,DREG(ECX));		gen_releasereg(DREG(ECX));	}	/* Branch taken */	gen_fill_branch(branch2);	gen_lea(DREG(EIP),DREG(EIP),0,0,eip_base);	gen_releasereg(DREG(EIP));	gen_jmp_ptr(&decode.block->link[1].to,offsetof(CacheBlock,cache.start));	dyn_closeblock();}static void dyn_ret_near(Bitu bytes) {	gen_protectflags();	dyn_reduce_cycles();	dyn_pop(DREG(EIP));	if (bytes) gen_dop_word_imm(DOP_ADD,true,DREG(ESP),bytes);	dyn_save_critical_regs();	gen_return(BR_Normal);	dyn_closeblock();}static void dyn_call_near_imm(void) {	Bits imm;	if (decode.big_op) imm=(Bit32s)decode_fetchd();	else imm=(Bit16s)decode_fetchw();	dyn_set_eip_end(DREG(TMPW));	dyn_push(DREG(TMPW));	gen_dop_word_imm(DOP_ADD,decode.big_op,DREG(TMPW),imm);	gen_dop_word(DOP_MOV,decode.big_op,DREG(EIP),DREG(TMPW));	dyn_reduce_cycles();	dyn_save_critical_regs();	gen_jmp_ptr(&decode.block->link[0].to,offsetof(CacheBlock,cache.start));	dyn_closeblock();}static void dyn_ret_far(Bitu bytes) {	gen_protectflags();	dyn_reduce_cycles();	dyn_set_eip_last_end(DREG(TMPW));	dyn_flags_gen_to_host();	dyn_save_critical_regs();	gen_call_function((void*)&CPU_RET,"%Id%Id%Drd",decode.big_op,bytes,DREG(TMPW));	gen_return_fast(BR_Normal);	dyn_closeblock();}static void dyn_call_far_imm(void) {	Bitu sel,off;	off=decode.big_op ? decode_fetchd() : decode_fetchw();	sel=decode_fetchw();	dyn_reduce_cycles();	dyn_set_eip_last_end(DREG(TMPW));	dyn_flags_gen_to_host();	dyn_save_critical_regs();	gen_call_function((void*)&CPU_CALL,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW));	gen_return_fast(BR_Normal);	dyn_closeblock();}static void dyn_jmp_far_imm(void) {	Bitu sel,off;	gen_protectflags();	off=decode.big_op ? decode_fetchd() : decode_fetchw();	sel=decode_fetchw();	dyn_reduce_cycles();	dyn_set_eip_last_end(DREG(TMPW));	dyn_flags_gen_to_host();	dyn_save_critical_regs();	gen_call_function((void*)&CPU_JMP,"%Id%Id%Id%Drd",decode.big_op,sel,off,DREG(TMPW));	gen_return_fast(BR_Normal);	dyn_closeblock();}static void dyn_iret(void) {	gen_protectflags();	dyn_flags_gen_to_host();	dyn_reduce_cycles();	dyn_set_eip_last_end(DREG(TMPW));	dyn_save_critical_regs();	gen_call_function((void*)&CPU_IRET,"%Id%Drd",decode.big_op,DREG(TMPW));	gen_return_fast(BR_Iret);	dyn_closeblock();}static void dyn_interrupt(Bitu num) {	gen_protectflags();	dyn_flags_gen_to_host();	dyn_reduce_cycles();	dyn_set_eip_last_end(DREG(TMPW));	dyn_save_critical_regs();	gen_call_function((void*)&CPU_Interrupt,"%Id%Id%Drd",num,CPU_INT_SOFTWARE,DREG(TMPW));	gen_return_fast(BR_Normal);	dyn_closeblock();}static void dyn_add_iocheck(Bitu access_size) {	if (cpu.pmode) {		gen_call_function((void *)&CPU_IO_Exception,"%Dw%Id",DREG(EDX),access_size);		dyn_check_bool_exception_al();	}}static void dyn_add_iocheck_var(Bit8u accessed_port,Bitu access_size) {	if (cpu.pmode) {		gen_call_function((void *)&CPU_IO_Exception,"%Id%Id",accessed_port,access_size);		dyn_check_bool_exception_al();	}}#ifdef X86_DYNFPU_DH_ENABLED#include "dyn_fpu_dh.h"#define dh_fpu_startup() {		\	fpu_used=true;				\	gen_protectflags();			\	gen_load_host(&dyn_dh_fpu.state_used,DREG(TMPB),4);	\	gen_dop_word_imm(DOP_CMP,true,DREG(TMPB),0);		\	gen_releasereg(DREG(TMPB));							\	save_info[used_save_info].branch_pos=gen_create_branch_long(BR_Z);		\	dyn_savestate(&save_info[used_save_info].state);	\	save_info[used_save_info].return_pos=cache.pos;		\	save_info[used_save_info].type=fpu_restore;			\	used_save_info++;									\}#endif#include "dyn_fpu.h"static CacheBlock * CreateCacheBlock(CodePageHandler * codepage,PhysPt start,Bitu max_opcodes) {	Bits i;/* Init a load of variables */	decode.code_start=start;	decode.code=start;	Bitu cycles=0;	decode.page.code=codepage;	decode.page.index=start&4095;	decode.page.wmap=codepage->write_map;	decode.page.invmap=codepage->invalidation_map;	decode.page.first=start >> 12;	decode.active_block=decode.block=cache_openblock();	decode.block->page.start=decode.page.index;	codepage->AddCacheBlock(decode.block);	gen_save_host_direct(&cache.block.running,(Bit32u)decode.block);	for (i=0;i<G_MAX;i++) {		DynRegs[i].flags&=~(DYNFLG_ACTIVE|DYNFLG_CHANGED);		DynRegs[i].genreg=0;	}	gen_reinit();	/* Start with the cycles check */	gen_protectflags();	gen_dop_word_imm(DOP_CMP,true,DREG(CYCLES),0);	save_info[used_save_info].branch_pos=gen_create_branch_long(BR_LE);	save_info[used_save_info].type=cycle_check;	used_save_info++;	gen_releasereg(DREG(CYCLES));	decode.cycles=0;#ifdef X86_DYNFPU_DH_ENABLED	bool fpu_used=false;#endif	while (max_opcodes--) {/* Init prefixes */		decode.big_addr=cpu.code.big;		decode.big_op=cpu.code.big;		decode.segprefix=0;		decode.rep=REP_NONE;		decode.cycles++;		decode.op_start=decode.code;restart_prefix:		Bitu opcode;		if (!decode.page.invmap) opcode=decode_fetchb();		else {			if (decode.page.index<4096) {				if (GCC_UNLIKELY(decode.page.invmap[decode.page.index]>=4)) goto illegalopcode;				opcode=decode_fetchb();			} else {				opcode=decode_fetchb();				if (GCC_UNLIKELY(decode.page.invmap && 					(decode.page.invmap[decode.page.index-1]>=4))) goto illegalopcode;			}		}		switch (opcode) {		case 0x00:dyn_dop_ebgb(DOP_ADD);break;		case 0x01:dyn_dop_evgv(DOP_ADD);break;		case 0x02:dyn_dop_gbeb(DOP_ADD);break;		case 0x03:dyn_dop_gvev(DOP_ADD);break;		case 0x04:gen_discardflags();gen_dop_byte_imm(DOP_ADD,DREG(EAX),0,decode_fetchb());break;		case 0x05:gen_discardflags();dyn_dop_word_imm(DOP_ADD,decode.big_op,DREG(EAX));break;		case 0x06:dyn_push_seg(es);break;		case 0x07:dyn_pop_seg(es);break;		case 0x08:dyn_dop_ebgb(DOP_OR);break;		case 0x09:dyn_dop_evgv(DOP_OR);break;		case 0x0a:dyn_dop_gbeb(DOP_OR);break;		case 0x0b:dyn_dop_gvev(DOP_OR);break;		case 0x0c:gen_discardflags();gen_dop_byte_imm(DOP_OR,DREG(EAX),0,decode_fetchb());break;		case 0x0d:gen_discardflags();gen_dop_word_imm(DOP_OR,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() :  decode_fetchw());break;		case 0x0e:dyn_push_seg(cs);break;		case 0x0f:		{			Bitu dual_code=decode_fetchb();			switch (dual_code) {			/* Short conditional jumps */			case 0x80:case 0x81:case 0x82:case 0x83:case 0x84:case 0x85:case 0x86:case 0x87:				case 0x88:case 0x89:case 0x8a:case 0x8b:case 0x8c:case 0x8d:case 0x8e:case 0x8f:					dyn_branched_exit((BranchTypes)(dual_code&0xf),					decode.big_op ? (Bit32s)decode_fetchd() : (Bit16s)decode_fetchw());					goto finish_block;			/* PUSH/POP FS */			case 0xa0:dyn_push_seg(fs);break;			case 0xa1:dyn_pop_seg(fs);break;			/* SHLD Imm/cl*/			case 0xa4:dyn_dshift_ev_gv(true,true);break;			case 0xa5:dyn_dshift_ev_gv(true,false);break;			/* PUSH/POP GS */			case 0xa8:dyn_push_seg(gs);break;			case 0xa9:dyn_pop_seg(gs);break;			/* SHRD Imm/cl*/			case 0xac:dyn_dshift_ev_gv(false,true);break;			case 0xad:dyn_dshift_ev_gv(false,false);break;					/* Imul Ev,Gv */			case 0xaf:dyn_imul_gvev(0);break;			/* LFS,LGS */			case 0xb4:dyn_load_seg_off_ea(fs);break;			case 0xb5:dyn_load_seg_off_ea(gs);break;			/* MOVZX Gv,Eb/Ew */			case 0xb6:dyn_mov_ev_gb(false);break;			case 0xb7:dyn_mov_ev_gw(false);break;			/* MOVSX Gv,Eb/Ew */			case 0xbe:dyn_mov_ev_gb(true);break;			case 0xbf:dyn_mov_ev_gw(true);break;			default:				DYN_LOG("Unhandled dual opcode 0F%02X",dual_code);				goto illegalopcode;			}		}break;		case 0x10:dyn_dop_ebgb(DOP_ADC);break;		case 0x11:dyn_dop_evgv(DOP_ADC);break;		case 0x12:dyn_dop_gbeb(DOP_ADC);break;		case 0x13:dyn_dop_gvev(DOP_ADC);break;		case 0x14:gen_needcarry();gen_dop_byte_imm(DOP_ADC,DREG(EAX),0,decode_fetchb());break;		case 0x15:gen_needcarry();gen_dop_word_imm(DOP_ADC,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() :  decode_fetchw());break;		case 0x16:dyn_push_seg(ss);break;		case 0x17:dyn_pop_seg(ss);break;		case 0x18:dyn_dop_ebgb(DOP_SBB);break;		case 0x19:dyn_dop_evgv(DOP_SBB);break;		case 0x1a:dyn_dop_gbeb(DOP_SBB);break;		case 0x1b:dyn_dop_gvev(DOP_SBB);break;		case 0x1c:gen_needcarry();gen_dop_byte_imm(DOP_SBB,DREG(EAX),0,decode_fetchb());break;		case 0x1d:gen_needcarry();gen_dop_word_imm(DOP_SBB,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() :  decode_fetchw());break;		case 0x1e:dyn_push_seg(ds);break;		case 0x1f:dyn_pop_seg(ds);break;		case 0x20:dyn_dop_ebgb(DOP_AND);break;		case 0x21:dyn_dop_evgv(DOP_AND);break;		case 0x22:dyn_dop_gbeb(DOP_AND);break;		case 0x23:dyn_dop_gvev(DOP_AND);break;		case 0x24:gen_discardflags();gen_dop_byte_imm(DOP_AND,DREG(EAX),0,decode_fetchb());break;		case 0x25:gen_discardflags();dyn_dop_word_imm(DOP_AND,decode.big_op,DREG(EAX));break;		case 0x26:dyn_segprefix(es);goto restart_prefix;		case 0x28:dyn_dop_ebgb(DOP_SUB);break;		case 0x29:dyn_dop_evgv(DOP_SUB);break;		case 0x2a:dyn_dop_gbeb(DOP_SUB);break;		case 0x2b:dyn_dop_gvev(DOP_SUB);break;		case 0x2c:gen_discardflags();gen_dop_byte_imm(DOP_SUB,DREG(EAX),0,decode_fetchb());break;		case 0x2d:gen_discardflags();gen_dop_word_imm(DOP_SUB,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() :  decode_fetchw());break;		case 0x2e:dyn_segprefix(cs);goto restart_prefix;		case 0x30:dyn_dop_ebgb(DOP_XOR);break;		case 0x31:dyn_dop_evgv(DOP_XOR);break;		case 0x32:dyn_dop_gbeb(DOP_XOR);break;		case 0x33:dyn_dop_gvev(DOP_XOR);break;		case 0x34:gen_discardflags();gen_dop_byte_imm(DOP_XOR,DREG(EAX),0,decode_fetchb());break;		case 0x35:gen_discardflags();gen_dop_word_imm(DOP_XOR,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() :  decode_fetchw());break;		case 0x36:dyn_segprefix(ss);goto restart_prefix;		case 0x38:dyn_dop_ebgb(DOP_CMP);break;		case 0x39:dyn_dop_evgv(DOP_CMP);break;		case 0x3a:dyn_dop_gbeb(DOP_CMP);break;		case 0x3b:dyn_dop_gvev(DOP_CMP);break;		case 0x3c:gen_discardflags();gen_dop_byte_imm(DOP_CMP,DREG(EAX),0,decode_fetchb());break;		case 0x3d:gen_discardflags();gen_dop_word_imm(DOP_CMP,decode.big_op,DREG(EAX),decode.big_op ? decode_fetchd() :  decode_fetchw());break;		case 0x3e:dyn_segprefix(ds);goto restart_prefix;		/* INC/DEC general register */		case 0x40:case 0x41:case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:				gen_needcarry();gen_sop_word(SOP_INC,decode.big_op,&DynRegs[opcode&7]);			break;		case 0x48:case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f:				gen_needcarry();gen_sop_word(SOP_DEC,decode.big_op,&DynRegs[opcode&7]);			break;		/* PUSH/POP General register */		case 0x50:case 0x51:case 0x52:case 0x53:case 0x55:case 0x56:case 0x57:				dyn_push(&DynRegs[opcode&7]);			break;		case 0x54:		/* PUSH SP is special */			gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(ESP));			dyn_push(DREG(TMPW));			gen_releasereg(DREG(TMPW));			break;		case 0x58:case 0x59:case 0x5a:case 0x5b:case 0x5c:case 0x5d:case 0x5e:case 0x5f:				dyn_pop(&DynRegs[opcode&7]);			break;		case 0x60:		/* PUSHA */			gen_dop_word(DOP_MOV,true,DREG(TMPW),DREG(ESP));			for (i=G_EAX;i<=G_EDI;i++) {				dyn_push_unchecked((i!=G_ESP) ? &DynRegs[i] : 

⌨️ 快捷键说明

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