84 lines
3.0 KiB
Rust

use prometeu_compiler::compiler::compile;
use prometeu_core::hardware::{AssetManager, Audio, Gfx, HardwareBridge, MemoryBanks, Pad, Touch};
use prometeu_core::virtual_machine::{HostContext, HostReturn, LogicalFrameEndingReason, NativeInterface, Value, VirtualMachine, VmFault};
use std::path::PathBuf;
use std::sync::Arc;
struct SimpleNative;
impl NativeInterface for SimpleNative {
fn syscall(&mut self, _id: u32, _args: &[Value], _ret: &mut HostReturn, _ctx: &mut HostContext) -> Result<(), VmFault> {
Ok(())
}
}
struct SimpleHardware {
gfx: Gfx,
audio: Audio,
pad: Pad,
touch: Touch,
assets: AssetManager,
}
impl SimpleHardware {
fn new() -> Self {
let banks = Arc::new(MemoryBanks::new());
Self {
gfx: Gfx::new(320, 240, banks.clone()),
audio: Audio::new(banks.clone()),
pad: Pad::default(),
touch: Touch::default(),
assets: AssetManager::new(vec![], vec![], banks.clone(), banks.clone()),
}
}
}
impl HardwareBridge for SimpleHardware {
fn gfx(&self) -> &Gfx { &self.gfx }
fn gfx_mut(&mut self) -> &mut Gfx { &mut self.gfx }
fn audio(&self) -> &Audio { &self.audio }
fn audio_mut(&mut self) -> &mut Audio { &mut self.audio }
fn pad(&self) -> &Pad { &self.pad }
fn pad_mut(&mut self) -> &mut Pad { &mut self.pad }
fn touch(&self) -> &Touch { &self.touch }
fn touch_mut(&mut self) -> &mut Touch { &mut self.touch }
fn assets(&self) -> &AssetManager { &self.assets }
fn assets_mut(&mut self) -> &mut AssetManager { &mut self.assets }
}
#[test]
fn test_integration_test01_link() {
let project_dir = PathBuf::from("../../test-cartridges/test01");
// Since the test runs from crates/prometeu-compiler, we need to adjust path if necessary.
// Actually, usually tests run from the workspace root if using cargo test --workspace,
// but if running from the crate dir, it's different.
// Let's try absolute path or relative to project root.
let mut root_dir = std::env::current_dir().unwrap();
while !root_dir.join("test-cartridges").exists() {
if let Some(parent) = root_dir.parent() {
root_dir = parent.to_path_buf();
} else {
break;
}
}
let _project_dir = root_dir.join("test-cartridges/test01");
let unit = compile(&project_dir).expect("Failed to compile and link");
let mut vm = VirtualMachine::default();
// Use initialize to load the ROM; entrypoint must be numeric or empty (defaults to 0)
vm.initialize(unit.rom, "frame").expect("Failed to initialize VM");
let mut native = SimpleNative;
let mut hw = SimpleHardware::new();
let mut ctx = HostContext::new(Some(&mut hw));
// Run for a bit
let report = vm.run_budget(1000, &mut native, &mut ctx).expect("VM execution failed");
// It should not trap. test01 might loop or return.
if let LogicalFrameEndingReason::Trap(t) = report.reason {
panic!("VM trapped: {:?}", t);
}
}