Implement LSR Instructions

This commit is contained in:
2025-07-23 21:30:38 -04:00
parent 211e243fc5
commit 454beffee6
2 changed files with 134 additions and 0 deletions

View File

@@ -283,6 +283,26 @@ void CPU::UpdateBITImmediateFlags16(const uint16_t memory_value, const uint16_t
} }
} }
void CPU::UpdateLSRFlags8(const uint8_t original_value, const uint8_t result) {
// Set carry flag if bit 0 was set
if (original_value & 0x01) {
P |= FLAG_C;
} else {
P &= ~FLAG_C;
}
UpdateNZ8(result);
}
void CPU::UpdateLSRFlags16(const uint16_t original_value, const uint16_t result) {
// Set carry flag if bit 0 was set
if (original_value & 0x0001) {
P |= FLAG_C;
} else {
P &= ~FLAG_C;
}
UpdateNZ16(result);
}
void CPU::ExecuteInstruction() { void CPU::ExecuteInstruction() {
// TODO: Actual Opcode decoding // TODO: Actual Opcode decoding
switch (const uint8_t opcode = bus->Read(PC++)) { switch (const uint8_t opcode = bus->Read(PC++)) {
@@ -467,6 +487,13 @@ void CPU::ExecuteInstruction() {
case 0xA4: LDY_DirectPage(); break; // LDY $nn case 0xA4: LDY_DirectPage(); break; // LDY $nn
case 0xB4: LDY_DirectPageX(); break; // LDY $nn,X case 0xB4: LDY_DirectPageX(); break; // LDY $nn,X
// LSR - Logical Shift Right
case 0x4A: LSR_Accumulator(); break; // LSR A
case 0x4E: LSR_Absolute(); break; // LSR $nnnn
case 0x5E: LSR_AbsoluteX(); break; // LSR $nnnn,X
case 0x46: LSR_DirectPage(); break; // LSR $nn
case 0x56: LSR_DirectPageX(); break; // LSR $nn,X
// Stack operations // Stack operations
case 0x48: PHA(); break; // PHA case 0x48: PHA(); break; // PHA
case 0x68: PLA(); break; // PLA case 0x68: PLA(); break; // PLA
@@ -3329,3 +3356,101 @@ void CPU::LDA_IndirectDirectPageLongY() {
if (D & 0xFF) cycles++; if (D & 0xFF) cycles++;
} }
} }
void CPU::LSR_Accumulator() {
if (P & FLAG_M) { // 8-bit mode
const uint8_t original = A & 0xFF;
const uint8_t result = original >> 1;
A = (A & 0xFF00) | result;
UpdateLSRFlags8(original, result);
cycles += 2;
} else { // 16-bit mode
const uint16_t original = A;
const uint16_t result = original >> 1;
A = result;
UpdateLSRFlags16(original, result);
cycles += 2;
}
}
void CPU::LSR_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 original = ReadByte(full_address);
const uint8_t result = original >> 1;
WriteByte(full_address, result);
UpdateLSRFlags8(original, result);
cycles += 6;
} else { // 16-bit mode
const uint16_t original = ReadWord(full_address);
const uint16_t result = original >> 1;
WriteWord(full_address, result);
UpdateLSRFlags16(original, result);
cycles += 8;
}
}
void CPU::LSR_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 original = ReadByte(full_address);
const uint8_t result = original >> 1;
WriteByte(full_address, result);
UpdateLSRFlags8(original, result);
cycles += 7;
} else { // 16-bit mode
const uint16_t original = ReadWord(full_address);
const uint16_t result = original >> 1;
WriteWord(full_address, result);
UpdateLSRFlags16(original, result);
cycles += 9;
}
}
void CPU::LSR_DirectPage() {
const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset;
if (P & FLAG_M) { // 8-bit mode
const uint8_t original = ReadByte(address);
const uint8_t result = original >> 1;
WriteByte(address, result);
UpdateLSRFlags8(original, result);
cycles += 5;
if (D & 0xFF) cycles++;
} else { // 16-bit mode
const uint16_t original = ReadWord(address);
const uint16_t result = original >> 1;
WriteWord(address, result);
UpdateLSRFlags16(original, result);
cycles += 7;
if (D & 0xFF) cycles++;
}
}
void CPU::LSR_DirectPageX() {
const uint8_t offset = ReadByte(PC++);
const uint32_t address = D + offset + X;
if (P & FLAG_M) { // 8-bit mode
const uint8_t original = ReadByte(address);
const uint8_t result = original >> 1;
WriteByte(address, result);
UpdateLSRFlags8(original, result);
cycles += 6;
if (D & 0xFF) cycles++;
} else { // 16-bit mode
const uint16_t original = ReadWord(address);
const uint16_t result = original >> 1;
WriteWord(address, result);
UpdateLSRFlags16(original, result);
cycles += 8;
if (D & 0xFF) cycles++;
}
}

View File

@@ -75,6 +75,9 @@ class CPU {
void UpdateBITImmediateFlags8(uint8_t memory_value, uint8_t acc_value); void UpdateBITImmediateFlags8(uint8_t memory_value, uint8_t acc_value);
void UpdateBITImmediateFlags16(uint16_t memory_value, uint16_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();
@@ -281,6 +284,12 @@ public:
void EOR_AbsoluteLongX(); void EOR_AbsoluteLongX();
void EOR_StackRelative(); void EOR_StackRelative();
void EOR_StackRelativeIndirectY(); void EOR_StackRelativeIndirectY();
void LSR_Accumulator();
void LSR_Absolute();
void LSR_AbsoluteX();
void LSR_DirectPage();
void LSR_DirectPageX();
}; };
#endif //CPU_H #endif //CPU_H