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 );
58 void Device::load(Program
& program
) {
60 while( program
.readNextSection(sec
) ) {
61 //only read flash bytes and data
63 core
->loadFlash( sec
.data(), sec
.address(), sec
.size() );
66 std::cout
<< "Flash: " << sec
.size() << " bytes at " << sec
.address() << std::endl
;
70 if( sec
.isEeprom() ) {
71 eeprom
->write( sec
.address(), sec
.data(), sec
.size() );
74 std::cout
<< "Eeprom: " << sec
.size() << " bytes at " << sec
.address() << std::endl
;
80 void Device::setClockFrequency(ClockFrequency frq
) {
81 this->frq
= 1000000000 / frq
;
82 clock
.reassignBreak( this, this->frq
);
85 void Device::buildCore(unsigned int ioSpaceSize
, unsigned int ramSize
,
86 unsigned int flashSize
, unsigned int pageSize
,
87 unsigned int stackMask
, int pcBytes
/*= 2*/,
89 core
= new Core(bus
, ioSpaceSize
, ramSize
, flashSize
,
90 pageSize
, stackMask
, pcBytes
, eram
);
93 void Device::buildHardware(const char *hwname
, HardwareSettings
& hws
) {
94 Hardware
*hw
= HardwareFactory::build(hwname
, hws
, bus
);
96 std::string name
, binding
;
97 while( hws
.getBinding(name
, binding
) ) {
99 std::cout
<< "Binding \"" << name
<< "\" to \"" << binding
<< "\"" << std::endl
;
102 if( ! hw
->attachReg( name
.c_str(), core
->getIoreg( binding
) ) )
103 throw util::RuntimeException(
104 util::format("%s::attachReg: unknown register %s") % hwname
% name
);
107 if( ! hw
->finishBuild() )
108 throw util::RuntimeException(
109 util::format("Failed to build hardware module %s: missing register") % hwname
);
111 bus
.addHardware( hw
);
113 // Special handling for eeprom
114 if( strcmp(hwname
, "eeprom") == 0 )
115 eeprom
= static_cast<Eeprom
*>( hw
);
118 void Device::addIOReg(unsigned int address
,
119 const std::string
& name
, unsigned char intial
) {
120 core
->addIOReg(address
, name
, intial
);
123 void Device::addInterrupt(unsigned int vector
, unsigned int address
,
125 bus
.addInterrupt( vector
, address
, name
);
128 void Device::addPin(unsigned int id
, const char *name
, unsigned int num
) {
130 std::cout
<< "Pin " << id
<< " => " << name
<< std::endl
;
133 if( pins
.size() == 0 )
136 Pin
*pin
= new Pin();
140 if( name
[0] == '[' ) {
141 static const std::string
delimiters(":");
142 std::string
names( name
+ 1, strlen(name
) - 2 );
144 // skip delimiters at beginning.
145 std::string::size_type lastPos
= names
.find_first_not_of(delimiters
, 0);
147 // find first "non-delimiter".
148 std::string::size_type pos
= names
.find_first_of(delimiters
, lastPos
);
150 while( std::string::npos
!= pos
|| std::string::npos
!= lastPos
) {
151 // found a name, add it to the map.
152 std::string n
= names
.substr(lastPos
, pos
- lastPos
);
153 name2pin
.insert( std::make_pair(n
, pin
) );
155 // skip delimiters. Note the "not_of"
156 lastPos
= names
.find_first_not_of(delimiters
, pos
);
158 // find next "non-delimiter"
159 pos
= names
.find_first_of(delimiters
, lastPos
);
162 name2pin
.insert( std::make_pair(name
, pin
) );
166 Pin
*Device::getPin(const std::string
& name
) const {
167 std::map
<std::string
, Pin
*>::const_iterator it
;
168 if( (it
= name2pin
.find( name
)) != name2pin
.end() )
171 throw util::RuntimeException(
172 util::format("No pin with name %s on this device") % name
);
175 void Device::addAnalyzer(const char *name
) {
176 core
->addAnalyzer( AnalyzerFactory::newAnalyzer(core
, name
) );
179 void Device::addAnalyzer(Analyzer
*analyzer
) {
180 core
->addAnalyzer( analyzer
);
183 void Device::trace(const char *tracefile
) {
184 core
->addAnalyzer( new TraceAnalyzer(core
, tracefile
) );
187 void Device::reset(unsigned int type
) {
192 void Device::step() {
193 if( ! bus
.isHoldingCPU() )
198 if( ! (allowStopping
&& core
->isStopped()) )
199 clock
.setBreakDelta( frq
, this );
202 DebugInterface
*Device::debugInterface() {
203 return new DebugInterface(*this, *core
);