From cc1439843edc7fa1d02edabe030464d59f2d759e Mon Sep 17 00:00:00 2001 From: PalindromicBreadLoaf Date: Wed, 23 Jul 2025 08:32:28 -0400 Subject: [PATCH] Implement Stack Instructions --- src/cpu.cpp | 137 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/cpu.h | 14 ++++++ 2 files changed, 147 insertions(+), 4 deletions(-) diff --git a/src/cpu.cpp b/src/cpu.cpp index 41fc769..deea920 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -102,12 +102,11 @@ void CPU::UpdateCompareFlags16(const uint16_t reg_value, const uint16_t compare_ // General Branching Code void CPU::DoBranch(const bool condition) { - const int8_t displacement = static_cast(ReadByte(PC)); + const auto displacement = static_cast(ReadByte(PC)); PC++; if (condition) { - // Save the current PC for page boundary check - const uint32_t old_pc = PC; + const uint32_t old_pc = PC; // Save the current PC for page boundary check PC = static_cast(static_cast(PC) + displacement); @@ -155,7 +154,7 @@ void CPU::ExecuteInstruction() { case 0x10: BPL_Relative(); break; // BPL $nn // CMP - Compare Accumulator - case 0xC9: CMP_Immediate(); break; // CMP #$nn or #$nnnn + case 0xC9: CMP_Immediate(); break; // CMP #$nn or #$nnnn case 0xCD: CMP_Absolute(); break; // CMP $nnnn case 0xDD: CMP_AbsoluteX(); break; // CMP $nnnn,X case 0xD9: CMP_AbsoluteY(); break; // CMP $nnnn,Y @@ -240,6 +239,21 @@ void CPU::ExecuteInstruction() { case 0xA4: LDY_DirectPage(); break; // LDY $nn case 0xB4: LDY_DirectPageX(); break; // LDY $nn,X + // Stack operations + case 0x48: PHA(); break; // PHA + case 0x68: PLA(); break; // PLA + case 0xDA: PHX(); break; // PHX + case 0xFA: PLX(); break; // PLX + case 0x5A: PHY(); break; // PHY + case 0x7A: PLY(); break; // PLY + case 0x08: PHP(); break; // PHP + case 0x28: PLP(); break; // PLP + case 0x8B: PHB(); break; // PHB + case 0xAB: PLB(); break; // PLB + case 0x0B: PHD(); break; // PHD + case 0x2B: PLD(); break; // PLD + case 0x4B: PHK(); break; // PHK + // More Subroutines case 0x60: RTS(); break; // RTS case 0x6B: RTL(); break; // RTL @@ -1614,4 +1628,119 @@ void CPU::RTL() { PC = (static_cast(PB) << 16) | ((return_addr + 1) & 0xFFFF); cycles += 6; +} + +void CPU::PHA() { + if (P & FLAG_M) { + // 8-bit mode: push low byte of accumulator + PushByte(A & 0xFF); + cycles += 3; + } else { + // 16-bit mode + PushWord(A); + cycles += 4; + } +} + +void CPU::PLA() { + if (P & FLAG_M) { + // 8-bit mode: pull into low byte, clear high byte + A = PopByte(); + UpdateNZ8(A & 0xFF); + cycles += 4; + } else { + // 16-bit mode + A = PopWord(); + UpdateNZ16(A); + cycles += 5; + } +} + +void CPU::PHX() { + if (P & FLAG_X) { + // 8-bit mode: push low byte of X + PushByte(X & 0xFF); + cycles += 3; + } else { + // 16-bit mode + PushWord(X); + cycles += 4; + } +} + +void CPU::PLX() { + if (P & FLAG_X) { + // 8-bit mode: pull into low byte, clear high byte + X = PopByte(); + UpdateNZ8(X & 0xFF); + cycles += 4; + } else { + // 16-bit mode + X = PopWord(); + UpdateNZ16(X); + cycles += 5; + } +} + +void CPU::PHY() { + if (P & FLAG_X) { + // 8-bit mode: push low byte of Y + PushByte(Y & 0xFF); + cycles += 3; + } else { + // 16-bit mode + PushWord(Y); + cycles += 4; + } +} + +void CPU::PLY() { + if (P & FLAG_X) { + // 8-bit mode: pull into low byte, clear high byte + Y = PopByte(); + UpdateNZ8(Y & 0xFF); + cycles += 4; + } else { + // 16-bit mode: pull full 16-bit value + Y = PopWord(); + UpdateNZ16(Y); + cycles += 5; + } +} + +void CPU::PHP() { + PushByte(P); + cycles += 3; +} + +void CPU::PLP() { + P = PopByte(); + cycles += 4; +} + +void CPU::PHB() { + PushByte(DB); + cycles += 3; +} + +void CPU::PLB() { + DB = PopByte(); + UpdateNZ8(DB); + cycles += 4; +} + +void CPU::PHD() { + PushWord(D); + cycles += 4; +} + +void CPU::PLD() { + D = PopWord(); + UpdateNZ16(D); + cycles += 5; +} + +void CPU::PHK() { + PushByte(PB); + cycles += 3; } \ No newline at end of file diff --git a/src/cpu.h b/src/cpu.h index 54444b3..2b3e64c 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -170,6 +170,20 @@ public: void JSR_AbsoluteIndirectX(); void RTS(); void RTL(); + + void PHA(); + void PLA(); + void PHX(); + void PLX(); + void PHY(); + void PLY(); + void PHP(); + void PLP(); + void PHB(); + void PLB(); + void PHD(); + void PLD(); + void PHK(); }; #endif //CPU_H