disasm/sim: changed interface, branch => br, features++
authorMartin Perner <martin@perner.cc>
Sat, 30 Oct 2010 12:01:34 +0000 (14:01 +0200)
committerMartin Perner <martin@perner.cc>
Sun, 31 Oct 2010 12:38:22 +0000 (13:38 +0100)
29 files changed:
2_isa/misc.ptex
3b_sim/CInstrFactory.cpp [new symlink]
3b_sim/CInstrFactory.hpp [new symlink]
3b_sim/Iinstr.hpp [new symlink]
3b_sim/ccpu.cpp
3b_sim/ccpu.hpp
3b_sim/cdat.hpp
3b_sim/cmem.cpp
3b_sim/cmem.hpp
3b_sim/cpmem.cpp [new file with mode: 0644]
3b_sim/cpmem.hpp [new file with mode: 0644]
3b_sim/disasm.cpp [new symlink]
3b_sim/disasm.h [new symlink]
3b_sim/instr [new symlink]
3b_sim/sim.cpp
3b_sim/uint32_from_hex.hpp [new symlink]
3c_disasm/CInstrFactory.cpp
3c_disasm/CInstrFactory.hpp
3c_disasm/Iinstr.hpp
3c_disasm/dasm.cpp
3c_disasm/disasm.cpp
3c_disasm/disasm.h
3c_disasm/instr/add.cpp
3c_disasm/instr/addi.cpp
3c_disasm/instr/branch.cpp
3c_disasm/instr/ldi.cpp
3c_disasm/instr/ldw.cpp
3c_disasm/instr/subi.cpp
3c_disasm/uint32_from_hex.hpp [new file with mode: 0644]

