Bug fix: check if vm exists
[avr-sim.git] / Eeprom.cpp
blob8e29170ced7b68f224f09bc7ea456d71646032c5
1 #include "Eeprom.h"
2 #include "Bus.h"
3 #include "Registers.h"
4 #include <cstring>
6 #define EERIE (1<<3)
7 #define EEMWE (1<<2)
8 #define EEWE (1<<1)
9 #define EERE (1<<0)
10 #define CLEAR 0xf8
12 namespace avr {
14 Eeprom::Eeprom(Bus & bus, unsigned int size)
15 : Hardware(bus), Memory(size), oldEecr(0) {
18 Eeprom::~Eeprom() {
21 void Eeprom::writeToAddress(unsigned int addr, unsigned char val) {
22 write(addr, &val);
25 unsigned char Eeprom::readFromAddress(unsigned int addr) {
26 return readByte(addr);
29 bool Eeprom::attachReg(const char *name, IORegister *reg) {
30 if( strcmp(name, "eecr") == 0 )
31 eecr = reg;
32 else if( strcmp(name, "eedr") == 0 )
33 eedr = reg;
34 else if( strcmp(name, "eearl") == 0 )
35 eearl = reg;
36 else if( strcmp(name, "eearh") == 0 )
37 eearh = reg;
38 else
39 return false;
41 reg->registerHW(this);
42 return true;
45 void Eeprom::regChanged( IORegister *reg ) {
46 if( reg == eearh )
47 eear = (eear & 0x00ff) | (*eearh << 8);
48 else if( reg == eearl )
49 eear = (eear & 0xff00) | (*eearl);
50 else if( reg == eecr )
51 setEECR( *eecr );
54 void Eeprom::step() {
55 switch( state ) {
56 case READY:
57 break;
59 case READ:
60 *eecr = *eecr & CLEAR;
61 writeToAddress( eear, *eedr );
62 state = READY;
63 break;
65 case WRITE:
66 *eecr = *eecr & CLEAR;
67 *eedr = readFromAddress( eear );
68 state = READY;
69 break;
71 case WRITE_ENABLED:
72 *eecr = *eecr & ~EEMWE;
73 state = READY;
74 break;
78 void Eeprom::setEECR( unsigned char eecr ) {
79 if( ((eecr & EEMWE) != 0) && (state == READY) ) {
80 state = WRITE_ENABLED;
81 bus.reassignBreakDelta(writeEnableCycles, this);
82 } else if( ((eecr & EEWE) != 0) && (state == WRITE_ENABLED) ) {
83 state = WRITE;
84 setHoldCycles( writeCycles );
85 bus.reassignBreakDelta(writeCycles, this);
86 } else if( (eecr & EERE) != 0 ) {
87 //EERE EEprom read enable
88 if( state == WRITE ) {
89 state = READ;
90 bus.clearBreak(this);
91 } else {
92 setHoldCycles( readCycles );
93 bus.reassignBreakDelta(readCycles, this);
95 } else if( (eecr & 0x07) != 0x00 ) {
96 state = READY;
97 bus.clearBreak( this );
100 oldEecr = eecr;