Reinstate operation timings (TBC)

Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
Adrian.Conlon 2017-07-15 23:19:46 +01:00
parent 3084d2341c
commit d1bb49143d
2 changed files with 55 additions and 24 deletions

View File

@ -163,15 +163,19 @@ namespace EightBit {
return m_memory.reference(); return m_memory.reference();
} }
uint8_t& AM_AbsoluteX() { uint8_t& AM_AbsoluteX(bool read = true) {
Address_AbsoluteX(); Address_AbsoluteX();
m_memory.ADDRESS() = m_memptr; m_memory.ADDRESS() = m_memptr;
if (read && (m_memory.ADDRESS().low == 0xff))
++cycles;
return m_memory.reference(); return m_memory.reference();
} }
uint8_t& AM_AbsoluteY() { uint8_t& AM_AbsoluteY(bool read = true) {
Address_AbsoluteY(); Address_AbsoluteY();
m_memory.ADDRESS() = m_memptr; m_memory.ADDRESS() = m_memptr;
if (read && (m_memory.ADDRESS().low == 0xff))
++cycles;
return m_memory.reference(); return m_memory.reference();
} }
@ -193,9 +197,11 @@ namespace EightBit {
return m_memory.reference(); return m_memory.reference();
} }
uint8_t& AM_IndirectIndexedY() { uint8_t& AM_IndirectIndexedY(bool read = true) {
Address_IndirectIndexedY(); Address_IndirectIndexedY();
m_memory.ADDRESS() = m_memptr; m_memory.ADDRESS() = m_memptr;
if (read && (m_memory.ADDRESS().low == 0xff))
++cycles;
return m_memory.reference(); return m_memory.reference();
} }
@ -203,7 +209,7 @@ namespace EightBit {
#pragma region 6502 addressing mode switching #pragma region 6502 addressing mode switching
uint8_t& AM_00(int bbb) { uint8_t& AM_00(int bbb, bool read = true) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_Immediate(); return AM_Immediate();
@ -214,7 +220,7 @@ namespace EightBit {
case 0b101: case 0b101:
return AM_ZeroPageX(); return AM_ZeroPageX();
case 0b111: case 0b111:
return AM_AbsoluteX(); return AM_AbsoluteX(read);
case 0b010: case 0b010:
case 0b100: case 0b100:
case 0b110: case 0b110:
@ -224,7 +230,7 @@ namespace EightBit {
} }
} }
uint8_t& AM_01(int bbb) { uint8_t& AM_01(int bbb, bool read = true) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_IndexedIndirectX(); return AM_IndexedIndirectX();
@ -235,19 +241,19 @@ namespace EightBit {
case 0b011: case 0b011:
return AM_Absolute(); return AM_Absolute();
case 0b100: case 0b100:
return AM_IndirectIndexedY(); return AM_IndirectIndexedY(read);
case 0b101: case 0b101:
return AM_ZeroPageX(); return AM_ZeroPageX();
case 0b110: case 0b110:
return AM_AbsoluteY(); return AM_AbsoluteY(read);
case 0b111: case 0b111:
return AM_AbsoluteX(); return AM_AbsoluteX(read);
default: default:
__assume(0); __assume(0);
} }
} }
uint8_t& AM_10(int bbb) { uint8_t& AM_10(int bbb, bool read = true) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_Immediate(); return AM_Immediate();
@ -260,7 +266,7 @@ namespace EightBit {
case 0b101: case 0b101:
return AM_ZeroPageX(); return AM_ZeroPageX();
case 0b111: case 0b111:
return AM_AbsoluteX(); return AM_AbsoluteX(read);
case 0b100: case 0b100:
case 0b110: case 0b110:
throw std::domain_error("Illegal addressing mode"); throw std::domain_error("Illegal addressing mode");
@ -269,7 +275,7 @@ namespace EightBit {
} }
} }
uint8_t& AM_10_x(int bbb) { uint8_t& AM_10_x(int bbb, bool read = true) {
switch (bbb) { switch (bbb) {
case 0b000: case 0b000:
return AM_Immediate(); return AM_Immediate();
@ -282,7 +288,7 @@ namespace EightBit {
case 0b101: case 0b101:
return AM_ZeroPageY(); return AM_ZeroPageY();
case 0b111: case 0b111:
return AM_AbsoluteY(); return AM_AbsoluteY(read);
case 0b100: case 0b100:
case 0b110: case 0b110:
throw std::domain_error("Illegal addressing mode"); throw std::domain_error("Illegal addressing mode");
@ -356,5 +362,7 @@ namespace EightBit {
uint8_t p; // processor status uint8_t p; // processor status
register16_t m_memptr; register16_t m_memptr;
std::array<int, 0x100> m_timings;
}; };
} }

View File

@ -3,6 +3,25 @@
EightBit::MOS6502::MOS6502(Memory& memory) EightBit::MOS6502::MOS6502(Memory& memory)
: Processor(memory) { : Processor(memory) {
m_timings = {
//// 0 1 2 3 4 5 6 7 8 9 A B C D E F
/* 0 */ 7, 6, 0, 0, 0, 4, 5, 0, 3, 2, 2, 0, 0, 4, 6, 0,
/* 1 */ 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
/* 2 */ 6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0,
/* 3 */ 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
/* 4 */ 6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0,
/* 5 */ 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
/* 6 */ 6, 6, 0, 0, 0, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0,
/* 7 */ 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
/* 8 */ 0, 6, 0, 0, 3, 3, 3, 0, 2, 0, 2, 0, 4, 4, 4, 0,
/* 9 */ 2, 6, 0, 0, 4, 4, 4, 0, 2, 5, 2, 0, 0, 5, 0, 0,
/* A */ 2, 6, 2, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0,
/* B */ 2, 5, 0, 0, 4, 4, 4, 0, 2, 4, 2, 0, 4, 4, 4, 0,
/* C */ 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
/* D */ 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
/* E */ 2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0,
/* F */ 2, 5, 0, 0, 0, 4, 6, 0, 2, 4, 0, 0, 0, 4, 7, 0,
};
} }
void EightBit::MOS6502::initialise() { void EightBit::MOS6502::initialise() {
@ -61,7 +80,7 @@ void EightBit::MOS6502::Interrupt(uint16_t vector) {
int EightBit::MOS6502::Execute(uint8_t cell) { int EightBit::MOS6502::Execute(uint8_t cell) {
cycles = 1; cycles = m_timings[cell];
// http://www.llx.com/~nparker/a2/opcodes.html // http://www.llx.com/~nparker/a2/opcodes.html
@ -110,7 +129,7 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
setFlag(P(), CF); setFlag(P(), CF);
break; break;
default: // BIT default: // BIT
BIT(AM_00(bbb)); BIT(AM_00(bbb, false));
break; break;
} }
break; break;
@ -168,7 +187,7 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
UpdateZeroNegativeFlags(A() = Y()); UpdateZeroNegativeFlags(A() = Y());
break; break;
default: // STY default: // STY
AM_00(bbb) = Y(); AM_00(bbb, false) = Y();
break; break;
} }
break; break;
@ -237,7 +256,7 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
ADC(AM_01(bbb)); ADC(AM_01(bbb));
break; break;
case 0b100: // STA case 0b100: // STA
AM_01(bbb) = A(); AM_01(bbb, false) = A();
break; break;
case 0b101: // LDA case 0b101: // LDA
LDA(AM_01(bbb)); LDA(AM_01(bbb));
@ -255,16 +274,16 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
case 0b10: case 0b10:
switch (aaa) { switch (aaa) {
case 0b000: // ASL case 0b000: // ASL
ASL(AM_10(bbb)); ASL(AM_10(bbb, false));
break; break;
case 0b001: // ROL case 0b001: // ROL
ROL(AM_10(bbb)); ROL(AM_10(bbb, false));
break; break;
case 0b010: // LSR case 0b010: // LSR
LSR(AM_10(bbb)); LSR(AM_10(bbb, false));
break; break;
case 0b011: // ROR case 0b011: // ROR
ROR(AM_10(bbb)); ROR(AM_10(bbb, false));
break; break;
case 0b100: case 0b100:
switch (bbb) { switch (bbb) {
@ -275,7 +294,7 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
S() = X(); S() = X();
break; break;
default: // STX default: // STX
AM_10_x(bbb) = X(); AM_10_x(bbb, false) = X();
break; break;
} }
break; break;
@ -295,7 +314,7 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
DEC(X()); DEC(X());
break; break;
default: // DEC default: // DEC
DEC(AM_10(bbb)); DEC(AM_10(bbb, false));
break; break;
} }
break; break;
@ -304,7 +323,7 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
case 0b010: // NOP case 0b010: // NOP
break; break;
default: // INC default: // INC
INC(AM_10(bbb)); INC(AM_10(bbb, false));
break; break;
} }
break; break;
@ -510,7 +529,11 @@ void EightBit::MOS6502::ADC_d(uint8_t data) {
//// ////
void EightBit::MOS6502::Branch(int8_t displacement) { void EightBit::MOS6502::Branch(int8_t displacement) {
auto page = PC().high;
PC().word += displacement; PC().word += displacement;
if (PC().high != page)
cycles++;
cycles++;
} }
void EightBit::MOS6502::Branch(bool flag) { void EightBit::MOS6502::Branch(bool flag) {