Support for the three-level hardware stack on devices such as the 90S1200 or the Tiny15l.
Signed-off-by: Onno Kortmann <[email protected]> --- src/at4433.cpp | 2 +- src/at8515.cpp | 2 +- src/atmega128.cpp | 2 +- src/hwstack.cpp | 25 +++++++++++++------------ src/hwstack.h | 26 +++++++++++++++++++++++--- 5 files changed, 39 insertions(+), 18 deletions(-) diff --git a/src/at4433.cpp b/src/at4433.cpp index 25656d0..f1ea1fc 100644 --- a/src/at4433.cpp +++ b/src/at4433.cpp @@ -46,7 +46,7 @@ AvrDevice(64, 128, 0, 4*1024) { irqSystem = new HWIrqSystem(this, 2); eeprom= new HWMegaEeprom(this, irqSystem, 256, 12); //we use a eeprom with irq here - stack = new HWStack(this, Sram, 0x00ff); + stack = new HWStack(this, Sram, 0x0100); portb= new HWPort(this, "B"); portc= new HWPort(this, "C"); diff --git a/src/at8515.cpp b/src/at8515.cpp index b319666..d7cdb9d 100644 --- a/src/at8515.cpp +++ b/src/at8515.cpp @@ -37,7 +37,7 @@ AvrDevice(64, 512, 0xfda0, 8192) { eeprom= new HWEeprom(this, 512); irqSystem = new HWIrqSystem(this, 2); - stack = new HWStack(this, Sram, 0xffff); + stack = new HWStack(this, Sram, 0x10000); porta= new HWPort(this, "A"); portb= new HWPort(this, "B"); diff --git a/src/atmega128.cpp b/src/atmega128.cpp index 0ece665..075bf40 100644 --- a/src/atmega128.cpp +++ b/src/atmega128.cpp @@ -40,7 +40,7 @@ AvrDevice_atmega128::AvrDevice_atmega128(): AvrDevice(224, 4096, 0xef00, 128*1024) { irqSystem = new HWIrqSystem(this, 4); //4 bytes per vector eeprom = new HWMegaEeprom( this, irqSystem, 4096, 22); - stack = new HWStack(this, Sram, 0xffff); + stack = new HWStack(this, Sram, 0x10000); porta= new HWPort(this, "A"); portb= new HWPort(this, "B"); portc= new HWPort(this, "C"); diff --git a/src/hwstack.cpp b/src/hwstack.cpp index d093f1c..911549d 100644 --- a/src/hwstack.cpp +++ b/src/hwstack.cpp @@ -32,10 +32,10 @@ RWSph::operator unsigned char() const { return hwstack->GetSph(); } -HWStack::HWStack(AvrDevice *c, MemoryOffsets *sr, unsigned int mask):Hardware(c), core(c) { - stackMask=mask; - mem=sr; - Reset(); +HWStack::HWStack(AvrDevice *c, MemoryOffsets *sr, unsigned int ceil):Hardware(c), core(c) { + stackCeil=ceil; + mem=sr; + Reset(); } void HWStack::Reset() { @@ -55,22 +55,23 @@ void HWStack::CheckBreakPoints() { void HWStack::Push(unsigned char val){ (*mem)[stackPointer]=val; stackPointer--; - stackPointer&=stackMask; - if (core->trace_on==1) traceOut << "SP=0x" << hex << stackPointer << dec << " " ; - CheckBreakPoints(); + if (stackPointer>0x1000000) + stackPointer=stackCeil-1; + if (core->trace_on==1) traceOut << "SP=0x" << hex << stackPointer << " 0x" << int(val) << dec << " "; + CheckBreakPoints(); } unsigned char HWStack::Pop(){ stackPointer++; - stackPointer&=stackMask; - if (core->trace_on==1) traceOut << "SP=0x" << hex << stackPointer << dec << " " ; - CheckBreakPoints(); + stackPointer%=stackCeil; + if (core->trace_on==1) traceOut << "SP=0x" << hex << stackPointer << " 0x" << int((*mem)[stackPointer]) << dec << " "; + CheckBreakPoints(); return (*mem)[stackPointer]; } void HWStack::SetSpl(unsigned char val) { stackPointer=stackPointer&0xffff00; stackPointer+=val; - stackPointer&=stackMask; + stackPointer%=stackCeil; if (core->trace_on==1) traceOut << "SP=0x" << hex << stackPointer << dec << " " ; CheckBreakPoints(); } @@ -78,7 +79,7 @@ void HWStack::SetSpl(unsigned char val) { void HWStack::SetSph(unsigned char val) { stackPointer=stackPointer&0xff00ff; stackPointer+=(val<<8); - stackPointer&=stackMask; + stackPointer%=stackCeil; if (core->trace_on==1) traceOut << "SP=0x" << hex << stackPointer << dec << " " ; CheckBreakPoints(); } diff --git a/src/hwstack.h b/src/hwstack.h index 9b9b54f..5180b52 100644 --- a/src/hwstack.h +++ b/src/hwstack.h @@ -31,17 +31,37 @@ #include <map> +/*! Implementation of the special three-level deep hardware stack which is + not accessible in any memory space on the devices which have this, for + example the ATTiny15L or the good old AT90S1200. */ +class ThreeLevelStack : public MemoryOffsets { + public: + ThreeLevelStack() : MemoryOffsets(0, 0) { + rwHandler=(RWMemoryMembers**)malloc(sizeof(RWMemoryMembers*) * 6); + for (size_t i=0; i < 6; i++) { + rwHandler[i]=new RWMemoryWithOwnMemory(0); + } + } + ~ThreeLevelStack() { + free(rwHandler); + } +}; + + class HWStack: public Hardware { protected: AvrDevice *core; MemoryOffsets *mem; unsigned int stackPointer; - unsigned int stackMask; + unsigned int stackCeil; multimap<unsigned int , Funktor* > breakPointList; //later the second parameter should be a function Pointer! public: - //the mask give the max width of the stack pointer, in smaller devices there are not all 16 bits available! - HWStack(AvrDevice *core, MemoryOffsets *sr, unsigned int mask); + /*!Ceil gives the maximum value (+1) for the stack pointer, in smaller devices + there are not all 16 bits available! + Ceil does not need to be a power of two. + */ + HWStack(AvrDevice *core, MemoryOffsets *sr, unsigned int ceil); void Push(unsigned char val); unsigned char Pop(); -- 1.5.6.5 _______________________________________________ Simulavr-devel mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/simulavr-devel
