mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-09-01 15:29:11 +00:00
Reinstate operation timings (TBC)
Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
parent
3084d2341c
commit
d1bb49143d
@ -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;
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user