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

📄 simulator.cpp

📁 一个可以模拟MIPS汇编语言在硬件上运行的模拟器。 该模拟器对于43条最常用的指令进行了实现。而且实现了端口通信
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <windows.h>
#include <conio.h>
#include <cstring>

#pragma comment(lib, "ws2_32.lib")


typedef	unsigned short word;
typedef unsigned short regis;
typedef word (*func) (word);
typedef void (*decode) (word);

const int LimitConsoleBuffer = 4096;

const word E_NOFILE = 1;
const word W_MMEXST = 2;
const word W_MMDRTY = 3;
const word E_UNKNOW = 4;
const word E_MMREAD = 5;
const word E_MMWRTE = 6;
const word E_MMNVST = 7;
const word E_NOFUNC = 8;
const word C_SBREAK = 9;
const word E_DIVZER = 10;
const int SCRN_X = 80;
const int SCRN_Y = 100;
const int BUFFER_SIZE_CLIENT = 1024;
int console_mode = -1;
int int_mode = 0;
const int const_int_step = 1024;


SOCKET server, client1, client2;

//*****************************************************************************
//寄存器堆
struct RegHeap
{
	regis T:1;
	regis regh[8];
	regis PC;
	regis RA;
	regis SP;
	regis HI;
	regis LO;
	regis IH;
	RegHeap();
	void list_regs();
};

RegHeap::RegHeap()
{
	T = 0;
	PC = 0x0001;
	SP = 0xDFFF;
}

void RegHeap::list_regs()
{
	for (int i=0;i<8;i++)
	{
		printf("    R%d = %04x",i,regh[i]);
		if ((i+1) % 4 == 0)
			printf("\n");
	}
	printf("    PC = %04x    RA = %04x    SP = %04x     T = %04x\n",PC,RA,SP,T);
	printf("    HI = %04x    LO = %04x\n",HI,LO);
}

struct RegHeap reg;
//*****************************************************************************
//用于生成Intel HEX File Formt形式文件的结构
struct Hex_16
{
	char colon;
	char datalen[2];
	char addr[4];
	char type[2];
	char data[4];
	char checksum[2];
    char newline;
	Hex_16();
	void create(word address, word bin_data);
};

Hex_16::Hex_16()
{
	colon = ':';
	datalen[0]='0';
	datalen[1]='2';
	newline='\n';
};

void Hex_16::create(word addr_, word data_)
{
	word address = addr_;
	word bin_data = data_;
	for(int i=0;i<4;i++)
	{
		if((address & 0xF)>=0 && (address & 0xF)<=9)
			addr[3-i] = char((address & 0xF)+48);
		else
			addr[3-i] = char((address & 0xf)+87);
		address >>= 4;
	}
	
	type[0]='0';
	type[1]='0';
	for(int i=0;i<4;i++)
	{
		if((bin_data & 0xF)>=0 && (bin_data & 0xF)<=9)
			data[3-i] = char((bin_data & 0xF)+48);
		else
			data[3-i] = char((bin_data & 0xf)+87);
		bin_data >>= 4;
	}
    
	char sum = (2+(addr_>>8&0xFF)+(addr_&0xFF)+(data_>>8&0xFF)+(data_&0xFF)) % 256;
    char check = ~sum + 1;

	for(int i=0;i<2;i++)
	{
		if((check & 0xF)>=0 && (check & 0xF)<=9)
			checksum[1-i] = char((check & 0xF)+48);
		else
			checksum[1-i] = char((check & 0xf)+87);
		check >>= 4;
	}
}

//内存
struct Memory
{
	word flags0, flags1;
	static const word MEM_SIZE = 0xE000;
	Memory();
	word can_vst(word index);
	word load_mem(char *rom_file);
	word read_mem(word );
	void save_mem(char *rom_file);
	void save_memFormat(char *rom_file, int pc);
	void write_mem(word ,word );
	word memory[MEM_SIZE];
	word Mrecv[2], Msend[2];
};

Memory::Memory()
{
	flags0 = 0;
	flags1 = 0;
	memset(memory,0,sizeof(word)*MEM_SIZE);
};

word Memory::load_mem(char *rom_file)
{
	FILE *rom_handle = fopen(rom_file,"rb");
	if (rom_handle == NULL)
		return E_NOFILE;
	fread(memory,sizeof(word),MEM_SIZE,rom_handle);
	fclose(rom_handle);
	return 0;
}

void Memory::save_mem(char *rom_file)
{
	FILE *rom_handle = fopen(rom_file,"wb+");
	fwrite(memory,sizeof(word),MEM_SIZE,rom_handle);
	fclose(rom_handle);
}

void Memory::save_memFormat(char *rom_file, int pc)
{
	char* endfile = ":00000001ff";
	int size = pc;

	word* mem16;
	mem16 = new word[size];
	memset(mem16, 0, size*sizeof(word));
	memcpy(mem16,memory,size*sizeof(word));

	Hex_16* hex16;
	hex16 = new Hex_16[size];
	for(int i=0; i<size; i++)
	{
		hex16[i].create(i,mem16[i]);
	}

	FILE *rom_handle = fopen(rom_file,"wb+");
	fwrite(hex16,16,size,rom_handle);
	fwrite(endfile,10,1,rom_handle);
	fclose(rom_handle);
}

