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

📄 simulator.cpp

📁 一个可以模拟MIPS汇编语言在硬件上运行的模拟器。 该模拟器对于43条最常用的指令进行了实现。而且实现了端口通信
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	*regis = (word)value;
	run_regs(1,argv);
}

void run_goto(int argc,char *argv[])
{
	int value = get_number(argv[1],16);
	if (value == -1)
		return ;
	word addr = (word)value;
	if (mem.can_vst(addr) != 0)
		return ;
	reg.PC = addr;
	run_regs(1,argv);
}

void run_server(int argc,char *argv[])
{
	if (argc == 2)
	{
		if (strcmp(argv[1],"int") != 0)
		{
			printf ("\n Unknown control identifier `%s'.\n",argv[1]);
			return ;
		}
	}
	else if (argc != 1)
	{
		printf ("\n Unknown control identifier  ");
		for (int i=1;i<argc;i++)
			printf(" `%s' ",argv[i]);
		printf("\n");
		return ;
	}
	//load kernel.cod
	printf("\n");
	if (system("cx.exe kernel.x -mk -okernel.cod") != 0)
	{
		return ;
	}
	t = mem.load_mem("kernel.cod");
	if (t != 0)
	{
		printf("\n   Can not load kernel.cod\n");
		return ;
	}
	printf("Waiting ...\n");
	WSADATA wsaData;
	int errcode=WSAStartup(0x101,&wsaData);
	if(errcode != 0)
	{
		printf("\n Failed to change mode...\n");
		return ;
	}

	sockaddr_in local;
	local.sin_family=AF_INET;				//Address family
	local.sin_addr.s_addr=INADDR_ANY;		//Wild card IP address
	local.sin_port=htons((u_short)8000);	//port to use

	server=socket(AF_INET,SOCK_STREAM,0);

	if(server == INVALID_SOCKET)
	{
		printf("\n Failed to create socket...\n");
		return ;
	}

	if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
	{
		printf("\n Failed to bind...\n");
		return ;
	}

	if(listen(server,2)!=0)
		return ;

	sockaddr_in from1, from2;
	int fromlen1=sizeof(from1);
	int fromlen2=sizeof(from2);
	unsigned long ul1 = 1;
	unsigned long ul2 = 1;
	int start, total;
	int len;
	char buffer[BUFFER_SIZE_CLIENT+1];
	client1 = accept(server,(struct sockaddr*)&from1,&fromlen1);
	sprintf(buffer,"--COM1--  Accept user from IP %s\r\n  ---------------------------------------------------\r\n",
		inet_ntoa(from1.sin_addr));
	len = strlen(buffer);
	ioctlsocket(client1,FIONBIO,(unsigned long *)&ul1);
	start = 0;
	while (start < len-1)
	{
		total = send(client1,buffer+start,len-start,0);
		start += total;
	}
	printf("\n   --COM1-- Connection from %s\n",inet_ntoa(from1.sin_addr));

	client2 = accept(server,(struct sockaddr*)&from2,&fromlen2);
	sprintf(buffer,"--COM2--  Accept user from IP %s\r\n  ---------------------------------------------------\r\n",
		inet_ntoa(from2.sin_addr));
	len = strlen(buffer);
	ioctlsocket(client2,FIONBIO,(unsigned long *)&ul2);
	start = 0;
	while (start < len-1)
	{
		total = send(client2,buffer+start,len-start,0);
		start += total;
	}
	printf("   --COM2-- Connection from %s\n",inet_ntoa(from2.sin_addr));

	//reset registers
	printf("Working ....\n");
	run_reset(1,NULL);
	for (int i=0;i<34;i++)
		pc_step(1);
	run_uasm(1,NULL);

	char ch;
	word *mem1 = &mem.memory[0x6001];
	word *mem3 = &mem.memory[0x6003];
	//设定寄存器状态
	*mem1 = *mem3 = 1;

	bool loop = true;
	word err;
	console_mode = 1;
	int steps = 0;
	if (argc == 2)
		int_mode = 1;
	int int_count = 0;
	while (loop)
	{
		if (steps == 200)
		{
			if (kbhit())
			{
				ch = getch();
				if (ch == 7)
					goto break_while;
				else if (ch == 21)
					asm_func_int(0x10);	//硬中断
			}
			steps = 0;
		}
		if (((*mem1) & 1) == 0)
		{
			ch = (char )(mem.Msend[0] & 0xFF);
			send(client1,&ch,1,0);
			if (ch <= 0x20 || ch >= 0x7E)
				printf("\nCOM1>>send <hex> %02x",ch);
			else printf("\nCOM1>>send %c",ch);
			(*mem1) |= 1;
		}
		if (((*mem1) & 2) == 0)
		{
			len = recv(client1,&ch,1,0);
			if (len == 0)
			{
				printf("\n     Lost COM1...\n");
				goto break_while;
			}
			else if (len == 1)
			{
				if (ch <= 0x20 || ch >= 0x7E)
					printf("\nCOM1>>received <hex> %02x",ch);
				else printf("\nCOM1>>received %c",ch);
				mem.Mrecv[0] = (word)ch;
				*mem1 |= 2;
			}
		}
		if (((*mem3) & 1) == 0)
		{
			ch = (char )(mem.Msend[1] & 0xFF);
			send(client2,&ch,1,0);
			if (ch <= 0x20 || ch >= 0x7E)
				printf("\nCOM2>>send <hex> %02x",ch);
			else printf("\nCOM2>>send %c",ch);
			(*mem3) |= 1;
		}
		if (((*mem3) & 2) == 0)
		{
			len = recv(client2,&ch,1,0);
			if (len == 0)
			{
				printf("\n     Lost COM2...\n");
				goto break_while;
			}
			else if (len == 1)
			{
				if (ch <= 0x20 || ch >= 0x7E)
					printf("\nCOM2>>received <hex> %02x",ch);
				else printf("\nCOM2>>received %c",ch);
				mem.Mrecv[1] = (word)ch;
				*mem3 |= 2;
			}
		}
		steps ++;
		err = pc_step(1);
		if (err)
		{
			goto break_while;
		}
		if (int_mode == 1)
		{
			if ((reg.IH & 0x8000) == 0)
				int_count = 0;
			else 
				int_count ++;
			if (int_count == const_int_step)
			{
				int_count = 0;
				asm_func_int(0x20);
			}
		}
	}
break_while:
	console_mode = -1;
	closesocket(client1);
	closesocket(client2);
	closesocket(server);
	WSACleanup();
	int_mode = 0;
}

