return boost::regex_replace(instr, e, format, boost::match_default | boost::format_all);
}
+void CCpu::registerExtension(Iext* ext)
+{
+ m_exts.push_back(ext);
+}
void CCpu::tick()
{
m_pc = m_pc_next;
m_pc_next += 4;
Iinstr* instr = this->getProg(m_pc);
+
if(instr == NULL) {
throw string("Out of Instructions!");
}
+
+ for(auto iter = m_exts.begin(); iter != m_exts.end(); ++iter) {
+ (*iter)->applyTick();
+ }
+
if(this->conditionMet(instr->getCondition())) {
cout << color(green,black) << "Executing: " << color(white,black) << colorifyInstr(instr->toString()) << endl;
instr->execInstr();
CDat CCpu::getRAM(const int addr) const
{
- return m_ram.get(addr);
+ if((addr & EXT_MODEL_OFFSET) == 0) {
+ return m_ram.get(addr);
+ }
+ else {
+ CDat result = 0;
+ for(auto iter = m_exts.begin(); iter != m_exts.end(); ++iter) {
+ result = (*iter)->readData(addr);
+ if(result != 0) {
+ break;
+ }
+ }
+ return result;
+ }
}
+
void CCpu::setRAM(const int addr, CDat data)
{
- m_ram.set(addr, data);
+ if((addr & EXT_MODEL_OFFSET) == 0) {
+ m_ram.set(addr, data);
+ }
+ else {
+ for(auto iter = m_exts.begin(); iter != m_exts.end(); ++iter) {
+ (*iter)->loadData(addr, data);
+ }
+ }
}
void CCpu::setProg(int addr, Iinstr* instr)
}
-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_perf(0), m_reg(regs), m_ram(ram), m_prog(prog), m_stack(0)
+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_perf(0), m_reg(regs), m_ram(ram), m_prog(prog), m_exts(0), m_stack(0)
{
}
#include "ccolor.h"
class Iinstr;
+class Iext;
+#include "iext.hpp"
#include <boost/regex.hpp>
#include "Iinstr.hpp"
CMem<CDat> m_reg, m_ram;
CPMem<Iinstr*> m_prog;
+ vector<Iext*> m_exts;
+
CDat m_stack;
+ static const int EXT_MODEL_OFFSET = 0x2000;
+
public:
void registerExtension() {};
void tick();
Iinstr* getProg(const int) const;
void setProg(const int, Iinstr*);
+ void registerExtension(Iext*);
+
CDat getPerf() const;
void setPerf(CDat);
void incPerf();
--- /dev/null
+#include "../iext.hpp"
+
+class Cprog : public Iext {
+ public:
+ Cprog() : m_writeAddress(0) {};
+ void applyTick() {};
+ void loadData(const int address, CDat value);
+ CDat readData(const int) { return 0; }
+ private:
+ int m_writeAddress;
+};
+
+void Cprog::loadData(const int address, CDat value)
+{
+ if(address == 0x2034) {
+ m_writeAddress = value;
+ //adress pointer
+ }
+ else if(address == 0x2038) {
+ this->m_cpu->setProg(m_writeAddress, m_disasm->decodeNum(value));
+ m_writeAddress += 4;
+ //data pointer
+ }
+}
--- /dev/null
+#ifndef __IEXT_I_
+#define __IEXT_I_
+
+class CCpu;
+
+#include "ccpu.hpp"
+
+class disasm;
+
+#include "disasm.h"
+
+
+class Iext {
+ public:
+ static void setCPU(CCpu* cpu) {m_cpu = cpu;}
+ static void setDisasm(disasm* dasm) { m_disasm = dasm; }
+
+ virtual ~Iext() {}
+ //called by cpu before every tick
+ virtual void applyTick() = 0;
+ virtual void loadData(const int address, CDat value) = 0;
+ virtual CDat readData(const int address) = 0;
+ static CCpu* m_cpu;
+ static disasm* m_disasm;
+};
+
+#endif
#include "CInstrFactory.hpp"
#include "uint32_from_hex.hpp"
+#include "iext.hpp"
+#include "extensions/cprog.hpp"
+
#include "SReadline/SReadline.h"
using namespace swift;
void close_prog(const std::vector<std::string> &);
CCpu* Iinstr::m_cpu;
+CCpu* Iext::m_cpu;
disasm* Iinstr::m_disasm;
+disasm* Iext::m_disasm;
CCpu* global_cpu = NULL;
global_cpu = &cpu;
Iinstr::setCPU(&cpu);
+ Iext::setCPU(&cpu);
disasm disasm(instr);
Iinstr::setDisasm(&disasm);
+ Iext::setDisasm(&disasm);
+
+ global_cpu->registerExtension(new Cprog());
vector<string> commentDefer;
vector<string> labelDefer;