2 * avr-sim: An atmel AVR simulator
3 * Copyright (C) 2008 Tom Haber
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "DeviceSettings.h"
22 #include "HardwareFactory.h"
24 #include "DebugInterface.h"
28 #include "TraceAnalyzer.h"
31 #include "RuntimeException.h"
40 Device::Device(sim::SimulationClock
& clock
, const char *devicename
, bool allowStopping
)
41 : sim::SimulationObject(clock
), core(0), allowStopping(allowStopping
) {
44 avr::DeviceSettings::load( this, devicename
);
49 frq
= 1000000000 / defaultFrequency
;
50 clock
.setBreakDelta( frq
, this );
57 for(size_t i
= 0; i
< pins
.size(); ++i
)
62 void Device::load(Program
& program
) {
64 while( program
.readNextSection(sec
) ) {
65 //only read flash bytes and data
67 core
->loadFlash( sec
.data(), sec
.address(), sec
.size() );
70 std::cout
<< "Flash: " << sec
.size() << " bytes at " << sec
.address() << std::endl
;
74 if( sec
.isEeprom() ) {
75 eeprom
->write( sec
.address(), sec
.data(), sec
.size() );
78 std::cout
<< "Eeprom: " << sec
.size() << " bytes at " << sec
.address() << std::endl
;
84 void Device::setClockFrequency(ClockFrequency frq
) {
85 this->frq
= 1000000000 / frq
;
86 clock
.reassignBreak( this, this->frq
);
89 void Device::buildCore(unsigned int ioSpaceSize
, unsigned int ramSize
,
90 unsigned int flashSize
, unsigned int pageSize
,
91 unsigned int stackMask
, int pcBytes
/*= 2*/,
93 core
= new Core(bus
, ioSpaceSize
, ramSize
, flashSize
,
94 pageSize
, stackMask
, pcBytes
, eram
);
97 void Device::buildHardware(const char *hwname
, HardwareSettings
& hws
) {
98 Hardware
*hw
= HardwareFactory::build(hwname
, hws
, bus
);
100 std::string name
, binding
;
101 while( hws
.getBinding(name
, binding
) ) {
103 std::cout
<< "Binding \"" << name
<< "\" to \"" << binding
<< "\"" << std::endl
;
106 if( ! hw
->attachReg( name
.c_str(), core
->getIoreg( binding
) ) )
107 throw util::RuntimeException(
108 util::format("%s::attachReg: unknown register %s") % hwname
% name
);
111 if( ! hw
->finishBuild() )
112 throw util::RuntimeException(
113 util::format("Failed to build hardware module %s: missing register") % hwname
);
115 bus
.addHardware( hw
);
117 // Special handling for eeprom
118 if( strcmp(hwname
, "eeprom") == 0 )
119 eeprom
= static_cast<Eeprom
*>( hw
);
122 void Device::addIOReg(unsigned int address
,
123 const std::string
& name
, unsigned char intial
) {
124 core
->addIOReg(address
, name
, intial
);
127 void Device::addInterrupt(unsigned int vector
, unsigned int address
,
129 bus
.addInterrupt( vector
, address
, name
);
132 void Device::addPin(unsigned int id
, const char *name
, unsigned int num
) {
134 std::cout
<< "Pin " << id
<< " => " << name
<< std::endl
;
137 if( pins
.size() == 0 )
140 Pin
*pin
= new Pin();
141 pins
[ id
- 1 ] = pin
;
144 if( name
[0] == '[' ) {
145 static const std::string
delimiters(":");
146 std::string
names( name
+ 1, strlen(name
) - 2 );
148 // skip delimiters at beginning.
149 std::string::size_type lastPos
= names
.find_first_not_of(delimiters
, 0);
151 // find first "non-delimiter".
152 std::string::size_type pos
= names
.find_first_of(delimiters
, lastPos
);
154 while( std::string::npos
!= pos
|| std::string::npos
!= lastPos
) {
155 // found a name, add it to the map.
156 std::string n
= names
.substr(lastPos
, pos
- lastPos
);
157 name2pin
.insert( std::make_pair(n
, pin
) );
159 // skip delimiters. Note the "not_of"
160 lastPos
= names
.find_first_not_of(delimiters
, pos
);
162 // find next "non-delimiter"
163 pos
= names
.find_first_of(delimiters
, lastPos
);
166 name2pin
.insert( std::make_pair(name
, pin
) );
170 Pin
*Device::getPin(const std::string
& name
) const {
171 std::map
<std::string
, Pin
*>::const_iterator it
;
172 if( (it
= name2pin
.find( name
)) != name2pin
.end() )
175 throw util::RuntimeException(
176 util::format("No pin with name %s on this device") % name
);
179 void Device::addAnalyzer(const char *name
) {
180 core
->addAnalyzer( AnalyzerFactory::newAnalyzer(core
, name
) );
183 void Device::addAnalyzer(Analyzer
*analyzer
) {
184 core
->addAnalyzer( analyzer
);
187 void Device::trace(const char *tracefile
) {
188 core
->addAnalyzer( new TraceAnalyzer(core
, tracefile
) );
191 void Device::reset(unsigned int type
) {
196 void Device::step() {
197 if( ! bus
.isHoldingCPU() )
202 if( ! (allowStopping
&& core
->isStopped()) )
203 clock
.setBreakDelta( frq
, this );
206 DebugInterface
*Device::debugInterface() {
207 return new DebugInterface(*this, *core
);