Skip to content

Commit

Permalink
feat(chip8): replace parcel with bit decoder
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Calls to OpcodeVariantParser.parse will no longer be available.
  • Loading branch information
Nate Catelli committed Aug 25, 2023
1 parent 56769d6 commit ef13c43
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 47 deletions.
3 changes: 0 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@ version = "0.2.2"
authors = ["Nate Catelli <[email protected]>"]
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"
Expand Down
20 changes: 4 additions & 16 deletions src/cpu/chip8/mod.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -339,24 +338,13 @@ where
fn next(&mut self) -> Option<Vec<microcode::Microcode>> {
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<microcode::Microcode> = ops
.generate(&self.state)
Expand Down
33 changes: 13 additions & 20 deletions src/cpu/chip8/operations/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Opcode, String> {
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 =
Expand Down Expand Up @@ -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.
Expand Down
11 changes: 3 additions & 8 deletions src/cpu/chip8/operations/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,14 @@ macro_rules! generate_parse_test {
$(
#[test]
fn $testname() {
let input: Vec<(usize, u8)> = $input_bytes
let input: Vec<u8> = $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[..])
);
}
)*
Expand Down

0 comments on commit ef13c43

Please sign in to comment.