X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=3b_sim%2Fsim.cpp;h=6cd72b16cce203b21229d2e44ade6b6a195eac20;hb=c0fc93c02587d16121457a37aa0f67ca6e3a2bc2;hp=bd7f5d0f48edbc341835885e7d3f0b5a759289af;hpb=78236d0bec463add160c1ef94042c0a529c3831d;p=calu.git diff --git a/3b_sim/sim.cpp b/3b_sim/sim.cpp index bd7f5d0..6cd72b1 100644 --- a/3b_sim/sim.cpp +++ b/3b_sim/sim.cpp @@ -20,8 +20,8 @@ #include "SReadline/SReadline.h" using namespace swift; -#define RAM_END (1000) -#define PROG_END (1000) +#define RAM_END (0x3000) +#define PROG_END (0x3000) #define REG_COUNT (16) typedef boost::function &)> Func; @@ -60,7 +60,7 @@ class CHelpExec { cout << "Available commands: " << endl; for(auto iter = m_completers.begin(); iter != m_completers.end(); ++iter) { - cout << setw(15) << (*iter).get<0>() << ": " << (*iter).get<2>() << endl; + cout << setw(19) << setfill(' ') << (*iter).get<0>() << ": " << (*iter).get<2>() << endl; } } }; @@ -68,24 +68,44 @@ class CHelpExec void close_prog(const std::vector &); CCpu* Iinstr::m_cpu; +disasm* Iinstr::m_disasm; CCpu* global_cpu = NULL; vector breakpoints; + +#include + +multimap dataCommentsStore, progCommentsStore, dataLabelStore, progLabelStore; +map dataLineCommentStore, progLineCommentStore; + bool ignoreBreak = false; +bool exitProg = false; + void doExit(const vector&) { - exit(EXIT_SUCCESS); + exitProg = true; } +unsigned int convertStringToNum(const std::string& in) +{ + if(in.substr(0,2) == "0x") { + return lexical_cast(in); + } + else { + return lexical_cast(in); + } +} + + void execStep(const vector& in) { int count = 1; if(in.size() == 2) { try { - count = lexical_cast(in.back()); + count = convertStringToNum(in.back()); } catch(bad_cast&) { cerr << "given parameter to step is not a number" << endl; @@ -100,7 +120,7 @@ void execStep(const vector& in) } else { ignoreBreak = true; - cout << "Breakpoint " << *breakp << " hit" << endl; + cout << color(white,red) << "Breakpoint" << color(white,black) << " 0x" << std::hex << setw(8) << setfill('0') << *breakp << std::hex << " hit" << endl; break; } } @@ -122,7 +142,7 @@ void execRun(const vector&) } else { ignoreBreak = true; - cout << "Breakpoint " << *breakp << " hit" << endl; + cout << color(white,red) << "Breakpoint" << color(white,black) << " 0x" << std::hex << setw(8) << setfill('0') << *breakp << std::hex << " hit" << endl; return; } } @@ -138,7 +158,7 @@ void setPC(const vector& in) CDat addr = 0; if(in.size() == 2) { try { - addr = lexical_cast(in.back()); + addr = convertStringToNum(in.back()); } catch(bad_cast&) { cerr << "given parameter is not a number" << endl; @@ -146,7 +166,7 @@ void setPC(const vector& in) } } global_cpu->setNextPC(addr); - cout << "Set programcounter to " << addr << endl; + cout << "Set programcounter to 0x" << std::hex << setw(8) << setfill('0') << addr << std::dec << endl; } @@ -159,7 +179,7 @@ void printReg(const vector& in) if(in.size() >= 2) { try { - start = lexical_cast(in[1]); + start = convertStringToNum(in[1]); if(start < 0 || start > (REG_COUNT-1)) { cerr << "start is out of range" << endl; return; @@ -174,7 +194,7 @@ void printReg(const vector& in) if(in.size() >= 3) { try { - end = lexical_cast(in[2]); + end = convertStringToNum(in[2]); if(start > end || end > (REG_COUNT-1)) { cerr << "end is out of range or smaller than start" << endl; return; @@ -187,7 +207,35 @@ void printReg(const vector& in) } for(i = start; i <= end; i++) { - cout << setw(2) << i << ": 0x" << std::hex << setw(8) << setfill('0') << global_cpu->getRegister(i) << " " << std::dec << setw(10) << setfill(' ') << global_cpu->getRegister(i) << endl; + cout << setw(2) << setfill('0') << i << ": 0x"; + cout << std::hex << setw(8) << setfill('0') << global_cpu->getRegister(i) << " "; + cout << std::dec << setw(10) << setfill(' ') << global_cpu->getRegister(i) << " "; + cout << std::dec << setw(10) << setfill(' ') << (int)global_cpu->getRegister(i) << endl; + } +} + +void setReg(const vector& in) +{ + int reg = 0; + CDat val = 0; + + if(in.size() >= 3) { + try { + reg = convertStringToNum(in[1]); + if(reg < 0 || reg > (REG_COUNT-1)) { + cerr << "register is out of range" << endl; + return; + } + + val = convertStringToNum(in[2]); + + cout << "Setting register " << reg << " to 0x" << std::hex << setw(8) << setfill('0') << val << std::dec << endl; + global_cpu->setRegister(reg,val); + } + catch(bad_cast&) { + cerr << "given parameter is not a number" << endl; + return; + } } } @@ -200,11 +248,12 @@ void printRAM(const vector& in) if(in.size() >= 2) { try { - start = lexical_cast(in[1]); + start = convertStringToNum(in[1]); if(start < 0 || start > (RAM_END-1)) { cerr << "start is out of range" << endl; return; } + start = (start & (~(BYTE_COUNT-1))) / BYTE_COUNT; end = start; } catch(bad_cast&) { @@ -215,23 +264,78 @@ void printRAM(const vector& in) if(in.size() >= 3) { try { - end = lexical_cast(in[2]); + end = convertStringToNum(in[2]); if(start > end || end > (RAM_END-1)) { cerr << "end is out of range or smaller than start" << endl; return; } + if(end % BYTE_COUNT != 0) { + end = ((end & (~(BYTE_COUNT-1))) / BYTE_COUNT)+1; + } + else { + end = ((end & (~(BYTE_COUNT-1))) / BYTE_COUNT); + } } catch(bad_cast&) { cerr << "given parameter is not a number" << endl; return; } } - - for(i = start*4; i <= end*4; i += 4) { - cout << std::hex << "0x" << setw(8) << setfill('0') << i << ": 0x" << std::hex << setw(8) << setfill('0') << global_cpu->getRAM(i) << " " << std::dec << setw(10) << setfill(' ') << global_cpu->getRAM(i) << endl; + for(i = start*BYTE_COUNT; i <= end*BYTE_COUNT; i += BYTE_COUNT) { + { + auto range = dataLabelStore.equal_range(i); + for(auto iter = range.first; iter != range.second; ++iter) { + cout << color(yellow,black) << iter->second << ":" << color(white,black) << endl; + } + } + { + auto range = dataCommentsStore.equal_range(i); + for(auto iter = range.first; iter != range.second; ++iter) { + cout << color(blue,black) << ";" << iter->second << color(white,black) << endl; + } + } + cout << std::hex << "0x" << setw(8) << setfill('0') << i << ": 0x"; + cout << std::hex << setw(8) << setfill('0') << global_cpu->getRAM(i) << " "; + cout << std::dec << setw(10) << setfill(' ') << global_cpu->getRAM(i) << " "; + cout << std::dec << setw(10) << setfill(' ') << (int)global_cpu->getRAM(i); + + auto iter = dataLineCommentStore.find(i); + if(iter != dataLineCommentStore.end()) { + cout << color(blue,black) << " ;" << iter->second << color(white,black); + } + cout << endl; + } } +void setRam(const vector& in) +{ + int addr = 0; + CDat val = 0; + + if(in.size() >= 3) { + try { + addr = convertStringToNum(in[1]); + if(addr < 0 || addr > (RAM_END-1)) { + cerr << "RAM-Address is out of range" << endl; + return; + } + + addr = (addr & (~(BYTE_COUNT-1))) / BYTE_COUNT; + val = convertStringToNum(in[2]); + + addr *= BYTE_COUNT; + + cout << "Setting RAM-Address 0x" << std::hex << setw(8) << setfill('0') << addr; + cout << " to 0x" << setw(8) << setfill('0') << val << std::dec << endl; + global_cpu->setRAM(addr,val); + } + catch(bad_cast&) { + cerr << "given parameter is not a number" << endl; + return; + } + } +} void printPROG(const vector& in) { int i, start = 0, end = 15; @@ -239,13 +343,18 @@ void printPROG(const vector& in) * 1) make 2 columns */ - if(in.size() >= 2) { + if(in.size() >= 2 && in[1][0] == 'c') { + start = global_cpu->getCurPC() / BYTE_COUNT; + end = start + 9; + } + else if(in.size() >= 2) { try { - start = lexical_cast(in[1]); + start = convertStringToNum(in[1]); if(start < 0 || start > (PROG_END-1)) { cerr << "start is out of range" << endl; return; } + start = (start & (~(BYTE_COUNT-1))) / BYTE_COUNT; end = start; } catch(bad_cast&) { @@ -256,36 +365,63 @@ void printPROG(const vector& in) if(in.size() >= 3) { try { - end = lexical_cast(in[2]); + end = convertStringToNum(in[2]); if(start > end || end > (PROG_END-1)) { cerr << "end is out of range or smaller than start" << endl; return; } + if(end % BYTE_COUNT != 0) { + end = ((end & (~(BYTE_COUNT-1))) / BYTE_COUNT)+1; + } + else { + end = ((end & (~(BYTE_COUNT-1))) / BYTE_COUNT); + } + } catch(bad_cast&) { cerr << "given parameter is not a number" << endl; return; } } + - for(i = start*4; i <= end*4; i += 4) { + for(i = start*BYTE_COUNT; i <= end*BYTE_COUNT; i += BYTE_COUNT) { + { + auto range = progLabelStore.equal_range(i); + for(auto iter = range.first; iter != range.second; ++iter) { + cout << color(yellow,black) << iter->second << ":" << color(white,black) << endl; + } + } + { + auto range = progCommentsStore.equal_range(i); + for(auto iter = range.first; iter != range.second; ++iter) { + cout << color(blue,black) << ";" << iter->second << color(white,black) << endl; + } + } + Iinstr* pi = global_cpu->getProg(i); if(pi == NULL) { - cout << std::hex << "0x" << setw(8) << setfill('0') << i << ": NOP" << endl; + cout << std::hex << "0x" << setw(8) << setfill('0') << i << ": NOP"; } else { - cout << std::hex << "0x" << setw(8) << setfill('0') << i << ": " << std::dec << pi->toString() << endl; + cout << std::hex << "0x" << setw(8) << setfill('0') << i << ": " << std::dec << global_cpu->colorifyInstr(pi->toString()); } + auto iter = progLineCommentStore.find(i); + if(iter != progLineCommentStore.end()) { + cout << color(blue,black) << " ;" << iter->second << color(white,black); + } + cout << endl; } } void setBreak(const vector& in) { - int addr = 0; + unsigned int addr = 0; if(in.size() == 2) { try { - addr = lexical_cast(in.back()); + addr = convertStringToNum(in.back()); breakpoints.push_back(addr); + cout << "Breakpoint 0x" << std::hex << setw(8) << setfill('0') << addr << std::dec << " set" << endl; } catch(bad_cast&) { cerr << "Given parameter is not a valid address" << endl; @@ -296,12 +432,31 @@ void setBreak(const vector& in) } } +void listBreaks(const vector&) +{ + for(auto iter = breakpoints.begin(); iter != breakpoints.end(); ++iter) { + cout << "Breakpoint at 0x" << std::hex << setw(8) << setfill('0') << *iter << std::dec << endl; + } +} + +void getPerf(const vector&) +{ + cout << "current perfcounter is " << std::dec << global_cpu->getPerf() << endl; +} + +void resetPerf(const vector&) +{ + cout << "reset perfcounter" << endl; + global_cpu->setPerf(0); +} + void printStatus(const vector&) { CDat stackp = global_cpu->getStack(); CDat stackd = global_cpu->getRAM(stackp); - cout << "Stack pointer: " << stackp << " @stackpointer: " << stackd << endl; + cout << "Stack pointer: 0x" << std::hex << setw(8) << setfill('0') << stackp << " @stackpointer: 0x" << setw(8) << stackd << std::dec << " (" << stackd << ")" << endl; cout << "PSW: 0x" << std::hex << setw(8) << setfill('0') << global_cpu->getFlags() << std::dec << endl; + cout << "cur PC: 0x" << std::hex << setw(8) << setfill('0') << global_cpu->getCurPC() << " next PC: 0x" << setw(8) << setfill('0') << global_cpu->getNextPC() << std::dec << endl; } @@ -382,12 +537,16 @@ int main(int argc, char* argv[]) Iinstr::setCPU(&cpu); + disasm disasm(instr); + Iinstr::setDisasm(&disasm); + + vector commentDefer; + vector labelDefer; std::string str = ""; int addr = 0; boost::char_separator sep(";", "", boost::keep_empty_tokens); boost::tokenizer > tokens(str, sep); - disasm disasm(instr); while(getline(inFile, str)) { int count = 0; tokens.assign(str); @@ -410,6 +569,15 @@ int main(int argc, char* argv[]) if(count == 1) { try { addr = lexical_cast(*tok_iter); + for(unsigned int i = 0; i < commentDefer.size(); i++) { + dataCommentsStore.insert(pair(addr, commentDefer.at(i))); + } + for(unsigned int i = 0; i < labelDefer.size(); i++) { + dataLabelStore.insert(pair(addr, labelDefer.at(i))); + } + + commentDefer.clear(); + labelDefer.clear(); } catch(bad_lexical_cast& e) { cerr << e.what() << endl; @@ -426,11 +594,30 @@ int main(int argc, char* argv[]) exit(EXIT_FAILURE); } } + else if(count == 4) { + if((*tok_iter).size() > 0) { + dataLabelStore.insert(pair(addr, *tok_iter)); + } + } + else if(count == 5) { + if((*tok_iter).size() > 0) { + dataLineCommentStore.insert(pair(addr, *tok_iter)); + } + } break; case 1: if(count == 1) { try { addr = lexical_cast(*tok_iter); + for(unsigned int i = 0; i < commentDefer.size(); i++) { + progCommentsStore.insert(pair(addr, commentDefer.at(i))); + } + for(unsigned int i = 0; i < labelDefer.size(); i++) { + progLabelStore.insert(pair(addr, labelDefer.at(i))); + } + + commentDefer.clear(); + labelDefer.clear(); } catch(bad_lexical_cast& e) { cerr << e.what() << endl; @@ -441,10 +628,28 @@ int main(int argc, char* argv[]) Iinstr *pi = disasm.decode(*tok_iter); cpu.setProg(addr, pi); } + else if(count == 4) { + if((*tok_iter).size() > 0) { + progLabelStore.insert(pair(addr, *tok_iter)); + } + } + else if(count == 5) { + if((*tok_iter).size() > 0) { + progLineCommentStore.insert(pair(addr, *tok_iter)); + } + } + break; case 2: + if((*tok_iter).size() > 0) { + commentDefer.push_back(*tok_iter); + } + break; case 3: - cerr << "ignoring labels and comments for now" << endl; + if((*tok_iter).size() > 0) { + labelDefer.push_back(*tok_iter); + } + break; default: cerr << "i was to lazy to implement the other format types for now" << endl; } @@ -471,18 +676,18 @@ int main(int argc, char* argv[]) cout << i << " : " << std::hex << i << std::dec << " " << data << endl; } */ - cpu.setRegister(1, 4); +/* cpu.setRegister(1, 4); cpu.setRegister(2, 0); cpu.setRAM(0,5); - cpu.setRAM(4,50); + cpu.setRAM(4,0x66334455); cpu.setRAM(8,32); cpu.setRAM(12,45); - +*/ // following: job of the bootloader //set stackpointer cpu.setStack(500); //set return to nowhere for ret - cpu.setRAM(500,50); + cpu.setRAM(500,500); SReadline Reader; @@ -494,13 +699,18 @@ int main(int argc, char* argv[]) Completers.push_back(CompleterElement("quit", &doExit, "Exits program")); Completers.push_back(CompleterElement("exit", &doExit, "Exits program")); Completers.push_back(CompleterElement("step [count]",&execStep, "Runs [count] ticks. if count is not given one tick is executed.")); - Completers.push_back(CompleterElement("dre [s] [e]",&printReg, "Prints registers. if s is given, only register s is printed. if s and e are given the registers from s to e are printed. if omitted all registers a printed.")); - Completers.push_back(CompleterElement("dra [s] [e]",&printRAM, "Prints RAM. if s is given, only RAM-Addr. s is printed. if s and e are given the RAM-Addrs from s to e are printed. if omitted the first 16 RAM-Addrs are printed.")); - Completers.push_back(CompleterElement("dpr [s] [e]",&printPROG, "Prints program. if s is given, only Prog-Addr. s is printed. if s and e are given the Prog-Addrs from s to e are printed. if omitted the first 16 Prog-Addrs are printed.")); + Completers.push_back(CompleterElement("dreg [s] [e]",&printReg, "Prints registers. if s is given, only register s is printed. if s and e are given the registers from s to e are printed. if omitted all registers a printed.")); + Completers.push_back(CompleterElement("ddata [s] [e]",&printRAM, "Prints RAM. if s is given, only RAM-Addr. s is printed. if s and e are given the RAM-Addrs from s to e are printed. if omitted the first 16 RAM-Addrs are printed.")); + Completers.push_back(CompleterElement("dprog [s] [e]",&printPROG, "Prints program. if s is given, only Prog-Addr. s is printed. if s and e are given the Prog-Addrs from s to e are printed. if omitted the first 16 Prog-Addrs are printed.")); Completers.push_back(CompleterElement("break addr",&setBreak, "Sets a breakpoint for address addr.")); + Completers.push_back(CompleterElement("listbreaks",&listBreaks, "Lists all breakpoints.")); Completers.push_back(CompleterElement("run",&execRun, "Runs till next breakpoint or end of program.")); Completers.push_back(CompleterElement("setpc [num]",&setPC, "Sets PC to num. if num is omitted 0 is used.")); + Completers.push_back(CompleterElement("setreg [s] [num]",&setReg, "Sets Register s to num.")); + Completers.push_back(CompleterElement("setdata [s] [num]",&setRam, "Sets RAM-Addr s to num.")); Completers.push_back(CompleterElement("status",&printStatus, "Prints status of CPU.")); + Completers.push_back(CompleterElement("getperf",&getPerf, "Prints performance counter.")); + Completers.push_back(CompleterElement("resetperf",&resetPerf, "Resets performance counter to 0.")); Reader.RegisterCompletions(Completers); @@ -508,12 +718,13 @@ int main(int argc, char* argv[]) vector Tokens, lastTokens; bool EndOfInput = false; - auto Found(Completers.end()); + //tilab g++44 doesn't like auto here + MyCompleterContainer::iterator Found(Completers.end()); Func lastFunc = NULL; - while(1) { + while(!exitProg) { UserInput = Reader.GetLine("> ", Tokens, EndOfInput); if(EndOfInput) { break;