void run_compile(int argc,char *argv[])
{
	if (argc < 2)
	{
		printf ("\n Not enough arguments.\n");
		return;
	}
	FILE *handle = fopen(argv[1],"rb");
	if (handle == NULL)
	{
		printf("\n     Can not find %s...\n",argv[1]);
		return ;
	}
	fclose(handle);
	printf("\n");
	char com[1024] = "cx.exe ";
	int len = 6;
	int lens;
	for (int i=1;i<argc;i++)
	{
		com[len++] = ' ';
		lens = strlen(argv[i]);
		memcpy(&com[len],argv[i],lens+1);
		len += lens;
	}
	com[len] = '\0';
	system(com);
}

void run_help(int argc,char *argv[]);

typedef void (* Tconsole_func) (int , char *[]);

struct Tcommand
{
	Tconsole_func func;
	char *func_name;
	char *func_description;
};

Tcommand commands [] = {
	{run_continue,"c","[int]\t\t\tcontinue executing"},
	{run_step,"s","\t\t\texecute one instruction"},
	{run_quit,"q","\t\t\tstop execution, and quit"},
	{run_setbreak,"b","<addr>\t\t\tset a breakpoint"},
	{run_infobreak,"lb","\t\t\tdisplay state of all breakpoints"},
	{run_delbreak,"db"," <num>\t\t\tdelete a breakpoint"},
	{run_regs,"r","\t\t\tlist of all CPU registers and their contents"},
	{run_view_bincode,"v"," [addr]\t\t\tscan memory (binary)"},
	{run_uasm,"u"," [addr]\t\t\tscan memory (assemble)"},
	{run_edit_mem,"em","[addr]\t\t\tedit memory (binary)"},
	{run_edit_asm,"ea","[addr]\t\t\tedit memory (assemble)"},
	{run_set_reg,"sr","<rigs> <value>\t\tchange a CPU register(Rx or SP) to value"},
	{run_reset,"reset","\t\t\treset registers"},
	{run_restart,"restart","\t\t\treset registers and continue executing"},
	{run_goto,"goto","<addr>\t\tchange PC to addr"},
	{run_load,"load","[file]\t\tload file to memory, default is code.cod"},
	{run_save,"save","[file]\t\tsave memory, default is rom.dat"},
	{run_saveFormat,"saveFormat","[file]\t\tsave memory as Intel HEX Filt Format,default is romFormat.dat"},
	{run_server,"server","[int]\t\tcompile and execute kernel.x"},
	{run_compile,"compile","<file> [...]\tcompile file"},
	{run_help,"help","\t\t\tlist of all commands"}
};