word Memory::can_vst(word index)
{
	if (index < 0x2800 || (index >= 0x4000 && index < 0x6004))
		return 0;
	else return E_MMNVST;
}

word Memory::read_mem(word index)
{
	if (index != 0x6000 && index != 0x6002)
		return memory[index];
	if (console_mode == 0)
	{
		char ch = getch();
		printf("%c",ch);
		memory[index] = (word)ch;
		return memory[index];
	}
	memory[index+1] &= 0xFFFD;
	return (Mrecv[(index-0x6000) >> 1] & 0xFF);
}

void Memory::write_mem(word index,word str)
{
	memory[index] = str;
	if (index == 0x6000 || index == 0x6002)
	{
		if (console_mode == 0)
			printf("%c",str);
		else
		{
			memory[index+1] &= 0xFFFE;
			Msend[(index-0x6000) >> 1] = (str & 0xFF);
		}
	}
}

struct Memory mem;
//*****************************************************************************
//定义全部汇编指令
word index1, index2 ,index3, offset, index_jr, index_b, F , t; //index_jr临时交给jr指令使用
word IR = 0;
word PC = reg.PC;
func asm_set[32];

void run_regs(int ,char *[]);
//int
word asm_func_int(word int_num)
{
	if ((reg.IH & 0x8000) == 0)
		return 0;
	printf("%x interrupted.\n", int_num);
	reg.SP --;
	if ((t = mem.can_vst(reg.SP)) != 0)
		return t;
	mem.memory[reg.SP] = reg.PC;
	reg.SP --;
	if ((t = mem.can_vst(reg.SP)) != 0)
		return t;
	mem.memory[reg.SP] = int_num;
	reg.PC = (reg.IH & 0x7FFF);
	return 0;
}

//ADDIU_SP_3OP
word asm_00(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	reg.regh[index1] = reg.SP+offset;
	return 0;
}

//NOP
word asm_01(word code)
{
	return 0;
}

//B
word asm_02(word code)
{
	PC = reg.PC;
	if ((t = mem.can_vst(PC)) != 0) return t;
	IR = mem.read_mem(PC);
	index_b = ((IR >> 11) & 0x001F);
	if (asm_set[index_b] == NULL)
		return E_UNKNOW;
	offset = (code & 0x7FF);
	if ((offset & 0x400) != 0)
		offset |= 0xF800;
	reg.PC += offset;
	asm_set[index_b](IR);
	return 0;
}

//BEQZ
word asm_04(word code)
{	
	PC = reg.PC;
	if ((t = mem.can_vst(PC)) != 0) return t;
	IR = mem.read_mem(PC);
	index_b = ((IR >> 11) & 0x001F);
	if (asm_set[index_b] == NULL)
		return E_UNKNOW;
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	if (reg.regh[index1] == 0)
	{
		reg.PC += offset;
		asm_set[index_b](IR);
	}
	return 0;
}

//BNEZ
word asm_05(word code)
{
	PC = reg.PC;
	if ((t = mem.can_vst(PC)) != 0) return t;
	IR = mem.read_mem(PC);
	index_b = ((IR >> 11) & 0x001F);
	if (asm_set[index_b] == NULL)
		return E_UNKNOW;
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	if (reg.regh[index1] != 0)
	{
		reg.PC += offset;
		asm_set[index_b](IR);
	}
	return 0;
}

//SLL SRL SRA
word asm_06(word code)
{
	index3 = (code & 0x3);
	code >>= 2;
	offset = (code & 0x7);
	code >>= 3;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	switch (index3)
	{
	case 0: //SLL
		reg.regh[index1] = (offset == 0) ? (reg.regh[index2] << 8) : (reg.regh[index2] << offset);
		return 0;
	case 2: //SRL
		reg.regh[index1] = (offset == 0) ? (reg.regh[index2] >> 8) : (reg.regh[index2] >> offset);
		return 0;
	case 3: //SRA
		reg.regh[index1] = (offset == 0) ? (((short )reg.regh[index2]) >> 8) : (((short )reg.regh[index2]) >> offset);
		return 0;
	default: return E_UNKNOW;
	}
}

//ADDIU_3OP
word asm_08(word code)
{
	offset = (code & 0xF);
	code >>= 4;
	index3 = (code & 0x1);
	code >>= 1;
	if (index3 != 0) 
		return E_UNKNOW;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	if ((offset & 0x8) != 0)
		offset |= 0xFFF0;
	reg.regh[index2] = reg.regh[index1]+offset;
	return 0;
}

//ADDIU
word asm_09(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0 )
		offset |= 0xFF00;
	reg.regh[index1] += offset;
	return 0;
}

//SLTI
word asm_10(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	reg.T = ((short)reg.regh[index1] < (short)offset) ? 1 : 0;
	return 0;
}