index 9ba12d87ea12d81251aa588a23537f952b98f0b1..9a1d553172eeecb23f9dabe8a02d45178aa398d9 100644 (file)
@@ -1,7 +1,7 @@
 ins ('32', 'jumpop', 'Branch/ret operation', '4 | 5 | 16 | 3 | 2 | 1 | 1',
 'Conditions | OpCode (10110) | Immediate | - | Type | +/- | S',
 'This instruction should be used with it\'s aliases branch, call, ret and reti. No flags will be affected by this instructions.','','',
-'branch-Branch relative-4/00|call-Branch relative and save pc to stack-4/01|ret-Return to adress on stack-4/10|ret-Return from interrupt to adress on stack-4/11');
+'br-Branch relative-4/00|call-Branch relative and save pc to stack-4/01|ret-Return to adress on stack-4/10|ret-Return from interrupt to adress on stack-4/11');
 
 ins ('32', 'branchreg', 'Branch; jump to value of reg', '4 | 5 | 4 | 16 | 1 | 1 | 1',
 'Conditions | OpCode (10111) | Register A | - | Type | +/- | -',
diff --git a/3b_sim/CInstrFactory.cpp b/3b_sim/CInstrFactory.cpp
new file mode 120000 (symlink)
index 0000000..6a2330e
--- /dev/null
@@ -0,0 +1 @@
+../3c_disasm/CInstrFactory.cpp
\ No newline at end of file
diff --git a/3b_sim/CInstrFactory.hpp b/3b_sim/CInstrFactory.hpp
new file mode 120000 (symlink)
index 0000000..016e9b2
--- /dev/null
@@ -0,0 +1 @@
+../3c_disasm/CInstrFactory.hpp
\ No newline at end of file
diff --git a/3b_sim/Iinstr.hpp b/3b_sim/Iinstr.hpp
new file mode 120000 (symlink)
index 0000000..c150d4e
--- /dev/null
@@ -0,0 +1 @@
+../3c_disasm/Iinstr.hpp
\ No newline at end of file
index 3ad97fb8bf7873ed55c6c530bb57dd4a88ab5677..3fee8752cf020539e12e78d511771c8ff6f9fc73 100644 (file)
 
 void CCpu::tick()
 {
+       // signal extensions
+       // Todo
+
        m_pc = m_pc_next;
        m_pc_next += 4;
+       Iinstr* instr = this->getProg(m_pc);
+       if(instr == NULL) {
+               throw string("Out of Instructions!");
+       }
+       if(this->conditionMet(instr->getCondition())) {
+               instr->execInstr();
+       }
+}
+
+bool CCpu::conditionMet(short cond)
+{
+       switch(cond) {
+               case NOT_EQUAL:
+                       return !this->m_Z;
+                       break;
+               case EQUAL:
+                       return this->m_Z;
+                       break;
+               case NOT_OVERFLOW:
+                       return !this->m_O;
+                       break;
+               case OVER_FLOW:
+                       return this->m_O;
+                       break;
+               case NOT_CARRY:
+                       return !this->m_C;
+                       break;
+               case CARRY:
+                       return this->m_C;
+                       break;
+               case NOT_SIGNED:
+                       return !this->m_S;
+                       break;
+               case SIGNED:
+                       return this->m_S;
+                       break;
+               case ABOVE:
+                       return (!this->m_C && !this->m_Z);
+                       break;
+               case BELOW_EQ:
+                       return (this->m_C || this->m_Z);
+                       break;
+               case GREATER_EQ:
+                       return (this->m_S == this->m_O);
+                       break;
+               case LESS:
+                       return (this->m_S != this->m_O);
+                       break;
+               case GREATER:
+                       return (!this->m_Z && (this->m_S == this->m_O));
+                       break;
+               case LESS_EQ:
+                       return (!this->m_Z || (this->m_S != this->m_O));
+                       break;
+               case ALWAYS:
+                       return true;
+                       break;
+               case NEVER:
+                       return false;
+                       break;
+               default:
+                       cerr << "What did you do? more than 16 values in 5 bits?!" << endl;
+                       return false;
+       }
+
+}
+
+CDat CCpu::getCurPC() const
+{
+       return m_pc;
 }
 
-CDat CCpu::getNextPC() const
+void CCpu::setNextPC(CDat val)
 {
-       return m_pc_next;
+       m_pc_next = val;
 }
 
+void CCpu::updateFlags(CDat val) {
+       this->m_Z = (val == 0);
+       this->m_S = ((val >> (BIT_LEN-1)) & 0x1);
+       this->m_C = false;
+       this->m_O = false;
+}
+
+void CCpu::updateFlags(bool z, bool o, bool c, bool s)
+{
+       this->m_Z = z;
+       this->m_O = o;
+       this->m_C = c;
+       this->m_S = s;
+}
+
+CDat CCpu::getRegister(const int addr) const
+{
+       return m_reg.get(addr);
+}
 
-//             CDat getRegister(const short) const {};
-//             void setRegister(const short, CDat&) {};
+void CCpu::setRegister(const int addr, CDat data)
+{
+       m_reg.set(addr, data);
+}
 
-//             CDat getRAM(const short) const {};
-//             void setRAM(const short, CDat&) {};
+CDat CCpu::getRAM(const int addr) const
+{
+       return m_ram.get(addr);
+}
+void CCpu::setRAM(const int addr, CDat data)
+{
+       m_ram.set(addr, data);
+}
 
 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)
+Iinstr* CCpu::getProg(const int addr) const
+{
+       return m_prog.get(addr);
+}
+
+int CCpu::getStack() const
+{
+       return this->m_stack;
+}
+
+void CCpu::setStack(const int val)
+{
+       this->m_stack = val;
+}
+
+CCpu::CCpu(int regs, int ram, int prog) : m_Z(false), m_S(false), m_C(false), m_O(false), m_pc(0), m_pc_next(0), m_reg(regs), m_ram(ram), m_prog(prog), m_stack(0)
 {
 }
 
index 89867efc9c8f13345622bc9dc7cb65fe102cec8f..e428f630dd637dcf0e5cdbcb5c53af1ed0140316 100644 (file)
@@ -1,36 +1,51 @@
-
-
 #ifndef __CPU__H__
 #define __CPU__H__
 
 #include "cdat.hpp"
 #include "cmem.hpp"
 #include "cpmem.hpp"
