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

📄 isp8sim.c

📁 Lattice 超精简8位软核CPU--Mico8
💻 C
📖 第 1 页 / 共 2 页
字号:
	case 15: { /* import/export & scratch pad access */
		int port = rb;

		if (!(instr & 0x4)) { /* import / export */
			char *opname = (instr & 1 ? "import" : "export");
			if (instr & 2) { /* indirect */
				fprintf(stdout,"\t%si\tR%02d,R%02d\n",opname,rd,rb);
			} else {
				fprintf(stdout,"\t%s\tR%02d,%d\n",opname,rd,rb);
			}
		} else { /* load/store from/to scratch pad */
			char *opname = (instr & 1 ? "lsp" : "ssp");
			if (instr & 2) { /* indirect */
				fprintf(stdout,"\t%si\tR%02d,R%02d\n",opname,rd,rb);
			} else {
				fprintf(stdout,"\t%s\tR%02d,%d\n",opname,rd,rb);
			}
		}
		break;
	}
	default:
		fprintf(stderr,"unknown instruction @pc = 0x%x\n",cpc);
		break;
	}
	
}

static void disass_prom()
{
	int i;
	
	for (i = 0 ; i < promsize ; i++) {
		disass(i,prom[i]);
	}
}

static void exec_i()
{
	unsigned int instr = prom[cpc];
	int rd       = (instr >> 8) & 0x1f;
	int rb       = (instr >> 3) & 0x1f;
	int konst    = (instr & 0xff);
	int broffset = (instr & 0xfff);
	int iskonst  = (instr >> 13) & 1;
	int port, zu = 0;
	int grp_code = ((instr >> 14) & 0xf);
	int tmp;
	int cpc_ch   = 0;
	int pushpc = 0;

	port = rb;
	
	if (trace)
		disass(cpc, instr);
	
	switch (grp_code) {
	case 0: /* sub */
	case 1: /* subc */
		regfile[rd] -= ((iskonst ? konst : regfile[rb]) + (grp_code & 1 ? carry : 0));
		carry = ((regfile[rd] & ~0xff) ? 1 : 0);
		zero  = (regfile[rd] == 0 ? 1 : 0);
		break;

	case 2: /* add */
	case 3: /* addc */
		regfile[rd] += ((iskonst ? konst : regfile[rb]) + (grp_code & 1 ? carry : 0));
		carry = ((regfile[rd] & ~0xff) ? 1 : 0);
		zero  = (regfile[rd] == 0 ? 1 : 0);
		break;
		
	case 4: /* mov */
		regfile[rd] = (iskonst ? konst : regfile[rb]);
		break;

	case 5: /* and */
		regfile[rd] &= (iskonst ? konst : regfile[rb]);
		zero  = (regfile[rd] == 0 ? 1 : 0);
		break;

	case 6: /* or */
		regfile[rd] |= (iskonst ? konst : regfile[rb]);
		zero  = (regfile[rd] == 0 ? 1 : 0);
		break;
		
	case 7: /* xor */
		regfile[rd] ^= (iskonst ? konst : regfile[rb]);
		zero  = (regfile[rd] == 0 ? 1 : 0);
		break;
		
	case 8: /* compare */
		tmp = regfile[rd] - (iskonst ? konst : regfile[rb]);
		carry = (( tmp & ~0xff) ? 1 : 0);
		zero  = ( tmp == 0 ? 1 : 0);
		break;
		
	case 9: /* test */
		tmp = regfile[rd] & (iskonst ? konst : regfile[rb]);
		zero  = ( tmp == 0 ? 1 : 0);
		break;
		
	case 10: { /* rotate group */ 
		unsigned char rval = regfile[rb] ;
		unsigned int  rcode = (instr & 0x3);
		unsigned oval = rval;

		switch (rcode) {
		case 0: /* ror */
			rval >>= 1;
			rval |= (oval & 1 ? 0x80 : 0);
			break;
		case 1: /* rol */
			rval <<= 1;
			rval |= (oval & 0x80 ? 1 : 0);
			break;
		case 2: /* rorc */
			rval >>= 1;
			rval |= (carry ? 0x80 : 0);
			carry = (oval & 1);
			break;
		case 3: /* rolc */
			rval <<= 1;
			rval |= (carry ? 1 : 0);
			carry = ((oval & 0x80) ? 1 : 0);
			break;
		}
		regfile[rd] = rval & 0xff;
		zero = ((rval & 0xff) == 0 ? 1 : 0);
		break;
	}
	case 11: { /* flag set/clear */
		switch (instr & 7) {
		case 0:
		case 1:
			carry = instr & 1;
			break;
		case 2:
		case 3:
			zero = instr & 1;
			break;
		case 4:
		case 5:
			ie = instr & 1;
			break;
		}
		break;
	}
	case 13:
		pushpc = 1;
		/* fall thru */
	case 12: { /* branch */
		/* sign extend */
		switch ((instr >> 10) & 0x7) {
                case 0:
                case 1:
                case 2:
                case 3:
                   // bz, bnz, callz, callnz, bc, bnc, callc, callnc
                   broffset &= 0x3ff;
                   broffset <<= (32 - 10);
                   broffset >>= (32 - 10);
                   break;
                case 4:
                   // b, call
                   broffset <<= (32 - 12);
                   broffset >>= (32 - 12);
                   break;
                default:
                   // cover hazard
                   broffset &= 0x3ff;
                   broffset <<= (32 - 10);
                   broffset >>= (32 - 10);
                }

		switch ((instr >> 10) & 0x7) {
		case 0:
			cpc_ch = zero;
			break;
		case 1:
			cpc_ch = !zero;
			break;
		case 2:
			cpc_ch = carry;
			break;
		case 3:
			cpc_ch = !carry;
			break;
		case 4:
			cpc_ch = 1;
			break;
		}
		if (pushpc) {			
			callstack[csp++] = cpc + 1;
			if (csp >= 16) csp = 0;
		}
		if (cpc_ch) cpc += broffset;
		break;
	}
	case 14: /* ret & iret */
		if (instr & (4 << 10)) {
			carry = carry_i;
			zero  = zero_i;
		}
		cpc_ch = 1;
		cpc = callstack[--csp];
		if (csp < 0) csp = 0;
		break;
	case 15: { /* import/export & scratch pad access */
		char buffer[32];
		char *spp;

		spp = xsp;
		if (instr & 2) { /* indirect */
                   port = regfile[rb] & 0xff;
		} else {
                   port = (instr & 0xf8) >> 3;
                }
		
		if (!(instr & 0x4)) { /* import / export */
			if (instr & 1) { /* import */
                           if (!no_import_text) {
				fprintf(stdout,"input value for port #(%d) : ",port);
				fflush(stdout);
				fgets(buffer,sizeof(buffer),stdin);
                           }
                                regfile[rd] = (unsigned char)strtoul(buffer, NULL, 0);
                                //regfile[rd] = buffer[0] & 0xff;
			} else {
				fprintf(stdout,"@%x %02X\n", port, regfile[rd] & 0xff);
				/* write to port #0xFF means exit simulator */
				if (port == 0xff) exit(0);
			}
		} else { /* load/store from/to scratch pad */
			if (instr & 1) 
				regfile[rd] = spp[port] & 0xff;
			else
				spp[port] = regfile[rd] & 0xff;			
		}
		break;
	}
	default:
		fprintf(stderr,"unknown instruction @pc = 0x%x\n",cpc);
		break;
	}

	if (trace) {
		int ach = 0;
		/* print flags changed */
		if (carry_o != carry) {
			fprintf(stdout,"\tCY=%d,",carry);
			ach++;
		}
		if (zero_o != zero) {
			fprintf(stdout,"\tZR=%d,",zero);
			ach++;
		}
		/* print register changed */
		if (oregfile[rd] != regfile[rd]) {
			fprintf(stdout,"\tR%02d = 0x%02X",rd, regfile[rd] & 0xFF);
			ach++;
		}
		if (ach) fprintf(stdout,"\n");
	}
	regfile[rd] &= 0xff;
	oregfile[rd] = regfile[rd];
	carry_o = carry;
	zero_o = zero;
	if (!cpc_ch) 
		cpc++;
}

