From f2070afe27d93c5c94321670cddb5e807932577e Mon Sep 17 00:00:00 2001 From: Tom Haber Date: Sat, 17 May 2008 17:27:02 +0200 Subject: [PATCH] Core calls analyzers --- Core.cpp | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- Core.h | 48 +++++++----------------------- Util.h | 48 +++++++++++++++++++++++++++++- 3 files changed, 152 insertions(+), 44 deletions(-) diff --git a/Core.cpp b/Core.cpp index 8728ee6..6ca0f62 100644 --- a/Core.cpp +++ b/Core.cpp @@ -4,6 +4,8 @@ #include "Instruction.h" #include "Trace.h" #include "Bus.h" +#include "Util.h" +#include "Analyzer.h" #include "DebugInterface.h" namespace avr { @@ -48,16 +50,34 @@ namespace avr { stack.attachReg("spl", regs.getIoreg("SPL")); } - int Core::writeFlash(unsigned int addr, word data) { - //flash.write(addr, (unsigned char *)&data, 2); - throw util::RuntimeException("Writing to flash is not yet supported"); + static void analyzeHelper(const std::list & ans, + void (Analyzer::*method)()) { + MethodCall call(method); + std::for_each( ans.begin(), ans.end(), call); + } + + template + static void analyzeHelper(const std::list & ans, + void (Analyzer::*method)(T), T val) { + MethodCall1 call(method, val); + std::for_each( ans.begin(), ans.end(), call); + } + + template + static void analyzeHelper(const std::list & ans, + void (Analyzer::*method)(T1,T2), + T1 x, T2 y) { + MethodCall2 call(method, x, y); + std::for_each( ans.begin(), ans.end(), call); } byte Core::readRegister(int i) const { if( (unsigned int)i >= registerSpaceSize ) throw util::RuntimeException("Tried to access not existing register"); - return R[i]; + byte val = R[i]; + analyzeHelper( analyzers, &Analyzer::readRegister, i, val ); + return val; } void Core::writeRegister(int i, byte val) { @@ -65,6 +85,66 @@ namespace avr { throw util::RuntimeException("Tried to access not existing register"); R[i] = val; + analyzeHelper( analyzers, &Analyzer::writeRegister, i, val ); + } + + byte Core::readStatus() const { + byte val = readIORegister(SReg); + analyzeHelper( analyzers, &Analyzer::readStatus, val ); + return val; + } + + void Core::writeStatus(byte val) { + writeIORegister(SReg, val); + analyzeHelper( analyzers, &Analyzer::writeStatus, val ); + } + + byte Core::readIORegister(int r) const { + IORegister & reg = regs.getIoreg(r); + + byte val = reg; + analyzeHelper( analyzers, &Analyzer::readIORegister, r, val ); + return val; + } + + void Core::writeIORegister(int r, byte val) { + IORegister & reg = regs.getIoreg(r); + reg = val; + analyzeHelper( analyzers, &Analyzer::writeIORegister, r, val ); + } + + byte Core::readByte(unsigned int addr) const { + byte val = mmu.readByte(addr); + analyzeHelper( analyzers, &Analyzer::readByte, addr, val ); + return val; + } + + void Core::writeByte(unsigned int addr, byte val) { + mmu.writeByte(addr, val); + analyzeHelper( analyzers, &Analyzer::writeByte, addr, val ); + } + + byte Core::readFlash(unsigned int addr) const { + byte val = flash.readByte(addr); + analyzeHelper( analyzers, &Analyzer::readFlash, addr, val ); + return val; + } + + int Core::writeFlash(unsigned int addr, word data) { + //flash.write(addr, (unsigned char *)&data, 2); + //analyzeHelper( analyzers, &Analyzer::writeFlash, addr, val ); + throw util::RuntimeException("Writing to flash is not yet supported"); + } + + void Core::push(byte val) { + stack.push(val); + analyzeHelper( analyzers, &Analyzer::push, val ); + } + + byte Core::pop() { + byte val = stack.pop(); + analyzeHelper( analyzers, &Analyzer::push, val ); + return val; } void Core::jump(sbyte offset, bool push /*= false*/) { @@ -77,6 +157,7 @@ namespace avr { } PC += offset; + analyzeHelper( analyzers, &Analyzer::jump, offset, push ); } void Core::call(dword addr, bool push /*= true*/) { @@ -89,6 +170,7 @@ namespace avr { } PC = addr; + analyzeHelper( analyzers, &Analyzer::call, addr, push ); } void Core::ret(bool interrupt /*= false*/) { @@ -99,12 +181,14 @@ namespace avr { } PC = val - 1; + analyzeHelper( analyzers, &Analyzer::ret, interrupt ); } word Core::fetchOperand() { PC++; unsigned int addr = PC<<1; word op = flash.readWord( addr ); + analyzeHelper( analyzers, &Analyzer::fetchOperand, op ); return op; } @@ -116,6 +200,7 @@ namespace avr { skip = 2; PC += skip; + analyzeHelper( analyzers, &Analyzer::skip ); return skip; } @@ -126,6 +211,7 @@ namespace avr { regs.reset(); bus.reset(); + analyzeHelper( analyzers, &Analyzer::reset, type ); } void Core::sleep() { @@ -138,6 +224,8 @@ namespace avr { // TODO The bit locations for the sleep mode are different between devices... throw util::ImplementationException("Instruction SLEEP not fully implemented"); } + + analyzeHelper( analyzers, &Analyzer::sleep, (unsigned int)sleepMode ); } bool Core::interrupt(unsigned int vector, unsigned int addr) { @@ -158,13 +246,14 @@ namespace avr { call( offset + addr, true ); S &= (unsigned char)~Ibit; + analyzeHelper( analyzers, &Analyzer::interrupt, vector, addr ); return true; } bool Core::step() { + unsigned int addr = PC<<1; if( cpuCycles <= 0 ) { try { - unsigned int addr = PC<<1; if( (dbgi == 0) || ! dbgi->checkBreak(addr) ) { // Fetch instruction word opcode = flash.readWord( addr ); @@ -185,6 +274,7 @@ namespace avr { cpuCycles--; } + analyzeHelper( analyzers, &Analyzer::step, addr, bus.ticks() ); return (cpuCycles == 0); } } diff --git a/Core.h b/Core.h index c614cdf..64faa89 100644 --- a/Core.h +++ b/Core.h @@ -10,10 +10,17 @@ #include "Stack.h" #include "Decoder.h" +#include + +/* + * TODO move all the memory related parts to MMU to reduce the interface size + */ + namespace avr { class ERam; class Bus; + class Analyzer; class DebugInterface; class Core { @@ -103,6 +110,9 @@ namespace avr { } sleepMode; private: + std::list analyzers; + + private: DebugInterface *dbgi; int cpuCycles; @@ -125,44 +135,6 @@ namespace avr { return regs.getIoreg(name); } - inline byte Core::readStatus() const { - return readIORegister(SReg); - } - - inline void Core::writeStatus(byte val) { - writeIORegister(SReg, val); - } - - inline byte Core::readIORegister(int r) const { - IORegister & reg = regs.getIoreg(r); - return reg; - } - - inline void Core::writeIORegister(int r, byte val) { - IORegister & reg = regs.getIoreg(r); - reg = val; - } - - inline byte Core::readByte(unsigned int addr) const { - return mmu.readByte(addr); - } - - inline void Core::writeByte(unsigned int addr, byte val) { - mmu.writeByte(addr, val); - } - - inline byte Core::readFlash(unsigned int addr) const { - return flash.readByte(addr); - } - - inline void Core::push(byte val) { - stack.push(val); - } - - inline byte Core::pop() { - return stack.pop(); - } - } #endif /*AVR_CORE_H*/ diff --git a/Util.h b/Util.h index 7ed4b47..5da5ee4 100644 --- a/Util.h +++ b/Util.h @@ -90,7 +90,53 @@ namespace { private: Method method; - }; + }; + + template + class MethodCall1 { + public: + typedef void (Class::*Method)(T); + + public: + MethodCall1(Method _method, T _x) { + method = _method; + x = _x; + }; + + public: + void operator()(Class *c) { + if( c != 0 ) + (c->*method)(x); + } + + private: + Method method; + T x; + }; + + template + class MethodCall2 { + public: + typedef void (Class::*Method)(T1,T2); + + public: + MethodCall2(Method _method, T1 _x, T2 _y) { + method = _method; + x = _x; + y = _y; + }; + + public: + void operator()(Class *c) { + if( c != 0 ) + (c->*method)(x, y); + } + + private: + Method method; + T1 x; + T2 y; + }; } -- 2.11.4.GIT