sim: labels and comments are now shown
[calu.git] / 3b_sim / sim.cpp
index 4fe52b06f5091ed974b4c88e7b0ae3040e0b3fda..3200e92a798370baf0ada9c066d7a80fc3d9e65c 100644 (file)
@@ -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<void (const vector<string> &)> 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,43 @@ class CHelpExec
 void close_prog(const std::vector<std::string> &);
 
 CCpu* Iinstr::m_cpu;
+disasm* Iinstr::m_disasm;
 
 CCpu* global_cpu = NULL;
 
 vector<CDat> breakpoints;
 
+#include <map>
+
+multimap<int,string> dataCommentsStore, progCommentsStore, dataLabelStore, progLabelStore;
+map<int,string> dataLineCommentStore, progLineCommentStore;
+
 bool ignoreBreak = false;
 
+bool exitProg = false;
+
 void doExit(const vector<string>&)
 {
-       exit(EXIT_SUCCESS);
+       exitProg = true;
 }
 
+unsigned int convertStringToNum(const std::string& in)
+{
+       if(in.substr(0,2) == "0x") {
+               return lexical_cast<uint32_from_hex>(in);
+       }
+       else {
+               return lexical_cast<unsigned int>(in);
+       }
+}
+
+
 void execStep(const vector<string>& in)
 {
        int count = 1;
        if(in.size() == 2) {
                try {
-                       count = lexical_cast<int>(in.back());
+                       count = convertStringToNum(in.back());
                }
                catch(bad_cast&) {
                        cerr << "given parameter to step is not a number" << endl;
@@ -100,7 +119,7 @@ void execStep(const vector<string>& 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 +141,7 @@ void execRun(const vector<string>&)
                        }
                        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 +157,7 @@ void setPC(const vector<string>& in)
        CDat addr = 0;
        if(in.size() == 2) {
                try {
-                       addr = lexical_cast<uint32_from_hex>(in.back());
+                       addr = convertStringToNum(in.back());
                }
                catch(bad_cast&) {
                        cerr << "given parameter is not a number" << endl;
@@ -146,7 +165,7 @@ void setPC(const vector<string>& 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 +178,7 @@ void printReg(const vector<string>& in)
 
        if(in.size() >= 2) {
                try {
-                       start = lexical_cast<int>(in[1]);
+                       start = convertStringToNum(in[1]);
                        if(start < 0 || start > (REG_COUNT-1)) {
                                cerr << "start is out of range" << endl;
                                return;
@@ -174,7 +193,7 @@ void printReg(const vector<string>& in)
 
        if(in.size() >= 3) {
                try {
-                       end = lexical_cast<int>(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 +206,35 @@ void printReg(const vector<string>& 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<string>& 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 +247,12 @@ void printRAM(const vector<string>& in)
 
        if(in.size() >= 2) {
                try {
-                       start = lexical_cast<int>(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 +263,78 @@ void printRAM(const vector<string>& in)
 
        if(in.size() >= 3) {
                try {
-                       end = lexical_cast<int>(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<string>& 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<string>& in)
 {
        int i, start = 0, end = 15;
@@ -239,13 +342,18 @@ void printPROG(const vector<string>& 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<int>(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 +364,63 @@ void printPROG(const vector<string>& in)
 
        if(in.size() >= 3) {
                try {
-                       end = lexical_cast<int>(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 << 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<string>& in)
 {
-       int addr = 0;
+       unsigned int addr = 0;
        if(in.size() == 2) {
                try {
-                       addr = lexical_cast<uint32_from_hex>(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,11 +431,29 @@ void setBreak(const vector<string>& in)
        }
 }
 
+void listBreaks(const vector<string>&)
+{
+       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<string>&)
+{
+       cout << "current perfcounter is " << std::dec << global_cpu->getPerf() << endl;
+}
+
+void resetPerf(const vector<string>&)
+{
+       cout << "reset perfcounter" << endl;
+       global_cpu->setPerf(0);
+}
+
 void printStatus(const vector<string>&)
 {
        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;
 
@@ -383,12 +536,16 @@ int main(int argc, char* argv[])
 
        Iinstr::setCPU(&cpu);
 
+       disasm disasm(instr);
+
+       Iinstr::setDisasm(&disasm);
 
+       vector<string> commentDefer;
+       vector<string> labelDefer;
        std::string str = "";
        int addr = 0;
        boost::char_separator<char> sep(";", "", boost::keep_empty_tokens);
        boost::tokenizer<boost::char_separator<char> > tokens(str, sep);
-       disasm disasm(instr);
        while(getline(inFile, str)) {
                int count = 0;
                tokens.assign(str);
@@ -411,6 +568,15 @@ int main(int argc, char* argv[])
                                        if(count == 1) {
                                                try {
                                                        addr = lexical_cast<uint32_from_hex>(*tok_iter);
+                                                       for(unsigned int i = 0; i < commentDefer.size(); i++) {
+                                                               dataCommentsStore.insert(pair<int,string>(addr, commentDefer.at(i)));
+                                                       }
+                                                       for(unsigned int i = 0; i < labelDefer.size(); i++) {
+                                                               dataLabelStore.insert(pair<int,string>(addr, labelDefer.at(i)));
+                                                       }
+
+                                                       commentDefer.clear();
+                                                       labelDefer.clear();
                                                }
                                                catch(bad_lexical_cast& e) {
                                                        cerr << e.what() << endl;
@@ -427,11 +593,30 @@ int main(int argc, char* argv[])
                                                        exit(EXIT_FAILURE);
                                                }
                                        }
+                                       else if(count == 4) {
+                                               if((*tok_iter).size() > 0) {
+                                                       dataLabelStore.insert(pair<int,string>(addr, *tok_iter));
+                                               }
+                                       }
+                                       else if(count == 5) {
+                                               if((*tok_iter).size() > 0) {
+                                                       dataLineCommentStore.insert(pair<int,string>(addr, *tok_iter));
+                                               }
+                                       }
                                        break;
                                case 1:
                                        if(count == 1) {
                                                try {
                                                        addr = lexical_cast<uint32_from_hex>(*tok_iter);
+                                                       for(unsigned int i = 0; i < commentDefer.size(); i++) {
+                                                               progCommentsStore.insert(pair<int,string>(addr, commentDefer.at(i)));
+                                                       }
+                                                       for(unsigned int i = 0; i < labelDefer.size(); i++) {
+                                                               progLabelStore.insert(pair<int,string>(addr, labelDefer.at(i)));
+                                                       }
+
+                                                       commentDefer.clear();
+                                                       labelDefer.clear();
                                                }
                                                catch(bad_lexical_cast& e) {
                                                        cerr << e.what() << endl;
@@ -442,10 +627,27 @@ 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<int,string>(addr, *tok_iter));
+                                               }
+                                       }
+                                       else if(count == 5) {
+                                               if((*tok_iter).size() > 0) {
+                                                       progLineCommentStore.insert(pair<int,string>(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;
@@ -473,18 +675,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;
 
@@ -500,9 +702,14 @@ int main(int argc, char* argv[])
        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);
 
@@ -510,12 +717,13 @@ int main(int argc, char* argv[])
        vector<string> 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;