void run_help (int argc, char * argv [])
{
	printf ("\n   List of commands:\n");
	for (unsigned int i=0; i<sizeof(commands)/sizeof(Tcommand);i++)
	{
		printf ("      %s %s\n", commands[i].func_name,commands[i].func_description);
	}
}

struct Tconsole
{
	HANDLE hstdout;
	COORD scrn;
	CONSOLE_SCREEN_BUFFER_INFO sbinf;
	int curcom;
	int totalcom;
	int sizecom;
	char **comlist;
	Tconsole()
	{
		sizecom = 4;
		curcom = totalcom = 0;
		comlist = (char **)malloc(sizeof(char *)*sizecom);
		hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
		WORD attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY | BACKGROUND_BLUE;
		SetConsoleTextAttribute(hstdout,attr);
		clearscrn();
		work();
	}	
	void clearscrn()
	{	
		int size;
		scrn.X = SCRN_X;
		scrn.Y = SCRN_Y;
		SetConsoleScreenBufferSize(hstdout,scrn);
		GetConsoleScreenBufferInfo(hstdout,&sbinf);
		size = SCRN_X*SCRN_Y;
		scrn.X = scrn.Y = 0;
		FillConsoleOutputAttribute(hstdout,sbinf.wAttributes,size,scrn,NULL);
		FillConsoleOutputCharacter(hstdout,' ',size,scrn,NULL);
		gotoxy(0,0);
	}
	void gotoxy(int xpos,int ypos)
	{
		scrn.X = xpos;
		scrn.Y = ypos;
		SetConsoleCursorPosition(hstdout,scrn);
	}
	void gotoxy_cur(int next)
	{
		if (next == 0)
			return ;
		GetConsoleScreenBufferInfo(hstdout,&sbinf);
		int pos = sbinf.dwCursorPosition.Y*SCRN_X+sbinf.dwCursorPosition.X+next;
		if (next > 0)
		{
			if (pos > SCRN_X*SCRN_Y)
				return ;
		}
		else 
		{
			if (pos < 0)
				return ;
		}
		scrn.X = pos%SCRN_X;
		scrn.Y = pos/SCRN_X;
		SetConsoleCursorPosition(hstdout,scrn);
	}
	void addcom(char *str)
	{
		comlist[totalcom] = (char *)malloc(sizeof(char)*(strlen(str)+1));
		memcpy(comlist[totalcom++],str,strlen(str)+1);
		if (totalcom == sizecom)
		{
			sizecom <<= 1;
			char **temp = (char **)malloc(sizeof(char *)*sizecom);
			for (int i=0;i<totalcom;i++)
				temp[i] = comlist[i];
			free(comlist);
			comlist = temp;
		}
		curcom = totalcom;
	}
	char *getcom(int next)
	{
		if (totalcom == 0)
			return NULL;
		switch (next)
		{
		case 0:
			if (curcom == 0)
				return NULL;
			else return comlist[--curcom];
		case 1:
			if (curcom == totalcom-1)
				return NULL;
			else return comlist[++curcom];
		case 2:
			return comlist[totalcom-1];
		default:
			return NULL;
		}
	}
	void work();
	void parse_and_run(char [], int );
};

void Tconsole::parse_and_run(char buffer[], int len)
{
	char *argv[64];
	int argc = 0;
	int in_command = 0;
	for (int i=0;buffer[i] != '\0';i++)
	{
		if (buffer[i] != ' ')
		{
			if (in_command == 0)
				argv[argc++] = &buffer[i];
			in_command = 1;
		}
		else
		{
			buffer[i] = '\0';
			in_command = 0;
		}
	}
	if (argc == 0)
		return ;
	for (unsigned int i=0;i<sizeof(commands)/sizeof(Tcommand);i++)
	{
		if (strcmp(commands[i].func_name,argv[0]) == 0)
		{
			commands[i].func(argc,argv);
			return ;
		}
	}
	if (argc == 1)
	{
		int value = get_number_10(argv[0],16);
		if (value != -1)
		{
			printf("\n   ");
			pc_decode((word)value);
			return ;
		}
		else 
		{
			printf ("\n Unknown control identifier `%s'.\n",argv[0]);
			return ;
		}
	}
	printf("\n  ->Unknown command. Use ``help'' to list commands.\n");
}

