4 #include <boost/tokenizer.hpp>
5 #include <boost/program_options.hpp>
6 #include <boost/lexical_cast.hpp>
11 #include <boost/function.hpp>
12 #include <boost/functional.hpp>
13 #include <boost/tuple/tuple.hpp>
17 #include "CInstrFactory.hpp"
18 #include "uint32_from_hex.hpp"
20 #include "SReadline/SReadline.h"
21 using namespace swift;
23 typedef boost::function<void (const vector<string> &)> Func;
24 typedef boost::tuple<string, Func> CompleterElement;
26 typedef list<CompleterElement> MyCompleterContainer;
31 // Creates a functor and memorises tokens
32 LookupFunctor(const vector<string>& tokens) : Tokens(tokens) {}
34 // Compares the first token only
35 bool operator()(const CompleterElement& ele) const
37 return (strncmp(Tokens.begin()->c_str(), ele.get<0>().c_str(), Tokens.begin()->size()) == 0);
41 const vector<string> &Tokens;
50 const MyCompleterContainer &m_completers;
53 CHelpExec(const MyCompleterContainer &cont) : m_completers(cont) {}
55 void operator() (const vector<string>&)
57 cout << "Available commands: " << endl;
58 for(auto iter = m_completers.begin(); iter != m_completers.end(); ++iter) {
59 cout << (*iter).get<0>() << endl;
64 void close_prog(const std::vector<std::string> &);
68 CCpu* global_cpu = NULL;
70 void doExit(const vector<string>&)
75 void execStep(const vector<string>& in)
80 count = lexical_cast<int>(in.back());
83 cerr << "given parameter to step is not a number" << endl;
90 catch(std::string& e) {
97 void printReg(const vector<string>&)
99 int i, start = 0, end = 15;
102 * 2) let use select registers to show (one register, range of registers)
105 for(i = start; i <= end; i++) {
106 cout << setw(2) << i << ": 0x" << std::hex << setw(8) << setfill('0') << global_cpu->getRegister(i) << std::dec << endl;
111 using boost::lexical_cast;
112 using boost::bad_lexical_cast;
116 using namespace boost::program_options;
117 namespace po = boost::program_options;
119 std::string progName;
121 int main(int argc, char* argv[])
126 po::options_description desc("Allowed options");
128 ("help,h","produce help message")
129 ("file,f",value<string>(), "input file")
132 po::positional_options_description p;
135 po::variables_map vm;
136 po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
139 if(vm.count("help")) {
140 cout << desc << endl;
144 if(vm.count("file")) {
146 cout << "going to open file " << vm["file"].as<string>() << endl;
148 inFile.open(vm["file"].as<string>(), ios::in);
150 cerr << "Error opening file " << vm["file"].as<string>() << endl;
155 cout << "not input file given!" << endl << endl;
156 cout << desc << endl;
160 catch(std::exception& ex) {
161 cout << ex.what() << endl;
165 string dir = "./instr/";
167 map<short, Iinstr*> instr;
169 CInstrFactory instrFab;
171 instrFab.loadLibsIntoMap(instr, dir);
173 catch(std::bad_alloc& e) {
174 cerr << progName << ": bad_alloc caught " << e.what() << endl;
177 catch(std::string& s) {
178 cerr << progName << ": " << s << endl;
182 CCpu cpu(16,1000,1000);
186 Iinstr::setCPU(&cpu);
189 std::string str = "";
191 boost::char_separator<char> sep(";", "", boost::keep_empty_tokens);
192 boost::tokenizer<boost::char_separator<char> > tokens(str, sep);
193 disasm disasm(instr);
194 while(getline(inFile, str)) {
199 for(auto tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
200 if(tok_iter == tokens.begin()) {
202 type = lexical_cast<int>(*tok_iter);
206 catch(bad_lexical_cast &) {
215 addr = lexical_cast<uint32_from_hex>(*tok_iter);
217 catch(bad_lexical_cast& e) {
218 cerr << e.what() << endl;
222 else if(count == 2) {
224 CDat data = lexical_cast<uint32_from_hex>(*tok_iter);
225 cpu.setRAM(addr, data);
227 catch(bad_lexical_cast& e) {
228 cerr << e.what() << endl;
236 addr = lexical_cast<uint32_from_hex>(*tok_iter);
238 catch(bad_lexical_cast& e) {
239 cerr << e.what() << endl;
243 else if(count == 2) {
244 Iinstr *pi = disasm.decode(*tok_iter);
245 cpu.setProg(addr, pi);
250 cerr << "ignoring labels and comments for now" << endl;
252 cerr << "i was to lazy to implement the other format types for now" << endl;
262 for(int i = 0; i <= 32; i += 4) {
263 Iinstr *pinstr = cpu.getProg(i);
265 cout << i << " : " << std::hex << i << std::dec << " " << pinstr->toString() << endl;
268 cout << "Null at " << i << " : " << std::hex << i << endl;
272 for(int i = 0; i <= 32; i += 4) {
273 CDat data = cpu.getRAM(i);
274 cout << i << " : " << std::hex << i << std::dec << " " << data << endl;
277 cpu.setRegister(1, 4);
278 cpu.setRegister(2, 0);
284 // following: job of the bootloader
287 //set return to nowhere for ret
292 MyCompleterContainer Completers;
294 CHelpExec HelpExec(Completers);
296 Completers.push_back(CompleterElement("help", boost::bind1st( boost::mem_fun( &CHelpExec::operator()), &HelpExec)));
297 Completers.push_back(CompleterElement("quit", &doExit));
298 Completers.push_back(CompleterElement("exit", &doExit));
299 Completers.push_back(CompleterElement("q", &doExit));
300 Completers.push_back(CompleterElement("step [count]",&execStep));
301 Completers.push_back(CompleterElement("reg",&printReg));
303 Reader.RegisterCompletions(Completers);
306 vector<string> Tokens, lastTokens;
307 bool EndOfInput = false;
309 auto Found(Completers.end());
311 Func lastFunc = NULL;
315 UserInput = Reader.GetLine("> ", Tokens, EndOfInput);
320 if(!Tokens.empty()) {
321 Found = find_if(Completers.begin(), Completers.end(), LookupFunctor(Tokens));
323 if(Found != Completers.end()) {
324 if((*Found).get<1>() != 0) {
325 lastFunc = (*Found).get<1>();
328 //(*Found).get<1>()(Tokens);
333 cout << "Unknown command. 'help' displays help" << endl;
337 if(lastFunc != NULL) {
338 lastFunc(lastTokens);
341 cout << "Unknown command. 'help' displays help" << endl;
348 for(int i = 0; ; i++) {
351 cout << " reg0: " << cpu.getRegister(0) << " reg1: " << cpu.getRegister(1);
352 cout << " reg2: " << cpu.getRegister(2) << " reg3: " << cpu.getRegister(3);
353 cout << " reg4: " << cpu.getRegister(4) << " reg5: " << cpu.getRegister(5);
354 cout << endl << endl;