Start adding enough infrastructure to support memory mapped IO on LR35902.

Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
Adrian.Conlon 2017-07-18 00:13:41 +01:00
parent 627d30e896
commit 35def4184a
3 changed files with 89 additions and 37 deletions

View File

@ -56,9 +56,45 @@ namespace EightBit {
virtual void reset(); virtual void reset();
virtual void initialise(); virtual void initialise();
protected:
virtual uint8_t fetchByte() {
auto returned = IntelProcessor::fetchByte();
m_memory.fireReadBusEvent();
return returned;
}
virtual void push(uint8_t value) {
IntelProcessor::push(value);
m_memory.fireWriteBusEvent();
}
virtual uint8_t pop() {
auto returned = IntelProcessor::pop();
m_memory.fireReadBusEvent();
return returned;
}
virtual void getWordViaMemptr(register16_t& value) {
value.low = memptrReference();
m_memory.fireReadBusEvent();
m_memory.ADDRESS().word++;
value.high = m_memory.reference();
m_memory.fireReadBusEvent();
}
virtual void setWordViaMemptr(register16_t value) {
memptrReference() = value.low;
m_memory.fireWriteBusEvent();
m_memory.ADDRESS().word++;
m_memory.reference() = value.high;
m_memory.fireWriteBusEvent();
}
private: private:
enum { BC_IDX, DE_IDX, HL_IDX }; enum { BC_IDX, DE_IDX, HL_IDX };
Bus& m_bus;
std::array<register16_t, 3> m_registers; std::array<register16_t, 3> m_registers;
register16_t m_accumulatorFlag; register16_t m_accumulatorFlag;

View File

@ -6,6 +6,7 @@
EightBit::LR35902::LR35902(Bus& memory) EightBit::LR35902::LR35902(Bus& memory)
: IntelProcessor(memory), : IntelProcessor(memory),
m_bus(memory),
m_ime(false), m_ime(false),
m_prefixCB(false) { m_prefixCB(false) {
} }
@ -464,26 +465,34 @@ void EightBit::LR35902::executeCB(int x, int y, int z, int p, int q) {
} }
adjustZero<LR35902>(F(), R(z)); adjustZero<LR35902>(F(), R(z));
cycles += 2; cycles += 2;
if (z == 6) if (z == 6) {
m_bus.fireWriteBusEvent();
cycles += 2; cycles += 2;
}
break; break;
case 1: // BIT y, r[z] case 1: // BIT y, r[z]
bit(y, R(z)); bit(y, R(z));
cycles += 2; cycles += 2;
if (z == 6) if (z == 6) {
m_bus.fireReadBusEvent();
cycles += 2; cycles += 2;
}
break; break;
case 2: // RES y, r[z] case 2: // RES y, r[z]
res(y, R(z)); res(y, R(z));
cycles += 2; cycles += 2;
if (z == 6) if (z == 6) {
m_bus.fireWriteBusEvent();
cycles += 2; cycles += 2;
}
break; break;
case 3: // SET y, r[z] case 3: // SET y, r[z]
set(y, R(z)); set(y, R(z));
cycles += 2; cycles += 2;
if (z == 6) if (z == 6) {
m_bus.fireWriteBusEvent();
cycles += 2; cycles += 2;
}
break; break;
} }
} }
@ -538,23 +547,19 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 0: case 0:
switch (p) { switch (p) {
case 0: // LD (BC),A case 0: // LD (BC),A
m_memory.ADDRESS() = BC(); m_memory.write(BC().word, A());
m_memory.reference() = A();
cycles += 2; cycles += 2;
break; break;
case 1: // LD (DE),A case 1: // LD (DE),A
m_memory.ADDRESS() = DE(); m_memory.write(DE().word, A());
m_memory.reference() = A();
cycles += 2; cycles += 2;
break; break;
case 2: // GB: LDI (HL),A case 2: // GB: LDI (HL),A
m_memory.ADDRESS().word = HL().word++; m_memory.write(HL().word++, A());
m_memory.reference() = A();
cycles += 2; cycles += 2;
break; break;
case 3: // GB: LDD (HL),A case 3: // GB: LDD (HL),A
m_memory.ADDRESS().word = HL().word--; m_memory.write(HL().word--, A());
m_memory.reference() = A();
cycles += 2; cycles += 2;
break; break;
} }
@ -562,23 +567,19 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 1: case 1:
switch (p) { switch (p) {
case 0: // LD A,(BC) case 0: // LD A,(BC)
m_memory.ADDRESS() = BC(); A() = m_memory.read(BC().word);
A() = m_memory.reference();
cycles += 2; cycles += 2;
break; break;
case 1: // LD A,(DE) case 1: // LD A,(DE)
m_memory.ADDRESS() = DE(); A() = m_memory.read(DE().word);
A() = m_memory.reference();
cycles += 2; cycles += 2;
break; break;
case 2: // GB: LDI A,(HL) case 2: // GB: LDI A,(HL)
m_memory.ADDRESS().word = HL().word++; A() = m_memory.read(HL().word++);
A() = m_memory.reference();
cycles += 2; cycles += 2;
break; break;
case 3: // GB: LDD A,(HL) case 3: // GB: LDD A,(HL)
m_memory.ADDRESS().word = HL().word--; A() = m_memory.read(HL().word--);
A() = m_memory.reference();
cycles += 2; cycles += 2;
break; break;
} }
@ -599,17 +600,23 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
case 4: // 8-bit INC case 4: // 8-bit INC
postIncrement(F(), ++R(y)); // INC r postIncrement(F(), ++R(y)); // INC r
cycles++; cycles++;
if (y == 6) if (y == 6) {
m_bus.fireWriteBusEvent();
cycles += 2; cycles += 2;
}
break; break;
case 5: // 8-bit DEC case 5: // 8-bit DEC
postDecrement(F(), --R(y)); // DEC r postDecrement(F(), --R(y)); // DEC r
cycles++; cycles++;
if (y == 6) if (y == 6) {
m_bus.fireWriteBusEvent();
cycles += 2; cycles += 2;
}
break; break;
case 6: // 8-bit load immediate case 6: // 8-bit load immediate
R(y) = fetchByte(); R(y) = fetchByte();
if (y == 6)
m_bus.fireWriteBusEvent();
cycles += 2; cycles += 2;
break; break;
case 7: // Assorted operations on accumulator/flags case 7: // Assorted operations on accumulator/flags
@ -652,8 +659,13 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
halt(); halt();
} else { } else {
R(y) = R(z); R(y) = R(z);
if ((y == 6) || (z == 6)) // M operations if ((y == 6) || (z == 6)) { // M operations
if (y == 6)
m_bus.fireWriteBusEvent();
else
m_bus.fireReadBusEvent();
cycles++; cycles++;
}
} }
cycles++; cycles++;
break; break;
@ -685,8 +697,10 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
break; break;
} }
cycles++; cycles++;
if (z == 6) if (z == 6) {
m_bus.fireReadBusEvent();
cycles++; cycles++;
}
break; break;
case 3: case 3:
switch (z) { switch (z) {
@ -698,8 +712,8 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
} else { } else {
switch (y) { switch (y) {
case 4: // GB: LD (FF00 + n),A case 4: // GB: LD (FF00 + n),A
m_memory.ADDRESS().word = 0xff00 + fetchByte(); m_bus.REG(fetchByte()) = A();
m_memory.reference() = A(); m_bus.fireWriteBusEvent();
cycles += 3; cycles += 3;
break; break;
case 5: { // GB: ADD SP,dd case 5: { // GB: ADD SP,dd
@ -715,8 +729,8 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
cycles += 4; cycles += 4;
break; break;
case 6: // GB: LD A,(FF00 + n) case 6: // GB: LD A,(FF00 + n)
m_memory.ADDRESS().word = 0xff00 + fetchByte(); A() = m_bus.REG(fetchByte());
A() = m_memory.reference(); m_bus.fireReadBusEvent();
cycles += 3; cycles += 3;
break; break;
case 7: { // GB: LD HL,SP + dd case 7: { // GB: LD HL,SP + dd
@ -768,25 +782,27 @@ void EightBit::LR35902::executeOther(int x, int y, int z, int p, int q) {
} else { } else {
switch (y) { switch (y) {
case 4: // GB: LD (FF00 + C),A case 4: // GB: LD (FF00 + C),A
m_memory.ADDRESS().word = 0xff00 + C(); m_bus.REG(C()) = A();
m_memory.reference() = A(); m_bus.fireWriteBusEvent();
cycles += 2; cycles += 2;
break; break;
case 5: // GB: LD (nn),A case 5: // GB: LD (nn),A
fetchWord(); fetchWord();
m_memory.ADDRESS() = MEMPTR(); m_memory.ADDRESS() = MEMPTR();
m_memory.reference() = A(); m_memory.reference() = A();
m_bus.fireWriteBusEvent();
cycles += 4; cycles += 4;
break; break;
case 6: // GB: LD A,(FF00 + C) case 6: // GB: LD A,(FF00 + C)
m_memory.ADDRESS().word = 0xff00 + C(); A() = m_bus.REG(C());
A() = m_memory.reference(); m_bus.fireReadBusEvent();
cycles += 2; cycles += 2;
break; break;
case 7: // GB: LD A,(nn) case 7: // GB: LD A,(nn)
fetchWord(); fetchWord();
m_memory.ADDRESS() = MEMPTR(); m_memory.ADDRESS() = MEMPTR();
A() = m_memory.reference(); A() = m_memory.reference();
m_bus.fireReadBusEvent();
cycles += 4; cycles += 4;
break; break;
} }

View File

@ -94,7 +94,7 @@ namespace EightBit {
return m_halfCarryTableSub[index & Mask3]; return m_halfCarryTableSub[index & Mask3];
} }
uint8_t fetchByte() { virtual uint8_t fetchByte() {
m_memory.ADDRESS().word = PC().word++; m_memory.ADDRESS().word = PC().word++;
return m_memory.reference(); return m_memory.reference();
} }
@ -104,7 +104,7 @@ namespace EightBit {
output.high = fetchByte(); output.high = fetchByte();
} }
void push(uint8_t value) { virtual void push(uint8_t value) {
m_memory.ADDRESS().word = --SP().word; m_memory.ADDRESS().word = --SP().word;
m_memory.reference() = value; m_memory.reference() = value;
} }
@ -114,7 +114,7 @@ namespace EightBit {
push(value.low); push(value.low);
} }
uint8_t pop() { virtual uint8_t pop() {
m_memory.ADDRESS().word = SP().word++; m_memory.ADDRESS().word = SP().word++;
return m_memory.reference(); return m_memory.reference();
} }
@ -136,13 +136,13 @@ namespace EightBit {
return m_memory.reference(); return m_memory.reference();
} }
void getWordViaMemptr(register16_t& value) { virtual void getWordViaMemptr(register16_t& value) {
value.low = memptrReference(); value.low = memptrReference();
m_memory.ADDRESS().word++; m_memory.ADDRESS().word++;
value.high = m_memory.reference(); value.high = m_memory.reference();
} }
void setWordViaMemptr(register16_t value) { virtual void setWordViaMemptr(register16_t value) {
memptrReference() = value.low; memptrReference() = value.low;
m_memory.ADDRESS().word++; m_memory.ADDRESS().word++;
m_memory.reference() = value.high; m_memory.reference() = value.high;