sim: fixed misc things
authorMartin Perner <martin@perner.cc>
Fri, 29 Oct 2010 17:21:04 +0000 (19:21 +0200)
committerMartin Perner <martin@perner.cc>
Sun, 31 Oct 2010 12:21:18 +0000 (13:21 +0100)
3b_sim/Makefile [new file with mode: 0644]
3b_sim/Makefile.flags [new file with mode: 0644]
3b_sim/ccpu.cpp [new file with mode: 0644]
3b_sim/ccpu.hpp [new file with mode: 0644]
3b_sim/cdat.hpp [new file with mode: 0644]
3b_sim/cmem.cpp [new file with mode: 0644]
3b_sim/cmem.hpp [new file with mode: 0644]
3b_sim/sim.cpp [new file with mode: 0644]

diff --git a/3b_sim/Makefile b/3b_sim/Makefile
new file mode 100644 (file)
index 0000000..e6d4b04
--- /dev/null
@@ -0,0 +1,34 @@
+-include Makefile.flags
+
+sources = cmem.cpp ccpu.cpp sim.cpp CInstrFactory.cpp disasm.cpp cpmem.cpp
+
+PROG=sim
+
+.PHONY:all
+all: libs $(PROG)
+
+$(PROG): $(sources:.cpp=.o)
+       $(CC) $(CPPFLAGS) $(CPPPROGOPT) -o $(PROG) $(sources:.cpp=.o)
+
+-include $(sources:.cpp=.d)
+.PHONY: libs
+libs:   
+#      $(MAKE) -C instr all
+
+$(sources:.cpp=.o):
+       $(CC) $(CPPFLAGS) -c  -o ${@} ${@:.o=.cpp}
+
+.PHONY:clean
+clean:  
+       rm -rf $(PROG) $(sources:.cpp=.o) $(sources:.cpp=.d)
+#      $(MAKE) -C instr clean
+
+.PHONY: run
+run: $(PROG)
+       ./$(PROG) sum.dthex
+
+%.d: %.cpp
+       @set -e; rm -f $@; \
+       $(CC) -MM $(CPPFLAGS) $< > $@.$$$$; \
+       sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+       rm -f $@.$$$$
diff --git a/3b_sim/Makefile.flags b/3b_sim/Makefile.flags
new file mode 100644 (file)
index 0000000..dfd097c
--- /dev/null
@@ -0,0 +1,6 @@
+CC := g++
+
+CPPFLAGS = -g3 -O2 -std=c++0x -Wnon-virtual-dtor -Weffc++ -pedantic -Werror -Wall -Wextra -W -Wshadow -fno-common -pedantic-errors -Wpointer-arith -Wcast-qual -Wcast-align -Woverloaded-virtual -Wswitch-default -Wempty-body -Wlogical-op
+
+CPPPROGOPT=-rdynamic -ldl -lboost_program_options
+CPPLIBOPT=-shared
diff --git a/3b_sim/ccpu.cpp b/3b_sim/ccpu.cpp
new file mode 100644 (file)
index 0000000..3ad97fb
--- /dev/null
@@ -0,0 +1,36 @@
+#include "ccpu.hpp"
+
+/*             CDat m_pc, m_pc_next;
+               CMem m_regfile, m_ram;
+*/
+
+//void registerExtension() {};
+
+void CCpu::tick()
+{
+       m_pc = m_pc_next;
+       m_pc_next += 4;
+}
+
+CDat CCpu::getNextPC() const
+{
+       return m_pc_next;
+}
+
+
+//             CDat getRegister(const short) const {};
+//             void setRegister(const short, CDat&) {};
+
+//             CDat getRAM(const short) const {};
+//             void setRAM(const short, CDat&) {};
+
+void CCpu::setProg(int addr, Iinstr* instr)
+{
+       m_prog.set(addr, instr);
+}
+
+CCpu::CCpu() : m_pc(0), m_pc_next(0), m_regfile(0), m_ram(0), m_prog(0)
+{
+}
+
+
diff --git a/3b_sim/ccpu.hpp b/3b_sim/ccpu.hpp
new file mode 100644 (file)
index 0000000..89867ef
--- /dev/null
@@ -0,0 +1,38 @@
+
+
+#ifndef __CPU__H__
+#define __CPU__H__
+
+#include "cdat.hpp"
+#include "cmem.hpp"
+#include "cpmem.hpp"
+#include "Iinstr.hpp"
+
+class CCpu {
+       private:
+
+               CDat m_pc, m_pc_next;
+               CMem<CDat> m_regfile, m_ram;
+               CPMem<Iinstr*> m_prog;
+
+       public:
+               void registerExtension() {};
+               void tick();
+
+               CDat getRegister(const int) const;
+               void setRegister(const int, CDat&);
+
+               CDat getRAM(const int) const;
+               void setRAM(const int, CDat&);
+
+               Iinstr* getProg(const int) const;
+               void setProg(const int, Iinstr*);
+
+               CDat getNextPC() const;
+
+               CCpu();
+
+};
+
+
+#endif
diff --git a/3b_sim/cdat.hpp b/3b_sim/cdat.hpp
new file mode 100644 (file)
index 0000000..e318aff
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef __CDAT_H__
+#define __CDAT_H__
+
+#include <string>
+#include <sstream>
+
+typedef int CDat;
+
+static_assert(sizeof(CDat) == 4, "The size of the datatype for int is NOT 4 bytes (32 Bit!)");
+#endif
diff --git a/3b_sim/cmem.cpp b/3b_sim/cmem.cpp
new file mode 100644 (file)
index 0000000..90886a2
--- /dev/null
@@ -0,0 +1,35 @@
+#include "cmem.hpp"
+
+using namespace std;
+
+template <class T>
+void CMem<T>::set(const MEMORY_ADDRESS address, const T& data)
+{
+       if(address >= MAX_MEMORY) {
+               stringstream error;
+               error << "memoryaddress " << address << " out of range";
+               throw out_of_range(error.str());
+       }
+
+       MEMORY_ADDRESS temp = address;
+       auto iter = m_memory.begin();
+       while(temp > 0) {
+               ++iter;
+               temp--;
+       }
+
+       iter = m_memory.insert(iter, data);
+       ++iter;
+       m_memory.erase(iter);
+}
+
+template <class T>
+void CMem<T>::get(const MEMORY_ADDRESS address, T& value) const
+{
+       if(address >= MAX_MEMORY) {
+               stringstream error;
+               error << "memoryaddress " << address << " out of range";
+               throw out_of_range(error.str());
+       }
+       value = m_memory[address];
+}
diff --git a/3b_sim/cmem.hpp b/3b_sim/cmem.hpp
new file mode 100644 (file)
index 0000000..195fe6c
--- /dev/null
@@ -0,0 +1,30 @@
+#ifndef __CMEM_H__
+#define __CMEM_H__
+
+#include "cdat.hpp"
+#include <vector>
+#include <stdexcept>
+
+typedef int MEMORY_ADDRESS;
+
+/**
+ * Name:    CMem
+ * Purpose: Class representing the memory of our emulated machine
+ */
+template <class T>
+class CMem
+{
+private:
+       //MAX_MEMORY-1 zugreifbare Speicherzellen
+       const int MAX_MEMORY;
+       std::vector<T> m_memory;
+public:
+       //wert aus referenz auslesen und in vetor speichern (index zugriff!)
+       //address 0 ist ProgramCounter
+       void set(const MEMORY_ADDRESS address, const T& data);
+       //retuniert referenz eines cdat objekts mit dem Wert von address
+       void get(const MEMORY_ADDRESS address, T& data) const;
+       CMem(int size) : MAX_MEMORY(size), m_memory(size) {};
+};
+
+#endif
diff --git a/3b_sim/sim.cpp b/3b_sim/sim.cpp
new file mode 100644 (file)
index 0000000..ae5b16b
--- /dev/null
@@ -0,0 +1,168 @@
+#include <iostream>
+#include <fstream>
+#include <boost/tokenizer.hpp>
+#include <boost/program_options.hpp>
+#include <boost/lexical_cast.hpp>
+#include <string>
+#include <map>
+
+#include "disasm.h"
+#include "ccpu.hpp"
+#include "CInstrFactory.hpp"
+
+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<string>(), "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<string>() << endl;
+#endif
+                       inFile.open(vm["file"].as<string>(), ios::in);
+                       if(!inFile) {
+                               cerr << "Error opening file " << vm["file"].as<string>() << 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<short, Iinstr*> 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;
+
+
+       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);
+               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<int>(*tok_iter);
+                                       count++;
+                                       continue;
+                               }
+                               catch(bad_lexical_cast &) {
+                                       break;
+                               }
+                               cout << endl;
+                       }
+                       switch(type) {
+                               case 2:
+                                       if(count == 1) {
+                                               cout << "; ";
+                                       }
+                                       cout << *tok_iter;
+                                       break;
+                               case 3:
+                                       if((*tok_iter).size() > 0) {
+                                               if(count > 1) {
+                                                       cout << endl;
+                                               }
+                                               cout << *tok_iter << ":";
+                                       }
+                                       break;
+                               case 1:
+                                       if(count == 1) {
+                                               out << "[0x" << *tok_iter << "]: ";
+                                               addr = lexical_cast<int>(*tok_iter);
+                                       }
+                                       else if(count == 2) {
+                                               cpu.setProg(addr, disasm.decode(*tok_iter));
+                                       }
+                                       else if(count == 3) {
+                                               //code saved in hex-file
+                                               //cout << *tok_iter ;
+                                       }
+                                       else if(count == 4) {
+                                               /* label */
+                                               if((*tok_iter).size() > 0) {
+                                                       cout << *tok_iter << ":" << endl;
+                                               }
+                                               cout << out.str();
+                                       }
+                                       else if(count == 5) {
+                                               if((*tok_iter).size() > 0) {
+                                                       cout << " ;";
+                                               }
+                                       }
+
+                                       if(count >= 5) {
+                                               cout << *tok_iter;
+                                       }
+                                       break;
+                               default:
+                                       cerr << "i was to lazy to implement the other format types for now" << endl;
+                       }
+                       count++;
+               }
+               if(type == 1 && count <= 4) {
+                       cout << out.str();
+               }
+               cout << endl;
+       }
+       inFile.close();
+
+       cout << endl;
+       return EXIT_SUCCESS;
+}