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 "Registers.h"
22 #include "AccessViolation.h"
26 MMU::MMU(unsigned int ioSpaceSize
, unsigned int ramSize
, ERam
*eram
)
27 : regs(ioSpaceSize
), sram(ramSize
), eram(eram
) {
29 static const char * Rnames
[32] = {
30 "r0", "r1", "r2", "r3", "r4", "r5",
31 "r6", "r7", "r8", "r9", "r10", "r11",
32 "r12", "r13", "r14", "r15", "r16", "r17",
33 "r18", "r19", "r20", "r21", "r22", "r23",
34 "r24", "r25", "r26", "r27", "r28", "r29",
37 for(int i
= 0; i
< 32; ++i
)
38 R
[i
].init(i
, Rnames
[i
]);
46 Register
& MMU::reg(int i
) {
47 if( (unsigned int)i
>= registerSpaceSize
)
48 throw AccessViolation("Tried to access not existing register");
53 const Register
& MMU::reg(int i
) const {
54 if( (unsigned int)i
>= registerSpaceSize
)
55 throw AccessViolation("Tried to access not existing register");
60 const std::string
& MMU::registerName(byte addr
) const {
61 if( addr
< registerSpaceSize
)
62 return R
[addr
].getName();
64 return regs
.getIoreg(addr
- registerSpaceSize
).getName();
67 const unsigned char *MMU::readRam(unsigned int offset
, unsigned int size
) const {
68 if( offset
< registerSpaceSize
+ regs
.size() )
69 throw AccessViolation("readRam: Tried to read to register area");
71 offset
-= registerSpaceSize
+ regs
.size();
72 return sram
.read(offset
, size
);
75 void MMU::writeRam(unsigned char *data
, unsigned int offset
, unsigned int size
) {
76 if( offset
< registerSpaceSize
+ regs
.size() )
77 throw AccessViolation("writeRam: Tried to write to register area");
79 offset
-= registerSpaceSize
+ regs
.size();
80 sram
.write(offset
, data
, size
);
83 byte
MMU::readByte(unsigned int offset
) const {
84 if( offset
< registerSpaceSize
)
87 offset
-= registerSpaceSize
;
88 if( offset
< regs
.size() )
89 return regs
.readByte(offset
);
91 offset
-= regs
.size();
92 if( offset
< sram
.size() )
93 return sram
.readByte(offset
);
95 offset
-= sram
.size();
96 // if( (eram != 0) && (offset < eram->size()) )
97 // return eram->readByte(offset);
99 throw AccessViolation();
102 word
MMU::readWord(unsigned int offset
) const {
103 if( offset
< regs
.size() + registerSpaceSize
)
104 throw AccessViolation();
106 offset
-= regs
.size() + registerSpaceSize
;
107 if( offset
< sram
.size() )
108 return sram
.readByte(offset
);
110 offset
-= sram
.size();
111 // if( (eram != 0) && (offset < eram->size()) )
112 // return eram->readByte(offset);
114 throw AccessViolation();
117 void MMU::writeByte(unsigned int offset
, byte val
) {
118 if( offset
< registerSpaceSize
)
121 offset
-= registerSpaceSize
;
122 if( offset
< regs
.size() )
123 return regs
.writeByte(offset
, val
);
125 offset
-= regs
.size();
126 if( offset
< sram
.size() )
127 return sram
.writeByte(offset
, val
);
129 offset
-= sram
.size();
130 // if( (eram != 0) && (offset < eram->size()) )
131 // return eram->writeByte(offset, val);
133 throw AccessViolation();
136 void MMU::writeWord(unsigned int offset
, word val
) {
137 if( offset
< regs
.size() + registerSpaceSize
)
138 throw AccessViolation();
140 offset
-= regs
.size() + registerSpaceSize
;
141 if( offset
< sram
.size() )
142 return sram
.writeWord(offset
, val
);
144 offset
-= sram
.size();
145 // if( (eram != 0) && (offset < eram->size()) )
146 // return eram->writeByte(offset, val);
148 throw AccessViolation();
151 void MMU::addIOReg(unsigned int address
,
152 const std::string
& name
, byte initial
) {
154 new IORegister(address
, name
, initial
);
155 regs
.addReg( address
- registerSpaceSize
, r
);