Fixed problem in DeviceSettings::strParam, returned wrong string
[avr-sim.git] / src / Eeprom.cpp
blob834522bceb2778b69fe8bca0fb8f595db55b7e39
1 /*
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/>.
19 #include "Eeprom.h"
20 #include "Bus.h"
21 #include "Registers.h"
22 #include <cstring>
24 #define EERIE (1<<3)
25 #define EEMWE (1<<2)
26 #define EEWE (1<<1)
27 #define EERE (1<<0)
28 #define CLEAR 0xf8
30 namespace avr {
32 Eeprom::Eeprom(Bus & bus, unsigned int size, unsigned int rdyVec)
33 : Hardware(bus), Memory(size), rdyVec(rdyVec), oldEecr(0) {
36 Eeprom::~Eeprom() {
39 void Eeprom::writeToAddress(unsigned int addr, unsigned char val) {
40 write(addr, &val);
43 unsigned char Eeprom::readFromAddress(unsigned int addr) {
44 return readByte(addr);
47 bool Eeprom::attachReg(const char *name, IORegister *reg) {
48 if( strcmp(name, "eecr") == 0 )
49 eecr = reg;
50 else if( strcmp(name, "eedr") == 0 ) {
51 eedr = reg;
52 return true;
53 } else if( strcmp(name, "eearl") == 0 )
54 eearl = reg;
55 else if( strcmp(name, "eearh") == 0 )
56 eearh = reg;
57 else
58 return false;
60 reg->registerHW(this);
61 return true;
64 void Eeprom::regChanged( IORegister *reg ) {
65 if( reg == eearh )
66 eear = (eear & 0x00ff) | (*eearh << 8);
67 else if( reg == eearl )
68 eear = (eear & 0xff00) | (*eearl);
69 else if( reg == eecr )
70 setEECR( *eecr );
73 void Eeprom::step() {
74 switch( state ) {
75 case READY:
76 break;
78 case WRITE:
79 eecr->set( *eecr & CLEAR );
80 writeToAddress( eear, *eedr );
82 if( (*eecr & EERIE) != 0 )
83 bus.raiseInterrupt(rdyVec);
85 state = READY;
86 break;
88 case READ:
89 eecr->set( *eecr & CLEAR );
90 *eedr = readFromAddress( eear );
92 state = READY;
93 break;
95 case WRITE_ENABLED:
96 eecr->set( *eecr & ~EEMWE );
97 state = READY;
98 break;
102 void Eeprom::setEECR( unsigned char eecr ) {
103 if( ((eecr & EEMWE) != 0) && (state == READY) ) {
104 state = WRITE_ENABLED;
105 bus.reassignBreakDelta(writeEnableCycles, this);
106 } else if( ((eecr & EEWE) != 0) && (state == WRITE_ENABLED) ) {
107 state = WRITE;
108 setHoldCycles( writeCycles );
109 bus.reassignBreakDelta(writeCycles, this);
110 } else if( (eecr & EERE) != 0 ) {
111 //EERE EEprom read enable
112 if( state == WRITE ) {
113 state = READ;
114 bus.clearBreak(this);
115 } else {
116 state = READ;
117 setHoldCycles( readCycles );
118 bus.reassignBreakDelta(readCycles, this);
121 state = READ;
122 } else if( (eecr & 0x07) != 0x00 ) {
123 state = READY;
124 bus.clearBreak( this );
127 oldEecr = eecr;