use criterion::{criterion_group, criterion_main, Criterion}; use emulator_6502::*; use std::env::var; use std::fs::*; use std::io::*; use std::path::PathBuf; struct BasicRam { ram: Box<[u8; u16::max_value() as usize + 1]>, complete: bool, } impl BasicRam { fn load_program(&mut self, start: usize, data: &mut Vec) { self.ram[start..start + data.len()].clone_from_slice(data); } } impl Interface6502 for BasicRam { fn read(&mut self, address: u16) -> u8 { match address { 0xfffe..=0xffff => { self.complete = true; //If brk has been called the test is complete 0xff //Keep program in an infinite break loop until test terminates } _ => self.ram[address as usize], } } fn write(&mut self, address: u16, data: u8) { self.ram[address as usize] = data } } /// Function for loading test programs fn load_test(ram: &mut BasicRam, file_name: &str, location: usize) -> Result<()> { let root_dir = &var("CARGO_MANIFEST_DIR").expect("$CARGO_MANIFEST_DIR"); let mut source_path = PathBuf::from(root_dir); source_path.push("tests/bins"); source_path.push(file_name); let mut file = File::open(source_path)?; let mut buffer = Vec::new(); file.read_to_end(&mut buffer)?; ram.load_program(location, &mut buffer); Ok(()) } fn bench_test() { let mut ram = BasicRam { ram: Box::new([0; u16::max_value() as usize + 1]), complete: false, }; load_test(&mut ram, "6502_bench.bin", 0x400).unwrap(); let mut cpu = MOS6502::new_start(0x400); while !ram.complete { cpu.cycle(&mut ram); } } #[cfg(feature = "binary_coded_decimal")] fn bcd_bench() -> Result<()> { std::env::set_var("RUST_LOG", "trace"); let mut ram = BasicRam { ram: Box::new([0; u16::max_value() as usize + 1]), complete: false, }; load_test(&mut ram, "6502_decimal_test.bin", 0x200)?; let mut cpu = MOS6502::new_start(0x200); let mut cycle_timeout = 0; while !ram.complete { cpu.cycle(&mut ram); cycle_timeout += 1; assert!(cycle_timeout < 46089520) //Timeout } assert_eq!(ram.ram[0x0b], 0); Ok(()) } fn criterion_benchmark(c: &mut Criterion) { c.bench_function("Loop Bench", |b| b.iter(bench_test)); if cfg!(feature = "binary_coded_decimal") { let mut group = c.benchmark_group("Binary Coded Decimal"); group.sample_size(10); group.bench_function("BCD Bench", |b| b.iter(bcd_bench)); } } criterion_group!(benches, criterion_benchmark); criterion_main!(benches);