--- /dev/null
+#include <string>
+#include <boost/dynamic_bitset.hpp>
+#include <iostream>
+#include <sstream>
+
+#ifndef __IINSTR_I_
+#define __IINSTR_I_
+
+/* concept from https://groups.google.com/group/comp.arch.embedded/msg/9d430b6d3da12c8f */
+#define to_HEX__(x) 0x##x##LU
+
+#define to_B5__(x) ((x & 0x0000FUL) ? 1 : 0) \
+ +((x & 0x000F0UL) ? 2 : 0) \
+ +((x & 0x00F00UL) ? 4 : 0) \
+ +((x & 0x0F000UL) ? 8 : 0) \
+ +((x & 0xF0000UL) ? 16 : 0)
+
+#define B5(x) ((unsigned char)to_B5__(to_HEX__(x)))
+
+using namespace std;
+using namespace boost;
+
+enum CONDITIONS {
+ NOT_EQUAL = 0,
+ EQUAL = 1,
+ NOT_OVERFLOW =2,
+ OVER_FLOW = 3,
+ NOT_CARRY = 4,
+ CARRY = 5,
+ NOT_SIGNED = 6,
+ SIGNED = 7,
+ ABOVE = 8,
+ BELOW_EQ = 9,
+ GREATER_EQ = 10,
+ LESS = 11,
+ GREATER = 12,
+ LESS_EQ = 13,
+ ALWAYS = 14,
+ NEVER = 15
+};
+
+class Iinstr {
+ protected:
+ short opcode;
+ std::string name;
+ short m_ra, m_rb, m_rd;
+ bool m_c, m_d, m_hl, m_f, m_s;
+ int m_imm;
+ short m_cond;
+ boost::dynamic_bitset<> argbits;
+ Iinstr() : opcode(0), name(""), m_ra(0), m_rb(0), m_rd(0), m_c(0), m_d(0), m_hl(0), m_f(0), m_s(0), m_imm(0), m_cond(ALWAYS), argbits(32) {}
+
+ int generate16ImmFill(const int value) {
+ int i = value;
+ if(m_hl == true && m_f == true) {
+ i <<= 16;
+ i |= 0x0000FFFF;
+ }
+ else if(m_hl == true && m_f == false) {
+ i <<= 16;
+ i &= 0xFFFF0000;
+ }
+ else if(m_hl == false && m_f == true) {
+ i |= 0xFFFF0000;
+ }
+ else {
+ i &= 0x0000FFFF;
+ }
+
+ return i;
+ }
+
+ int generate16ImmSign(const int value) {
+ int i = value;
+ if(m_hl == true) {
+ i <<= 16;
+ }
+ else if(m_s == true && (i & 0x8000) != 0) {
+ i |= 0xFFFF0000;
+ }
+
+ return i;
+ }
+
+ int generate12ImmSign(const int value) {
+ int i = value;
+ if(m_s == true && (i & 0x0800) != 0) {
+ i |= 0xFFFFF000;
+ }
+
+ return i;
+ }
+
+ int generate15ImmSign(const int value) {
+ int i = value;
+ if(m_s == true && (i & 0x4000) != 0) {
+ i |= 0xFFFF8000;
+ }
+
+ return i;
+ }
+
+
+
+ int getRegister(boost::dynamic_bitset<> bits) {
+ bits.resize(4);
+ return bits.to_ulong();
+ }
+
+ public:
+ virtual ~Iinstr() {}
+ virtual short getOpcode() { return this->opcode; }
+ virtual std::string getName() { return this->name; }
+ virtual void loadBits(boost::dynamic_bitset<> bits) { argbits = bits; }
+ virtual void evalInstr() = 0;
+ virtual void execInstr() = 0;
+ virtual std::string toString() = 0;
+
+ void decodeCondition(short condition) {
+ if(condition >= 0 && condition <= 15) {
+ m_cond = condition;
+ }
+ else {
+ throw std::string("Invalid Condition!");
+ }
+ }
+
+ protected:
+ std::string getConditionFlag()
+ {
+ stringstream cond;
+ switch(m_cond) {
+ case NOT_EQUAL:
+ cond << "{nq,nz}";
+ break;
+ case EQUAL:
+ cond << "{eq,zs}";
+ break;
+ case NOT_OVERFLOW:
+ cond << "no";
+ break;
+ case OVER_FLOW:
+ cond << "ov";
+ break;
+ case NOT_CARRY:
+ cond << "{nc,ae}";
+ break;
+ case CARRY:
+ cond << "{cs,bl}";
+ break;
+ case NOT_SIGNED:
+ cond << "{ns,nn}";
+ break;
+ case SIGNED:
+ cond << "{ss,ns}";
+ break;
+ case ABOVE:
+ cond << "ab";
+ break;
+ case BELOW_EQ:
+ cond << "be";
+ break;
+ case GREATER_EQ:
+ cond << "ge";
+ break;
+ case LESS:
+ cond << "lt";
+ break;
+ case GREATER:
+ cond << "gt";
+ break;
+ case LESS_EQ:
+ cond << "le";
+ break;
+ case ALWAYS:
+ cond << "";
+ break;
+ case NEVER:
+ cond << "nv";
+ break;
+ default:
+ cerr << "What did you do? more than 16 values in 5 bits?!" << endl;
+ }
+
+ return cond.str();
+ }
+};
+#endif