Begin by enclosing all thoughts within <thinking> tags, exploring multiple angles and approaches.
Break down the solution into clear steps within <step> tags. Start with a 20-step budget, requesting more for complex problems if needed.
Use <count> tags after each step to show the remaining budget. Stop when reaching 0.
Continuously adjust your reasoning based on intermediate results and reflections, adapting your strategy as you progress.
Regularly evaluate progress using <reflection> tags. Be critical and honest about your reasoning process.
Assign a quality score between 0.0 and 1.0 using <reward> tags after each reflection. Use this to guide your approach:

0.8+: Continue current approach
0.5-0.7: Consider minor adjustments
Below 0.5: Seriously consider backtracking and trying a different approach


If unsure or if reward score is low, backtrack and try a different approach, explaining your decision within <thinking> tags.
For mathematical problems, show all work explicitly using LaTeX for formal notation and provide detailed proofs.
Explore multiple solutions individually if possible, comparing approaches in reflections.
Use thoughts as a scratchpad, writing out all calculations and reasoning explicitly.
Synthesize the final answer within <answer> tags, providing a clear, concise summary.
Conclude with a final reflection on the overall solution, discussing effectiveness, challenges, and solutions. Assign a final reward score. Напиши программу для 6502 "калькулятор" для проверки моего эмулятора #include <iostream>  
#include <cstdint> 
#include <array> 
#include <unordered_map> 
#include <functional> 
#include <iomanip> 
#include <sstream>
// Memory class to handle 64KB memory
class Memory {
public:
	static const size_t SIZE = 65536; // Corrected to size_t for 65536
	std::array<uint8_t, SIZE> data;
	Memory() {
		data.fill(0); // Initialize all memory to 0
	}

	uint8_t Read(uint16_t address) const {
		return data[address];
	}

	void Write(uint16_t address, uint8_t value) {
		data[address] = value;
	}
};

// CPU class representing the 6502 processor 
class CPU {
public:
	// Registers
	uint8_t A = 0; // Accumulator
	uint8_t X = 0; // X Register
	uint8_t Y = 0; // Y Register 
	uint8_t SP = 0xFF; // Stack Pointer (Stack starts at 0x0100)
	uint16_t PC = 0x8000; // Program Counter

	// Status Flags
	bool C = false; // Carry Flag
	bool Z = false; // Zero Flag
	bool I = false; // Interrupt Disable
	bool D = false; // Decimal Mode
	bool B = false; // Break Command
	bool V = false; // Overflow Flag
	bool N = false; // Negative Flag

	using InstructionHandler = std::function<void(Memory&)>;

	void ExecuteInstruction(uint8_t opcode, Memory& memory);
	void InitializeInstructions();
	uint8_t Fetch(Memory& memory) {
		return memory.Read(PC++);
	}
private: std::unordered_map<uint8_t, InstructionHandler> instructionSet;
	   void UpdateZeroAndNegativeFlags(uint8_t value) {
		   Z = (value == 0);
		   N = (value & 0x80) != 0;
	   }

	   void Push(uint8_t value, Memory& memory) {
		   memory.Write(0x0100 + SP, value);
		   SP--;
	   }

	   uint8_t Pull(Memory& memory) {
		   SP++;
		   return memory.Read(0x0100 + SP);
	   }
};

