From 31d88f201bf427d70924b9737ecdb6e0611939d3 Mon Sep 17 00:00:00 2001 From: Martin Perner Date: Fri, 29 Oct 2010 19:21:04 +0200 Subject: [PATCH] sim: fixed misc things --- 3b_sim/Makefile | 34 +++++++++ 3b_sim/Makefile.flags | 6 ++ 3b_sim/ccpu.cpp | 36 +++++++++ 3b_sim/ccpu.hpp | 38 ++++++++++ 3b_sim/cdat.hpp | 10 +++ 3b_sim/cmem.cpp | 35 +++++++++ 3b_sim/cmem.hpp | 30 ++++++++ 3b_sim/sim.cpp | 168 ++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 357 insertions(+) create mode 100644 3b_sim/Makefile create mode 100644 3b_sim/Makefile.flags create mode 100644 3b_sim/ccpu.cpp create mode 100644 3b_sim/ccpu.hpp create mode 100644 3b_sim/cdat.hpp create mode 100644 3b_sim/cmem.cpp create mode 100644 3b_sim/cmem.hpp create mode 100644 3b_sim/sim.cpp diff --git a/3b_sim/Makefile b/3b_sim/Makefile new file mode 100644 index 0000000..e6d4b04 --- /dev/null +++ b/3b_sim/Makefile @@ -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 index 0000000..dfd097c --- /dev/null +++ b/3b_sim/Makefile.flags @@ -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 index 0000000..3ad97fb --- /dev/null +++ b/3b_sim/ccpu.cpp @@ -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 index 0000000..89867ef --- /dev/null +++ b/3b_sim/ccpu.hpp @@ -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 m_regfile, m_ram; + CPMem 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 index 0000000..e318aff --- /dev/null +++ b/3b_sim/cdat.hpp @@ -0,0 +1,10 @@ +#ifndef __CDAT_H__ +#define __CDAT_H__ + +#include +#include + +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 index 0000000..90886a2 --- /dev/null +++ b/3b_sim/cmem.cpp @@ -0,0 +1,35 @@ +#include "cmem.hpp" + +using namespace std; + +template +void CMem::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 +void CMem::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 index 0000000..195fe6c --- /dev/null +++ b/3b_sim/cmem.hpp @@ -0,0 +1,30 @@ +#ifndef __CMEM_H__ +#define __CMEM_H__ + +#include "cdat.hpp" +#include +#include + +typedef int MEMORY_ADDRESS; + +/** + * Name: CMem + * Purpose: Class representing the memory of our emulated machine + */ +template +class CMem +{ +private: + //MAX_MEMORY-1 zugreifbare Speicherzellen + const int MAX_MEMORY; + std::vector 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 index 0000000..ae5b16b --- /dev/null +++ b/3b_sim/sim.cpp @@ -0,0 +1,168 @@ +#include +#include +#include +#include +#include +#include +#include + +#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(), "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; + + + 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 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(*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; +} -- 2.25.1