83 lines
2.9 KiB
Rust
83 lines
2.9 KiB
Rust
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; entrypoint must be numeric or empty (defaults to 0)
|
|
vm.initialize(unit.rom, "").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);
|
|
}
|
|
}
|