// Initialize the instruction set (opcode table)
void CPU::InitializeInstructions() {
	// LDA Immediate
	instructionSet[0xA9] = [this](Memory& memory) { uint8_t value = Fetch(memory); A = value; UpdateZeroAndNegativeFlags(A); std::cout << "LDA Immediate: A = " << +A << "\n"; };

	// LDA Zero Page
	instructionSet[0xA5] = [this](Memory& memory) {
		uint8_t addr = Fetch(memory);
		A = memory.Read(addr);
		UpdateZeroAndNegativeFlags(A);
		std::cout << "LDA Zero Page: A = " << +A << " from 0x" << std::hex << +addr << "\n";
		};

	// LDA Absolute
	instructionSet[0xAD] = [this](Memory& memory) {
		uint16_t address = Fetch(memory) | (Fetch(memory) << 8);
		A = memory.Read(address);
		UpdateZeroAndNegativeFlags(A);
		std::cout << "LDA Absolute: A = " << +A << " from 0x" << std::hex << address << "\n";
		};

	// STA Zero Page
	instructionSet[0x85] = [this](Memory& memory) {
		uint8_t addr = Fetch(memory);
		memory.Write(addr, A);
		std::cout << "STA Zero Page: memory[0x" << std::hex << +addr << "] = " << +A << "\n";
		};

	// STA Absolute
	instructionSet[0x8D] = [this](Memory& memory) {
		uint16_t address = Fetch(memory) | (Fetch(memory) << 8);
		memory.Write(address, A);
		std::cout << "STA Absolute: memory[0x" << std::hex << address << "] = " << +A << "\n";
		};

	// ADC Immediate
	instructionSet[0x69] = [this](Memory& memory) {
		uint8_t value = Fetch(memory);
		uint16_t result = A + value + (C ? 1 : 0);
		V = (~(A ^ value) & (A ^ result)) & 0x80;
		C = result > 0xFF;
		A = result & 0xFF;
		UpdateZeroAndNegativeFlags(A);
		std::cout << "ADC Immediate: A = " << +A << "\n";
		};

	// ADC Zero Page
	instructionSet[0x65] = [this](Memory& memory) {
		uint8_t addr = Fetch(memory);
		uint8_t value = memory.Read(addr);
		uint16_t result = A + value + (C ? 1 : 0);
		V = (~(A ^ value) & (A ^ result)) & 0x80;
		C = result > 0xFF;
		A = result & 0xFF;
		UpdateZeroAndNegativeFlags(A);
		std::cout << "ADC Zero Page: A = " << +A << "\n";
		};

	// AND Immediate
	instructionSet[0x29] = [this](Memory& memory) {
		uint8_t value = Fetch(memory);
		A &= value;
		UpdateZeroAndNegativeFlags(A);
		std::cout << "AND Immediate: A = " << +A << "\n";
		};

	// ORA Immediate
	instructionSet[0x09] = [this](Memory& memory) {
		uint8_t value = Fetch(memory);
		A |= value;
		UpdateZeroAndNegativeFlags(A);
		std::cout << "ORA Immediate: A = " << +A << "\n";
		};

	// EOR Immediate
	instructionSet[0x49] = [this](Memory& memory) {
		uint8_t value = Fetch(memory);
		A ^= value;
		UpdateZeroAndNegativeFlags(A);
		std::cout << "EOR Immediate: A = " << +A << "\n";
		};

	// ASL Accumulator
	instructionSet[0x0A] = [this](Memory& memory) {
		C = (A & 0x80) != 0;
		A <<= 1;
		UpdateZeroAndNegativeFlags(A);
		std::cout << "ASL Accumulator: A = " << +A << ", C = " << C << "\n";
		};

	// LSR Accumulator
	instructionSet[0x4A] = [this](Memory& memory) {
		C = (A & 0x01) != 0;
		A >>= 1;
		UpdateZeroAndNegativeFlags(A);
		std::cout << "LSR Accumulator: A = " << +A << ", C = " << C << "\n";
		};

	// ROL Accumulator
	instructionSet[0x2A] = [this](Memory& memory) {
		bool oldC = C;
		C = (A & 0x80) != 0;
		A = (A << 1) | (oldC ? 1 : 0);
		UpdateZeroAndNegativeFlags(A);
		std::cout << "ROL Accumulator: A = " << +A << ", C = " << C << "\n";
		};

	// ROR Accumulator
	instructionSet[0x6A] = [this](Memory& memory) {
		bool oldC = C;
		C = (A & 0x01) != 0;
		A = (A >> 1) | (oldC ? 0x80 : 0x00);
		UpdateZeroAndNegativeFlags(A);
		std::cout << "ROR Accumulator: A = " << +A << ", C = " << C << "\n";
		};

	// CMP Immediate
	instructionSet[0xC9] = [this](Memory& memory) {
		uint8_t value = Fetch(memory);
		uint8_t temp = A - value;
		C = A >= value;
		Z = (temp == 0);
		N = (temp & 0x80) != 0;
		std::cout << "CMP Immediate: A = " << +A << ", Value = " << +value << "\n";
		};

	// CMP Zero Page
	instructionSet[0xC5] = [this](Memory& memory) {
		uint8_t addr = Fetch(memory);
		uint8_t value = memory.Read(addr);
		uint8_t temp = A - value;
		C = A >= value;
		Z = (temp == 0);
		N = (temp & 0x80) != 0;
		std::cout << "CMP Zero Page: A = " << +A << ", Value = " << +value << "\n";
		};

	// DEC Zero Page
	instructionSet[0xC6] = [this](Memory& memory) {
		uint8_t addr = Fetch(memory);
		uint8_t value = memory.Read(addr);
		value--;
		memory.Write(addr, value);
		Z = (value == 0);
		N = (value & 0x80) != 0;
		std::cout << "DEC Zero Page: memory[0x" << std::hex << +addr << "] = " << +value << "\n";
		};

	// INC Zero Page
	instructionSet[0xE6] = [this](Memory& memory) {
		uint8_t addr = Fetch(memory);
		uint8_t value = memory.Read(addr);
		value++;
		memory.Write(addr, value);
		Z = (value == 0);
		N = (value & 0x80) != 0;
		std::cout << "INC Zero Page: memory[0x" << std::hex << +addr << "] = " << +value << "\n";
		};

	// BEQ Relative
	instructionSet[0xF0] = [this](Memory& memory) {
		int8_t offset = static_cast<int8_t>(Fetch(memory));
		if (Z) {
			PC += offset;
			std::cout << "BEQ Branch taken to PC = 0x" << std::hex << PC << "\n";
		}
		else {
			std::cout << "BEQ Branch not taken\n";
		}
		};

	// BNE Relative
	instructionSet[0xD0] = [this](Memory& memory) {
		int8_t offset = static_cast<int8_t>(Fetch(memory));
		if (!Z) {
			PC += offset;
			std::cout << "BNE Branch taken to PC = 0x" << std::hex << PC << "\n";
		}
		else {
			std::cout << "BNE Branch not taken\n";
		}
		};

	// BCS Relative
	instructionSet[0xB0] = [this](Memory& memory) {
		int8_t offset = static_cast<int8_t>(Fetch(memory));
		if (C) {
			PC += offset;
			std::cout << "BCS Branch taken to PC = 0x" << std::hex << PC << "\n";
		}
		else {
			std::cout << "BCS Branch not taken\n";
		}
		};

	// BCC Relative
	instructionSet[0x90] = [this](Memory& memory) {
		int8_t offset = static_cast<int8_t>(Fetch(memory));
		if (!C) {
			PC += offset;
			std::cout << "BCC Branch taken to PC = 0x" << std::hex << PC << "\n";
		}
		else {
			std::cout << "BCC Branch not taken\n";
		}
		};

	// BMI Relative
	instructionSet[0x30] = [this](Memory& memory) {
		int8_t offset = static_cast<int8_t>(Fetch(memory));
		if (N) {
			PC += offset;
			std::cout << "BMI Branch taken to PC = 0x" << std::hex << PC << "\n";
		}
		else {
			std::cout << "BMI Branch not taken\n";
		}
		};

	// BPL Relative
	instructionSet[0x10] = [this](Memory& memory) {
		int8_t offset = static_cast<int8_t>(Fetch(memory));
		if (!N) {
			PC += offset;
			std::cout << "BPL Branch taken to PC = 0x" << std::hex << PC << "\n";
		}
		else {
			std::cout << "BPL Branch not taken\n";
		}
		};

	// BVS Relative
	instructionSet[0x70] = [this](Memory& memory) {
		int8_t offset = static_cast<int8_t>(Fetch(memory));
		if (V) {
			PC += offset;
			std::cout << "BVS Branch taken to PC = 0x" << std::hex << PC << "\n";
		}
		else {
			std::cout << "BVS Branch not taken\n";
		}
		};

	// BVC Relative
	instructionSet[0x50] = [this](Memory& memory) {
		int8_t offset = static_cast<int8_t>(Fetch(memory));
		if (!V) {
			PC += offset;
			std::cout << "BVC Branch taken to PC = 0x" << std::hex << PC << "\n";
		}
		else {
			std::cout << "BVC Branch not taken\n";
		}
		};

	// CLC (Clear Carry Flag)
	instructionSet[0x18] = [this](Memory& memory) {
		C = false;
		std::cout << "CLC: Carry Flag cleared\n";
		};

	// SEC (Set Carry Flag)
	instructionSet[0x38] = [this](Memory& memory) {
		C = true;
		std::cout << "SEC: Carry Flag set\n";
		};

	// CLI (Clear Interrupt Disable)
	instructionSet[0x58] = [this](Memory& memory) {
		I = false;
		std::cout << "CLI: Interrupt Disable Flag cleared\n";
		};

	// SEI (Set Interrupt Disable)
	instructionSet[0x78] = [this](Memory& memory) {
		I = true;
		std::cout << "SEI: Interrupt Disable Flag set\n";
		};

	// CLV (Clear Overflow Flag)
	instructionSet[0xB8] = [this](Memory& memory) {
		V = false;
		std::cout << "CLV: Overflow Flag cleared\n";
		};

	// CLD (Clear Decimal Mode)
	instructionSet[0xD8] = [this](Memory& memory) {
		D = false;
		std::cout << "CLD: Decimal Mode Flag cleared\n";
		};

	// SED (Set Decimal Mode)
	instructionSet[0xF8] = [this](Memory& memory) {
		D = true;
		std::cout << "SED: Decimal Mode Flag set\n";
		};

	// BIT Zero Page
	instructionSet[0x24] = [this](Memory& memory) {
		uint8_t addr = Fetch(memory);
		uint8_t value = memory.Read(addr);
		Z = ((A & value) == 0);
		V = (value & 0x40) != 0;
		N = (value & 0x80) != 0;
		std::cout << "BIT Zero Page: Z = " << Z << ", V = " << V << ", N = " << N << "\n";
		};

	// NOP
	instructionSet[0xEA] = [this](Memory& memory) {
		std::cout << "NOP: No Operation\n";
		};

	// BRK
	instructionSet[0x00] = [this](Memory& memory) {
		Push((PC >> 8) & 0xFF, memory); // Push high byte of PC
		Push(PC & 0xFF, memory);        // Push low byte of PC
		uint8_t status = (C ? 0x01 : 0x00) |
			(Z ? 0x02 : 0x00) |
			(I ? 0x04 : 0x00) |
			(D ? 0x08 : 0x00) |
			(B ? 0x10 : 0x00) |
			(V ? 0x40 : 0x00) |
			(N ? 0x80 : 0x00);
		Push(status, memory);
		I = true; // Disable interrupts
		// Normally, BRK would set PC to the interrupt vector
		PC = 0xFFFE;
		std::cout << "BRK: Software interrupt, PC set to 0x" << std::hex << PC << "\n";
		};

	// RTI
	instructionSet[0x40] = [this](Memory& memory) {
		uint8_t status = Pull(memory);
		C = status & 0x01;
		Z = status & 0x02;
		I = status & 0x04;
		D = status & 0x08;
		B = status & 0x10;
		V = status & 0x40;
		N = status & 0x80;
		uint8_t low = Pull(memory);
		uint8_t high = Pull(memory);
		PC = (high << 8) | low;
		std::cout << "RTI: Returning to PC = 0x" << std::hex << PC << "\n";
		};
}

