use prometeu_compiler::compiler::compile; use prometeu_core::hardware::{AssetManager, Audio, Gfx, HardwareBridge, MemoryBanks, Pad, Touch}; use prometeu_core::virtual_machine::{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, _hw: &mut dyn HardwareBridge) -> 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 and resolve entrypoint vm.initialize(unit.rom, "frame").expect("Failed to initialize VM"); let mut native = SimpleNative; let mut hw = SimpleHardware::new(); // Run for a bit let report = vm.run_budget(1000, &mut native, &mut hw).expect("VM execution failed"); // It should not trap. test01 might loop or return. if let LogicalFrameEndingReason::Trap(t) = report.reason { panic!("VM trapped: {:?}", t); } }