Skip to content

Commit

Permalink
SPC700: remove hidden allocation (in anyhow) from instruction decode
Browse files Browse the repository at this point in the history
  • Loading branch information
twvd committed Jun 8, 2024
1 parent e4f2f80 commit 8d1164a
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 18 deletions.
10 changes: 5 additions & 5 deletions src/cpu_spc700/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,14 @@ where
"{} - {}\n --> {}",
self.cycles,
self.regs,
self.peek_next_instr().unwrap()
self.peek_next_instr()
)
}

/// Fetches and decodes the next instruction at PC
pub fn peek_next_instr(&self) -> Result<Instruction> {
pub fn peek_next_instr(&self) -> Instruction {
let mut busiter = BusIterator::new_from(&self.bus, self.regs.pc);
Instruction::decode(&mut busiter)
Instruction::decode(&mut busiter).expect("SPC700 instruction decode error")
}

/// Fetches and decodes the next instruction at PC
Expand All @@ -53,8 +53,8 @@ where
for i in 0.. {
let pc = self.regs.pc as SpcAddress;
match Instruction::decode(&mut fetched.clone().into_iter()) {
Err(_) => fetched.push(self.read_tick(pc.wrapping_add(i))),
Ok(i) => return Ok(i),
None => fetched.push(self.read_tick(pc.wrapping_add(i))),
Some(instruction) => return Ok(instruction),
}
}

Expand Down
19 changes: 6 additions & 13 deletions src/cpu_spc700/instruction.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
use std::fmt;

use anyhow::Result;
use arrayvec::ArrayVec;
use thiserror::Error;

use super::instruction_table::INSTRUCTION_TABLE;
use super::regs::Register;
Expand Down Expand Up @@ -123,12 +121,6 @@ pub enum InstructionType {
ROL,
}

#[derive(Debug, Error)]
enum DecodeErr {
#[error("End of instruction stream")]
EndOfStream,
}

/// A decoded instruction
pub struct Instruction {
/// Reference to definition in instruction table
Expand All @@ -146,12 +138,13 @@ pub struct Instruction {

impl Instruction {
/// Try to decode a single instruction from an iterator.
pub fn decode(stream: &mut impl Iterator<Item = u8>) -> Result<Instruction> {
pub fn decode(stream: &mut impl Iterator<Item = u8>) -> Option<Instruction> {
let mut raw: ArrayVec<u8, MAX_INSTRUCTION_LEN> = ArrayVec::new();
let mut rd = || -> Result<u8> {
let b = stream.next().ok_or(DecodeErr::EndOfStream)?;
let mut rd = || -> Option<u8> {
// Assuming the stream wraps at the end, no errors will be thrown.
let b = stream.next()?;
raw.push(b);
Ok(b)
Some(b)
};

let opcode = rd()?;
Expand All @@ -174,7 +167,7 @@ impl Instruction {
immediate[0] = args[0];
}

Ok(Instruction {
Some(Instruction {
def,
immediate,
raw,
Expand Down

0 comments on commit 8d1164a

Please sign in to comment.