start implementing instructions
This commit is contained in:
@@ -8,6 +8,7 @@ pub enum CpuType {
|
||||
}
|
||||
|
||||
pub trait Cpu {
|
||||
fn new() -> Self;
|
||||
fn get_type() -> CpuType;
|
||||
fn get_regs(&mut self) -> &mut Registers;
|
||||
fn fetch(&self, _: &Memory, _: u64) -> Option<Instruction> {
|
||||
@@ -21,7 +22,7 @@ pub trait Cpu {
|
||||
fn advance(&mut self) -> bool {
|
||||
false
|
||||
}
|
||||
fn decode_execute(&mut self, instr: Instruction) -> Result<(), Error>;
|
||||
|
||||
fn reset(&mut self);
|
||||
fn should_service_interrupt(&self) -> bool;
|
||||
fn update_compare_interrupt(&mut self);
|
||||
|
||||
@@ -3,10 +3,10 @@ use crate::core::{
|
||||
mem::Memory,
|
||||
registers::Registers,
|
||||
};
|
||||
use utils::{
|
||||
error::{Error, Severity, Type::UnhandledInstruction},
|
||||
instruction::Instruction,
|
||||
};
|
||||
use utils::{error::Error, instruction::Instruction};
|
||||
|
||||
pub mod decode;
|
||||
pub mod instructions;
|
||||
|
||||
pub struct Interpreter {
|
||||
regs: Registers,
|
||||
@@ -15,6 +15,14 @@ pub struct Interpreter {
|
||||
}
|
||||
|
||||
impl Cpu for Interpreter {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
regs: Registers::new(),
|
||||
delay_slot: false,
|
||||
prev_delay_slot: false,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_type() -> super::cpu::CpuType {
|
||||
Interpreter
|
||||
}
|
||||
@@ -65,16 +73,9 @@ impl Cpu for Interpreter {
|
||||
Ok(1)
|
||||
}
|
||||
|
||||
fn decode_execute(&mut self, instr: Instruction) -> Result<(), Error> {
|
||||
match instr.opcode() {
|
||||
_ => Err(Error {
|
||||
severity: Severity::Error,
|
||||
err_type: UnhandledInstruction(instr),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
fn reset(&mut self) {
|
||||
todo!("reset")
|
||||
self.regs = Registers::new();
|
||||
self.delay_slot = false;
|
||||
self.prev_delay_slot = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
use utils::{
|
||||
error::{Error, Severity, Type::UnhandledInstruction},
|
||||
instruction::Instruction,
|
||||
};
|
||||
|
||||
use crate::core::interpreter::Interpreter;
|
||||
|
||||
impl Interpreter {
|
||||
pub fn decode_special(&mut self, instr: Instruction) -> Result<(), Error> {
|
||||
match instr.special() {
|
||||
Instruction::SLL => {
|
||||
if instr.0 == 0 {
|
||||
Ok(()) // nop
|
||||
} else {
|
||||
Ok(self.sll(instr))
|
||||
}
|
||||
}
|
||||
Instruction::ADD => Ok(self.add(instr)),
|
||||
Instruction::ADDU => Ok(self.addu(instr)),
|
||||
_ => Err(Error {
|
||||
severity: Severity::Fatal,
|
||||
err_type: UnhandledInstruction(instr),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn decode_execute(&mut self, instr: Instruction) -> Result<(), Error> {
|
||||
match instr.opcode() {
|
||||
Instruction::SPECIAL => self.decode_special(instr),
|
||||
_ => Err(Error {
|
||||
severity: Severity::Error,
|
||||
err_type: UnhandledInstruction(instr),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#![allow(dead_code)]
|
||||
#![allow(unused)]
|
||||
|
||||
use utils::{
|
||||
error::{Error, Severity, Type::UnhandledInstruction},
|
||||
instruction::Instruction,
|
||||
};
|
||||
|
||||
use crate::core::interpreter::Interpreter;
|
||||
|
||||
impl Interpreter {
|
||||
pub fn add(&mut self, instr: Instruction) {
|
||||
let rs = self.regs.read::<i64>(instr.rs()) as u32;
|
||||
let rt = self.regs.read::<i64>(instr.rt()) as u32;
|
||||
let (rd, overflow) = rs.overflowing_add(rt);
|
||||
if overflow {
|
||||
todo!("add overflow!")
|
||||
}
|
||||
|
||||
self.regs.write(instr.rd(), rd as i32);
|
||||
}
|
||||
|
||||
pub fn addu(&mut self, instr: Instruction) {
|
||||
let rs = self.regs.read::<i64>(instr.rs()) as i32;
|
||||
let rt = self.regs.read::<i64>(instr.rt()) as i32;
|
||||
let rd = rs + rt;
|
||||
self.regs.write(instr.rd(), rd);
|
||||
}
|
||||
|
||||
pub fn sll(&mut self, instr: Instruction) {
|
||||
let rd = self.regs.read::<i64>(instr.rt()) << instr.sa();
|
||||
self.regs.write(instr.rd(), rd);
|
||||
}
|
||||
}
|
||||
@@ -5,16 +5,16 @@ bitfield! {
|
||||
pub struct Instruction(pub u32): FromStorage, IntoStorage, DerefStorage {
|
||||
pub special: u8 @ 0..6,
|
||||
pub regimm: u8 @ 16..21,
|
||||
pub rt: u8 @ 16..21,
|
||||
pub rt: usize @ 16..21,
|
||||
pub cop_rt: u8 @ 16..21,
|
||||
pub rs: u8 @ 21..26,
|
||||
pub rs: usize @ 21..26,
|
||||
pub cop_rs: u8 @ 21..26,
|
||||
pub opcode: u8 @ 26..32,
|
||||
pub imm: u16 @ 0..16,
|
||||
pub target: u32 @ 0..26,
|
||||
pub funct: u8 @ 0..6,
|
||||
pub sa: u8 @ 6..11,
|
||||
pub rd: u8 @ 11..16,
|
||||
pub rd: usize @ 11..16,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user