// SPDX-License-Identifier: AGPL-3.0-or-later //! Implementation of instructions for MOS 6502. /// List of all instructions for MOS 6502. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Instruction { /// Jump to subroutine. /// /// The JSR instruction pushes the address (minus one) of the return point on to the stack and /// then sets the program counter to the target memory address. Jsr, /// Load accumulator. /// /// Loads a byte of memory into the accumulator, setting the zero and negative flags as /// appropriate. Lda, } /// Addressing modes for MOS 6502. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum AddressingMode { /// Absolute mode. /// /// Instructions using absolute addressing contain a full 16 bit address to identify the /// target location. Absolute, /// Immediate mode. Immediate, /// Zero Page mode. ZeroPage, /// ZeroPage.X mode. ZeroPageX, } /// Operation retrieved from decoding an opcode. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct Operation { /// [`AddressingMode`] pub addressing_mode: AddressingMode, /// [`Instruction`] pub instruction: Instruction, } impl Operation { /// Creates a new operation from the `instruction` and `addressing_mode`. pub const fn new(instruction: Instruction, addressing_mode: AddressingMode) -> Self { Self { addressing_mode, instruction, } } } /// Gets the operation from the passed in opcode. Returns [`None`] if no /// operation exists. pub const fn get_operation(opcode: u8) -> Option { match opcode { 0x20 => Some(Operation::new(Instruction::Jsr, AddressingMode::Absolute)), 0xA5 => Some(Operation::new(Instruction::Lda, AddressingMode::ZeroPage)), 0xA9 => Some(Operation::new(Instruction::Lda, AddressingMode::Immediate)), 0xB5 => Some(Operation::new(Instruction::Lda, AddressingMode::ZeroPageX)), _ => None, } }