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

📄 star.c

📁 著名ARC模拟器源码,包括多个平台
💻 C
📖 第 1 页 / 共 5 页
字号:
		emit("push edx\n");		emit("add edx,[__vbr]\n");	}	emit("call readmemorydword\n");	if(cputype >= 68010) {		emit("pop edx\n");	}	emit("push ecx\n");/* dest. PC */	sr2cx();	emit("push ecx\n");/* old SR */	supervisor();	/*	** Exception handlers do not like being traced, so clear the SR trace	** flag as well as the trace tricky bit.	**	** Leave the cycle leftover count alone, in case we still need to	** call attention to other unrelated tricky bits.	*/	emit("and byte[__sr+1],27h\n");	emit("mov byte[__trace_trickybit],0\n");	emit("mov ecx,esi\n");	emit("sub ecx,ebp\n");	if(cputype >= 68010) {		emit("push ecx\n");/* old PC */		emit("mov ecx,edx\n");	}	emit("mov edx,[__a7]\n");	if(cputype >= 68010) {		emit("and ecx,0FFCh\n");/* Format code */		emit("sub edx,byte 2\n");		emit("call writememoryword\n");		emit("pop ecx\n");	}	emit("sub edx,byte 4\n");	emit("call writememorydword\n");	emit("pop ecx\n");/* old SR */	emit("sub edx,byte 2\n");	emit("call writememoryword\n");	emit("mov [__a7],edx\n");	emit("pop esi\n");/* dest. PC */	emit("ret\n");}/***************************************************************************//* Privilege violation */static void gen_privilege_violation(void){	align(16);	emit("privilege_violation:\n");	emit("sub esi,byte 2\n");	emit("mov edx,20h\n");	emit("call group_1_exception\n");	perform_cached_rebase();	ret_timing((cputype==68010)?38:34);}/***************************************************************************/static void usereg(void) {	emit("and ebx,byte 7\n");}/* usereg only where applicable */static void selective_usereg(void) {	switch(main_eamode) {	case dreg: case areg:	case aind: case ainc: case adec:	case adsp: case axdp:		usereg();	default:		break;	}}static void selftest(int size) {	emit("test %s,%s\n", x86cx[size], x86cx[size]);}/***************************************************************************//* Get condition: Less Than (N^V)** If true, the x86 sign flag will be set */static void getcondition_l_s_ns(void) {	emit("push eax\n");	emit("neg al\n");	emit("xor al,ah\n");	emit("pop eax\n");}/* Get condition: Less Than or Equal ((N^V)|Z)** If true, the x86 sign flag will be set */static void getcondition_le_s_ns(void) {	emit("push eax\n");	emit("neg al\n");	emit("xor al,ah\n");	emit("add ah,ah\n");	emit("or al,ah\n");	emit("pop eax\n");}static char optcc[5];static char optrc[5];static void getcondition(int cc) {	switch(cc) {	case 0x0:	case 0x1:		break;	case 0x2:/* a */		emit("test ah,41h\n");		sprintf(optcc, "z");		sprintf(optrc, "nz");		break;	case 0x3:/* be */		emit("test ah,41h\n");		sprintf(optcc, "nz");		sprintf(optrc, "z");		break;	case 0x4:/* nc */		emit("test ah,1\n");		sprintf(optcc, "z");		sprintf(optrc, "nz");		break;	case 0x5:/* c */		emit("test ah,1\n");		sprintf(optcc, "nz");		sprintf(optrc, "z");		break;	case 0x6:/* ne */		emit("test ah,40h\n");		sprintf(optcc, "z");		sprintf(optrc, "nz");		break;	case 0x7:/* e */		emit("test ah,40h\n");		sprintf(optcc, "nz");		sprintf(optrc, "z");		break;	case 0x8:/* no */		emit("test al,1\n");		sprintf(optcc, "z");		sprintf(optrc, "nz");		break;	case 0x9:/* o */		emit("test al,1\n");		sprintf(optcc, "nz");		sprintf(optrc, "z");		break;	case 0xA:/* ns */		emit("or ah,ah\n");		sprintf(optcc, "ns");		sprintf(optrc, "s");		break;	case 0xB:/* s */		emit("or ah,ah\n");		sprintf(optcc, "s");		sprintf(optrc, "ns");		break;	case 0xC:/* ge */		getcondition_l_s_ns();		sprintf(optcc, "ns");		sprintf(optrc, "s");		break;	case 0xD:/* l */		getcondition_l_s_ns();		sprintf(optcc, "s");		sprintf(optrc, "ns");		break;	case 0xE:/* g */		getcondition_le_s_ns();		sprintf(optcc, "ns");		sprintf(optrc, "s");		break;	case 0xF:/* le */		getcondition_le_s_ns();		sprintf(optcc, "s");		sprintf(optrc, "ns");		break;	default:break;	}}static void flags(void) {	emit("lahf\n");	emit("seto al\n");}static void flags_v0(void) {	emit("lahf\n");	emit("mov al,0\n");}/* Put one of the x86 flags into the 68K zero flag. */static void flag_to_z(char *f) {	int myline = linenum; linenum += 2;	emit("j%s short ln%d\n", f, myline);	emit("and ah,0BFh\n");	emit("jmp short ln%d\n", myline + 1);	emit("ln%d:\n", myline);	emit("or ah,40h\n");	emit("ln%d:\n", myline + 1);}/* carry to X flag */static void c2x(void) {	emit("setc [__xflag]\n");}/* with previous flags in another register, adjust for non-changing zero */static void adjzero(char *reg) {	int myline = linenum; linenum++;	emit("jnz short ln%d\n", myline);	emit("or %s,0BFh\n", reg);	emit("and ah,%s\n", reg);	emit("ln%d:\n", myline);}/* Check for privilege violation */static void privilegecheck(void) {	emit("test byte[__sr+1],20h\n");	emit("jz near privilege_violation\n");}/****************************************************************************** EFFECTIVE ADDRESS GENERATION****************************************************************************//*** There are five types of EA activity:**** 1. Read:       precalc -> read -> postcalc** 2. Write:      precalc -> write -> postcalc** 3. R-M-W:      precalc -> read -> (modify) -> write -> postcalc** 4. Move:       Read followed by Write** 5. Control:    precalc*//* Calculate address */static void ea_step_precalc(int size, enum eamode mode, int reg) {	char regs[100];	if(reg == -1) sprintf(regs, "ebx*4");	else sprintf(regs, "%d", reg * 4);	switch(mode) {	case dreg: case areg:		break;	case aind: case ainc: case adec:		emit("mov edx,[__areg+%s]\n",regs);		if(mode == adec) {			/* Compensate for byte-sized stack ops */			if(size == 1) {				if(reg == -1) {					emit("cmp bl,7\n");					emit("adc edx,byte -2\n");				} else if(reg == 7) {					emit("sub edx,byte 2\n");				} else {					emit("dec edx\n");				}			} else {				emit("sub edx,byte %d\n", size);			}		}		break;	case adsp:		emit("movsx edx,word[esi]\n");		emit("add esi,byte 2\n");		emit("add edx,[__areg+%s]\n", regs);		break;	case axdp:		emit("call decode_ext\n");		emit("add edx,[__areg+%s]\n", regs);		break;	case absw:		emit("movsx edx,word[esi]\n");		emit("add esi,byte 2\n");		break;	case absl:		emit("mov edx,dword[esi]\n");		emit("add esi,byte 4\n");		emit("rol edx,16\n");		break;	case pcdp:		emit("movsx edx,word[esi]\n");		emit("add edx,esi\n");		emit("sub edx,ebp\n");		emit("add esi,byte 2\n");		break;	case pcxd:		emit("call decode_ext\n");		emit("add edx,esi\n");		emit("sub edx,ebp\n");		emit("sub edx,byte 2\n");		break;	case immd:		break;	default:		emit("#error ea_step_precalc\n");		break;	}}static void ea_step_read(int size, enum eamode mode, int reg) {	char regs[100];	if(reg == -1) sprintf(regs, "ebx*4");	else sprintf(regs, "%d", reg * 4);	switch(mode) {	case dreg: emit("mov ecx,[__dreg+%s]\n", regs); break;	case areg: emit("mov ecx,[__areg+%s]\n", regs); break;	case aind: case ainc: case adec:	case adsp: case axdp:	case absw: case absl:	case pcdp: case pcxd:		emit("call readmemory%s\n", sizename[size]);		break;	case immd:		switch(size) {		case 1:		case 2:			emit("mov cx,[esi]\n");			emit("add esi,byte 2\n");			break;		case 4:			emit("mov ecx,[esi]\n");			emit("add esi,byte 4\n");			emit("rol ecx,16\n");			break;		default:			emit("#error ea_step_read\n");			break;		}		break;	default:		emit("#error ea_step_read\n");		break;	}}/*** Special case for when you need to load a word and sign-extend it.** This cuts some fat out of a few instructions (i.e. MOVEA).*/static void ea_step_read_signword(enum eamode mode, int reg) {	char regs[100];	if(reg == -1) sprintf(regs, "ebx*4");	else sprintf(regs, "%d", reg * 4);	switch(mode) {	case dreg: emit("movsx ecx,word[__dreg+%s]\n", regs); break;	case areg: emit("movsx ecx,word[__areg+%s]\n", regs); break;	case aind: case ainc: case adec:	case adsp: case axdp:	case absw: case absl:	case pcdp: case pcxd:		emit("call readmemory%s\n", sizename[2]);		emit("movsx ecx,cx\n");		break;	case immd:		emit("movsx ecx,word[esi]\n");		emit("add esi,byte 2\n");		break;	default:		emit("#error ea_step_read_signword\n");		break;	}}static void ea_step_write(int size, enum eamode mode, int reg) {	char regs[100];	if(reg == -1) sprintf(regs, "ebx*4");	else sprintf(regs, "%d", reg * 4);	switch(mode) {	case dreg:		emit("mov [__dreg+%s],%s\n", regs, x86cx[size]);		break;	case aind: case ainc: case adec:	case adsp: case axdp:	case absw: case absl:		emit("call writememory%s\n", sizename[size]);		break;	default:		emit("#error ea_step_write\n");		break;	}}static void ea_step_postcalc(int size, enum eamode mode, int reg) {	char regs[100];	if(reg == -1) sprintf(regs, "ebx*4");	else sprintf(regs, "%d", reg * 4);	switch(mode) {	case ainc:		/* Compensate for byte-sized stack ops */		if(size == 1) {			if(reg == -1) {				emit("cmp bl,7\n");				emit("sbb edx,byte -2\n");			} else if(reg == 7) {				emit("add edx,byte 2\n");			} else {				emit("inc edx\n");			}		} else {			emit("add edx,byte %d\n", size);		}		/* Fall through */	case adec:		/* Store already-predecremented address */		emit("mov [__areg+%s],edx\n", regs);		break;	case dreg: case areg:	case aind: case adsp: case axdp:	case absw: case absl:	case pcdp: case pcxd:	case immd:		break;	default:		emit("#error ea_step_postcalc\n");		break;	}}/* Combined EA routines */static void ea_load(int size, enum eamode mode, int reg) {	ea_step_precalc (size, mode, reg);	ea_step_read    (size, mode, reg);	ea_step_postcalc(size, mode, reg);}static void ea_load_signword(enum eamode mode, int reg) {	ea_step_precalc      (2, mode, reg);	ea_step_read_signword(   mode, reg);	ea_step_postcalc     (2, mode, reg);}static void ea_store(int size, enum eamode mode, int reg) {	ea_step_precalc (size, mode, reg);	ea_step_write   (size, mode, reg);	ea_step_postcalc(size, mode, reg);}static void ea_rmw_load(int size, enum eamode mode, int reg) {	ea_step_precalc (size, mode, reg);	ea_step_read    (size, mode, reg);}static void ea_rmw_store(int size, enum eamode mode, int reg) {	ea_step_write   (size, mode, reg);	ea_step_postcalc(size, mode, reg);}static void ea_control(enum eamode mode, int reg) {	ea_step_precalc (0, mode, reg);}static void main_ea_load(void) {	ea_load(main_size, main_eamode, -1);}static void main_ea_load_signed(void) {	if(main_size < 4) {		ea_load_signword(main_eamode, -1);	} else {		ea_load(main_size, main_eamode, -1);	}}static void main_ea_store(void) {	ea_store(main_size, main_eamode, -1);}static void main_ea_rmw_load(void) {	ea_rmw_load(main_size, main_eamode, -1);}stati

⌨️ 快捷键说明

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