Refactor LDX/Y Instructions

This commit is contained in:
2025-07-29 10:34:12 -04:00
parent 45f688e8c9
commit 1ab1ec57de
2 changed files with 35 additions and 121 deletions

View File

@@ -217,6 +217,23 @@ void CPU::LDA_Mem(const uint32_t address, const int base_cycles, const bool addD
if (addPageCrossCycle && ((base & 0xFF00) != ((base + offset) & 0xFF00))) cycles++; if (addPageCrossCycle && ((base & 0xFF00) != ((base + offset) & 0xFF00))) cycles++;
} }
void CPU::LD_Index(uint32_t address, const bool isX, const int base_cycles, const bool addDPExtraCycle = false, const bool addPageCrossCycle = false, const uint16_t base = 0, const uint16_t offset = 0) {
const bool is8Bit = P & FLAG_X;
const uint16_t value = is8Bit ? ReadByte(address) : ReadWord(address);
if (isX) {
X = value;
is8Bit ? UpdateNZ8(X & 0xFF) : UpdateNZ16(X);
} else {
Y = value;
is8Bit ? UpdateNZ8(Y & 0xFF) : UpdateNZ16(Y);
}
cycles += base_cycles + (is8Bit ? 0 : 1);
if (addDPExtraCycle && (D & 0xFF)) cycles++;
if (addPageCrossCycle && ((base & 0xFF00) != ((base + offset) & 0xFF00))) cycles++;
}
void CPU::UpdateASLFlags8(const uint8_t original_value, const uint8_t result) { void CPU::UpdateASLFlags8(const uint8_t original_value, const uint8_t result) {
if (original_value & 0x80) { if (original_value & 0x80) {
P |= FLAG_C; P |= FLAG_C;
@@ -1021,83 +1038,29 @@ void CPU::LDX_Immediate() {
} }
void CPU::LDX_Absolute() { void CPU::LDX_Absolute() {
const uint16_t address = ReadWord(PC); const uint16_t addr = ReadWord(PC);
PC += 2; PC += 2;
if (P & FLAG_X) { LD_Index(addr, true, 4);
// 8-bit mode
X = ReadByte(address);
UpdateNZ8(X & 0xFF);
cycles += 4;
} else {
// 16-bit mode
X = ReadWord(address);
UpdateNZ16(X);
cycles += 5;
}
} }
void CPU::LDX_AbsoluteY() { void CPU::LDX_AbsoluteY() {
const uint16_t base_address = ReadWord(PC); const uint16_t base = ReadWord(PC);
PC += 2; PC += 2;
const uint32_t address = base_address + Y;
// Page boundary crossing adds a cycle LD_Index(base + Y, true, 4, false, true, base, Y);
if ((base_address & 0xFF00) != (address & 0xFF00)) {
cycles++;
}
if (P & FLAG_X) {
// 8-bit mode
X = ReadByte(address);
UpdateNZ8(X & 0xFF);
cycles += 4;
} else {
// 16-bit mode
X = ReadWord(address);
UpdateNZ16(X);
cycles += 5;
}
} }
void CPU::LDX_DirectPage() { void CPU::LDX_DirectPage() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset; LD_Index(D + offset, true, 3, true);
if (P & FLAG_X) {
// 8-bit mode
X = ReadByte(address);
UpdateNZ8(X & 0xFF);
cycles += 3;
} else {
// 16-bit mode
X = ReadWord(address);
UpdateNZ16(X);
cycles += 4;
}
// Extra cycle if D register is not page-aligned
if (D & 0xFF) cycles++;
} }
void CPU::LDX_DirectPageY() { void CPU::LDX_DirectPageY() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset + (P & FLAG_X ? (Y & 0xFF) : Y); const uint16_t y_offset = (P & FLAG_X) ? (Y & 0xFF) : Y;
if (P & FLAG_X) { LD_Index(D + offset + y_offset, true, 4, true);
// 8-bit mode
X = ReadByte(address);
UpdateNZ8(X & 0xFF);
cycles += 4;
} else {
// 16-bit mode
X = ReadWord(address);
UpdateNZ16(X);
cycles += 5;
}
// Extra cycle if D register is not page-aligned
if (D & 0xFF) cycles++;
} }
// Load Y Register Instructions // Load Y Register Instructions
@@ -1117,83 +1080,30 @@ void CPU::LDY_Immediate() {
} }
void CPU::LDY_Absolute() { void CPU::LDY_Absolute() {
const uint16_t address = ReadWord(PC); const uint16_t addr = ReadWord(PC);
PC += 2; PC += 2;
if (P & FLAG_X) { LD_Index(addr, false, 4);
// 8-bit mode
Y = ReadByte(address);
UpdateNZ8(Y & 0xFF);
cycles += 4;
} else {
// 16-bit mode
Y = ReadWord(address);
UpdateNZ16(Y);
cycles += 5;
}
} }
void CPU::LDY_AbsoluteX() { void CPU::LDY_AbsoluteX() {
const uint16_t base_address = ReadWord(PC); const uint16_t base = ReadWord(PC);
PC += 2; PC += 2;
const uint32_t address = base_address + X;
// Page boundary crossing adds a cycle LD_Index(base + X, false, 4, false, true, base, X);
if ((base_address & 0xFF00) != (address & 0xFF00)) {
cycles++;
}
if (P & FLAG_X) {
// 8-bit mode
Y = ReadByte(address);
UpdateNZ8(Y & 0xFF);
cycles += 4;
} else {
// 16-bit mode
Y = ReadWord(address);
UpdateNZ16(Y);
cycles += 5;
}
} }
void CPU::LDY_DirectPage() { void CPU::LDY_DirectPage() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset;
if (P & FLAG_X) { LD_Index(D + offset, false, 3, true);
// 8-bit mode
Y = ReadByte(address);
UpdateNZ8(Y & 0xFF);
cycles += 3;
} else {
// 16-bit mode
Y = ReadWord(address);
UpdateNZ16(Y);
cycles += 4;
}
// Extra cycle if D register is not page-aligned
if (D & 0xFF) cycles++;
} }
void CPU::LDY_DirectPageX() { void CPU::LDY_DirectPageX() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset + (P & FLAG_X ? (X & 0xFF) : X); const uint16_t x_offset = (P & FLAG_X) ? (X & 0xFF) : X;
if (P & FLAG_X) { LD_Index(D + offset + x_offset, false, 4, true);
// 8-bit mode
Y = ReadByte(address);
UpdateNZ8(Y & 0xFF);
cycles += 4;
} else {
// 16-bit mode
Y = ReadWord(address);
UpdateNZ16(Y);
cycles += 5;
}
// Extra cycle if D register is not page-aligned
if (D & 0xFF) cycles++;
} }
//Store operations implementation //Store operations implementation

View File

@@ -70,6 +70,10 @@ class CPU {
void LDA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base, void LDA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base,
uint16_t offset); uint16_t offset);
void LD_Index(uint32_t address, bool isX, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle,
uint16_t base,
uint16_t offset);
// General ORA Logic // General ORA Logic
void ORA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base_address, void ORA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base_address,
uint16_t offset); uint16_t offset);