📄 simulator.cpp
字号:
case 3: //SLTU
reg.T = (reg.regh[index1] < reg.regh[index2]) ? 1 : 0;
return 0;
case 4: //SLLV
reg.regh[index2] = (reg.regh[index2] << reg.regh[index1]);
return 0;
case 6: //SRLV
reg.regh[index2] = (reg.regh[index2] >> reg.regh[index1]);
return 0;
case 7: //SRAV
reg.regh[index2] = (((short )reg.regh[index2]) >> reg.regh[index1]);
return 0;
case 10: //CMP
reg.T = ((reg.regh[index1] ^ reg.regh[index2]) == 0) ? 0 : 1;
return 0;
case 11: //NEG
reg.regh[index1] = -reg.regh[index2];
return 0;
case 12: //AND
reg.regh[index1] &= reg.regh[index2];
return 0;
case 13: //OR
reg.regh[index1] |= reg.regh[index2];
return 0;
case 14: //XOR
reg.regh[index1] ^= reg.regh[index2];
return 0;
case 15: //NOT
reg.regh[index1] = ~reg.regh[index2];
return 0;
case 16: //MFHI
reg.regh[index1] = reg.HI;
return 0;
case 18: //MFLO
reg.regh[index1] = reg.LO;
return 0;
case 24: //MULT
mul = (int)reg.regh[index1]*(int)reg.regh[index2];
reg.HI = (word)((mul >> 16) & 0xFFFF);
reg.LO = (word)(mul & 0xFFFF);
return 0;
case 25: //MULTU
mul = (unsigned int)(reg.regh[index1])*(unsigned int)(reg.regh[index2]);
reg.HI = (word)((mul >> 16) & 0xFFFF);
reg.LO = (word)(mul & 0xFFFF);
return 0;
case 26: //DIV
if (reg.regh[index2] == 0)
return E_DIVZER;
reg.LO = (word)((short)reg.regh[index1]/(short)reg.regh[index2]);
reg.HI = (word)((short)reg.regh[index1]%(short)reg.regh[index2]);
return 0;
case 27: //DIVU
if (reg.regh[index2] == 0)
return E_DIVZER;
reg.LO = reg.regh[index1]/reg.regh[index2];
reg.HI = reg.regh[index1]%reg.regh[index2];
return 0;
default: return E_UNKNOW;
}
}
//MFIH MTIH
word asm_30(word code)
{
offset = (code & 0xFF);
code = (code >> 8);
index1 = (code & 7);
switch (offset)
{
case 0: //MFIH
reg.regh[index1] = reg.IH;
return 0;
case 1: //MTIH
printf("\nMTIH : %04x ", reg.regh[index1]);
reg.IH = reg.regh[index1];
return 0;
default:
return E_UNKNOW;
}
}
word asm_31(word code)
{
index1 = (code & 0xF);
code = (code >> 4);
index2 = (code & 0x7F);
if (index2 != 0)
return E_UNKNOW;
return asm_func_int(index1);
}
//*****************************************************************************
//模拟
struct TASM
{
char *name;
int code;
int x,y,z;
};
int asm_total;
const struct TASM const_asm[] = {
{"ADDSP3",1793,63743,65280,65535},
{"B",4096,63488,65535,65535},
{"BEQZ",9984,63743,65280,65535},
{"BNEZ",12032,63743,65280,65535},
{"SLL",14308,63743,65311,65507},
{"SRL",14310,63743,65311,65507},
{"SRA",14311,63743,65311,65507},
{"ADDIU3",18400,63743,65311,65520},
{"ADDIU",20224,63743,65280,65535},
{"SLTI",22272,63743,65280,65535},
{"SLTUI",24321,63743,65280,65535},
{"BTEQZ",24576,65280,65535,65535},
{"BTNEZ",24832,65280,65535,65535},
{"SW-RS",25089,65280,65535,65535},
{"ADDSP",25344,65280,65535,65535},
{"MTSP",25824,65311,65535,65535},
{"MOVE",26599,65311,65528,65535},
{"LI",28417,63743,65280,65535},
{"CMPI",30465,63743,65280,65535},
{"LW-SP",38657,63743,65280,65535},
{"LW",40929,63743,65311,65504},
{"SW-SP",55041,63743,65280,65535},
{"SW",57313,63743,65311,65504},
{"ADDU",59389,63743,65311,65507},
{"SUBU",59391,63743,65311,65507},
{"JR",61184,63743,65535,65535},
{"MFHI",61200,63743,65535,65535},
{"MFLO",61202,63743,65535,65535},
{"MFPC",61248,63743,65535,65535},
{"SLT",61410,63743,65311,65535},
{"SLTU",61411,63743,65311,65535},
{"SLLV",61412,63743,65311,65535},
{"SRLV",61414,63743,65311,65535},
{"SRAV",61415,63743,65311,65535},
{"CMP",61418,63743,65311,65535},
{"NEG",61419,63743,65311,65535},
{"AND",61420,63743,65311,65535},
{"OR",61421,63743,65311,65535},
{"XOR",61422,63743,65311,65535},
{"NOT",61423,63743,65311,65535},
{"MULT",61432,63743,65311,65535},
{"MULTU",61433,63743,65311,65535},
{"DIV",61434,63743,65311,65535},
{"DIVU",61435,63743,65311,65535},
{"NOP",2048,65535,65535,65535,},
{"INT",63489,65520,65535,65535},
{"MFIH",63232,63743,65535,65535},
{"MTIH",63233,63743,65535,65535}
};
void init()
{
asm_total = (int)(sizeof(const_asm)/sizeof(struct TASM));
memset(asm_set,0,sizeof(func)*32);
asm_set[0] = asm_00;
asm_set[1] = asm_01;
asm_set[2] = asm_02;
// asm_set[3] = asm_03;
asm_set[4] = asm_04;
asm_set[5] = asm_05;
asm_set[6] = asm_06;
// asm_set[7] = asm_07;
asm_set[8] = asm_08;
asm_set[9] = asm_09;
asm_set[10] = asm_10;
asm_set[11] = asm_11;
asm_set[12] = asm_12;
asm_set[13] = asm_13;
asm_set[14] = asm_14;
// asm_set[15] = asm_15;
// asm_set[16] = asm_16;
// asm_set[17] = asm_17;
asm_set[18] = asm_18;
asm_set[19] = asm_19;
// asm_set[20] = asm_20;
// asm_set[21] = asm_21;
// asm_set[22] = asm_22;
// asm_set[23] = asm_23;
// asm_set[24] = asm_24;
// asm_set[25] = asm_25;
asm_set[26] = asm_26;
asm_set[27] = asm_27;
asm_set[28] = asm_28;
asm_set[29] = asm_29;
asm_set[30] = asm_30;
asm_set[31] = asm_31;
}
struct BreakStack
{
int btotal;
int bsize;
word *list;
BreakStack()
{
btotal = 0;
bsize = 4;
list = (word *)malloc(sizeof(word)*bsize);
}
word binsert(word addr)
{
word tmp;
if ((tmp = mem.can_vst(addr)) != 0) return tmp;
for (int i=0;i<btotal;i++)
{
if (list[i] == addr)
return 0;
}
list[btotal++] = addr;
if (btotal == bsize)
{
bsize <<= 1;
word *temp = (word *)malloc(sizeof(word)*bsize);
for (int i=0;i<btotal;i++)
temp[i] = list[i];
free(list);
list = temp;
}
for (int i=0;i<btotal-1;i++)
{
int min = i;
for (int j=i+1;j<btotal;j++)
{
if (list[j] < list[min])
min = j;
}
if (min == i)
continue;
word tmp = list[i];
list[i] = list[min];
list[min] = tmp;
}
return 0;
}
void delbp(int index)
{
if (index >= 0 && index < btotal)
{
for (int i=index+1;i<btotal;i++)
list[i-1] = list[i];
btotal --;
}
}
int is_break(word addr)
{
for (int i=0;i<btotal;i++)
{
if (list[i] < addr)
continue;
if (list[i] == addr)
return 1;
if (list[i] > addr)
return 0;
}
return 0;
}
void list_break()
{
printf("\n > BreakPoints: total = %d\n",btotal);
for (int i=0;i<btotal;i++)
printf(" %d\t%04x\n",i,list[i]);
}
};
struct BreakStack breakstack;
struct AsmID
{
char *name;
int id;
};
struct AsmID IDList[] = {
{"ADDSP3",0},
{"B",2},
{"BEQZ",4},
{"BNEZ",5},
{"SLL",6},
{"SRL",6},
{"SRA",6},
{"ADDIU3",8},
{"ADDIU",9},
{"SLTI",10},
{"SLTUI",11},
{"BTEQZ",12},
{"BTNEZ",12},
{"SW-RS",12},
{"ADDSP",12},
{"MOVE",12},
{"MTSP",12},
{"LI",13},
{"CMPI",14},
{"LW-SP",18},
{"LW",19},
{"SW-SP",26},
{"SW",27},
{"ADDU",28},
{"SUBU",28},
{"JR",29},
{"MFHI",29},
{"MFLO",29},
{"JALR",29},
{"SLT",29},
{"SLTU",29},
{"SLLV",29},
{"SRLV",29},
{"SRAV",29},
{"CMP",29},
{"NEG",29},
{"AND",29},
{"OR",29},
{"XOR",29},
{"NOT",29},
{"MULT",29},
{"MULTU",29},
{"DIV",29},
{"DIVU",29},
{"MFPC",29}
};
AsmID RegsList[] = {
{"R0",0},
{"R1",1},
{"R2",2},
{"R3",3},
{"R4",4},
{"R5",5},
{"R6",6},
{"R7",7}
};
//执行一条指令
//FILE* PCout = fopen("PC.log", "w");
word pc_step(int next = 0)
{
PC = reg.PC;
// fprintf(PCout, "%04x\n", PC);
// fflush(PCout);
if ((t = mem.can_vst(PC)) != 0) return t;
IR = mem.read_mem(PC);
if (next == 0 && breakstack.is_break(PC) != 0)
return C_SBREAK;
index1 = ((IR >> 11)& 0x001F);
if (asm_set[index1] == NULL)
return E_NOFUNC;
else
{
reg.PC++;
return asm_set[index1](IR);
}
}
int get_regs_id(char argv[])
{
if (strlen(argv) != 2)
return -1;
for (int i=0;i<8;i++)
{
if (strcmp(argv,RegsList[i].name) == 0)
return RegsList[i].id;
}
printf("%s",argv);
return -1;
}
int get_number_10(char argv[],int lenlimit)
{
int value = 0, len = strlen(argv);
char ch;
for (int i=0;i<len;i++)
{
ch = argv[i];
value *= 10;
if (ch >= '0' && ch <= '9')
value |= (ch-'0') & 0xF;
else return -1;
}
if (value >> lenlimit != 0)
return -1;
return value;
}
int get_number(char argv[],int lenlimit,int bin_mode = 0)
{
int value = 0, len = strlen(argv);
char ch;
for (int i=0;i<len;i++)
{
ch = argv[i];
value <<= 4;
if (ch >= '0' && ch <= '9')
value |= (ch-'0') & 0xF;
else if (ch >= 'A' && ch <= 'F')
value |= (ch-'A'+10) & 0xF;
else if (ch >= 'a' && ch <= 'f')
value |= (ch-'a'+10) & 0xF;
else return -1;
}
if (bin_mode == 0)
{
if (value >> lenlimit != 0)
return -1;
}
else
{
if ((value & (~lenlimit)) != 0)
return -1;
}
return value;
}
void pc_decode(word code)
{
const struct TASM *p = const_asm;
int i;
word j ,k;
for (i=0;i<asm_total;i++)
{
j = ((*p).code & (*p).x & (*p).y & (*p).z);
k = (code & (*p).x & (*p).y & (*p).z);
if (j == k)
break;
p ++;
}
printf(" <%04x>",code);
if (i == asm_total)
{
printf("--- UNKNOWN ---");
return ;
}
printf(" %s",(*p).name);
word regs[3];
word num;
regs[0] = ~(*p).x;
regs[1] = ~(*p).y;
regs[2] = ~(*p).z;
for (i=0;i<3;i++)
{
if (regs[i] != 0)
{
k = (regs[i] & (*p).code);
num = (regs[i] & code);
if (regs[i] == k)
{
while ((regs[i] & 1) == 0)
{
num = (num >> 1);
regs[i] = (regs[i] >> 1);
}
printf(" R%d",num);
}
else if (k == 0)
{
while ((regs[i] & 1) == 0)
{
num = (num >> 1);
regs[i] = (regs[i] >> 1);
}
j = ~regs[i];
if ((num & (j >> 1)) != 0)
num = (num | j);
printf(" %04x",num);
}
else
{
while ((regs[i] & 1) == 0)
{
num = (num >> 1);
regs[i] = (regs[i] >> 1);
}
printf(" %04x",num);
}
}
}
}
void run_regs(int ,char *[]);
void run_continue(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 ;
}
printf("\n");
word err;
char ch;
int step = 0;
console_mode = 0;
if (argc == 2)
int_mode = 1;
int int_count = 0;
while ((err = pc_step()) == 0)
{
if (step == 0x100)
{
if (kbhit())
{
while (kbhit())
{
ch = getch();
if (ch == 7)
{
run_regs(1,argv);
console_mode = -1;
return ;
}
else if (ch == 21)
asm_func_int(0x10);
}
}
step = 0;
}
step ++;
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);
}
}
}
switch (err)
{
case C_SBREAK:
printf("\n [%04x] %04x ",PC,IR);
pc_decode(IR);
break;
case E_NOFUNC:
printf("\n no such function\n");
break ;
case E_MMNVST:
printf("\n Can not read memory : [%04x] ",PC);
pc_decode(IR);
break ;
default: printf("\n error %d\n",err);
break;
}
console_mode = -1;
int_mode = 0;
}
void run_step(int argc,char *argv[])
{
word err;
console_mode = 0;
if (argc == 1)
{
err = pc_step(1);
PC = reg.PC;
if (mem.can_vst(PC) != 0 || err != 0)
printf(" Cannot read memory\n");
else
{
IR = mem.read_mem(PC);
printf("\n [%04x] %04x ",PC,IR);
pc_decode(IR);
}
}
else
{
int value = get_number(argv[1],16);
if (value == -1)
{
printf ("\n Unknown control identifier `%s'.\n", argv [1]);
console_mode = -1;
return ;
}
for (int i=0;i<value;i++)
{
err = pc_step(1);
if (err != 0)
{
PC = reg.PC;
if (mem.can_vst(PC) != 0)
printf("\n Cannot read memory\n");
else
{
IR = mem.read_mem(PC);
printf("\n [%04x] %04x ",PC,IR);
pc_decode(IR);
}
break;
}
}
run_regs(1,argv);
}
console_mode = -1;
}
void run_quit(int argc,char *argv[])
{
if (argc != 1)
{
printf ("\n Unknown control identifier `%s'.\n", argv [1]);
return ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -