This repository has been archived on 2024-11-26. You can view files and clone it, but cannot push or open issues or pull requests.
sysforge/src/cpu.rs

91 lines
2.6 KiB
Rust
Raw Normal View History

2024-11-24 18:47:56 +01:00
// 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.
2024-11-24 22:03:13 +01:00
pub fn create(debug: bool, initial_state: [u8; 256]) -> ExampleCPU {
2024-11-24 18:47:56 +01:00
return ExampleCPU {
debug: debug,
execution_pointer: 0,
operands: [0; 3],
ram: initial_state,
registers: [0; 8],
};
}
2024-11-24 22:03:13 +01:00
pub fn start(&mut self) {
loop {
self.fetch_and_decode()
}
}
2024-11-24 18:47:56 +01:00
// This fetches the operands, based on the position of the execution_pointer, then runs the selected instruction.
2024-11-24 22:03:13 +01:00
fn fetch_and_decode(&mut self) {
2024-11-24 18:47:56 +01:00
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];
2024-11-24 18:49:15 +01:00
if self.debug {
println!(
"0x{:02X} 0x{:02X} 0x{:02X}",
self.operands[0], self.operands[1], self.operands[2]
);
}
2024-11-24 18:47:56 +01:00
match self.operands[0] {
2024-11-24 22:03:13 +01:00
0 => self.nop(),
1 => self.load(),
2 => self.store(),
3 => self.add(),
4 => self.sub(),
5 => self.jump(),
6 => self.jpiz(),
2024-11-24 18:47:56 +01:00
_ => 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;
}
}
}