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}