+
+class Iinstr;
+
 #include "Iinstr.hpp"
 
+
 class CCpu {
        private:
 
+               bool m_Z, m_S, m_C, m_O;
+
                CDat m_pc, m_pc_next;
-               CMem<CDat> m_regfile, m_ram;
+               CMem<CDat> m_reg, m_ram;
                CPMem<Iinstr*> m_prog;
 
+               CDat m_stack;
+
        public:
                void registerExtension() {};
                void tick();
 
                CDat getRegister(const int) const;
-               void setRegister(const int, CDat&);
+               void setRegister(const int, CDat);
 
                CDat getRAM(const int) const;
-               void setRAM(const int, CDat&);
+               void setRAM(const int, CDat);
 
                Iinstr* getProg(const int) const;
                void setProg(const int, Iinstr*);
 
-               CDat getNextPC() const;
+               CDat getCurPC() const;
+               void setNextPC(CDat);
+
+               void updateFlags(CDat);
+               void updateFlags(bool z, bool o, bool c, bool s);
+
+               bool conditionMet(short);
+
+               int getStack() const;
+               void setStack(const int);
 
-               CCpu();
+               CCpu(int,int,int);
 
 };
 
index e318affdae42e6e56a0d19126009224c28093f17..e9f88f6f93156657238620d78c951d4a469f56c8 100644 (file)
@@ -6,5 +6,7 @@
 
 typedef int CDat;
 
-static_assert(sizeof(CDat) == 4, "The size of the datatype for int is NOT 4 bytes (32 Bit!)");
+#define BIT_LEN 32
+
+//static_assert(sizeof(CDat) == 4, "The size of the datatype for int is NOT 4 bytes (32 Bit!)");
 #endif
index 90886a23eb4e1fdc929f51f42d0af7b87925ec84..22c80e6722b2b5f0340bd290133d96c5b57540af 100644 (file)
@@ -2,7 +2,7 @@
 
 using namespace std;
 