void Tconsole::work()
{
	char *com;
	int cur = 0;
	int len = 0;
	char ch;
	char buffer[LimitConsoleBuffer+1];
	buffer[len] = '\0';
	printf(">>");
	while (true)
	{
		ch = getch();
		if (ch == 8)
		{
			if (cur != 0)
			{
				if (cur == len)
				{
					cur --;
					buffer[--len] = '\0';
					gotoxy_cur(-1);
					printf(" ");
					gotoxy_cur(-1);
				}
				else
				{
					memcpy(&buffer[cur-1],&buffer[cur],len-cur);
					buffer[--len] = '\0';
					printf("\b%s ",&buffer[--cur]);
					gotoxy_cur(cur-len-1);
				}
			}
		}
		else if (ch == -32)
		{
			ch = getch();
			switch (ch)
			{
			case 75: //left
				if (cur != 0)
				{
					cur --;
					gotoxy_cur(-1);
				}
				break;
			case 77: //right
				if (cur != len)
				{
					cur ++;
					gotoxy_cur(1);
				}
				break;
			case 72: //up
				if (curcom != 0)
				{
					for(int i=0;i<len;i++)
						buffer[i] = ' ';
					gotoxy_cur(-cur);
					printf("%s",buffer);
					gotoxy_cur(-len);
					com = getcom(0);							
					cur = len = strlen(com);
					memcpy(buffer,com,len+1);
					printf("%s",buffer);
				}
				break;
			case 80: //down
				if (totalcom != 0 && curcom < totalcom-1)
				{
					for(int i=0;i<len;i++)
						buffer[i] = ' ';
					gotoxy_cur(-cur);
					printf("%s",buffer);
					gotoxy_cur(-len);
					com = getcom(1);							
					cur = len = strlen(com);
					memcpy(buffer,com,len+1);
					printf("%s",buffer);
				}
				break;
			case 71: //home
				gotoxy_cur(-cur);
				cur = 0;
				break;
			case 79: //end
				gotoxy_cur(len-cur);
				cur = len;
				break;
			case 83: //delete
				if (cur != len)
				{
					len--;
					memcpy(&buffer[cur],&buffer[cur+1],len-cur);
					buffer[len] = '\0';
					printf("%s ",&buffer[cur]);
					gotoxy_cur(cur-len-1);
				}
				break;
			}
		}
		else if (ch == 13)
		{
			if (len != 0)
			{
				addcom(buffer);
				parse_and_run(buffer,len);
			}
			else if (totalcom != 0)
			{
				com = getcom(2);
				len = strlen(com);
				memcpy(buffer,com,len+1);
				parse_and_run(buffer,len);
			}
			printf("\n>>");
			cur = len = 0;
			buffer[len] = '\0';
		}
		else if (ch == 27)
		{
			for (int i=0;i<len;i++)
				buffer[i] = ' ';
			gotoxy_cur(-cur);
			printf("%s",buffer);
			gotoxy_cur(-len);
			cur = len = 0;
			buffer[len] = '\0';
		}
		else
		{
			if (ch <= 126 && ch >= 32)
			{
				if (cur == len)
				{
					if (len != LimitConsoleBuffer)
					{
						cur ++;
						buffer[len++] = ch;
						buffer[len] = '\0';
						printf("%c",ch);
					}
				}
				else
				{
					if (len == LimitConsoleBuffer)
					{
						memcpy(&buffer[cur+1],&buffer[cur],len-cur-1);
						buffer[cur] = ch;
						printf("%s",&buffer[cur++]);
						gotoxy_cur(cur-len);
					}
					else
					{
						memcpy(&buffer[cur+1],&buffer[cur],len-cur);
						buffer[++len] = '\0';
						buffer[cur] = ch;
						printf("%s",&buffer[cur++]);
						gotoxy_cur(cur-len);
					}
				}
			}
		}
	}
}

int main ()
{
	init();
	Tconsole console;
	return 0;
}

⌨️ 快捷键说明

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