mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-04-06 12:37:33 +00:00
Make the 6502 a little more compatible with other processor implementations.
Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
parent
867b0d5260
commit
4f491f110e
@ -12,18 +12,36 @@
|
||||
namespace EightBit {
|
||||
class MOS6502 : public Processor {
|
||||
public:
|
||||
struct opcode_decoded_t {
|
||||
|
||||
int aaa;
|
||||
int bbb;
|
||||
int cc;
|
||||
|
||||
opcode_decoded_t() {
|
||||
aaa = bbb = cc = 0;
|
||||
}
|
||||
|
||||
opcode_decoded_t(uint8_t opcode) {
|
||||
aaa = (opcode & 0b11100000) >> 5; // 0 - 7
|
||||
bbb = (opcode & 0b00011100) >> 2; // 0 - 7
|
||||
cc = (opcode & 0b00000011); // 0 - 3
|
||||
}
|
||||
};
|
||||
|
||||
enum StatusBits {
|
||||
NF = 0x80, // Negative
|
||||
VF = 0x40, // Overflow
|
||||
RF = 0x20, // reserved
|
||||
BF = 0x10, // Brk
|
||||
DF = 0x08, // D (use BCD for arithmetic)
|
||||
IF = 0x04, // I (IRQ disable)
|
||||
ZF = 0x02, // Zero
|
||||
CF = 0x01, // Carry
|
||||
NF = Bit7, // Negative
|
||||
VF = Bit6, // Overflow
|
||||
RF = Bit5, // reserved
|
||||
BF = Bit4, // Brk
|
||||
DF = Bit3, // D (use BCD for arithmetic)
|
||||
IF = Bit2, // I (IRQ disable)
|
||||
ZF = Bit1, // Zero
|
||||
CF = Bit0, // Carry
|
||||
};
|
||||
|
||||
MOS6502(Memory& memory);
|
||||
virtual ~MOS6502();
|
||||
|
||||
Signal<MOS6502> ExecutingInstruction;
|
||||
Signal<MOS6502> ExecutedInstruction;
|
||||
@ -58,6 +76,8 @@ namespace EightBit {
|
||||
virtual int Execute(uint8_t cell);
|
||||
|
||||
private:
|
||||
register16_t& MEMPTR() { return m_memptr; }
|
||||
|
||||
void adjustZero(uint8_t datum) { clearFlag(P(), ZF, datum); }
|
||||
void adjustNegative(uint8_t datum) { setFlag(P(), NF, datum & NF); }
|
||||
|
||||
@ -79,61 +99,55 @@ namespace EightBit {
|
||||
#pragma region Addresses
|
||||
|
||||
void Address_Absolute() {
|
||||
FetchWord(m_memptr);
|
||||
FetchWord(MEMPTR());
|
||||
}
|
||||
|
||||
void Address_ZeroPage() {
|
||||
m_memptr.low = FetchByte();
|
||||
m_memptr.high = 0;
|
||||
MEMPTR().low = FetchByte();
|
||||
MEMPTR().high = 0;
|
||||
}
|
||||
|
||||
void Address_ZeroPageIndirect() {
|
||||
Address_ZeroPage();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
GetWord(m_memptr);
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
GetWord(MEMPTR());
|
||||
}
|
||||
|
||||
void Address_Indirect() {
|
||||
Address_Absolute();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
GetWord(m_memptr);
|
||||
}
|
||||
|
||||
void Address_IndirectX() {
|
||||
Address_Absolute();
|
||||
m_memory.ADDRESS().word = m_memptr.word + X();
|
||||
GetWord(m_memptr);
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
GetWord(MEMPTR());
|
||||
}
|
||||
|
||||
void Address_ZeroPageX() {
|
||||
Address_ZeroPage();
|
||||
m_memptr.low += X();
|
||||
MEMPTR().low += X();
|
||||
}
|
||||
|
||||
void Address_ZeroPageY() {
|
||||
Address_ZeroPage();
|
||||
m_memptr.low += Y();
|
||||
MEMPTR().low += Y();
|
||||
}
|
||||
|
||||
void Address_AbsoluteX() {
|
||||
Address_Absolute();
|
||||
m_memptr.word += X();
|
||||
MEMPTR().word += X();
|
||||
}
|
||||
|
||||
void Address_AbsoluteY() {
|
||||
Address_Absolute();
|
||||
m_memptr.word += Y();
|
||||
MEMPTR().word += Y();
|
||||
}
|
||||
|
||||
void Address_IndexedIndirectX() {
|
||||
Address_ZeroPageX();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
GetWord(m_memptr);
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
GetWord(MEMPTR());
|
||||
}
|
||||
|
||||
void Address_IndirectIndexedY() {
|
||||
Address_ZeroPageIndirect();
|
||||
m_memptr.word += Y();
|
||||
MEMPTR().word += Y();
|
||||
}
|
||||
|
||||
#pragma endregion Addresses
|
||||
@ -154,22 +168,22 @@ namespace EightBit {
|
||||
uint8_t& AM_Absolute() {
|
||||
m_busRW = true;
|
||||
Address_Absolute();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
return m_memory.reference();
|
||||
}
|
||||
|
||||
uint8_t& AM_ZeroPage() {
|
||||
m_busRW = true;
|
||||
Address_ZeroPage();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
return m_memory.reference();
|
||||
}
|
||||
|
||||
uint8_t& AM_AbsoluteX(bool read = true) {
|
||||
m_busRW = true;
|
||||
Address_AbsoluteX();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
if (read && (m_memory.ADDRESS().low == 0xff))
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
if (read && (m_memory.ADDRESS().low == Mask8))
|
||||
++cycles;
|
||||
return m_memory.reference();
|
||||
}
|
||||
@ -177,8 +191,8 @@ namespace EightBit {
|
||||
uint8_t& AM_AbsoluteY(bool read = true) {
|
||||
m_busRW = true;
|
||||
Address_AbsoluteY();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
if (read && (m_memory.ADDRESS().low == 0xff))
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
if (read && (m_memory.ADDRESS().low == Mask8))
|
||||
++cycles;
|
||||
return m_memory.reference();
|
||||
}
|
||||
@ -186,29 +200,29 @@ namespace EightBit {
|
||||
uint8_t& AM_ZeroPageX() {
|
||||
m_busRW = true;
|
||||
Address_ZeroPageX();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
return m_memory.reference();
|
||||
}
|
||||
|
||||
uint8_t& AM_ZeroPageY() {
|
||||
m_busRW = true;
|
||||
Address_ZeroPageY();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
return m_memory.reference();
|
||||
}
|
||||
|
||||
uint8_t& AM_IndexedIndirectX() {
|
||||
m_busRW = true;
|
||||
Address_IndexedIndirectX();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
return m_memory.reference();
|
||||
}
|
||||
|
||||
uint8_t& AM_IndirectIndexedY(bool read = true) {
|
||||
m_busRW = true;
|
||||
Address_IndirectIndexedY();
|
||||
m_memory.ADDRESS() = m_memptr;
|
||||
if (read && (m_memory.ADDRESS().low == 0xff))
|
||||
m_memory.ADDRESS() = MEMPTR();
|
||||
if (read && (m_memory.ADDRESS().low == Mask8))
|
||||
++cycles;
|
||||
return m_memory.reference();
|
||||
}
|
||||
@ -309,36 +323,22 @@ namespace EightBit {
|
||||
|
||||
#pragma endregion 6502 addressing modes
|
||||
|
||||
void DEC(uint8_t& output);
|
||||
|
||||
void ROR(uint8_t& output);
|
||||
|
||||
void LSR(uint8_t& output);
|
||||
|
||||
void BIT(uint8_t data);
|
||||
|
||||
void INC(uint8_t& output);
|
||||
|
||||
void ROL(uint8_t& output);
|
||||
|
||||
void ASL(uint8_t& output);
|
||||
|
||||
void ORA(uint8_t data);
|
||||
|
||||
void AND(uint8_t data);
|
||||
|
||||
void SBC(uint8_t data);
|
||||
void SBC_b(uint8_t data);
|
||||
void SBC_d(uint8_t data);
|
||||
|
||||
void EOR(uint8_t data);
|
||||
|
||||
void CMP(uint8_t first, uint8_t second);
|
||||
|
||||
void LDA(uint8_t data);
|
||||
void LDY(uint8_t data);
|
||||
void LDX(uint8_t data);
|
||||
|
||||
void ADC(uint8_t data);
|
||||
void ADC_b(uint8_t data);
|
||||
void ADC_d(uint8_t data);
|
||||
@ -355,7 +355,6 @@ namespace EightBit {
|
||||
void RTS();
|
||||
void JMP_abs();
|
||||
void JMP_ind();
|
||||
void JMP_absxind();
|
||||
void BRK();
|
||||
|
||||
const uint16_t PageOne = 0x100;
|
||||
@ -372,6 +371,7 @@ namespace EightBit {
|
||||
register16_t m_memptr;
|
||||
|
||||
std::array<int, 0x100> m_timings;
|
||||
std::array<opcode_decoded_t, 0x100> m_decodedOpcodes;
|
||||
|
||||
bool m_busRW;
|
||||
};
|
||||
|
@ -24,21 +24,28 @@ EightBit::MOS6502::MOS6502(Memory& memory)
|
||||
};
|
||||
}
|
||||
|
||||
EightBit::MOS6502::~MOS6502() {
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::initialise() {
|
||||
|
||||
Processor::initialise();
|
||||
|
||||
for (int i = 0; i < 0x100; ++i) {
|
||||
m_decodedOpcodes[i] = i;
|
||||
}
|
||||
|
||||
PC().word = 0;
|
||||
X() = 0x80;
|
||||
X() = Bit7;
|
||||
Y() = 0;
|
||||
A() = 0;
|
||||
|
||||
P() = 0;
|
||||
setFlag(P(), RF);
|
||||
|
||||
S() = 0xff;
|
||||
S() = Mask8;
|
||||
|
||||
m_memptr.word = 0;
|
||||
MEMPTR().word = 0;
|
||||
}
|
||||
|
||||
int EightBit::MOS6502::step() {
|
||||
@ -89,15 +96,13 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
// The aaa and cc bits determine the opcode, and the bbb
|
||||
// bits determine the addressing mode.
|
||||
|
||||
auto aaa = (cell & 0b11100000) >> 5;
|
||||
auto bbb = (cell & 0b00011100) >> 2;
|
||||
auto cc = (cell & 0b00000011);
|
||||
const auto& decoded = m_decodedOpcodes[cell];
|
||||
|
||||
switch (cc) {
|
||||
switch (decoded.cc) {
|
||||
case 0b00:
|
||||
switch (aaa) {
|
||||
switch (decoded.aaa) {
|
||||
case 0b000:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b000: // BRK
|
||||
BRK();
|
||||
break;
|
||||
@ -115,7 +120,7 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
}
|
||||
break;
|
||||
case 0b001:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b000: // JSR
|
||||
JSR_abs();
|
||||
break;
|
||||
@ -129,14 +134,14 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
setFlag(P(), CF);
|
||||
break;
|
||||
default: // BIT
|
||||
BIT(AM_00(bbb, false));
|
||||
BIT(AM_00(decoded.bbb));
|
||||
assert(m_busRW);
|
||||
m_memory.read();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b010:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b000: // RTI
|
||||
RTI();
|
||||
break;
|
||||
@ -157,7 +162,7 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
}
|
||||
break;
|
||||
case 0b011:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b000: // RTS
|
||||
RTS();
|
||||
break;
|
||||
@ -178,9 +183,9 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
}
|
||||
break;
|
||||
case 0b100:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b010: // DEY
|
||||
DEC(Y());
|
||||
adjustNZ(--Y());
|
||||
break;
|
||||
case 0b100: // BCC
|
||||
Branch(!(P() & CF));
|
||||
@ -189,14 +194,14 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
adjustNZ(A() = Y());
|
||||
break;
|
||||
default: // STY
|
||||
AM_00(bbb, false);
|
||||
AM_00(decoded.bbb, false);
|
||||
assert(m_busRW);
|
||||
m_memory.write(Y());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b101:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b010: // TAY
|
||||
adjustNZ(Y() = A());
|
||||
break;
|
||||
@ -207,16 +212,16 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
clearFlag(P(), VF);
|
||||
break;
|
||||
default: // LDY
|
||||
LDY(AM_00(bbb));
|
||||
adjustNZ(Y() = AM_00(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b110:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b010: // INY
|
||||
INC(Y());
|
||||
adjustNZ(++Y());
|
||||
break;
|
||||
case 0b100: // BNE
|
||||
Branch(!(P() & ZF));
|
||||
@ -225,16 +230,16 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
clearFlag(P(), DF);
|
||||
break;
|
||||
default: // CPY
|
||||
CMP(Y(), AM_00(bbb));
|
||||
CMP(Y(), AM_00(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b111:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b010: // INX
|
||||
INC(X());
|
||||
adjustNZ(++X());
|
||||
break;
|
||||
case 0b100: // BEQ
|
||||
Branch((P() & ZF) != 0);
|
||||
@ -243,7 +248,7 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
setFlag(P(), DF);
|
||||
break;
|
||||
default: // CPX
|
||||
CMP(X(), AM_00(bbb));
|
||||
CMP(X(), AM_00(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
@ -252,44 +257,44 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
}
|
||||
break;
|
||||
case 0b01:
|
||||
switch (aaa) {
|
||||
switch (decoded.aaa) {
|
||||
case 0b000: // ORA
|
||||
ORA(AM_01(bbb));
|
||||
adjustNZ(A() |= AM_01(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b001: // AND
|
||||
AND(AM_01(bbb));
|
||||
adjustNZ(A() &= AM_01(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b010: // EOR
|
||||
EOR(AM_01(bbb));
|
||||
adjustNZ(A() ^= AM_01(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b011: // ADC
|
||||
ADC(AM_01(bbb));
|
||||
ADC(AM_01(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b100: // STA
|
||||
AM_01(bbb, false);
|
||||
AM_01(decoded.bbb, false);
|
||||
assert(m_busRW);
|
||||
m_memory.write(A());
|
||||
break;
|
||||
case 0b101: // LDA
|
||||
LDA(AM_01(bbb));
|
||||
adjustNZ(A() = AM_01(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b110: // CMP
|
||||
CMP(A(), AM_01(bbb));
|
||||
CMP(A(), AM_01(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b111: // SBC
|
||||
SBC(AM_01(bbb));
|
||||
SBC(AM_01(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
@ -298,29 +303,29 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
}
|
||||
break;
|
||||
case 0b10:
|
||||
switch (aaa) {
|
||||
switch (decoded.aaa) {
|
||||
case 0b000: // ASL
|
||||
ASL(AM_10(bbb, false));
|
||||
ASL(AM_10(decoded.bbb, false));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b001: // ROL
|
||||
ROL(AM_10(bbb, false));
|
||||
ROL(AM_10(decoded.bbb, false));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b010: // LSR
|
||||
LSR(AM_10(bbb, false));
|
||||
LSR(AM_10(decoded.bbb, false));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b011: // ROR
|
||||
ROR(AM_10(bbb, false));
|
||||
ROR(AM_10(decoded.bbb, false));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
case 0b100:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b010: // TXA
|
||||
adjustNZ(A() = X());
|
||||
break;
|
||||
@ -328,42 +333,42 @@ int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
S() = X();
|
||||
break;
|
||||
default: // STX
|
||||
AM_10_x(bbb, false);
|
||||
AM_10_x(decoded.bbb, false);
|
||||
assert(m_busRW);
|
||||
m_memory.write(X());
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b101:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b110: // TSX
|
||||
adjustNZ(X() = S());
|
||||
break;
|
||||
default: // LDX
|
||||
LDX(AM_10_x(bbb));
|
||||
adjustNZ(X() = AM_10_x(decoded.bbb));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b110:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b010: // DEX
|
||||
DEC(X());
|
||||
adjustNZ(--X());
|
||||
break;
|
||||
default: // DEC
|
||||
DEC(AM_10(bbb, false));
|
||||
adjustNZ(--AM_10(decoded.bbb, false));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b111:
|
||||
switch (bbb) {
|
||||
switch (decoded.bbb) {
|
||||
case 0b010: // NOP
|
||||
break;
|
||||
default: // INC
|
||||
INC(AM_10(bbb, false));
|
||||
adjustNZ(++AM_10(decoded.bbb, false));
|
||||
if (m_busRW)
|
||||
m_memory.read();
|
||||
break;
|
||||
@ -415,10 +420,6 @@ void EightBit::MOS6502::FetchWord(register16_t& output) {
|
||||
|
||||
////
|
||||
|
||||
void EightBit::MOS6502::DEC(uint8_t& target) {
|
||||
adjustNZ(--target);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::ROR(uint8_t& output) {
|
||||
auto carry = P() & CF;
|
||||
setFlag(P(), CF, output & CF);
|
||||
@ -437,10 +438,6 @@ void EightBit::MOS6502::BIT(uint8_t data) {
|
||||
setFlag(P(), VF, data & VF);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::INC(uint8_t& output) {
|
||||
adjustNZ(++output);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::ROL(uint8_t& output) {
|
||||
uint8_t result = (output << 1) | (P() & CF);
|
||||
setFlag(P(), CF, output & Bit7);
|
||||
@ -448,18 +445,10 @@ void EightBit::MOS6502::ROL(uint8_t& output) {
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::ASL(uint8_t& output) {
|
||||
setFlag(P(), CF, (output & 0x80) >> 7);
|
||||
setFlag(P(), CF, (output & Bit7) >> 7);
|
||||
adjustNZ(output <<= 1);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::ORA(uint8_t data) {
|
||||
adjustNZ(A() |= data);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::AND(uint8_t data) {
|
||||
adjustNZ(A() &= data);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::SBC(uint8_t data) {
|
||||
if (P() & DF)
|
||||
SBC_d(data);
|
||||
@ -472,7 +461,7 @@ void EightBit::MOS6502::SBC_b(uint8_t data) {
|
||||
difference.word = A() - data - (~P() & CF);
|
||||
|
||||
adjustNZ(difference.low);
|
||||
setFlag(P(), VF, (A() ^ data) & (A() ^ difference.low) & 0x80);
|
||||
setFlag(P(), VF, (A() ^ data) & (A() ^ difference.low) & NF);
|
||||
clearFlag(P(), CF, difference.high);
|
||||
|
||||
A() = difference.low;
|
||||
@ -486,7 +475,7 @@ void EightBit::MOS6502::SBC_d(uint8_t data) {
|
||||
|
||||
adjustNZ(difference.low);
|
||||
|
||||
setFlag(P(), VF, (A() ^ data) & (A() ^ difference.low) & 0x80);
|
||||
setFlag(P(), VF, (A() ^ data) & (A() ^ difference.low) & NF);
|
||||
clearFlag(P(), CF, difference.high);
|
||||
|
||||
auto low = (uint8_t)(lowNibble(A()) - lowNibble(data) - carry);
|
||||
@ -503,10 +492,6 @@ void EightBit::MOS6502::SBC_d(uint8_t data) {
|
||||
A() = promoteNibble(high) | lowNibble(low);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::EOR(uint8_t data) {
|
||||
adjustNZ(A() ^= data);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::CMP(uint8_t first, uint8_t second) {
|
||||
register16_t result;
|
||||
result.word = first - second;
|
||||
@ -514,18 +499,6 @@ void EightBit::MOS6502::CMP(uint8_t first, uint8_t second) {
|
||||
clearFlag(P(), CF, result.high);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::LDA(uint8_t data) {
|
||||
adjustNZ(A() = data);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::LDY(uint8_t data) {
|
||||
adjustNZ(Y() = data);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::LDX(uint8_t data) {
|
||||
adjustNZ(X() = data);
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::ADC(uint8_t data) {
|
||||
if (P() & DF)
|
||||
ADC_d(data);
|
||||
@ -539,7 +512,7 @@ void EightBit::MOS6502::ADC_b(uint8_t data) {
|
||||
sum.word = A() + data + (P() & CF);
|
||||
|
||||
adjustNZ(sum.low);
|
||||
setFlag(P(), VF, ~(A() ^ data) & (A() ^ sum.low) & 0x80);
|
||||
setFlag(P(), VF, ~(A() ^ data) & (A() ^ sum.low) & NF);
|
||||
setFlag(P(), CF, sum.high & CF);
|
||||
|
||||
A() = sum.low;
|
||||
@ -558,7 +531,7 @@ void EightBit::MOS6502::ADC_d(uint8_t data) {
|
||||
low += 6;
|
||||
|
||||
auto high = (uint8_t)(highNibble(A()) + highNibble(data) + (low > 0xf ? 1 : 0));
|
||||
setFlag(P(), VF, ~(A() ^ data) & (A() ^ promoteNibble(high)) & 0x80);
|
||||
setFlag(P(), VF, ~(A() ^ data) & (A() ^ promoteNibble(high)) & NF);
|
||||
|
||||
if (high > 9)
|
||||
high += 6;
|
||||
@ -602,7 +575,7 @@ void EightBit::MOS6502::JSR_abs() {
|
||||
Address_Absolute();
|
||||
PC().word--;
|
||||
PushWord(PC());
|
||||
PC() = m_memptr;
|
||||
PC() = MEMPTR();
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::RTI() {
|
||||
@ -617,17 +590,12 @@ void EightBit::MOS6502::RTS() {
|
||||
|
||||
void EightBit::MOS6502::JMP_abs() {
|
||||
Address_Absolute();
|
||||
PC() = m_memptr;
|
||||
PC() = MEMPTR();
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::JMP_ind() {
|
||||
Address_Indirect();
|
||||
PC() = m_memptr;
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::JMP_absxind() {
|
||||
Address_IndirectX();
|
||||
PC() = m_memptr;
|
||||
PC() = MEMPTR();
|
||||
}
|
||||
|
||||
void EightBit::MOS6502::BRK() {
|
||||
|
11
inc/Memory.h
11
inc/Memory.h
@ -32,15 +32,8 @@ namespace EightBit {
|
||||
class Memory {
|
||||
public:
|
||||
|
||||
static uint8_t highByte(uint16_t value) {
|
||||
return value >> 8;
|
||||
}
|
||||
|
||||
static uint8_t lowByte(uint16_t value) {
|
||||
return value & 0xff;
|
||||
}
|
||||
|
||||
Memory(uint16_t addressMask);
|
||||
virtual ~Memory();
|
||||
|
||||
// Only fired with read/write methods
|
||||
Signal<AddressEventArgs> WrittenByte;
|
||||
@ -68,7 +61,7 @@ namespace EightBit {
|
||||
return m_locked[effective] ? placeDATA(m_bus[effective]) : referenceDATA(m_bus[effective]);
|
||||
}
|
||||
|
||||
virtual uint16_t effectiveAddress(uint16_t address) const {
|
||||
virtual int effectiveAddress(int address) const {
|
||||
return address & m_addressMask;
|
||||
}
|
||||
|
||||
|
@ -38,11 +38,11 @@ namespace EightBit {
|
||||
Bit0 = 0x1,
|
||||
};
|
||||
|
||||
static uint8_t highNibble(uint8_t value) { return value >> 4; }
|
||||
static uint8_t lowNibble(uint8_t value) { return value & Mask4; }
|
||||
static int highNibble(int value) { return value >> 4; }
|
||||
static int lowNibble(int value) { return value & Mask4; }
|
||||
|
||||
static uint8_t promoteNibble(uint8_t value) { return value << 4; }
|
||||
static uint8_t demoteNibble(uint8_t value) { return highNibble(value); }
|
||||
static int promoteNibble(int value) { return value << 4; }
|
||||
static int demoteNibble(int value) { return highNibble(value); }
|
||||
|
||||
const Memory& getMemory() const { return m_memory; }
|
||||
|
||||
|
@ -14,6 +14,9 @@ EightBit::Memory::Memory(uint16_t addressMask)
|
||||
m_data = &(m_bus[m_address.word]);
|
||||
}
|
||||
|
||||
EightBit::Memory::~Memory() {
|
||||
}
|
||||
|
||||
uint8_t EightBit::Memory::peek(uint16_t address) const {
|
||||
return m_bus[address];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user