Implement ORA Instructions

This commit is contained in:
2025-07-23 21:42:46 -04:00
parent 454beffee6
commit 8706874c4d
2 changed files with 337 additions and 0 deletions

View File

@@ -456,6 +456,23 @@ void CPU::ExecuteInstruction() {
// No Operation // No Operation
case 0xEA: NOP(); break; //NOP case 0xEA: NOP(); break; //NOP
// ORA - Inclusive OR
case 0x09: ORA_Immediate(); break; // ORA #$nn or #$nnnn
case 0x0D: ORA_Absolute(); break; // ORA $nnnn
case 0x1D: ORA_AbsoluteX(); break; // ORA $nnnn,X
case 0x19: ORA_AbsoluteY(); break; // ORA $nnnn,Y
case 0x05: ORA_DirectPage(); break; // ORA $nn
case 0x15: ORA_DirectPageX(); break; // ORA $nn,X
case 0x12: ORA_IndirectDirectPage(); break; // ORA ($nn)
case 0x07: ORA_IndirectDirectPageLong(); break; // ORA [$nn]
case 0x01: ORA_IndexedIndirectDirectPageX(); break; // ORA ($nn,X)
case 0x11: ORA_IndirectDirectPageY(); break; // ORA ($nn),Y
case 0x17: ORA_IndirectDirectPageLongY(); break; // ORA [$nn],Y
case 0x0F: ORA_AbsoluteLong(); break; // ORA $nnnnnn
case 0x1F: ORA_AbsoluteLongX(); break; // ORA $nnnnnn,X
case 0x03: ORA_StackRelative(); break; // ORA $nn,S
case 0x13: ORA_StackRelativeIndirectY(); break; // ORA ($nn,S),Y
// LDA - Load Accumulator // LDA - Load Accumulator
case 0xA9: LDA_Immediate(); break; // LDA #$nn or #$nnnn case 0xA9: LDA_Immediate(); break; // LDA #$nn or #$nnnn
case 0xAD: LDA_Absolute(); break; // LDA $nnnn case 0xAD: LDA_Absolute(); break; // LDA $nnnn
@@ -3453,4 +3470,308 @@ void CPU::LSR_DirectPageX() {
cycles += 8; cycles += 8;
if (D & 0xFF) cycles++; if (D & 0xFF) cycles++;
} }
}
void CPU::ORA_Immediate() {
if (P & FLAG_M) { // 8-bit mode
const uint8_t operand = ReadByte(PC++);
A = (A & 0xFF00) | ((A & 0xFF) | operand);
UpdateNZ8(A & 0xFF);
cycles += 2;
} else { // 16-bit mode
const uint16_t operand = ReadWord(PC);
PC += 2;
A |= operand;
UpdateNZ16(A);
cycles += 3;
}
}
void CPU::ORA_Absolute() {
const uint16_t address = ReadWord(PC);
PC += 2;
const uint32_t full_address = (DB << 16) | address;
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;
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 5;
}
}
void CPU::ORA_AbsoluteX() {
const uint16_t base_address = ReadWord(PC);
PC += 2;
const uint32_t full_address = (DB << 16) | (base_address + X);
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 + 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() {
const uint16_t base_address = ReadWord(PC);
PC += 2;
const uint32_t full_address = (DB << 16) | (base_address + 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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset;
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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset + X;
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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset;
const uint16_t indirect_address = ReadWord(pointer_address);
const uint32_t full_address = (DB << 16) | indirect_address;
if (P & FLAG_M) { // 8-bit mode
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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset;
const uint32_t full_address = ReadByte(pointer_address) |
(ReadByte(pointer_address + 1) << 8) |
(ReadByte(pointer_address + 2) << 16);
if (P & FLAG_M) { // 8-bit mode
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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset + X;
const uint16_t indirect_address = ReadWord(pointer_address);
const uint32_t full_address = (DB << 16) | indirect_address;
if (P & FLAG_M) { // 8-bit mode
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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset;
const uint16_t base_address = ReadWord(pointer_address);
const uint32_t full_address = (DB << 16) | (base_address + 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 += 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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = D + offset;
const uint32_t base_address = ReadByte(pointer_address) |
(ReadByte(pointer_address + 1) << 8) |
(ReadByte(pointer_address + 2) << 16);
const uint32_t full_address = base_address + 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 += 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() {
const uint32_t address = ReadByte(PC) | (ReadByte(PC + 1) << 8) | (ReadByte(PC + 2) << 16);
PC += 3;
if (P & FLAG_M) { // 8-bit mode
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() {
const uint32_t base_address = ReadByte(PC) | (ReadByte(PC + 1) << 8) | (ReadByte(PC + 2) << 16);
PC += 3;
const uint32_t full_address = base_address + X;
if (P & FLAG_M) { // 8-bit mode
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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t address = SP + offset;
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() {
const uint8_t offset = ReadByte(PC++);
const uint32_t pointer_address = SP + offset;
const uint16_t base_address = ReadWord(pointer_address);
const uint32_t full_address = (DB << 16) | (base_address + 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 += 7;
} else { // 16-bit mode
const uint16_t operand = ReadWord(full_address);
A |= operand;
UpdateNZ16(A);
cycles += 8;
}
} }

View File

@@ -290,6 +290,22 @@ public:
void LSR_AbsoluteX(); void LSR_AbsoluteX();
void LSR_DirectPage(); void LSR_DirectPage();
void LSR_DirectPageX(); void LSR_DirectPageX();
void ORA_Immediate();
void ORA_Absolute();
void ORA_AbsoluteX();
void ORA_AbsoluteY();
void ORA_DirectPage();
void ORA_DirectPageX();
void ORA_IndirectDirectPage();
void ORA_IndirectDirectPageLong();
void ORA_IndexedIndirectDirectPageX();
void ORA_IndirectDirectPageY();
void ORA_IndirectDirectPageLongY();
void ORA_AbsoluteLong();
void ORA_AbsoluteLongX();
void ORA_StackRelative();
void ORA_StackRelativeIndirectY();
}; };
#endif //CPU_H #endif //CPU_H