-template <class T>
+template <typename T>
 void CMem<T>::set(const MEMORY_ADDRESS address, const T& data)
 {
        if(address >= MAX_MEMORY) {
@@ -23,13 +23,16 @@ void CMem<T>::set(const MEMORY_ADDRESS address, const T& data)
        m_memory.erase(iter);
 }
 
-template <class T>
-void CMem<T>::get(const MEMORY_ADDRESS address, T& value) const
+template <typename T>
+T CMem<T>::get(const MEMORY_ADDRESS address) const
 {
        if(address >= MAX_MEMORY) {
                stringstream error;
                error << "memoryaddress " << address << " out of range";
                throw out_of_range(error.str());
        }
-       value = m_memory[address];
+       return m_memory[address];
 }
+
+
+template class CMem<int>;
index 195fe6c1077cbda3e6e6dca735d233cab393d397..d5cd593704290ae31f1dae36e44fd614eb17a8ff 100644 (file)
@@ -5,13 +5,15 @@
 #include <vector>
 #include <stdexcept>
 
+
 typedef int MEMORY_ADDRESS;
 
+
 /**
  * Name:    CMem
  * Purpose: Class representing the memory of our emulated machine
  */
-template <class T>
+template <typename T>
 class CMem
 {
 private:
@@ -19,11 +21,8 @@ private:
        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;
+       T get(const MEMORY_ADDRESS address) const;
        CMem(int size) : MAX_MEMORY(size), m_memory(size) {};
 };
 
diff --git a/3b_sim/cpmem.cpp b/3b_sim/cpmem.cpp
new file mode 100644 (file)
index 0000000..31205e6
--- /dev/null
@@ -0,0 +1,53 @@
+
+//i'm sorry
+//pervert forwarding
+//didn't know (or was to lazy) to find another fix
+#define __CPU__H__
+class CCpu;
+
+#include "cpmem.hpp"
+
+using namespace std;
+
+template <typename T>
+void CPMem<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 <typename T>
+T CPMem<T>::get(const MEMORY_ADDRESS address) const
+{
+       if(address >= MAX_MEMORY) {
+               stringstream error;
+               error << "memoryaddress " << address << " out of range";
+               throw out_of_range(error.str());
+       }
+       return m_memory[address];
+}
+
+template <typename T>
+CPMem<T>::~CPMem()
+{
+       for(auto iter = m_memory.begin(); iter != m_memory.end(); ++iter) {
+               delete (*iter);
+       }
+}
+
+
+template class CPMem<Iinstr*>;
diff --git a/3b_sim/cpmem.hpp b/3b_sim/cpmem.hpp
new file mode 100644 (file)
index 0000000..fd09f3c
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef __CPMEM_H__
+#define __CPMEM_H__
+
+template <typename T>
+class CPMem;
+
+#include "cdat.hpp"
+#include <vector>
+#include <stdexcept>
+#include <stdlib.h>
+
+#include "Iinstr.hpp"
+
+typedef int MEMORY_ADDRESS;
+
+/**
+ * Name:    CMem
+ * Purpose: Class representing the memory of our emulated machine
+ */
+template <typename T>
+class CPMem
+{
+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
+       T get(const MEMORY_ADDRESS address) const;
+       CPMem(int size) : MAX_MEMORY(size), m_memory(size, NULL) {};
+       ~CPMem();
+};
+
+#endif
diff --git a/3b_sim/disasm.cpp b/3b_sim/disasm.cpp
new file mode 120000 (symlink)
index 0000000..4aeda7f
--- /dev/null
@@ -0,0 +1 @@
+../3c_disasm/disasm.cpp
\ No newline at end of file
diff --git a/3b_sim/disasm.h b/3b_sim/disasm.h
new file mode 120000 (symlink)
index 0000000..d38dcdb
--- /dev/null
@@ -0,0 +1 @@
+../3c_disasm/disasm.h
\ No newline at end of file
diff --git a/3b_sim/instr b/3b_sim/instr
new file mode 120000 (symlink)
index 0000000..b58fe4c
--- /dev/null
@@ -0,0 +1 @@
+../3c_disasm/instr
\ No newline at end of file
index ae5b16bfc781818a9dc2eee0c2aa03ec3e589526..9d2fb5a00d259c23ce42cd930958fdb166f2e9c4 100644 (file)
@@ -9,6 +9,9 @@
 #include "disasm.h"
 #include "ccpu.hpp"
 #include "CInstrFactory.hpp"
+#include "uint32_from_hex.hpp"
+
+CCpu* Iinstr::m_cpu;
 
 using boost::lexical_cast;
 using boost::bad_lexical_cast;
@@ -82,7 +85,9 @@ int main(int argc, char* argv[])
        }
 
 
-       CCpu cpu;
+       CCpu cpu(16,1000,1000);
+
+       Iinstr::setCPU(&cpu);
 
 
        std::string str = "";
@@ -108,61 +113,98 @@ int main(int argc, char* argv[])
                                cout << endl;
                        }
                        switch(type) {
-                               case 2:
+                               case 0:
                                        if(count == 1) {
-                                               cout << "; ";
+                                               try {
+                                                       addr = lexical_cast<uint32_from_hex>(*tok_iter);
+                                               }
+                                               catch(bad_lexical_cast& e) {
+                                                       cerr << e.what() << endl;
+                                                       exit(EXIT_FAILURE);
+                                               }
                                        }
-                                       cout << *tok_iter;
-                                       break;
-                               case 3:
-                                       if((*tok_iter).size() > 0) {
-                                               if(count > 1) {
-                                                       cout << endl;
+                                       else if(count == 2) {
+                                               try {
+                                                       CDat data = lexical_cast<uint32_from_hex>(*tok_iter);
+                                                       cpu.setRAM(addr, data);
+                                               }
+                                               catch(bad_lexical_cast& e) {
+                                                       cerr << e.what() << endl;
+                                                       exit(EXIT_FAILURE);
                                                }
-                                               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;
+                                               try {
+                                                       addr = lexical_cast<uint32_from_hex>(*tok_iter);
                                                }
-                                               cout << out.str();
-                                       }
-                                       else if(count == 5) {
-                                               if((*tok_iter).size() > 0) {
-                                                       cout << " ;";
+                                               catch(bad_lexical_cast& e) {
+                                                       cerr << e.what() << endl;
+                                                       exit(EXIT_FAILURE);
                                                }
                                        }
-
-                                       if(count >= 5) {
-                                               cout << *tok_iter;
+                                       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++;
                }
-               if(type == 1 && count <= 4) {
-                       cout << out.str();
-               }
-               cout << endl;
        }
        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);
+
+       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;
 }
diff --git a/3b_sim/uint32_from_hex.hpp b/3b_sim/uint32_from_hex.hpp
new file mode 120000 (symlink)
index 0000000..7f140c3
--- /dev/null
@@ -0,0 +1 @@
+../3c_disasm/uint32_from_hex.hpp
\ No newline at end of file
index b3aed2787217b2d4b4ac6a647982104fdafc4644..56c37fd214bc6707a137be4c33af9d4e3ac4d060 100644 (file)
@@ -116,6 +116,23 @@ size_t CInstrFactory::getNumFiles()
        return m_files.size();
 }
 
