Skip to content

Commit

Permalink
add memory write command
Browse files Browse the repository at this point in the history
  • Loading branch information
chanmix51 committed Apr 7, 2024
1 parent e734670 commit 42ee4de
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 8 deletions.
2 changes: 1 addition & 1 deletion soft65c02_lib/src/memory/ram.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl AddressableIO for RAM {
if location + data.len() > self.ram.len() {
Err(MemoryError::WriteOverflow(data.len(), location))
} else {
for (offset, value) in data.into_iter().enumerate() {
for (offset, value) in data.iter().enumerate() {
self.ram[location + offset] = *value;
}
Ok(())
Expand Down
10 changes: 5 additions & 5 deletions soft65c02_tester/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ impl Command for RegisterCommand {
pub enum MemoryCommand {
Flush,
Load(String),
Write { address: u16, bytes: Vec<u8> },
Write { address: usize, bytes: Vec<u8> },
}

impl Command for MemoryCommand {
Expand All @@ -108,12 +108,12 @@ impl Command for MemoryCommand {
Self::Write { address, bytes } => match bytes.len() {
0 => vec!["nothing was written".to_string()],
1 => {
memory.write(*address as usize, bytes)?;
memory.write(*address, bytes)?;
vec!["1 byte written".to_string()]
}
_ => {
memory.write(*address as usize, bytes)?;
vec![format!("{} bytes written", bytes.len())]
n => {
memory.write(*address, bytes)?;
vec![format!("{n} bytes written")]
}
},
_ => todo!(),
Expand Down
48 changes: 46 additions & 2 deletions soft65c02_tester/src/pest_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,22 @@ impl MemoryCommandParser {

let command = match pair.as_rule() {
Rule::memory_flush => MemoryCommand::Flush,
Rule::memory_write => {
let mut pairs = pair.into_inner();
let address = parse_memory(
&pairs
.next()
.expect("there shall be a memory address argument to memory write")
.as_str()[3..],
)?;
let bytes = parse_bytes(
pairs
.next()
.expect("There shall be some bytes to write to memory.")
.as_str(),
)?;
MemoryCommand::Write { address, bytes }
}
_ => {
panic!("Unexpected pair '{pair:?}'. memory_{{load,flush,write}} expected.");
}
Expand All @@ -49,6 +65,21 @@ mod memory_command_parser_tests {

assert!(matches!(command, MemoryCommand::Flush));
}

#[test]
fn test_memory_write() {
let input = "memory write #0x1234 0x(01,02,03)";
let pairs = PestParser::parse(Rule::memory_instruction, input)
.unwrap()
.next()
.unwrap()
.into_inner();
let command = MemoryCommandParser::from_pairs(pairs).unwrap();

assert!(
matches!(command, MemoryCommand::Write { address, bytes } if address == 0x1234 && bytes == vec![0x01, 0x02, 0x03])
);
}
}
pub struct RegisterCommandParser;

Expand Down Expand Up @@ -278,6 +309,19 @@ mod cli_command_parser_test {
CliCommand::Memory(MemoryCommand::Flush)
));
}

#[test]
fn test_memory_write_parser() {
let cli_command = CliCommandParser::from("memory write #0x1234 0x(12,23,34,45)").unwrap();

assert!(matches!(
cli_command,
CliCommand::Memory(MemoryCommand::Write {
address,
bytes
}) if address == 0x1234 && bytes == vec![0x12, 0x23, 0x34, 0x45]
));
}
}

fn parse_memory(addr: &str) -> AppResult<usize> {
Expand Down Expand Up @@ -360,10 +404,10 @@ fn parse_source_value(node: &Pair<Rule>) -> AppResult<Source> {
}

#[allow(dead_code)]
fn parse_bytes(bytes: &str) -> Vec<u8> {
fn parse_bytes(bytes: &str) -> AppResult<Vec<u8>> {
bytes
.split(',')
.map(|x| hex::decode(x.trim()).unwrap()[0])
.map(|x| hex::decode(x.trim()).map(|v| v[0]).map_err(|e| anyhow!(e)))
.collect()
}

Expand Down

0 comments on commit 42ee4de

Please sign in to comment.