From ef13c43912c88d3e238ef834d1882c1b0ada8f44 Mon Sep 17 00:00:00 2001 From: Nate Catelli Date: Fri, 25 Aug 2023 19:50:31 +0000 Subject: [PATCH] feat(chip8): replace parcel with bit decoder BREAKING CHANGE: Calls to OpcodeVariantParser.parse will no longer be available. --- Cargo.toml | 3 --- src/cpu/chip8/mod.rs | 20 ++++------------ src/cpu/chip8/operations/mod.rs | 33 +++++++++++---------------- src/cpu/chip8/operations/tests/mod.rs | 11 +++------ 4 files changed, 20 insertions(+), 47 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 426a269..37d9473 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,6 @@ version = "0.2.2" authors = ["Nate Catelli "] edition = "2021" -[dependencies] -parcel = { git = "https://github.com/ncatelli/parcel", tag = "v2.0.1" } - [dependencies.isa-mos6502] git = "https://github.com/ncatelli/isa-mos6502" tag = "v1.1.0" diff --git a/src/cpu/chip8/mod.rs b/src/cpu/chip8/mod.rs index 1965a68..34eb852 100644 --- a/src/cpu/chip8/mod.rs +++ b/src/cpu/chip8/mod.rs @@ -1,7 +1,6 @@ use crate::address_map::{AddressMap, Addressable}; use crate::cpu::Execute; use crate::cpu::{register::Register, Cpu, StepState}; -use parcel::Parser; use super::ExecuteMut; @@ -339,24 +338,13 @@ where fn next(&mut self) -> Option> { use crate::cpu::Generate; let pc = self.state.pc.read(); - let opcodes: [(usize, u8); 2] = [ - (pc as usize, self.state.address_space.read(pc)), - ((pc as usize + 1), self.state.address_space.read(pc + 1)), + let opcodes: [u8; 2] = [ + self.state.address_space.read(pc), + self.state.address_space.read(pc + 1), ]; // Parse correct operation - let ops = match operations::OpcodeVariantParser.parse(&opcodes[..]) { - Ok(parcel::MatchStatus::Match { - span: _, - remainder: _, - inner: op, - }) => Ok(op), - _ => Err(format!( - "No match found for {:#02x}", - u16::from_be_bytes([opcodes[0].1, opcodes[1].1]) - )), - } - .unwrap(); + let ops = operations::decode_bytes_to_opcode(opcodes).unwrap(); let microcode_steps: Vec = ops .generate(&self.state) diff --git a/src/cpu/chip8/operations/mod.rs b/src/cpu/chip8/operations/mod.rs index 6277199..84de6ba 100644 --- a/src/cpu/chip8/operations/mod.rs +++ b/src/cpu/chip8/operations/mod.rs @@ -8,7 +8,6 @@ use crate::cpu::chip8::{ }; use crate::cpu::Generate; use crate::prelude::v1::Register; -use parcel::prelude::v1::*; use std::convert::TryFrom; pub mod addressing_mode; @@ -175,13 +174,13 @@ where } } -/// Provides a Parser type for the OpcodeVariant enum. Constructing an -/// OpcodeVariant from a stream of bytes. -pub struct OpcodeVariantParser; +pub(crate) fn decode_bytes_to_opcode(bytes: impl AsRef<[u8]>) -> Result { + let bin_data = bytes.as_ref(); -impl<'a> Parser<'a, &'a [(usize, u8)], Opcode> for OpcodeVariantParser { - fn parse(&self, input: &'a [(usize, u8)]) -> parcel::ParseResult<&'a [(usize, u8)], Opcode> { - let ms = input.get(0..2).map(|v| [v[0].1, v[1].1]).and_then(|bytes| { + bin_data + .get(0..2) + .map(|v| [v[0], v[1]]) + .and_then(|bytes| { let [[first, second], [third, fourth]] = [u8::to_be_nibbles(&bytes[0]), u8::to_be_nibbles(&bytes[1])]; let dest_reg: GpRegisters = @@ -229,19 +228,13 @@ impl<'a> Parser<'a, &'a [(usize, u8)], Opcode> for OpcodeVariantParser { [0xf, _, 0x6, 0x5] => Some(Opcode::ReadRegistersFromMemory(dest_reg)), _ => None, } - }); - - // if we get a match, set the appropiate match status headers. - match ms { - Some(op) => Ok(MatchStatus::Match { - /// increment end span to cover non-inclusivity. - span: input[0].0..(input[1].0 + 1), - inner: op, - remainder: &input[2..], - }), - None => Ok(MatchStatus::NoMatch(input)), - } - } + }) + .ok_or_else(|| { + format!( + "No match found for {:#02x}", + u16::from_be_bytes([bin_data[0], bin_data[1]]) + ) + }) } /// Clear the display. diff --git a/src/cpu/chip8/operations/tests/mod.rs b/src/cpu/chip8/operations/tests/mod.rs index d006a14..abeea98 100644 --- a/src/cpu/chip8/operations/tests/mod.rs +++ b/src/cpu/chip8/operations/tests/mod.rs @@ -7,19 +7,14 @@ macro_rules! generate_parse_test { $( #[test] fn $testname() { - let input: Vec<(usize, u8)> = $input_bytes + let input: Vec = $input_bytes .to_be_bytes() .iter() .copied() - .enumerate() .collect(); assert_eq!( - Ok(MatchStatus::Match { - span: 0..2, - remainder: &input[2..], - inner: $variant, - }), - OpcodeVariantParser.parse(&input[..]) + Ok($variant), + decode_bytes_to_opcode(&input[..]) ); } )*