disasm/sim: changed interface, branch => br, features++
[calu.git] / 3b_sim / sim.cpp
1 #include <iostream>
2 #include <fstream>
3 #include <boost/tokenizer.hpp>
4 #include <boost/program_options.hpp>
5 #include <boost/lexical_cast.hpp>
6 #include <string>
7 #include <map>
8
9 #include "disasm.h"
10 #include "ccpu.hpp"
11 #include "CInstrFactory.hpp"
12 #include "uint32_from_hex.hpp"
13
14 CCpu* Iinstr::m_cpu;
15
16 using boost::lexical_cast;
17 using boost::bad_lexical_cast;
18
19 using namespace std;
20
21 using namespace boost::program_options;
22 namespace po = boost::program_options;
23
24 std::string progName;
25
26 int main(int argc, char* argv[])
27 {
28         progName = argv[0];
29         ifstream inFile;
30         try {
31                 po::options_description desc("Allowed options");
32                 desc.add_options()
33                 ("help,h","produce help message")
34                 ("file,f",value<string>(), "input file")
35                 ;
36
37                 po::positional_options_description p;
38                 p.add("file",1);
39
40                 po::variables_map vm;
41                 po::store(po::command_line_parser(argc, argv).options(desc).positional(p).run(), vm);
42                 po::notify(vm);
43
44                 if(vm.count("help")) {
45                         cout << desc << endl;
46                         return EXIT_FAILURE;
47                 }
48
49                 if(vm.count("file")) {
50 #ifdef DEBUG 
51                         cout << "going to open file " << vm["file"].as<string>() << endl;
52 #endif
53                         inFile.open(vm["file"].as<string>(), ios::in);
54                         if(!inFile) {
55                                 cerr << "Error opening file " << vm["file"].as<string>() << endl;
56                                 return EXIT_FAILURE;
57                         }
58                 }
59                 else {
60                         cout << "not input file given!" << endl << endl;
61                         cout << desc << endl;
62                         return EXIT_FAILURE;
63                 }
64         }
65         catch(std::exception& ex) {
66                 cout << ex.what() << endl;
67         }
68
69
70         string dir = "./instr/";
71
72         map<short, Iinstr*> instr;
73
74         CInstrFactory instrFab;
75         try {
76                 instrFab.loadLibsIntoMap(instr, dir);
77         }
78         catch(std::bad_alloc& e) {
79                 cerr << progName << ": bad_alloc caught " << e.what() << endl;
80                 exit(EXIT_FAILURE); 
81         }
82         catch(std::string& s) {
83                 cerr << progName << ": " << s << endl;
84                 exit(EXIT_FAILURE);
85         }
86
87
88         CCpu cpu(16,1000,1000);
89
90         Iinstr::setCPU(&cpu);
91
92
93         std::string str = "";
94         int addr = 0;
95         boost::char_separator<char> sep(";", "", boost::keep_empty_tokens);
96         boost::tokenizer<boost::char_separator<char> > tokens(str, sep);
97         disasm disasm(instr);
98         while(getline(inFile, str)) {
99                 int count = 0;
100                 tokens.assign(str);
101                 stringstream out;
102                 int type = 0;
103                 for(auto tok_iter = tokens.begin(); tok_iter != tokens.end(); ++tok_iter) {
104                         if(tok_iter == tokens.begin()) {
105                                 try {
106                                         type = lexical_cast<int>(*tok_iter);
107                                         count++;
108                                         continue;
109                                 }
110                                 catch(bad_lexical_cast &) {
111                                         break;
112                                 }
113                                 cout << endl;
114                         }
115                         switch(type) {
116                                 case 0:
117                                         if(count == 1) {
118                                                 try {
119                                                         addr = lexical_cast<uint32_from_hex>(*tok_iter);
120                                                 }
121                                                 catch(bad_lexical_cast& e) {
122                                                         cerr << e.what() << endl;
123                                                         exit(EXIT_FAILURE);
124                                                 }
125                                         }
126                                         else if(count == 2) {
127                                                 try {
128                                                         CDat data = lexical_cast<uint32_from_hex>(*tok_iter);
129                                                         cpu.setRAM(addr, data);
130                                                 }
131                                                 catch(bad_lexical_cast& e) {
132                                                         cerr << e.what() << endl;
133                                                         exit(EXIT_FAILURE);
134                                                 }
135                                         }
136                                         break;
137                                 case 1:
138                                         if(count == 1) {
139                                                 try {
140                                                         addr = lexical_cast<uint32_from_hex>(*tok_iter);
141                                                 }
142                                                 catch(bad_lexical_cast& e) {
143                                                         cerr << e.what() << endl;
144                                                         exit(EXIT_FAILURE);
145                                                 }
146                                         }
147                                         else if(count == 2) {
148                                                 Iinstr *pi = disasm.decode(*tok_iter);
149                                                 cpu.setProg(addr, pi);
150                                         }
151                                         break;
152                                 case 2:
153                                 case 3:
154                                         cerr << "ignoring labels and comments for now" << endl;
155                                 default:
156                                         cerr << "i was to lazy to implement the other format types for now" << endl;
157                         }
158                         count++;
159                 }
160         }
161         inFile.close();
162
163         cout << endl;
164
165
166         for(int i = 0; i <= 32; i += 4) {
167                 Iinstr *pinstr = cpu.getProg(i);
168                 if(pinstr != NULL) {
169                         cout << i << " : " << std::hex << i << std::dec << " " << pinstr->toString() << endl;
170                 }
171                 else {
172                         cout << "Null at " << i << " : " << std::hex << i << endl;
173                 }
174         }
175
176         for(int i = 0; i <= 32; i += 4) {
177                 CDat data = cpu.getRAM(i);
178                 cout << i << " : " << std::hex << i << std::dec << " " << data << endl;
179         }
180
181         cpu.setRegister(1, 4);
182         cpu.setRegister(2, 0);
183         cpu.setRAM(0,5);
184         cpu.setRAM(4,50);
185         cpu.setRAM(8,32);
186         cpu.setRAM(12,45);
187
188         // following: job of the bootloader
189         //set stackpointer
190         cpu.setStack(500);
191         //set return to nowhere for ret
192         cpu.setRAM(500,50);
193
194         for(int i = 0; ; i++) {
195                 try {
196                         cpu.tick();
197                         cout << " reg0: " << cpu.getRegister(0) <<  " reg1: " << cpu.getRegister(1);
198                         cout << " reg2: " << cpu.getRegister(2) <<  " reg3: " << cpu.getRegister(3);
199                         cout << " reg4: " << cpu.getRegister(4) <<  " reg5: " << cpu.getRegister(5);
200                         cout << endl << endl;
201
202                 }
203                 catch(string& e) {
204                         cerr << e << endl;
205                         break;
206                 }
207         }
208
209         return EXIT_SUCCESS;
210 }