diff --git a/src/cpu.cpp b/src/cpu.cpp index a469f3e..dd91c6a 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -202,6 +202,24 @@ uint16_t CPU::AdjustDecimal(const uint16_t binary_result, const bool is_16bit) { return result; } +void CPU::UpdateASLFlags8(const uint8_t original_value, const uint8_t result) { + if (original_value & 0x80) { + P |= FLAG_C; + } else { + P &= ~FLAG_C; + } + UpdateNZ8(result); +} + +void CPU::UpdateASLFlags16(const uint16_t original_value, const uint16_t result) { + if (original_value & 0x8000) { + P |= FLAG_C; + } else { + P &= ~FLAG_C; + } + UpdateNZ16(result); +} + void CPU::ExecuteInstruction() { // TODO: Actual Opcode decoding switch (const uint8_t opcode = bus->Read(PC++)) { @@ -239,6 +257,13 @@ void CPU::ExecuteInstruction() { case 0x23: AND_StackRelative(); break; // AND $nn,S case 0x33: AND_StackRelativeIndirectY(); break; // AND ($nn,S),Y + // ASL - Accumulator Shift Left + case 0x0A: ASL_Accumulator(); break; // ASL A + case 0x0E: ASL_Absolute(); break; // ASL $nnnn + case 0x1E: ASL_AbsoluteX(); break; // ASL $nnnn,X + case 0x06: ASL_DirectPage(); break; // ASL $nn + case 0x16: ASL_DirectPageX(); break; // ASL $nn,X + // Branch Instructions case 0xF0: BEQ_Relative(); break; // BEQ $nn case 0xD0: BNE_Relative(); break; // BNE $nn @@ -2364,13 +2389,13 @@ void CPU::AND_IndirectDirectPageLongY() { const uint32_t full_address = base_address + Y; if (P & FLAG_M) { // 8-bit mode - uint8_t operand = ReadByte(full_address); + 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 - uint16_t operand = ReadWord(full_address); + const uint16_t operand = ReadWord(full_address); A &= operand; UpdateNZ16(A); cycles += 7; @@ -2447,4 +2472,102 @@ void CPU::AND_StackRelativeIndirectY() { UpdateNZ16(A); cycles += 8; } +} + +void CPU::ASL_Accumulator() { + if (P & FLAG_M) { // 8-bit mode + const uint8_t original = A & 0xFF; + const uint8_t result = original << 1; + A = (A & 0xFF00) | result; + UpdateASLFlags8(original, result); + cycles += 2; + } else { // 16-bit mode + const uint16_t original = A; + const uint16_t result = original << 1; + A = result; + UpdateASLFlags16(original, result); + cycles += 2; + } +} + +void CPU::ASL_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); + UpdateASLFlags8(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); + UpdateASLFlags16(original, result); + cycles += 8; + } +} + +void CPU::ASL_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); + UpdateASLFlags8(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); + UpdateASLFlags16(original, result); + cycles += 9; + } +} + +void CPU::ASL_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); + UpdateASLFlags8(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); + UpdateASLFlags16(original, result); + cycles += 7; + if (D & 0xFF) cycles++; + } +} + +void CPU::ASL_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); + UpdateASLFlags8(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); + UpdateASLFlags16(original, result); + cycles += 8; + if (D & 0xFF) cycles++; + } } \ No newline at end of file diff --git a/src/cpu.h b/src/cpu.h index 761b6b2..cbb2729 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -75,6 +75,10 @@ public: // Helper method to check for decimal mode adjustment static uint16_t AdjustDecimal(uint16_t binary_result, bool is_16bit); + // Helper methods for ASL stuff + void UpdateASLFlags8(uint8_t original_value, uint8_t result); + void UpdateASLFlags16(uint16_t original_value, uint16_t result); + // Instruction implementations // TODO: Implement remaining instructions void CMP_Immediate(); @@ -222,6 +226,12 @@ public: void AND_AbsoluteLongX(); void AND_StackRelative(); void AND_StackRelativeIndirectY(); + + void ASL_Accumulator(); + void ASL_Absolute(); + void ASL_AbsoluteX(); + void ASL_DirectPage(); + void ASL_DirectPageX(); }; #endif //CPU_H