simulavr  1.1.0
rwmem.cpp
Go to the documentation of this file.
1 /*
2  ****************************************************************************
3  *
4  * simulavr - A simulator for the Atmel AVR family of microcontrollers.
5  * Copyright (C) 2001, 2002, 2003 Klaus Rudolph
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  ****************************************************************************
22  *
23  * $Id$
24  */
25 
26 /*
27  * All here defined types are used to simulate the
28  * read write address space. This means also registers
29  * io-data space, internal and external sram
30  */
31 
32 #include <cstdio>
33 
34 #include "avrerror.h"
35 #include "traceval.h"
36 #include "avrdevice.h"
37 #include "helper.h"
38 #include "rwmem.h"
39 
40 using namespace std;
41 
43  const std::string &_tracename,
44  const int index):
45  registry(_reg),
46  tracename(_tracename),
47  isInvalid(false)
48 {
49  if (_tracename.size()) {
50  tv = new TraceValue(8, registry->GetTraceValuePrefix() + _tracename, index);
51  if (!registry) {
52  avr_error("registry not initialized for RWMemoryMember '%s'.", _tracename.c_str());
53  }
55  } else {
56  tv=0;
57  }
58 }
59 
61  tv(NULL),
62  registry(NULL),
63  tracename(""),
64  isInvalid(true) {}
65 
66 RWMemoryMember::operator unsigned char() const {
67  if (tv)
68  tv->read();
69  return get();
70 }
71 
72 unsigned char RWMemoryMember::operator=(unsigned char val) {
73  set(val);
74  if (tv)
75  tv->write(val);
76  return val;
77 }
78 
79 unsigned char RWMemoryMember::operator=(const RWMemoryMember &mm) {
80  if (mm.tv)
81  mm.tv->read();
82  unsigned char v=mm.get();
83  set(v);
84  if (tv)
85  tv->write(v);
86  return v;
87 }
88 
91  RWMemoryMember(registry, "CLKPR"),
92  Hardware(core),
93  _core(core) {
95  value = 3;
96  else
97  value = 0;
98  activate = 0;
99 
100  // connect to core to get core cycles
101  core->AddToCycleList(this);
102 }
103 
106  value = 3;
107  else
108  value = 0;
109  activate = 0;
110 }
111 
112 unsigned int CLKPRRegister::CpuCycle(void) {
113  // control clock set activation
114  if(activate > 0) {
115  activate--;
116  value &= 0x7f; // reset CLKPCE, if set
117  }
118  return 0;
119 }
120 
121 void CLKPRRegister::set(unsigned char v) {
122  if(v == 0x80) {
123  // set activation period
124  if(activate == 0) activate = 4;
125  } else if((v & 0x80) == 0) {
126  if(activate > 0) {
127  string buf = "<invalid>";
128  unsigned char i = v & 0x0f;
129  if(i <= 8)
130  buf = "CKx" + int2str(1 << i);
131  // set clock prescaler
132  avr_warning("CLKPR: change clock prescaler to %s (0x%x)", buf.c_str(), i);
133  }
134  }
135  value = v;
136 }
137 
140  RWMemoryMember(registry, "XDIV"),
141  Hardware(core)
142 {
143  Reset();
144 }
145 
146 void XDIVRegister::set(unsigned char v) {
147  bool old_enbl = (value & 0x80) == 0x80, new_enbl = (v & 0x80) == 0x80;
148  if(new_enbl) {
149  if(!old_enbl) {
150  // enable clock divider
151  avr_warning("XDIV: clock divider enabled, CKx%d", 129 - (v & 0x7f));
152  // if XDIVEN == 1, XDIV[6:0] are only changeable, if XDIVEN == 0 before!
153  value = v;
154  }
155  } else {
156  if(old_enbl)
157  // disable clock divider
158  avr_warning("XDIV: clock divider disabled, CKx1");
159  value = v;
160  }
161 }
162 
165  int cal):
166  RWMemoryMember(registry, "OSCCAL"),
167  Hardware(core),
168  cal_type(cal)
169 {
170  Reset();
171 }
172 
174  // set factory calibration value, the used value is just a interpolation from datasheet!
175  // The real value could differ from device to device.
176  if(cal_type == OSCCAL_V3)
177  value = 85;
178  else
179  value = 42;
180 }
181 
182 void OSCCALRegister::set(unsigned char v) {
183  if(cal_type == OSCCAL_V4)
184  v &= 0x7f;
185  if(value != v)
186  avr_warning("OSCCAL: change oscillator calibration value to 0x%x", v);
187  value = v;
188 }
189 
190 RAM::RAM(TraceValueCoreRegister *_reg, const std::string &name, const size_t number, const size_t maxsize) {
191  corereg = _reg;
192  value = 0xaa;
193  if(name.size()) {
194  tv = new TraceValue(8, corereg->GetTraceValuePrefix() + name, number);
195  if(!corereg) {
196  avr_error("registry not initialized for RWMemoryMember '%s'.", name.c_str());
197  }
198  corereg->RegisterTraceSetValue(tv, name, maxsize);
199  } else {
200  tv = NULL;
201  }
202 }
203 
204 unsigned char RAM::get() const { return value; }
205 
206 void RAM::set(unsigned char v) { value=v; }
207 
209  RWMemoryMember(),
210  core(_c),
211  addr(_a),
212  value(0xAA) {}
213 
214 unsigned char InvalidMem::get() const {
215  string s = "Invalid read access from IO[0x" + int2hex(addr) + "], PC=0x" + int2hex(core->PC * 2);
216  unsigned int a = addr & core->dataAddressMask;
217  unsigned int r = core->GetMemIOSize() + core->GetMemRegisterSize() + core->GetMemIRamSize() + core->GetMemERamSize();
219  avr_error("%s", s.c_str());
221  avr_warning("%s", s.c_str());
222  if(a < r)
223  return value;
224  return 0;
225 }
226 
227 void InvalidMem::set(unsigned char c) {
228  string s = "Invalid write access to IO[0x" + int2hex(addr) +
229  "]=0x" + int2hex(c) + ", PC=0x" + int2hex(core->PC * 2);
230  unsigned int a = addr & core->dataAddressMask;
231  unsigned int r = core->GetMemIOSize() + core->GetMemRegisterSize() + core->GetMemIRamSize() + core->GetMemERamSize();
233  avr_error("%s", s.c_str());
235  avr_warning("%s", s.c_str());
236  if(a < r)
237  value = c;
238 }
239 
240 NotSimulatedRegister::NotSimulatedRegister(const char * oname, const char * rname)
241  : obj_name(oname),
242  reg_name(rname) {}
243 
244 unsigned char NotSimulatedRegister::get() const {
246  avr_warning("%s register %s not simulated (read from register)", obj_name, reg_name);
247  return 0;
248 }
249 
250 void NotSimulatedRegister::set(unsigned char c) {
252  avr_warning("%s register %s not simulated (write 0x%02x to register)", obj_name, reg_name, (unsigned)c);
253 }
254 
272 NotSimulatedRegister NSR_XMC_XMCRA = NotSimulatedRegister("External memory control", "XMCRA");
273 NotSimulatedRegister NSR_XMC_XMCRB = NotSimulatedRegister("External memory control", "XMCRB");
274 
276  &NSR_TWI_TWAMR,
277  &NSR_TWI_TWCR,
278  &NSR_TWI_TWDR,
279  &NSR_TWI_TWAR,
280  &NSR_TWI_TWSR,
281  &NSR_TWI_TWBR,
282  &NSR_ADC_DIDR0,
283  &NSR_ADC_DIDR1,
284  &NSR_ADC_DIDR2,
285  &NSR_MCU_PRR,
286  &NSR_MCU_PRR0,
287  &NSR_MCU_PRR1,
289  &NSR_MCU_MCUCR,
290  &NSR_MCU_MCUSR,
291  &NSR_MCU_SMCR,
292  &NSR_OCD_OCDR,
293  &NSR_XMC_XMCRA,
294  &NSR_XMC_XMCRB,
295 };
296 
299  avr_error("wrong register id for NotSimulatedRegister");
300  return NSR[reg];
301 }
302 
304  RWMemoryMember(registry, name)
305 {
306  Reset();
307 }
308 
309 unsigned char IOSpecialReg::get() const {
310  unsigned char val = value;
311  for(size_t i = 0; i < clients.size(); i++)
312  val = clients[i]->get_from_client(this, val);
313  return val;
314 }
315 
316 void IOSpecialReg::set(unsigned char val) {
317  for(size_t i = 0; i < clients.size(); i++)
318  val = clients[i]->set_from_reg(this, val);
319  value = val;
321 }
322 
323 // EOF
oscillator version 3.x and older, 8bit, one range
Definition: rwmem.h:179
unsigned int CpuCycle(void)
Definition: rwmem.cpp:112
Basic AVR device, contains the core functionality.
Definition: avrdevice.h:66
unsigned int GetMemERamSize(void)
Get configured external RAM size.
Definition: avrdevice.h:196
void read()
Log a read access.
Definition: traceval.cpp:93
void Reset(void)
Definition: rwmem.cpp:173
const char * obj_name
Definition: rwmem.h:240
virtual unsigned char get() const =0
void AddToCycleList(Hardware *hw)
Definition: avrdevice.cpp:51
AvrFuses * fuses
Definition: avrdevice.h:100
void set(unsigned char v)
Definition: rwmem.cpp:146
NotSimulatedRegister NSR_TWI_TWCR
Definition: rwmem.cpp:256
unsigned int GetMemIRamSize(void)
Get configured internal RAM size.
Definition: avrdevice.h:194
NotSimulatedRegister NSR_TWI_TWAMR
Definition: rwmem.cpp:255
void hardwareChange(unsigned char val)
Definition: rwmem.h:439
TraceValueRegister * registry
Definition: rwmem.h:106
XDIVRegister(AvrDevice *core, TraceValueRegister *registry)
Definition: rwmem.cpp:138
NotSimulatedRegister NSR_MCU_SMCR
Definition: rwmem.cpp:270
NotSimulatedRegister NSR_TWI_TWDR
Definition: rwmem.cpp:257
unsigned int dataAddressMask
which bits in address are significant
Definition: avrdevice.h:97
unsigned char value
Definition: rwmem.h:196
NotSimulatedRegister NSR_MCU_MCUSR
Definition: rwmem.cpp:269
int cal_type
Definition: rwmem.h:197
unsigned char value
Definition: rwmem.h:151
NotSimulatedRegister NSR_TWI_TWSR
Definition: rwmem.cpp:259
const bool isInvalid
Definition: rwmem.h:108
lfuse: CKDIV8 bit
Definition: flashprog.h:114
unsigned char activate
Definition: rwmem.h:152
RAM(TraceValueCoreRegister *registry, const std::string &tracename, const size_t number, const size_t maxsize)
Definition: rwmem.cpp:190
InvalidMem(AvrDevice *core, int addr)
Definition: rwmem.cpp:208
STL namespace.
void Reset(void)
Register reset functionality, sets internal register value to 0.
Definition: rwmem.h:432
NotSimulatedRegister NSR_MCU_WDTCSR
Definition: rwmem.cpp:267
NotSimulatedRegister NSR_MCU_PRR0
Definition: rwmem.cpp:265
NotSimulatedRegister NSR_MCU_MCUCR
Definition: rwmem.cpp:268
void Reset(void)
Definition: rwmem.h:163
unsigned char value
Internal register value.
Definition: rwmem.h:453
IOSpecialReg(TraceValueRegister *registry, const std::string &tracename)
Creates a IOSpecialReg instance, see RWMemoryMember for more info.
Definition: rwmem.cpp:303
NotSimulatedRegister NSR_TWI_TWBR
Definition: rwmem.cpp:260
std::string int2hex(int i)
Convert int into hex string.
Definition: helper.cpp:65
NotSimulatedRegister NSR_MCU_PRR
Definition: rwmem.cpp:264
void set(unsigned char)
Definition: rwmem.cpp:227
NotSimulatedRegister NSR_XMC_XMCRB
Definition: rwmem.cpp:273
NotSimulatedRegister NSR_XMC_XMCRA
Definition: rwmem.cpp:272
#define avr_error(...)
Definition: avrerror.h:135
unsigned char value
Definition: rwmem.h:234
Build a register for TraceValue&#39;s.
Definition: traceval.h:442
TraceValue * tv
Definition: rwmem.h:105
void RegisterTraceValue(TraceValue *t)
Registers a TraceValue for this register.
Definition: traceval.cpp:217
unsigned char get() const
Get value method, see RWMemoryMember.
Definition: rwmem.cpp:309
bool abortOnInvalidAccess
Flag, that simulation abort if an invalid access occured, default is false.
Definition: avrdevice.h:107
std::vector< IOSpecialRegClient * > clients
clients-list with registered clients
Definition: rwmem.h:447
void Reset(void)
Definition: rwmem.cpp:104
AvrDevice * core
Definition: rwmem.h:223
NotSimulatedRegister * NSR[NotSimulatedRegister::NSR_size]
Definition: rwmem.cpp:275
NotSimulatedRegister NSR_ADC_DIDR0
Definition: rwmem.cpp:261
Member of any memory area in an AVR device.
Definition: rwmem.h:42
unsigned int GetMemIOSize(void)
Get configured IO memory space size.
Definition: avrdevice.h:190
void write(unsigned val)
Log a write access on this value.
Definition: traceval.cpp:84
NotSimulatedRegister NSR_ADC_DIDR1
Definition: rwmem.cpp:262
unsigned char get() const
Definition: rwmem.cpp:204
std::string int2str(int i)
Convert an int into a string.
Definition: helper.cpp:59
NotSimulatedRegister NSR_ADC_DIDR2
Definition: rwmem.cpp:263
void set(unsigned char)
Definition: rwmem.cpp:250
int addr
Definition: rwmem.h:224
NotSimulatedRegister NSR_MCU_PRR1
Definition: rwmem.cpp:266
NotSimulatedRegister NSR_OCD_OCDR
Definition: rwmem.cpp:271
CLKPRRegister(AvrDevice *core, TraceValueRegister *registry)
Definition: rwmem.cpp:89
unsigned char operator=(unsigned char val)
Write access on memory.
Definition: rwmem.cpp:72
void set(unsigned char)
Set value method, see RWMemoryMember.
Definition: rwmem.cpp:316
unsigned char get() const
Definition: rwmem.cpp:244
NotSimulatedRegister(const char *oname, const char *rname)
Definition: rwmem.cpp:240
#define avr_warning(...)
Definition: avrerror.h:133
unsigned int GetMemRegisterSize(void)
Get configured register space size.
Definition: avrdevice.h:192
RWMemoryMember(void)
Definition: rwmem.cpp:60
oscillator version 4.x, 7bit, one range
Definition: rwmem.h:180
const std::string GetTraceValuePrefix(void)
Returns the scope prefix.
Definition: traceval.h:487
const std::string tracename
Definition: rwmem.h:107
unsigned char value
Definition: rwmem.h:170
OSCCALRegister(AvrDevice *core, TraceValueRegister *registry, int cal)
Definition: rwmem.cpp:163
static NotSimulatedRegister * getRegister(int reg)
Definition: rwmem.cpp:297
bool global_suppress_memory_warnings
flag to suppress invalid memory usage warnings
Definition: avrerror.cpp:237
NotSimulatedRegister NSR_TWI_TWAR
Definition: rwmem.cpp:258
unsigned int PC
Definition: avrdevice.h:93
bool GetFuseBit(int index)
Get fuse bit by bit index, starts with 0 on lfuse bit 0, bit = 0 means true!
Definition: flashprog.h:125
void set(unsigned char v)
Definition: rwmem.cpp:121
unsigned char get() const
Definition: rwmem.cpp:214
void set(unsigned char v)
Definition: rwmem.cpp:182
void set(unsigned char)
Definition: rwmem.cpp:206
const char * reg_name
Definition: rwmem.h:241
An IO register which is not simulated in the moment. Reads and writes are ignored and produce warning...
Definition: rwmem.h:238
AvrDevice * _core
Definition: rwmem.h:150