static void print_help(char *pname)
{
	fprintf(stdout,"usage %s: [options] promfilename\n",pname);
	fprintf(stdout,"\t-p promsize. (default 512)\n");
	fprintf(stdout,"\t-ix promfile is hex (default)\n");	
	fprintf(stdout,"\t-ib promfile is binary\n");
	fprintf(stdout,"\t-t trace instructions\n");
	fprintf(stdout,"\t-d disassemble\n");
	fprintf(stdout,"\t-h this message\n");
}

static void msg_print(char *pname)
{
	fprintf(stdout,"usage %s: [options] promfilename\n",pname);
	fprintf(stdout,"\t-p promsize. (default 512)\n");

}
int main(int argc, char *argv[])
{
	int i;
	if (argc < 2) {
		print_help(argv[0]);
		exit(-1);
	}
	
	for (i = 1; i < argc ; i++ ) {
		if (argv[i][0] == '-') {
			switch (argv[i][1]) {
			case 'h':
				print_help(argv[0]);
				exit(-1);
			case 'i':
				if (argv[i][2] == 'x') {
					imode = IMODE_HEX;
				} else if (argv[i][2] == 'b') {
					imode = IMODE_BIN;
				}
				break;
			case 'p':
				i++;
				if (sscanf(argv[i],"%d",&promsize) != 1) {
					fprintf(stdout,"invalid promsize %s\n",argv[i]);
					exit(-1);
				}
				break;
			case 'd':
				disa = 1;
				break;
			case 't':
				trace = 1;
				break;
                        case 'n':
                                no_import_text = 1;
                                break;
			default:
				fprintf(stdout,"invalid option %s\n",argv[i]);
				print_help(argv[0]);
				exit(-1);
			}
		} else {
			/* assume it is promfile name */
			promfname = strdup(argv[i]);
			if (!(promf = fopen(promfname,"r"))) {
				error_exit("cannot open promfile %s",promfname);
			}
		}
	}
	
	load_prom();
	memset(regfile,0,sizeof(regfile));
	memset(oregfile,0,sizeof(oregfile));

	if (disa) {
		disass_prom();
		exit(0);
	}

	while (1) {
		exec_i();
	}
}

⌨️ 快捷键说明

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