2 #include "RuntimeException.h"
3 #include "ImplementationException.h"
4 #include "Instruction.h"
7 #include "DebugInterface.h"
11 Core::Core(Bus
& bus
, unsigned int ioSpaceSize
,
12 unsigned int ramSize
, unsigned int flashSize
,
13 word stackMask
, int pcBytes
, ERam
*eram
/*= 0*/)
14 : regs( ioSpaceSize
),
15 sram( ramSize
), flash(flashSize
),
16 eram(eram
), mmu( R
, regs
, sram
, eram
),
17 stack(bus
, mmu
, stackMask
), bus(bus
),
18 pc_bytes( pcBytes
), dbgi(0) {
20 static const char * Rnames
[32] = {
21 "r0", "r1", "r2", "r3", "r4", "r5",
22 "r6", "r7", "r8", "r9", "r10", "r11",
23 "r12", "r13", "r14", "r15", "r16", "r17",
24 "r18", "r19", "r20", "r21", "r22", "r23",
25 "r24", "r25", "r26", "r27", "r28", "r29",
28 for(int i
= 0; i
< 32; ++i
)
29 R
[i
].init(i
, Rnames
[i
]);
37 void Core::addIOReg(unsigned int address
,
38 const std::string
& name
, byte initial
) {
40 new IORegister(address
+ registerSpaceSize
, name
, initial
);
41 regs
.addReg( address
, r
);
45 // Get some special registers
46 SReg
= regs
.getIoreg("SREG")->getAddress() - registerSpaceSize
;
47 stack
.attachReg("sph", regs
.getIoreg("SPH"));
48 stack
.attachReg("spl", regs
.getIoreg("SPL"));
51 int Core::writeFlash(unsigned int addr
, word data
) {
52 //flash.write(addr, (unsigned char *)&data, 2);
53 throw util::RuntimeException("Writing to flash is not yet supported");
56 byte
Core::readRegister(int i
) const {
57 if( (unsigned int)i
>= registerSpaceSize
)
58 throw util::RuntimeException("Tried to access not existing register");
63 void Core::writeRegister(int i
, byte val
) {
64 if( (unsigned int)i
>= registerSpaceSize
)
65 throw util::RuntimeException("Tried to access not existing register");
70 void Core::jump(sbyte offset
, bool push
/*= false*/) {
73 for(int tt
= 0; tt
< pc_bytes
; tt
++) {
74 stack
.push( val
& 0xff );
82 void Core::call(dword addr
, bool push
/*= true*/) {
85 for(int tt
= 0; tt
< pc_bytes
; tt
++) {
86 stack
.push( val
& 0xff );
94 void Core::ret(bool interrupt
/*= false*/) {
96 for(int tt
= 0; tt
< pc_bytes
; tt
++) {
104 word
Core::fetchOperand() {
106 unsigned int addr
= PC
<<1;
107 word op
= flash
.readWord( addr
);
113 unsigned int addr
= (PC
+1)<<1;
114 word opcode
= flash
.readWord( addr
);
115 if( decoder
.is2WordInstruction(opcode
) )
122 void Core::reset(unsigned int type
) {
123 Trace::instance().reset(type
);
132 const IORegister
& mcucr
= *regs
.getIoreg("MCUCR");
133 static const byte sleepEnable
= (1<<5);
134 if( mcucr
& sleepEnable
) {
135 //const IORegister *emcucr = regs.getIoreg("EMCUCR", false);
136 sleepMode
= SLEEP_MODE_IDLE
;
138 // TODO The bit locations for the sleep mode are different between devices...
139 throw util::ImplementationException("Instruction SLEEP not fully implemented");
143 bool Core::interrupt(unsigned int vector
, unsigned int addr
) {
145 // TODO IVSEL bit in GICR
147 static const unsigned char Ibit
= 0x80;
149 IORegister
& S
= getIoreg(SReg
);
150 if( (S
& Ibit
) == 0 )
153 Trace::instance().interrupt( addr
);
157 unsigned int offset
= 0;
158 call( offset
+ addr
, true );
160 S
&= (unsigned char)~Ibit
;
165 if( cpuCycles
<= 0 ) {
167 unsigned int addr
= PC
<<1;
168 if( (dbgi
== 0) || ! dbgi
->checkBreak(addr
) ) {
170 word opcode
= flash
.readWord( addr
);
171 Trace::instance().pc_trace( addr
);
172 //std::cout << "Fetch opcode: " << std::hex << opcode << std::dec << std::endl;
173 Instruction
& instr
= decoder
.decode(opcode
);
174 cpuCycles
= instr(this) - 1;
178 } catch( util::ImplementationException
& ex
) {
179 std::cerr
<< ex
.message() << ": continuing" << std::endl
;
184 // Waiting for instruction to finish
188 return (cpuCycles
== 0);