#include #include #include #include #include #include #include #include #include #include #include #include #include "disasm.h" #include "ccpu.hpp" #include "CInstrFactory.hpp" #include "uint32_from_hex.hpp" #include "SReadline/SReadline.h" using namespace swift; typedef boost::function &)> Func; typedef boost::tuple CompleterElement; typedef list MyCompleterContainer; class LookupFunctor { public: // Creates a functor and memorises tokens LookupFunctor(const vector& tokens) : Tokens(tokens) {} // Compares the first token only bool operator()(const CompleterElement& ele) const { return (strncmp(Tokens.begin()->c_str(), ele.get<0>().c_str(), Tokens.begin()->size()) == 0); } private: const vector &Tokens; }; class CHelpExec { private: const MyCompleterContainer &m_completers; public: CHelpExec(const MyCompleterContainer &cont) : m_completers(cont) {} void operator() (const vector&) { cout << "Available commands: " << endl; for(auto iter = m_completers.begin(); iter != m_completers.end(); ++iter) { cout << (*iter).get<0>() << endl; } } }; void close_prog(const std::vector &); CCpu* Iinstr::m_cpu; CCpu* global_cpu = NULL; void doExit(const vector&) { exit(EXIT_SUCCESS); } void execStep(const vector& in) { int count = 1; if(in.size() == 2) { try { count = lexical_cast(in.back()); } catch(bad_cast&) { cerr << "given parameter to step is not a number" << endl; } } while(count > 0) { try { global_cpu->tick(); } catch(std::string& e) { cerr << e << endl; } count--; } } void printReg(const vector&) { int i, start = 0, end = 15; /* Todo: * 1) make 2 columns * 2) let use select registers to show (one register, range of registers) */ for(i = start; i <= end; i++) { cout << setw(2) << i << ": 0x" << std::hex << setw(8) << setfill('0') << global_cpu->getRegister(i) << std::dec << endl; } } using boost::lexical_cast; using boost::bad_lexical_cast; using namespace std; using namespace boost::program_options; namespace po = boost::program_options; std::string progName; int main(int argc, char* argv[]) { progName = argv[0]; ifstream inFile; try { po::options_description desc("Allowed options"); desc.add_options() ("help,h","produce help message") ("file,f",value(), "input file") ; po::positional_options_description p; p.add("file",1); po::variables_map vm; po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm); po::notify(vm); if(vm.count("help")) { cout << desc << endl; return EXIT_FAILURE; } if(vm.count("file")) { #ifdef DEBUG cout << "going to open file " << vm["file"].as() << endl; #endif inFile.open(vm["file"].as(), ios::in); if(!inFile) { cerr << "Error opening file " << vm["file"].as() << endl; return EXIT_FAILURE; } } else { cout << "not input file given!" << endl << endl; cout << desc << endl; return EXIT_FAILURE; } } catch(std::exception& ex) { cout << ex.what() << endl; } string dir = "./instr/"; map instr; CInstrFactory instrFab; try { instrFab.loadLibsIntoMap(instr, dir); } catch(std::bad_alloc& e) { cerr << progName << ": bad_alloc caught " << e.what() << endl; exit(EXIT_FAILURE); } catch(std::string& s) { cerr << progName << ": " << s << endl; exit(EXIT_FAILURE); } CCpu cpu(16,1000,1000); global_cpu = &cpu; Iinstr::setCPU(&cpu); 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); stringstream out; int type = 0; for(auto tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) { if(tok_iter == tokens.begin()) { try { type = lexical_cast(*tok_iter); count++; continue; } catch(bad_lexical_cast &) { break; } cout << endl; } switch(type) { case 0: if(count == 1) { try { addr = lexical_cast(*tok_iter); } catch(bad_lexical_cast& e) { cerr << e.what() << endl; exit(EXIT_FAILURE); } } else if(count == 2) { try { CDat data = lexical_cast(*tok_iter); cpu.setRAM(addr, data); } catch(bad_lexical_cast& e) { cerr << e.what() << endl; exit(EXIT_FAILURE); } } break; case 1: if(count == 1) { try { addr = lexical_cast(*tok_iter); } catch(bad_lexical_cast& e) { cerr << e.what() << endl; exit(EXIT_FAILURE); } } else if(count == 2) { Iinstr *pi = disasm.decode(*tok_iter); cpu.setProg(addr, pi); } break; case 2: case 3: cerr << "ignoring labels and comments for now" << endl; default: cerr << "i was to lazy to implement the other format types for now" << endl; } count++; } } inFile.close(); cout << endl; /* for(int i = 0; i <= 32; i += 4) { Iinstr *pinstr = cpu.getProg(i); if(pinstr != NULL) { cout << i << " : " << std::hex << i << std::dec << " " << pinstr->toString() << endl; } else { cout << "Null at " << i << " : " << std::hex << i << endl; } } for(int i = 0; i <= 32; i += 4) { CDat data = cpu.getRAM(i); cout << i << " : " << std::hex << i << std::dec << " " << data << endl; } */ cpu.setRegister(1, 4); cpu.setRegister(2, 0); cpu.setRAM(0,5); cpu.setRAM(4,50); 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); SReadline Reader; MyCompleterContainer Completers; CHelpExec HelpExec(Completers); Completers.push_back(CompleterElement("help", boost::bind1st( boost::mem_fun( &CHelpExec::operator()), &HelpExec))); Completers.push_back(CompleterElement("quit", &doExit)); Completers.push_back(CompleterElement("exit", &doExit)); Completers.push_back(CompleterElement("q", &doExit)); Completers.push_back(CompleterElement("step [count]",&execStep)); Completers.push_back(CompleterElement("reg",&printReg)); Reader.RegisterCompletions(Completers); string UserInput; vector Tokens, lastTokens; bool EndOfInput = false; auto Found(Completers.end()); Func lastFunc = NULL; while(1) { UserInput = Reader.GetLine("> ", Tokens, EndOfInput); if(EndOfInput) { break; } if(!Tokens.empty()) { Found = find_if(Completers.begin(), Completers.end(), LookupFunctor(Tokens)); if(Found != Completers.end()) { if((*Found).get<1>() != 0) { lastFunc = (*Found).get<1>(); lastFunc(Tokens); lastTokens = Tokens; //(*Found).get<1>()(Tokens); } } else { lastFunc = NULL; cout << "Unknown command. 'help' displays help" << endl; } } else { if(lastFunc != NULL) { lastFunc(lastTokens); } else { cout << "Unknown command. 'help' displays help" << endl; } } } /* for(int i = 0; ; i++) { try { cpu.tick(); cout << " reg0: " << cpu.getRegister(0) << " reg1: " << cpu.getRegister(1); cout << " reg2: " << cpu.getRegister(2) << " reg3: " << cpu.getRegister(3); cout << " reg4: " << cpu.getRegister(4) << " reg5: " << cpu.getRegister(5); cout << endl << endl; } catch(string& e) { cerr << e << endl; break; } } */ return EXIT_SUCCESS; }