111 lines
3.6 KiB
Rust
111 lines
3.6 KiB
Rust
use std::path::Path;
|
|
|
|
use ferris_boi::cpu::Processor;
|
|
use include_dir::{include_dir, Dir};
|
|
use test_generator::test_resources;
|
|
|
|
use super::TestCase;
|
|
|
|
const TESTDATA_DIR: Dir<'_> = include_dir!("$CARGO_MANIFEST_DIR/tests/cpu/jsmoo/testdata");
|
|
|
|
#[test_resources("tests/cpu/jsmoo/testdata/*.json")]
|
|
fn test_jsmoo_test(filename: &str) {
|
|
let basename = Path::new(filename).file_name().unwrap();
|
|
let testdata_file = TESTDATA_DIR
|
|
.get_file(basename)
|
|
.expect("could not find data file");
|
|
let test_cases = serde_json::from_slice::<Vec<TestCase>>(testdata_file.contents())
|
|
.expect("failed to parse test data file");
|
|
|
|
for test_case in test_cases {
|
|
let test_name = test_case.name;
|
|
println!("{test_name}");
|
|
let mut processor = Processor::default();
|
|
processor.registers.a = test_case.initial.a;
|
|
processor.registers.b = test_case.initial.b;
|
|
processor.registers.c = test_case.initial.c;
|
|
processor.registers.d = test_case.initial.d;
|
|
processor.registers.e = test_case.initial.e;
|
|
processor
|
|
.registers
|
|
.set_raw_flag_bits(test_case.initial.f)
|
|
.unwrap();
|
|
processor.registers.h = test_case.initial.h;
|
|
processor.registers.l = test_case.initial.l;
|
|
processor.registers.program_counter = test_case.initial.pc;
|
|
processor.registers.stack_pointer = test_case.initial.sp;
|
|
|
|
for (addr, value) in test_case.initial.ram {
|
|
processor
|
|
.memory
|
|
.set(addr.into(), value)
|
|
.unwrap_or_else(|err| {
|
|
panic!("failed to set up initial memory for test {test_name}: {err}")
|
|
});
|
|
}
|
|
|
|
processor.run_next_instruction();
|
|
|
|
assert_eq!(
|
|
test_case.r#final.a, processor.registers.a,
|
|
"register a value was incorrect"
|
|
);
|
|
assert_eq!(
|
|
test_case.r#final.b, processor.registers.b,
|
|
"register b value was incorrect"
|
|
);
|
|
assert_eq!(
|
|
test_case.r#final.c, processor.registers.c,
|
|
"register c value was incorrect"
|
|
);
|
|
assert_eq!(
|
|
test_case.r#final.d, processor.registers.d,
|
|
"register d value was incorrect"
|
|
);
|
|
assert_eq!(
|
|
test_case.r#final.e, processor.registers.e,
|
|
"register e value was incorrect"
|
|
);
|
|
assert_eq!(
|
|
test_case.r#final.f,
|
|
processor.registers.get_raw_flag_bits(),
|
|
"register f value was incorrect"
|
|
);
|
|
assert_eq!(
|
|
test_case.r#final.h, processor.registers.h,
|
|
"register h value was incorrect"
|
|
);
|
|
assert_eq!(
|
|
test_case.r#final.l, processor.registers.l,
|
|
"register l value was incorrect"
|
|
);
|
|
|
|
assert_eq!(
|
|
test_case.r#final.pc, processor.registers.program_counter,
|
|
"program counter was incorrect"
|
|
);
|
|
assert_eq!(
|
|
test_case.r#final.sp, processor.registers.stack_pointer,
|
|
"stack pointer was incorrect"
|
|
);
|
|
|
|
for (addr, value) in test_case.r#final.ram {
|
|
let stored_val = processor
|
|
.memory
|
|
.get(addr.into())
|
|
.unwrap_or_else(|_| panic!("failed to set up final memory for test {test_name}"));
|
|
|
|
assert_eq!(
|
|
value, stored_val,
|
|
"memory did not match at address 0x{addr:0X}"
|
|
);
|
|
}
|
|
|
|
let num_cycles_expected = test_case.cycles.len() * 4;
|
|
assert_eq!(
|
|
u128::try_from(num_cycles_expected).unwrap(),
|
|
processor.num_cycles
|
|
);
|
|
}
|
|
}
|