+void CInstrFactory::loadLibsIntoMap(map<short, Iinstr*>& instr, string dir)
+{
+#ifdef DEBUG
+               cout << "Loaded " << this->searchLibsInDir(dir) << " Libraryfiles" << endl;
+#else
+               this->searchLibsInDir(dir);
+#endif
+               while(this->getNumFiles() >= 1) {
+                       Iinstr* pinstr = this->getNextInstr();
+                       instr.insert(make_pair(pinstr->getOpcode(),pinstr));
+#ifdef DEBUG
+                       cout << "found: " << pinstr->getName() << " its opcode is : " << pinstr->getOpcode() << endl;
+#endif
+               }
+}
+
+
 /**
  * Name:    ~CInstrFactory
  * Purpose: Destructor of the Object
index 7a1c342540f2dbb89dfe0e87afe5b99fbebd14ff..55fc449560f0d635e2abf400f9fcb2bd4ced686d 100644 (file)
@@ -38,6 +38,7 @@ public:
        Iinstr* getNextInstr();
        size_t getNumFiles();
        size_t searchLibsInDir(std::string dir);
+       void loadLibsIntoMap(map<short, Iinstr*>& instr, string dir);
        CInstrFactory() : m_libStore(), m_files() {};
        ~CInstrFactory();
 };
index d590dc70720c2a52dbdb5b41a52580b6414731e9..416db47a869cb6041163165d5e96d968b6477e78 100644 (file)
@@ -1,10 +1,15 @@
+#ifndef __IINSTR_I_
+#define __IINSTR_I_
+
 #include <string>
 #include <boost/dynamic_bitset.hpp>
 #include <iostream>
 #include <sstream>
 
-#ifndef __IINSTR_I_
-#define __IINSTR_I_
+class CCpu;
+
+#include "ccpu.hpp"
+
 
 /* concept from https://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f */
 #define to_HEX__(x) 0x##x##LU
@@ -16,6 +21,7 @@
                   +((x & 0xF0000UL) ? 16 : 0) 
 
 #define B5(x) ((unsigned char)to_B5__(to_HEX__(x)))
+/* end concept */
 
 using namespace std;
 using namespace boost;
@@ -107,7 +113,12 @@ class Iinstr {
                        return bits.to_ulong();
                }
 
+               static CCpu* m_cpu;
+
        public:
+
+               static void setCPU(CCpu* cpu) { m_cpu = cpu; }
+
                virtual ~Iinstr() {}
                virtual short getOpcode() { return this->opcode; }
                virtual std::string getName() { return this->name; }