// Execute an instruction based on the fetched opcode 
void CPU::ExecuteInstruction(uint8_t opcode, Memory& memory) {
	if (instructionSet.find(opcode) != instructionSet.end()) {
		instructionSet[opcode](memory);
	}
	else {
		std::cerr << "Unknown opcode: 0x" << std::hex << +opcode << "\n";
	}
}

int main() {
	Memory memory; CPU cpu; cpu.InitializeInstructions();
	// Example setup of memory for various instructions
	// Program:
	// LDA #$0A      ; Load 10 into A
	// ADC #$05      ; Add 5 to A (A = 15)
	// AND #$0F      ; A = A AND 15 (A = 15)
	// ORA #$F0      ; A = A OR 240 (A = 255)
	// EOR #$0F      ; A = A XOR 15 (A = 240)
	// STA $10       ; Store A at 0x10
	// INX           ; Increment X (X = 1)
	// DEX           ; Decrement X (Not implemented, should trigger unknown opcode)
	// ASL           ; Arithmetic Shift Left A
	// JMP $8000     ; Jump back to start
	// NOP           ; No Operation
	// BRK           ; Break

	memory.Write(0x8000, 0xA9); // LDA Immediate
	memory.Write(0x8001, 0x0A); // Value 10
	memory.Write(0x8002, 0x69); // ADC Immediate
	memory.Write(0x8003, 0x05); // Value 5
	memory.Write(0x8004, 0x29); // AND Immediate
	memory.Write(0x8005, 0x0F); // Value 15
	memory.Write(0x8006, 0x09); // ORA Immediate
	memory.Write(0x8007, 0xF0); // Value 240
	memory.Write(0x8008, 0x49); // EOR Immediate
	memory.Write(0x8009, 0x0F); // Value 15
	memory.Write(0x800A, 0x85); // STA Zero Page
	memory.Write(0x800B, 0x10); // Address 0x10
	memory.Write(0x800C, 0xE8); // INX
	memory.Write(0x800D, 0xCA); // DEX (Not implemented)
	memory.Write(0x800E, 0x0A); // ASL Accumulator
	memory.Write(0x800F, 0x4C); // JMP Absolute
	memory.Write(0x8010, 0x00); // Low byte of JMP address
	memory.Write(0x8011, 0x80); // High byte of JMP address
	memory.Write(0x8012, 0xEA); // NOP
	memory.Write(0x8013, 0x00); // BRK

	// Run the program until BRK is encountered or a maximum number of instructions is executed
	bool running = true;
	int instructionCount = 0;
	const int MAX_INSTRUCTIONS = 100;

	while (running && instructionCount < MAX_INSTRUCTIONS) {
		uint8_t opcode = cpu.Fetch(memory);
		cpu.ExecuteInstruction(opcode, memory);
		instructionCount++;

		if (opcode == 0x00) { // BRK
			running = false;
		}
	}

	// Check result
	std::cout << "Accumulator: " << +cpu.A << "\n";
	std::cout << "X Register: " << +cpu.X << "\n";
	std::cout << "Memory[0x10]: " << +memory.Read(0x10) << "\n";

	return 0;
}