sixfiveohtwo/
processor.rs

1// Imports
2use crate::memory::Memory;
3use crate::opcodes::*;
4use crate::registers::Registers;
5
6// Structs
7
8///////////////
9// Processor //
10///////////////
11
12#[derive(Debug)]
13pub struct Processor {
14    registers: Registers,
15    memory: Memory,
16}
17
18impl Processor {
19    pub fn new(memory_size: u16, program: Option<Vec<u8>>) -> Self {
20        // Make the memory and registers
21        let registers = Registers::new();
22        let mut memory = Memory::new(memory_size);
23
24        // Load the program into memory
25        if let Some(program) = program {
26            memory.load(program, 0x8000);
27        }
28
29        // Return the processor
30        Self { registers, memory }
31    }
32
33    fn fetch(&mut self) -> u8 {
34        // Get the byte at the program counter
35        let opcode = self.memory.read(self.registers.pc);
36
37        // Increment the program counter
38        self.registers.pc += 1;
39
40        // Return the byte
41        opcode
42    }
43
44    fn execute(&mut self, opcode: u8) {
45        // Execute the instruction
46        match opcode {
47            // Loadstore
48            // LDA => self.lda(), TODO: Add this instruction
49            // LDX => self.ldx(), TODO: Add this instruction
50            // LDY => self.ldy(), TODO: Add this instruction
51            // STA => self.sta(), TODO: Add this instruction
52            // STX => self.stx(), TODO: Add this instruction
53            // STY => self.sty(), TODO: Add this instruction
54
55            // Transfer
56            TAX => self.tax(), // Transfer Accumulator to X
57            TAY => self.tay(), // Transfer Accumulator to Y
58            TXA => self.txa(), // Transfer X to Accumulator
59            TYA => self.tya(), // Transfer Y to Accumulator
60
61            // Unknown opcode
62            _ => {
63                panic!("Unknown opcode: {:#X}", opcode);
64            }
65        }
66    }
67
68    pub fn run(&mut self) {
69        // Fetch and execute instructions
70        loop {
71            let instruction = self.fetch();
72            self.execute(instruction);
73        }
74    }
75
76    pub fn step(&mut self) {
77        // Fetch and execute one instruction
78        let instruction = self.fetch();
79        self.execute(instruction);
80    }
81
82    // Instructions ----------------------------------------------------------------
83
84    // Transfer
85
86    // Transfer Accumulator to X
87    pub fn tax(&mut self) {
88        self.registers.x = self.registers.acc;
89    }
90
91    // Transfer Accumulator to Y
92    pub fn tay(&mut self) {
93        self.registers.y = self.registers.acc;
94    }
95
96    // Transfer X to Accumulator
97    pub fn txa(&mut self) {
98        self.registers.acc = self.registers.x;
99    }
100
101    // Transfer Y to Accumulator
102    pub fn tya(&mut self) {
103        self.registers.acc = self.registers.y;
104    }
105}