// SPDX-License-Identifier: LGPL-3.0-or-later // Copyright (c) 2024 Patrick_Pluto // This is an example implementation of a CPU emulator. You can copy this for your own custom ISA, or do something else. pub struct ExampleCPU { debug: bool, execution_pointer: u8, operands: [u8; 3], ram: [u8; 256], registers: [u8; 8], } impl ExampleCPU { // Here is where you can create your own CPU Instance. pub fn create(debug: bool, initial_state: [u8; 256]) -> ExampleCPU { return ExampleCPU { debug: debug, execution_pointer: 0, operands: [0; 3], ram: initial_state, registers: [0; 8], }; } pub fn start(&mut self) { loop { self.fetch_and_decode() } } // This fetches the operands, based on the position of the execution_pointer, then runs the selected instruction. fn fetch_and_decode(&mut self) { self.operands[0] = self.ram[self.execution_pointer as usize]; self.operands[1] = self.ram[(self.execution_pointer + 1) as usize]; self.operands[2] = self.ram[(self.execution_pointer + 2) as usize]; if self.debug { println!( "0x{:02X} 0x{:02X} 0x{:02X}", self.operands[0], self.operands[1], self.operands[2] ); } match self.operands[0] { 0 => self.nop(), 1 => self.load(), 2 => self.store(), 3 => self.add(), 4 => self.sub(), 5 => self.jump(), 6 => self.jpiz(), _ => self.nop(), }; } // Here is where all of the implementations of the instructions should go. fn nop(&mut self) { self.execution_pointer += 1; } fn load(&mut self) { self.registers[self.operands[1] as usize] = self.ram[self.operands[2] as usize]; self.execution_pointer += 3; } fn store(&mut self) { self.ram[self.operands[1] as usize] = self.registers[self.operands[2] as usize]; self.execution_pointer += 3; } fn add(&mut self) { self.registers[self.operands[1] as usize] += self.registers[self.operands[2] as usize]; self.execution_pointer += 3; } fn sub(&mut self) { self.registers[self.operands[1] as usize] -= self.registers[self.operands[2] as usize]; self.execution_pointer += 3; } fn jump(&mut self) { self.execution_pointer = self.operands[1]; } fn jpiz(&mut self) { if self.operands[2] == 0 { self.execution_pointer = self.operands[1]; } else { self.execution_pointer += 3; } } }