@@ -115,6 +126,11 @@ class Iinstr {
                virtual void evalInstr() = 0;
                virtual void execInstr() = 0;
                virtual std::string toString() = 0;
+               virtual Iinstr* getNew() = 0;
+                       
+               short getCondition() {
+                       return m_cond;
+               }
 
                void decodeCondition(short condition) {
                        if(condition >= 0 && condition <= 15) {
@@ -126,6 +142,7 @@ class Iinstr {
                }
 
        protected:
+
                std::string getConditionFlag()
                {
                        stringstream cond;
@@ -185,4 +202,5 @@ class Iinstr {
                        return cond.str();
                }
 };
+
 #endif
index 08796f1509558df10aea8eae1c4f11b6e56c8e2a..177da6e6d7d3c40a44a704c03d1866cf212e25a0 100644 (file)
@@ -69,18 +69,7 @@ int main(int argc, char* argv[])
 
        CInstrFactory instrFab;
        try {
-#ifdef DEBUG
-               cout << "Loaded " << instrFab.searchLibsInDir(dir) << " Libraryfiles" << endl;
-#else
-               instrFab.searchLibsInDir(dir);
-#endif
-               while(instrFab.getNumFiles() >= 1) {
-                       Iinstr* pinstr = instrFab.getNextInstr();
-                       instr.insert(make_pair(pinstr->getOpcode(),pinstr));
-#ifdef DEBUG
-                       cout << "found: " << instr->getName() << " its opcode is : " << instr->getOpcode() << endl;
-#endif
-               }
+               instrFab.loadLibsIntoMap(instr, dir);
        }
        catch(std::bad_alloc& e) {
                cerr << progName << ": bad_alloc caught " << e.what() << endl;
@@ -131,7 +120,7 @@ int main(int argc, char* argv[])
                                                out << "[0x" << *tok_iter << "]: ";
                                        }
                                        else if(count == 2) {
-                                               out << disasm.decode(*tok_iter);
+                                               out << disasm.decodeToString(*tok_iter);
                                        }
                                        else if(count == 3) {
                                                //code saved in hex-file
index b389d0361a501c5418b77ccbc7eefd5681876783..0c6c5f09119e6dde572aa5e20ec2cf3f831b3f73 100644 (file)
@@ -4,7 +4,7 @@
 
 using namespace boost;
 
-std::string disasm::decode(std::string str)
+Iinstr* disasm::decode(std::string str)
 {
        /* we need 0x prefix */
        string hex = "0x";
@@ -30,19 +30,25 @@ std::string disasm::decode(std::string str)
                instr->decodeCondition(condition.to_ulong());
                instr->loadBits(args);
                instr->evalInstr();
-               return instr->toString();
+               return instr;
        }
        catch(std::string &e) {
                cerr << " Error: " << e << endl;
        }
-       return "";
+       return NULL;
+}
+
+std::string disasm::decodeToString(std::string str)
+{
+       return this->decode(str)->toString();
 }
 
 Iinstr* disasm::decodeOpcode(short opcode)
 {
        auto iter = instrs.find(opcode);
        if(iter != instrs.end()) {
-               return iter->second;
+               Iinstr* p = (iter->second)->getNew();
+               return p;
        }
        else {
                stringstream err;
index 908a3ee3936d00a42357f3ba6ab17079410cf10d..078bd17ba3806f0d3f5c45d97a26b271fcd0efb8 100644 (file)
@@ -2,6 +2,7 @@
 #include <string>
 #include <map>
 
+#include "uint32_from_hex.hpp"
 #include "Iinstr.hpp"
 
 using namespace std;
@@ -10,27 +11,13 @@ class disasm {
 
        private:
                std::map<short,Iinstr*> instrs;
-       class uint32_from_hex   // For use with boost::lexical_cast
-       {
-               typedef unsigned int uint32;
-               uint32 value;
-               public:
-                       operator uint32() const {
-                               return value;
-                       }
-                       friend std::istream& operator>>(std::istream& in, uint32_from_hex& outValue)
-                       {
-                               in >> std::hex >> outValue.value;
-                               return in;
-                       }
-       };
-
        protected:
                void decodeCondition(short);
                Iinstr* decodeOpcode(short);
 
        public:
                disasm(std::map<short,Iinstr*> map) : instrs(map) {};
-               std::string decode(std::string);
+               Iinstr* decode(std::string);
+               std::string decodeToString(std::string str);
 };
 
index 7cdf820def5d026441eb02ca3a19d29d3fd7780b..f196794d3d45a82e50ff298d25d83a9100e94ccd 100644 (file)
@@ -6,6 +6,7 @@ class Cadd : public Iinstr {
                void evalInstr();
                void execInstr();
                std::string toString();
+               Iinstr* getNew();
 };
 
 /**
@@ -19,6 +20,10 @@ extern "C" Iinstr* create_instruction() {
     return new Cadd();
 }
 
+Iinstr* Cadd::getNew() {
+       return new Cadd();
+}
+
 /**
  * Name:      destroy_instruction
  * Purpose:   if compiled as shared library, this functions destoys the 
@@ -53,7 +58,10 @@ void Cadd::evalInstr()
 
 void Cadd::execInstr()
 {
-       cout << "should exec" << this->toString() << endl;
+       cout << "should exec " << this->toString() << endl;
+       CDat val = this->m_cpu->getRegister(m_ra) + this->m_cpu->getRegister(m_rb);
+       this->m_cpu->setRegister(m_rd, val);
+       this->m_cpu->updateFlags(val);
 }
 
 std::string Cadd::toString()
index 2ccdc0469658d62ccff7ea145f936716b4e8f587..bb10a08af3f47476786339779967533f7eb5df41 100644 (file)
@@ -6,6 +6,7 @@ class Caddi : public Iinstr {
                void evalInstr();
                void execInstr();
                std::string toString();
+               Iinstr* getNew();
 };
 
 /**
@@ -19,6 +20,11 @@ extern "C" Iinstr* create_instruction() {
     return new Caddi();
 }
 
+Iinstr* Caddi::getNew() {
+       return new Caddi();
+}
+
+
 /**
  * Name:      destroy_instruction
  * Purpose:   if compiled as shared library, this functions destoys the 
@@ -57,6 +63,9 @@ void Caddi::evalInstr()
 void Caddi::execInstr()
 {
        cout << "should exec " << this->toString() << endl;
+       CDat reg = this->m_cpu->getRegister(m_ra) + this->m_imm;
+       this->m_cpu->setRegister(m_rd, reg);
+       this->m_cpu->updateFlags(reg);
 }
 
 std::string Caddi::toString()
index 37682d7ed816ec78e316797d1eed407801363258..90a56cbce8258d2a882f1ade81f48015784fdeb4 100644 (file)
@@ -9,6 +9,7 @@ class Cbranch : public Iinstr {
                void evalInstr();
                void execInstr();
                std::string toString();
+               Iinstr* getNew();
 };
 
 /**
@@ -22,6 +23,10 @@ extern "C" Iinstr* create_instruction() {
     return new Cbranch();
 }
 
+Iinstr* Cbranch::getNew()
+{
+       return new Cbranch();
+}
 /**
  * Name:      destroy_instruction
  * Purpose:   if compiled as shared library, this functions destoys the 
@@ -50,9 +55,9 @@ void Cbranch::evalInstr()
        type.resize(2);
        this->m_typ = type.to_ulong();
 
-       switch(m_typ) {
+       switch(this->m_typ) {
                case 0:
-                       this->name = "branch";
+                       this->name = "br";
                        break;
                case 1:
                        this->name = "call";
@@ -77,7 +82,28 @@ void Cbranch::evalInstr()
 
 void Cbranch::execInstr()
 {
-       cout << "should exec" << this->toString() << endl;
+       cout << "should exec " << this->toString() << endl;
+       CDat pc = this->m_cpu->getCurPC();
+       switch(this->m_typ) {
+               case 1:
+                       {
+                       CDat sp = this->m_cpu->getStack();
+                       this->m_cpu->setRAM(sp, pc);
+                       sp -= 4;
+                       this->m_cpu->setStack(sp);
+                       }
+               case 0:
+                       this->m_cpu->setNextPC(pc+this->m_imm);
+                       break;
+               case 2:
+               case 3:
+                       this->m_cpu->setNextPC(this->m_cpu->getRAM(this->m_cpu->getStack()));
+                       this->m_cpu->setStack(this->m_cpu->getStack()+4);
+                       break;
+               default:
+                       // nothing
+                       this->m_cpu->setNextPC(400);
+       }
 }
 
 std::string Cbranch::toString()
index 2c523a1f254afdfb77a35edd7d74ce5a0eb9b606..98e72cae80a54ac0f54d5a9a94bb06b80abea34f 100644 (file)
@@ -7,6 +7,7 @@ class Cldi : public Iinstr {
                void evalInstr();
                void execInstr();
                std::string toString();
+               Iinstr* getNew();
 };
 
 /**
@@ -20,6 +21,10 @@ extern "C" Iinstr* create_instruction() {
     return new Cldi();
 }
 
+Iinstr* Cldi::getNew()
+{
+    return new Cldi();
+}
 /**
  * Name:      destroy_instruction
  * Purpose:   if compiled as shared library, this functions destoys the 
@@ -54,6 +59,7 @@ void Cldi::evalInstr()
 void Cldi::execInstr()
 {
        cout << "should exec " << this->toString() << endl;
+       this->m_cpu->setRegister(this->m_rd, this->m_imm);
 }
 
 std::string Cldi::toString()
index b77450c30e7b2cb055189168c571b18beb245797..354e23fa28dc24c30d6e34d9099a35534140e44f 100644 (file)
@@ -7,6 +7,7 @@ class Cldw : public Iinstr {
                void evalInstr();
                void execInstr();
                std::string toString();
+               Iinstr* getNew();
 };
 
 /**
@@ -20,6 +21,11 @@ extern "C" Iinstr* create_instruction() {
     return new Cldw();
 }
 
+Iinstr* Cldw::getNew()
+{
+    return new Cldw();
+}
+
 /**
  * Name:      destroy_instruction
  * Purpose:   if compiled as shared library, this functions destoys the 
@@ -55,6 +61,10 @@ void Cldw::evalInstr()
 void Cldw::execInstr()
 {
        cout << "should exec " << this->toString() << endl;
+       CDat val = this->m_cpu->getRegister(this->m_ra);
+       val += m_imm;
+       val = this->m_cpu->getRAM(val);
+       this->m_cpu->setRegister(this->m_rd,val);
 }
 
 std::string Cldw::toString()
index a988f814d9fb69933b0ea4b535686be349f4ebb8..8a90ae825f308b1ebf907ea60a9f40ba9743a028 100644 (file)
@@ -6,6 +6,7 @@ class Csubi : public Iinstr {
                void evalInstr();
                void execInstr();
                std::string toString();
+               Iinstr* getNew();
 };
 
 /**
@@ -19,6 +20,10 @@ extern "C" Iinstr* create_instruction() {
     return new Csubi();
 }
 
+Iinstr* Csubi::getNew() {
+       return new Csubi();
+}
+
 /**
  * Name:      destroy_instruction
  * Purpose:   if compiled as shared library, this functions destoys the 
@@ -57,6 +62,9 @@ void Csubi::evalInstr()
 void Csubi::execInstr()
 {
        cout << "should exec " << this->toString() << endl;
+       CDat reg = this->m_cpu->getRegister(m_ra) - this->m_imm;
+       this->m_cpu->setRegister(m_rd, reg);
+       this->m_cpu->updateFlags(reg);
 }
 
 std::string Csubi::toString()
diff --git a/3c_disasm/uint32_from_hex.hpp b/3c_disasm/uint32_from_hex.hpp
new file mode 100644 (file)
index 0000000..cea3537
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef __UINT32_FROM_HEX_H__
+#define __UINT32_FROM_HEX_H__
+
+class uint32_from_hex   // For use with boost::lexical_cast
+{
+       typedef unsigned int uint32;
+       uint32 value;
+       public:
+               operator uint32() const {
+                       return value;
+               }
+               friend std::istream& operator>>(std::istream& in, uint32_from_hex& outValue)
+               {
+                       in >> std::hex >> outValue.value;
+                       return in;
+               }
+};
+
+#endif