2023-12-21 13:01:38 +11:00
|
|
|
use std::time::{Duration, Instant};
|
|
|
|
|
|
|
|
use common::emulator_setup;
|
|
|
|
use gb_emu_lib::connect::{EmulatorCoreTrait, RomFile};
|
|
|
|
|
|
|
|
mod common;
|
|
|
|
|
|
|
|
#[test]
|
2024-06-16 11:48:05 +10:00
|
|
|
fn cpu_instrs() -> anyhow::Result<()> {
|
2023-12-21 13:01:38 +11:00
|
|
|
run_blargg_test("cpu_instrs\n\n01:ok 02:ok 03:ok 04:ok 05:ok 06:ok 07:ok 08:ok 09:ok 10:ok 11:ok \n\nPassed all tests", include_bytes!(
|
|
|
|
"../../test-roms/blargg/cpu_instrs/cpu_instrs.gb"
|
|
|
|
),None)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2024-06-16 11:48:05 +10:00
|
|
|
fn instr_timing() -> anyhow::Result<()> {
|
2023-12-21 13:01:38 +11:00
|
|
|
run_blargg_test(
|
|
|
|
"instr_timing\n\n\nPassed",
|
|
|
|
include_bytes!("../../test-roms/blargg/instr_timing/instr_timing.gb"),
|
|
|
|
Some(vec!["Failed"]),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2024-06-16 11:48:05 +10:00
|
|
|
fn mem_timing() -> anyhow::Result<()> {
|
2023-12-21 13:01:38 +11:00
|
|
|
run_blargg_test(
|
|
|
|
"mem_timing\n\n\nPassed",
|
|
|
|
include_bytes!("../../test-roms/blargg/mem_timing/mem_timing.gb"),
|
|
|
|
None,
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
2024-06-16 11:48:05 +10:00
|
|
|
#[derive(Debug, thiserror::Error)]
|
|
|
|
enum TestError {
|
|
|
|
#[error("Timeout")]
|
|
|
|
Timeout(String),
|
|
|
|
}
|
|
|
|
|
2023-12-21 13:01:38 +11:00
|
|
|
fn run_blargg_test<const N: usize>(
|
|
|
|
correct_output: &str,
|
|
|
|
rom: &[u8; N],
|
|
|
|
extra_end: Option<Vec<&str>>,
|
2024-06-16 11:48:05 +10:00
|
|
|
) -> anyhow::Result<()> {
|
2023-12-21 13:01:38 +11:00
|
|
|
let mut emu = emulator_setup(RomFile::Raw(rom.to_vec()))?;
|
|
|
|
|
|
|
|
let mut end_strings = extra_end.unwrap_or_default();
|
|
|
|
end_strings.append(&mut vec![".", "tests"]);
|
|
|
|
|
|
|
|
let mut chars = String::new();
|
|
|
|
|
|
|
|
let began = Instant::now();
|
|
|
|
let timeout = Duration::from_secs(60);
|
|
|
|
|
|
|
|
'outer: loop {
|
|
|
|
emu.core.run(100);
|
|
|
|
while let Ok(v) = emu.serial_rx.try_recv() {
|
|
|
|
chars.push(v as char);
|
|
|
|
if end_strings.iter().any(|end| chars.ends_with(end)) {
|
|
|
|
break 'outer;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if began.elapsed() > timeout {
|
2024-06-16 11:48:05 +10:00
|
|
|
return Err(TestError::Timeout(format!("Test timed out: output was {chars}")).into());
|
2023-12-21 13:01:38 +11:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
assert_eq!(correct_output, chars);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|