drisc.cpp
/* \file drisc.cpp * * RiSC-16 Simulator */ #include <stdio.h> #include <stdlib.h> #include <time.h> #include <iostream> #include <string> using namespace std; #include "strtoken.h" int mem[512]; int nwords = 0; int mem_check(int addr); void read_memory(FILE *in); void show_memory(FILE *out); void show_registers(FILE *out); void simulate(FILE *out); int main(int argc, char *argv[]) { FILE *in, *out; string filename; errno_t nerr; if (argc<2) { cout << "usage: drisc hexfile\n"; return EXIT_FAILURE; } filename = argv[1]; nerr = fopen_s(&in,filename.c_str(),"r"); if (nerr) { cout << "file: " << filename << " not found\n"; return EXIT_FAILURE; } read_memory(in); fclose(in); out = stdout; fprintf(out,"<html>\n"); simulate(out); fprintf(out,"<h3>Registers</h3>\n"); show_registers(out); fprintf(out,"<h3>Memory</h3>\n"); show_memory(out); fprintf(out,"</html>\n"); return EXIT_SUCCESS; } int mem_check(int addr) { if (addr<0 || addr>=nwords) { return 1; } return 0; } void show_memory(FILE *out) { int i,flag=0; fprintf(out,"<p><table border>\n"); fprintf(out,"<p><tr bgcolor=CCCCFF><th>addr"); for (i=0; i<16; i++) fprintf(out,"<th>%X",i); fprintf(out,"\n"); for (i=0; i<nwords; i++) { flag = i%16; if (flag==0) fprintf(out,"<tr align=center><td bgcolor=FFFFCC>%04X",i); fprintf(out,"<td>%04X",mem[i]); if (flag==7) fprintf(out,"\n"); } while (flag++ < 15) fprintf(out,"<td><br>"); fprintf(out,"</table>\n"); } void read_memory(FILE *in) { char buf[512]; char *inp, *next; int field; bool done = false; nwords = 0; while (!done) { fgets(buf,511,in); if (feof(in)) break; next = buf; while (*next==' ') next++; while (next) { inp = next; while (*inp==' ') inp++; // eat blanks if (*inp=='\n') break; next = strqtrm(inp,' '); sscanf_s(inp,"%x",&field); //if (field>0) printf("%04X\n",field); mem[nwords++] = field; } } } int regs[] = {0xBAD0,0x1111,0x2222,0x3333,0x4444,0x5555,0x6666,0x7777}; int reg(int n) { if (n>0) return regs[n]; return 0; } void show_registers(FILE *out) { int i; fprintf(out,"<p><table border>\n"); fprintf(out,"<p><tr bgcolor=CCCCFF><th>format"); for (i=1; i<8; i++) fprintf(out,"<th>r%d",i); fprintf(out,"\n"); fprintf(out,"<tr align=center><th>hex"); for (i=1; i<8; i++) { fprintf(out,"<td>%04X",reg(i)); } fprintf(out,"<tr align=center><th>decimal"); for (i=1; i<8; i++) { fprintf(out,"<td>%d",(short)reg(i)); } fprintf(out,"\n</table>\n"); } string cmd[] = { "NOP", "LWI", "SWI", "LI", "LUI", "LW", "SW", "ADDI", "ALU1", "ALU2", "BNE", "JALR"}; string cmd_alu1[] = { "ADD", "SUB" }; string cmd_alu2[] = { "AND", "OR", "XOR", "NOR" }; const int NOP = 0, LWI = 1, SWI = 2, LI = 3, LUI = 4, LW = 5, SW=6, ADDI = 7, ALU1 = 8, ALU2 = 9, BNE = 10, JALR = 11; string opcode_memnomic(int opcode,int opx) { char str[64]; if (opcode==ALU1) return cmd_alu1[opx]; if (opcode==ALU2) return cmd_alu2[opx]; if (opcode<12) return cmd[opcode]; sprintf_s(str,63,"NOP: %0X",opcode); return str; } const int HALT = 0x0000; void simulate(FILE *out) { int pc, nextpc; int inst, immed, immse, maddr; int opx, imm5; int range_error; int opcode, rd=0, ra=0, rb=0; int qa, qb, qd=0, ncycle=0; bool done = false; fprintf(out,"<h3>Simulation Results</h3>\n"); fprintf(out,"<p><table border>\n"); fprintf(out,"<tr bgcolor=CCCCFF><th>#<th>pc<th>op<th>rd<th>qd<th>immed\n"); nextpc = 0; while (!done) { inst = mem[nextpc]; opcode = inst>>11; rd = (inst>>8)&0x7; ra = (inst>>5)&0x7; rb = (inst>>2)&0x7; immed = inst&0xFF; if (immed>>7) immse = 0xFFFFFF00| immed; else immse = immed; imm5 = inst&0x1F; if (imm5>>4) imm5 = 0xFFFFFFE0 | imm5; qa = reg(ra); qb = reg(rb); maddr = immed; range_error = 0; if (inst==HALT) break; pc = nextpc; nextpc++; opx = immed&0x3; switch (opcode) { case LI: qd = immse; break; case LUI: ra = rd; qa = reg(ra); qd = (immed<<8)|(qa&0xFF); break; case SWI: // SW rb = rd; rd = 0; qb = reg(rb); maddr = immed; qd = maddr; range_error = mem_check(maddr); if (!range_error) mem[maddr] = qb; break; case SW: rb = rd; rd = 0; qb = reg(rb); maddr = qa+imm5; qd = maddr; range_error = mem_check(maddr); if (!range_error) mem[maddr] = qb; break; case LWI: maddr = immed; range_error = mem_check(maddr); if (!range_error) qd = mem[maddr]; break; case LW: maddr = reg(ra)+imm5; range_error = mem_check(maddr); if (!range_error) qd = mem[maddr]; break; case ADDI: qd = qa + imm5; break; case ALU1: switch (opx) { case 0: qd = qa+qb; // add break; case 1: qd = qa-qb; // subtract break; } break; case ALU2: switch (opx) { case 0: qd = qa & qb; break; case 1: qd = qa | qb; break; case 2: qd = qa ^ qb; break; case 3: qd = !(qa|qb); break; } break; case BNE: rb = rd; rd = 0; qd = reg(rb)!=qa; if (qd) nextpc = nextpc + imm5; break; case JALR: qd = nextpc; nextpc = qa; break; default: rd = 0; break; } qd &= 0xFFFF; bool we = opcode!=SW && opcode!=SWI; if (rd && we) regs[rd] = qd; fprintf(out,"<tr><td bgcolor=FFFFCC>%d<td>%02X",++ncycle,pc); fprintf(out,"<td>%s<td>%d<td>%04X", opcode_memnomic(opcode,opx).c_str(),rd,qd); if (opcode>0) { fprintf(out,"<td>%04X\n",immed); if (range_error) printf("address %x out of range\n",maddr); } else fprintf(out,"<td><br>\n"); if (ncycle>60) break; } fprintf(out,"</table>\n"); } void parse(FILE *in, FILE *out) { char buf[512]; char *inp, *next; int opcode, ra, rb, rc, field; int count, code, n; string token; bool done = false; /* * Go through input file, line by line */ n = 0; while (!done) { fgets(buf,511,in); if (feof(in)) break; //fprintf(out,"%s",buf); if (*buf=='#') continue; next = buf; /* * parse current line */ count = 0; opcode = ra = rb = rc = 0; while (next) { /* * search for '<', and copy prior text to * output stream */ inp = next; next = strqtrm(inp,','); sscanf_s(inp,"%d",&field); //fprintf(out,"count %d field %d\n",count,field); switch (count) { case 0: token = inp; //fprintf(out,"%s %d\n",token.c_str(),opcode); count = 1; break; case 1: ra = field; count = 2; break; case 2: rb = field; count = 3; break; case 3: rc = field; count = 4; break; default: break; } } code = ((opcode&0x7)<<13) | ((ra&0x7)<<10) | ((rb&0x7)<<7) | (rc&0x7F);; fprintf(out,"%04X\n",code); n++; } while (n++ < 32) fprintf(out,"0000\n"); }
Maintained by John Loomis, updated Wed Apr 06 22:45:07 2011