//SLTUI
word asm_11(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	reg.T = (reg.regh[index1] < offset) ? 1 : 0;
	return 0;
}

//BTEQZ BTNEZ SW-RA-SP ADDIU_SP MOVE
word asm_12(word code)
{
	PC = reg.PC;
	if ((t = mem.can_vst(PC)) != 0) return t;
	IR = mem.read_mem(PC);
	index_b = ((IR >> 11) & 0x001F);
	if (asm_set[index_b] == NULL)
		return E_UNKNOW;
	offset = (code & 0xFF);
	code >>= 8;
	index3 = (code & 0x7);
	switch (index3)
	{
	case 0: //BTEQZ
		if (reg.T == 0)
		{
			if ((offset & 0x80) != 0)
				offset |= 0xFF00;
			reg.PC += offset;
			asm_set[index_b](IR);
		}
		return 0;
	case 1: //BTNEZ
		if (reg.T != 0)
		{
			if ((offset & 0x80) != 0)
				offset |= 0xFF00;
			reg.PC += offset;
			asm_set[index_b](IR);
		}
		return 0;
	case 2: //SW-RA-SP
		F = reg.SP+offset;
		if ((t = mem.can_vst(F)) != 0) return t;
		mem.write_mem(F,reg.RA);
		return 0;
	case 3: // ADDIU_SP
		if ((offset & 0x80) != 0)
			offset |= 0xFF00;
		reg.SP += offset;
		return 0;
	case 4: //MTSP
		index1 = (offset >> 5);
		reg.SP = reg.regh[index1];
		return 0;
	case 7: //MOVE
		index2 = (offset & 0x7);
		offset >>= 3;
		if ((offset & 0x3) != 0)
			return E_UNKNOW;
		offset >>= 2;
		index1 = (offset & 0x7);
		reg.regh[index1] = reg.regh[index2];
		return 0;
	default: return E_UNKNOW;
	}
}

//LI
word asm_13(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	reg.regh[index1] = offset;
	return 0;
}

//CMPI
word asm_14(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	reg.T = ((reg.regh[index1] ^ offset) == 0) ? 0 : 1;
	return 0;
}

//LW-SP
word asm_18(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	F = reg.SP+offset;
	if ((t = mem.can_vst(F)) != 0) return t;
	reg.regh[index1] = mem.read_mem(F);
	return 0;
}

//LW
word asm_19(word code)
{
	offset = (code & 0x1F);
	code >>= 5;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	F = reg.regh[index1]+offset;
	if ((t = mem.can_vst(F)) != 0) return t;
	reg.regh[index2] = mem.read_mem(F);
	return 0;
}

//SW-SP
word asm_26(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	F = reg.SP+offset;
	if ((t = mem.can_vst(F)) != 0) return t;
	mem.write_mem(F,reg.regh[index1]);
	return 0;
}

//SW
word asm_27(word code)
{
	offset = (code & 0x1F);
	code >>= 5;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	F = reg.regh[index1]+offset;
	if ((t = mem.can_vst(F)) != 0) return t;
	mem.write_mem(F,reg.regh[index2]);
	return 0;
}

//ADDU SUBU
word asm_28(word code)
{
	offset = (code & 0x3);
	code >>= 2;
	index3 = (code & 0x7);
	code >>= 3;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	switch (offset)
	{
	case 1: //ADDU
		reg.regh[index3] = reg.regh[index1]+reg.regh[index2];
		return 0;
	case 3: //SUBU
		reg.regh[index3] = reg.regh[index1]-reg.regh[index2];
		return 0;
	default: return E_UNKNOW;
	}
}

//JR(ra) JR MFHI MFLO JALR SLT SLTU SLLV SRLV SRAV CMP NEG AND OR XOR NOT MULT MULTU DIV DIVU
word asm_29(word code)
{
	index3 = (code & 0x1F);
	code >>= 5;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	if (index3 == 0)
	{
		switch (index2)
		{
		case 0: //JR
			PC = reg.PC;
			if ((t = mem.can_vst(PC)) != 0) return t;
			IR = mem.read_mem(PC);
			index_jr = ((IR >> 11) & 0x001F);
			if (asm_set[index_jr] == NULL)
				return E_UNKNOW;
			else
			{
				reg.PC = reg.regh[index1];
				asm_set[index_jr](IR);
				return 0;
			}
		case 2: //MFPC
			reg.regh[index1] = reg.PC;
			return 0;
		case 1: //JR(ra)
			if (index1 != 0) return E_UNKNOW;
			reg.PC = reg.RA;
			return 0;
		case 6: //JALR
			reg.RA = reg.PC;
			reg.PC = reg.regh[index1];
			return 0;
		default: return E_UNKNOW;
		}
	}
	unsigned int mul;
	switch (index3)
	{
	case 2: //SLT
		reg.T = ((short)reg.regh[index1] < (short)reg.regh[index2]) ? 1 : 0;
		return 0;

⌨️ 快捷键说明

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