Hopefully not break ORA instructions with refactoring

This commit is contained in:
2025-07-28 13:30:12 -04:00
parent 265cd69937
commit d40414efd8
2 changed files with 67 additions and 235 deletions

View File

@@ -302,6 +302,24 @@ void CPU::UpdateLSRFlags16(const uint16_t original_value, const uint16_t result)
UpdateNZ16(result); UpdateNZ16(result);
} }
void CPU::ORA_Mem(const uint32_t address, const int base_cycles, const bool addDPExtraCycle = false, const bool addPageCrossCycle = false, const uint16_t base_address = 0, const uint16_t offset = 0) {
if (P & FLAG_M) {
const uint8_t operand = ReadByte(address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += base_cycles;
if (addDPExtraCycle && (D & 0xFF)) cycles++;
if (addPageCrossCycle && ((base_address & 0xFF00) != ((base_address + offset) & 0xFF00))) cycles++;
} else {
const uint16_t operand = ReadWord(address);
A |= operand;
UpdateNZ16(A);
cycles += base_cycles + 1;
if (addDPExtraCycle && (D & 0xFF)) cycles++;
if (addPageCrossCycle && ((base_address & 0xFF00) != ((base_address + offset) & 0xFF00))) cycles++;
}
}
// ROL/ROR helper methods // ROL/ROR helper methods
uint8_t CPU::ROL8(uint8_t value) { uint8_t CPU::ROL8(uint8_t value) {
const bool old_carry = (P & FLAG_C) != 0; const bool old_carry = (P & FLAG_C) != 0;
@@ -3891,290 +3909,99 @@ void CPU::ORA_Immediate() {
void CPU::ORA_Absolute() { void CPU::ORA_Absolute() {
const uint16_t address = ReadWord(PC); const uint16_t address = ReadWord(PC);
PC += 2; PC += 2;
const uint32_t full_address = (DB << 16) | address;
if (P & FLAG_M) { // 8-bit mode ORA_Mem((DB << 16) | address, 4);
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 4;
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 5;
}
} }
void CPU::ORA_AbsoluteX() { void CPU::ORA_AbsoluteX() {
const uint16_t base_address = ReadWord(PC); const uint16_t base = ReadWord(PC);
PC += 2; PC += 2;
const uint32_t full_address = (DB << 16) | (base_address + X);
if (P & FLAG_M) { // 8-bit mode ORA_Mem((DB << 16) | (base + X), 4, false, true, base, X);
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 4;
if ((base_address & 0xFF00) != ((base_address + X) & 0xFF00)) {
cycles++;
}
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 5;
if ((base_address & 0xFF00) != ((base_address + X) & 0xFF00)) {
cycles++;
}
}
} }
void CPU::ORA_AbsoluteY() { void CPU::ORA_AbsoluteY() {
const uint16_t base_address = ReadWord(PC); const uint16_t base = ReadWord(PC);
PC += 2; PC += 2;
const uint32_t full_address = (DB << 16) | (base_address + Y); ORA_Mem((DB << 16) | (base + Y), 4, false, true, base, Y);
if (P & FLAG_M) { // 8-bit mode
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 4;
if ((base_address & 0xFF00) != ((base_address + Y) & 0xFF00)) {
cycles++;
}
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 5;
if ((base_address & 0xFF00) != ((base_address + Y) & 0xFF00)) {
cycles++;
}
}
} }
void CPU::ORA_DirectPage() { void CPU::ORA_DirectPage() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset; ORA_Mem(D + offset, 3, true);
if (P & FLAG_M) { // 8-bit mode
const uint8_t operand = ReadByte(address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 3;
if (D & 0xFF) cycles++;
} else { // 16-bit mode
const uint16_t operand = ReadWord(address);
A |= operand;
UpdateNZ16(A);
cycles += 4;
if (D & 0xFF) cycles++;
}
} }
void CPU::ORA_DirectPageX() { void CPU::ORA_DirectPageX() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset + X; ORA_Mem(D + offset + X, 4, true);
if (P & FLAG_M) { // 8-bit mode
const uint8_t operand = ReadByte(address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 4;
if (D & 0xFF) cycles++;
} else { // 16-bit mode
const uint16_t operand = ReadWord(address);
A |= operand;
UpdateNZ16(A);
cycles += 5;
if (D & 0xFF) cycles++;
}
} }
void CPU::ORA_IndirectDirectPage() { void CPU::ORA_IndirectDirectPage() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset; const uint32_t addr = D + offset;
const uint16_t indirect_address = ReadWord(pointer_address); const uint16_t indirect = ReadWord(addr);
const uint32_t full_address = (DB << 16) | indirect_address;
if (P & FLAG_M) { // 8-bit mode ORA_Mem((DB << 16) | indirect, 5, true);
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 5;
if (D & 0xFF) cycles++;
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 6;
if (D & 0xFF) cycles++;
}
} }
void CPU::ORA_IndirectDirectPageLong() { void CPU::ORA_IndirectDirectPageLong() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset; const uint32_t addr = D + offset;
const uint32_t full_address = ReadByte(pointer_address) | const uint32_t long_addr = ReadByte(addr) | (ReadByte(addr + 1) << 8) | (ReadByte(addr + 2) << 16);
(ReadByte(pointer_address + 1) << 8) |
(ReadByte(pointer_address + 2) << 16);
if (P & FLAG_M) { // 8-bit mode ORA_Mem(long_addr, 6, true);
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 6;
if (D & 0xFF) cycles++;
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 7;
if (D & 0xFF) cycles++;
}
} }
void CPU::ORA_IndexedIndirectDirectPageX() { void CPU::ORA_IndexedIndirectDirectPageX() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset + X; const uint32_t addr = D + offset + X;
const uint16_t indirect_address = ReadWord(pointer_address); const uint16_t indirect = ReadWord(addr);
const uint32_t full_address = (DB << 16) | indirect_address;
if (P & FLAG_M) { // 8-bit mode ORA_Mem((DB << 16) | indirect, 6, true);
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 6;
if (D & 0xFF) cycles++;
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 7;
if (D & 0xFF) cycles++;
}
} }
void CPU::ORA_IndirectDirectPageY() { void CPU::ORA_IndirectDirectPageY() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset; const uint32_t pointer_addr = D + offset;
const uint16_t base_address = ReadWord(pointer_address); const uint16_t base = ReadWord(pointer_addr);
const uint32_t full_address = (DB << 16) | (base_address + Y);
if (P & FLAG_M) { // 8-bit mode ORA_Mem((DB << 16) | (base + Y), 5, true, true, base, Y);
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 5;
if (D & 0xFF) cycles++;
if ((base_address & 0xFF00) != ((base_address + Y) & 0xFF00)) {
cycles++;
}
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 6;
if (D & 0xFF) cycles++;
if ((base_address & 0xFF00) != ((base_address + Y) & 0xFF00)) {
cycles++;
}
}
} }
void CPU::ORA_IndirectDirectPageLongY() { void CPU::ORA_IndirectDirectPageLongY() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset; const uint32_t pointer = D + offset;
const uint32_t base_address = ReadByte(pointer_address) | const uint32_t base = ReadByte(pointer) |
(ReadByte(pointer_address + 1) << 8) | (ReadByte(pointer + 1) << 8) |
(ReadByte(pointer_address + 2) << 16); (ReadByte(pointer + 2) << 16);
const uint32_t full_address = base_address + Y;
if (P & FLAG_M) { // 8-bit mode ORA_Mem(base + Y, 6, true);
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 6;
if (D & 0xFF) cycles++;
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 7;
if (D & 0xFF) cycles++;
}
} }
void CPU::ORA_AbsoluteLong() { void CPU::ORA_AbsoluteLong() {
const uint32_t address = ReadByte(PC) | (ReadByte(PC + 1) << 8) | (ReadByte(PC + 2) << 16); const uint32_t addr = ReadByte(PC) | (ReadByte(PC + 1) << 8) | (ReadByte(PC + 2) << 16);
PC += 3; PC += 3;
if (P & FLAG_M) { // 8-bit mode ORA_Mem(addr, 5);
const uint8_t operand = ReadByte(address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 5;
} else { // 16-bit mode
const uint16_t operand = ReadWord(address);
A |= operand;
UpdateNZ16(A);
cycles += 6;
}
} }
void CPU::ORA_AbsoluteLongX() { void CPU::ORA_AbsoluteLongX() {
const uint32_t base_address = ReadByte(PC) | (ReadByte(PC + 1) << 8) | (ReadByte(PC + 2) << 16); const uint32_t base = ReadByte(PC) | (ReadByte(PC + 1) << 8) | (ReadByte(PC + 2) << 16);
PC += 3; PC += 3;
const uint32_t full_address = base_address + X;
if (P & FLAG_M) { // 8-bit mode ORA_Mem(base + X, 5);
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 5;
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 6;
}
} }
void CPU::ORA_StackRelative() { void CPU::ORA_StackRelative() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t address = SP + offset; ORA_Mem(SP + offset, 4);
if (P & FLAG_M) { // 8-bit mode
const uint8_t operand = ReadByte(address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 4;
} else { // 16-bit mode
uint16_t operand = ReadWord(address);
A |= operand;
UpdateNZ16(A);
cycles += 5;
}
} }
void CPU::ORA_StackRelativeIndirectY() { void CPU::ORA_StackRelativeIndirectY() {
const uint8_t offset = ReadByte(PC++); const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = SP + offset; const uint32_t pointer = SP + offset;
const uint16_t base_address = ReadWord(pointer_address); const uint16_t base = ReadWord(pointer);
const uint32_t full_address = (DB << 16) | (base_address + Y); ORA_Mem((DB << 16) | (base + Y), 7);
if (P & FLAG_M) { // 8-bit mode
const uint8_t operand = ReadByte(full_address);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 7;
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 8;
}
} }
void CPU::MVN() { void CPU::MVN() {

View File

@@ -67,18 +67,9 @@ class CPU {
// Helper method to check for decimal mode adjustment // Helper method to check for decimal mode adjustment
static uint16_t AdjustDecimal(uint16_t binary_result, bool is_16bit); static uint16_t AdjustDecimal(uint16_t binary_result, bool is_16bit);
// Helper methods for ASL stuff // General ORA Logic
void UpdateASLFlags8(uint8_t original_value, uint8_t result); void ORA_Mem(uint32_t address, int base_cycles, bool addDPExtraCycle, bool addPageCrossCycle, uint16_t base_address,
void UpdateASLFlags16(uint16_t original_value, uint16_t result); uint16_t offset);
// Helper methods for BIT
void UpdateBITFlags8(uint8_t memory_value, uint8_t acc_value);
void UpdateBITFlags16(uint16_t memory_value, uint16_t acc_value);
void UpdateBITImmediateFlags8(uint8_t memory_value, uint8_t acc_value);
void UpdateBITImmediateFlags16(uint16_t memory_value, uint16_t acc_value);
void UpdateLSRFlags8(uint8_t original_value, uint8_t result);
void UpdateLSRFlags16(uint16_t original_value, uint16_t result);
//Helper Methods for Rotate Right/Left //Helper Methods for Rotate Right/Left
uint8_t ROL8(uint8_t value); uint8_t ROL8(uint8_t value);
@@ -98,8 +89,22 @@ class CPU {
void SBC_FromAddress_PageCross(uint32_t address, uint16_t base_address, uint16_t offset, int base_cycles_8bit, void SBC_FromAddress_PageCross(uint32_t address, uint16_t base_address, uint16_t offset, int base_cycles_8bit,
int base_cycles_16bit); int base_cycles_16bit);
// General STZ Logic
void STZ_ToAddress(uint32_t address, int base_cycles_8bit, int base_cycles_16bit); void STZ_ToAddress(uint32_t address, int base_cycles_8bit, int base_cycles_16bit);
// Helper methods for ASL stuff
void UpdateASLFlags8(uint8_t original_value, uint8_t result);
void UpdateASLFlags16(uint16_t original_value, uint16_t result);
// Helper methods for BIT
void UpdateBITFlags8(uint8_t memory_value, uint8_t acc_value);
void UpdateBITFlags16(uint16_t memory_value, uint16_t acc_value);
void UpdateBITImmediateFlags8(uint8_t memory_value, uint8_t acc_value);
void UpdateBITImmediateFlags16(uint16_t memory_value, uint16_t acc_value);
void UpdateLSRFlags8(uint8_t original_value, uint8_t result);
void UpdateLSRFlags16(uint16_t original_value, uint16_t result);
public: public:
explicit CPU(Bus* memory_bus) : bus(memory_bus) { explicit CPU(Bus* memory_bus) : bus(memory_bus) {
Reset(); Reset();