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"
38 Device::Device(SimulationClock
& clock
, const char *devicename
, bool allowStopping
)
39 : SimulationObject(clock
), core(0), allowStopping(allowStopping
) {
42 avr::DeviceSettings::load( this, devicename
);
47 frq
= 1000000000 / defaultFrequency
;
48 clock
.setBreakDelta( frq
, this );
56 void Device::load(Program
& program
) {
58 while( program
.readNextSection(sec
) ) {
59 //only read flash bytes and data
61 core
->loadFlash( sec
.data(), sec
.address(), sec
.size() );
64 std::cout
<< "Flash: " << sec
.size() << " bytes at " << sec
.address() << std::endl
;
68 if( sec
.isEeprom() ) {
69 eeprom
->write( sec
.address(), sec
.data(), sec
.size() );
72 std::cout
<< "Eeprom: " << sec
.size() << " bytes at " << sec
.address() << std::endl
;
78 void Device::setClockFrequency(ClockFrequency frq
) {
79 this->frq
= 1000000000 / frq
;
80 clock
.reassignBreak( this, this->frq
);
83 void Device::buildCore(unsigned int ioSpaceSize
, unsigned int ramSize
,
84 unsigned int flashSize
, unsigned int pageSize
,
85 unsigned int stackMask
, int pcBytes
/*= 2*/,
87 core
= new Core(bus
, ioSpaceSize
, ramSize
, flashSize
,
88 pageSize
, stackMask
, pcBytes
, eram
);
91 void Device::buildHardware(const char *hwname
, HardwareSettings
& hws
) {
92 Hardware
*hw
= HardwareFactory::build(hwname
, hws
, bus
);
94 std::string name
, binding
;
95 while( hws
.getBinding(name
, binding
) ) {
97 std::cout
<< "Binding \"" << name
<< "\" to \"" << binding
<< "\"" << std::endl
;
100 if( ! hw
->attachReg( name
.c_str(), core
->getIoreg( binding
) ) )
101 throw util::RuntimeException(
102 util::format("%s::attachReg: unknown register %s") % hwname
% name
);
105 if( ! hw
->finishBuild() )
106 throw util::RuntimeException(
107 util::format("Failed to build hardware module %s: missing register") % hwname
);
109 bus
.addHardware( hw
);
111 // Special handling for eeprom
112 if( strcmp(hwname
, "eeprom") == 0 )
113 eeprom
= static_cast<Eeprom
*>( hw
);
116 void Device::addIOReg(unsigned int address
,
117 const std::string
& name
, unsigned char intial
) {
118 core
->addIOReg(address
, name
, intial
);
121 void Device::addInterrupt(unsigned int vector
, unsigned int address
,
123 bus
.addInterrupt( vector
, address
, name
);
126 void Device::addPin(unsigned int id
, const char *name
, unsigned int num
) {
128 std::cout
<< "Pin " << id
<< " => " << name
<< std::endl
;
131 if( pins
.size() == 0 )
134 Pin
*pin
= new Pin();
138 if( name
[0] == '[' ) {
139 static const std::string
delimiters(":");
140 std::string
names( name
+ 1, strlen(name
) - 2 );
142 // skip delimiters at beginning.
143 std::string::size_type lastPos
= names
.find_first_not_of(delimiters
, 0);
145 // find first "non-delimiter".
146 std::string::size_type pos
= names
.find_first_of(delimiters
, lastPos
);
148 while( std::string::npos
!= pos
|| std::string::npos
!= lastPos
) {
149 // found a name, add it to the map.
150 std::string n
= names
.substr(lastPos
, pos
- lastPos
);
151 name2pin
.insert( std::make_pair(n
, pin
) );
153 // skip delimiters. Note the "not_of"
154 lastPos
= names
.find_first_not_of(delimiters
, pos
);
156 // find next "non-delimiter"
157 pos
= names
.find_first_of(delimiters
, lastPos
);
160 name2pin
.insert( std::make_pair(name
, pin
) );
164 Pin
*Device::getPin(const std::string
& name
) const {
165 std::map
<std::string
, Pin
*>::const_iterator it
;
166 if( (it
= name2pin
.find( name
)) != name2pin
.end() )
169 throw util::RuntimeException(
170 util::format("No pin with name %s on this device") % name
);
173 void Device::addAnalyzer(ScriptEngine
*vm
, const char *name
) {
174 AnalyzerFactory factory
;
175 core
->addAnalyzer( factory
.newAnalyzer(core
, vm
, name
) );
178 void Device::trace(const char *tracefile
) {
179 core
->addAnalyzer( new TraceAnalyzer(core
, tracefile
) );
182 void Device::reset(unsigned int type
) {
187 void Device::step() {
188 if( ! bus
.isHoldingCPU() )
193 if( ! (allowStopping
&& core
->isStopped()) )
194 clock
.setBreakDelta( frq
, this );
197 DebugInterface
*Device::debugInterface() {
198 return new DebugInterface(*this, *core
);