implements PLN-0108

This commit is contained in:
bQUARKz 2026-06-15 06:04:29 +01:00
parent f45b3a38cb
commit 117a18ee72
Signed by: bquarkz
SSH Key Fingerprint: SHA256:Z7dgqoglWwoK6j6u4QC87OveEq74WOhFN+gitsxtkf8
5 changed files with 155 additions and 147 deletions

View File

@ -174,7 +174,7 @@ mod tests {
use crate::firmware::firmware_state::HubHomeStep;
use prometeu_bytecode::assembler::assemble;
use prometeu_bytecode::model::{BytecodeModule, FunctionMeta, SyscallDecl};
use prometeu_drivers::hardware::Hardware;
use prometeu_drivers::TestPlatform;
use prometeu_hal::app_mode::AppMode;
use prometeu_hal::cartridge::AssetsPayloadSource;
use prometeu_hal::color::Color;
@ -267,28 +267,28 @@ mod tests {
}
}
fn load_shell_running_firmware() -> (Firmware, Hardware, InputSignals, TaskId) {
fn load_shell_running_firmware() -> (Firmware, TestPlatform, InputSignals, TaskId) {
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
firmware.load_cartridge(valid_cartridge(AppMode::Shell));
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
let task_id = match &firmware.state {
FirmwareState::ShellRunning(step) => step.task_id,
other => panic!("expected ShellRunning state, got {:?}", other),
};
(firmware, hardware, signals, task_id)
(firmware, platform, signals, task_id)
}
fn hub_home_firmware() -> (Firmware, Hardware) {
fn hub_home_firmware() -> (Firmware, TestPlatform) {
let mut firmware = Firmware::new(None);
firmware.state = FirmwareState::HubHome(HubHomeStep);
firmware.state_initialized = false;
(firmware, Hardware::new())
(firmware, TestPlatform::new())
}
fn focus_window(firmware: &mut Firmware, owner: WindowOwner) {
@ -306,11 +306,11 @@ mod tests {
#[test]
fn load_cartridge_transitions_to_app_crashes_when_vm_init_fails() {
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
firmware.load_cartridge(invalid_game_cartridge());
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
match &firmware.state {
FirmwareState::AppCrashes(step) => match &step.report {
@ -326,18 +326,18 @@ mod tests {
#[test]
fn game_running_transitions_to_app_crashes_when_runtime_surfaces_trap() {
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
firmware.load_cartridge(trapping_game_cartridge());
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
let task_id = match &firmware.state {
FirmwareState::GameRunning(step) => step.task_id,
other => panic!("expected GameRunning state, got {:?}", other),
};
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
match &firmware.state {
FirmwareState::AppCrashes(step) => match &step.report {
@ -359,11 +359,11 @@ mod tests {
#[test]
fn reset_routes_hub_boot_target_to_splash_screen() {
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
firmware.boot_target = BootTarget::Hub;
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::SplashScreen(_)));
}
@ -371,12 +371,12 @@ mod tests {
#[test]
fn reset_routes_cartridge_boot_target_to_launch_hub() {
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
firmware.boot_target =
BootTarget::Cartridge { path: "missing-cart".into(), debug: false, debug_port: 7777 };
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::LaunchHub(_)));
}
@ -384,11 +384,11 @@ mod tests {
#[test]
fn load_cartridge_routes_system_apps_to_system_running() {
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
firmware.load_cartridge(valid_cartridge(AppMode::Shell));
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::ShellRunning(_)));
assert!(firmware.os.windows().focused_window().is_some());
@ -398,18 +398,18 @@ mod tests {
#[test]
fn system_running_ticks_focused_system_app_through_hub_pipeline() {
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
firmware.load_cartridge(valid_cartridge(AppMode::Shell));
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
let task_id = match &firmware.state {
FirmwareState::ShellRunning(step) => step.task_id,
other => panic!("expected ShellRunning state, got {:?}", other),
};
let tick_index_before_system_update = firmware.os.vm().tick_index();
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::ShellRunning(_)));
assert!(firmware.os.windows().focused_window_belongs_to_task(task_id));
@ -418,10 +418,10 @@ mod tests {
#[test]
fn hub_home_does_not_launch_shell_before_home_input_is_armed() {
let (mut firmware, mut hardware) = hub_home_firmware();
let (mut firmware, mut platform) = hub_home_firmware();
let signals = InputSignals { f_signal: true, x_pos: 112, y_pos: 108, ..Default::default() };
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::HubHome(_)));
assert_eq!(firmware.os.windows().window_count(), 0);
@ -429,11 +429,11 @@ mod tests {
#[test]
fn hub_home_click_launches_shell_a_as_native_shell_task_window() {
let (mut firmware, mut hardware) = hub_home_firmware();
firmware.tick(&InputSignals::default(), &mut hardware);
let (mut firmware, mut platform) = hub_home_firmware();
firmware.tick(&InputSignals::default(), &mut platform);
let signals = InputSignals { f_signal: true, x_pos: 112, y_pos: 108, ..Default::default() };
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
let task_id = match &firmware.state {
FirmwareState::ShellRunning(step) => step.task_id,
@ -452,11 +452,11 @@ mod tests {
#[test]
fn hub_home_click_launches_shell_b_as_native_shell_task_window() {
let (mut firmware, mut hardware) = hub_home_firmware();
firmware.tick(&InputSignals::default(), &mut hardware);
let (mut firmware, mut platform) = hub_home_firmware();
firmware.tick(&InputSignals::default(), &mut platform);
let signals = InputSignals { f_signal: true, x_pos: 256, y_pos: 108, ..Default::default() };
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
let task_id = match &firmware.state {
FirmwareState::ShellRunning(step) => step.task_id,
@ -475,10 +475,10 @@ mod tests {
#[test]
fn shell_running_start_close_uses_lifecycle_and_returns_hub_home() {
let (mut firmware, mut hardware, _signals, task_id) = load_shell_running_firmware();
let (mut firmware, mut platform, _signals, task_id) = load_shell_running_firmware();
let close_signals = InputSignals { start_signal: true, ..Default::default() };
firmware.tick(&close_signals, &mut hardware);
firmware.tick(&close_signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::HubHome(_)));
assert_eq!(firmware.os.lifecycle().task_state(task_id), Some(TaskState::Closed));
@ -490,11 +490,11 @@ mod tests {
#[test]
fn shell_running_close_click_uses_lifecycle_and_returns_hub_home() {
let (mut firmware, mut hardware, _signals, task_id) = load_shell_running_firmware();
let (mut firmware, mut platform, _signals, task_id) = load_shell_running_firmware();
let close_signals =
InputSignals { f_signal: true, x_pos: 420, y_pos: 24, ..Default::default() };
firmware.tick(&close_signals, &mut hardware);
firmware.tick(&close_signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::HubHome(_)));
assert_eq!(firmware.os.lifecycle().task_state(task_id), Some(TaskState::Closed));
@ -506,10 +506,10 @@ mod tests {
#[test]
fn shell_running_closes_task_and_returns_hub_home_without_focused_window() {
let (mut firmware, mut hardware, signals, task_id) = load_shell_running_firmware();
let (mut firmware, mut platform, signals, task_id) = load_shell_running_firmware();
firmware.os.windows().remove_all_windows();
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::HubHome(_)));
assert_eq!(firmware.os.lifecycle().task_state(task_id), Some(TaskState::Closed));
@ -521,10 +521,10 @@ mod tests {
#[test]
fn shell_running_closes_task_and_returns_hub_home_for_focused_hub_window() {
let (mut firmware, mut hardware, signals, task_id) = load_shell_running_firmware();
let (mut firmware, mut platform, signals, task_id) = load_shell_running_firmware();
focus_window(&mut firmware, WindowOwner::Hub);
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::HubHome(_)));
assert_eq!(firmware.os.lifecycle().task_state(task_id), Some(TaskState::Closed));
@ -536,10 +536,10 @@ mod tests {
#[test]
fn shell_running_closes_task_and_returns_hub_home_for_focused_overlay_window() {
let (mut firmware, mut hardware, signals, task_id) = load_shell_running_firmware();
let (mut firmware, mut platform, signals, task_id) = load_shell_running_firmware();
focus_window(&mut firmware, WindowOwner::Overlay);
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::HubHome(_)));
assert_eq!(firmware.os.lifecycle().task_state(task_id), Some(TaskState::Closed));
@ -551,10 +551,10 @@ mod tests {
#[test]
fn shell_running_closes_task_and_returns_hub_home_for_other_task_window() {
let (mut firmware, mut hardware, signals, task_id) = load_shell_running_firmware();
let (mut firmware, mut platform, signals, task_id) = load_shell_running_firmware();
focus_window(&mut firmware, WindowOwner::Task(TaskId(task_id.0 + 1)));
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::HubHome(_)));
assert_eq!(firmware.os.lifecycle().task_state(task_id), Some(TaskState::Closed));
@ -567,11 +567,11 @@ mod tests {
#[test]
fn load_cartridge_routes_game_apps_to_game_running() {
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
firmware.load_cartridge(valid_cartridge(AppMode::Game));
firmware.tick(&signals, &mut hardware);
firmware.tick(&signals, &mut platform);
assert!(matches!(firmware.state, FirmwareState::GameRunning(_)));
assert_eq!(firmware.os.windows().window_count(), 0);

View File

@ -5,11 +5,10 @@ use prometeu_bytecode::TRAP_TYPE;
use prometeu_bytecode::Value;
use prometeu_bytecode::assembler::assemble;
use prometeu_bytecode::model::{BytecodeModule, ConstantPoolEntry, FunctionMeta, SyscallDecl};
use prometeu_drivers::hardware::Hardware;
use prometeu_drivers::TestPlatform;
use prometeu_drivers::{GlyphBankPoolInstaller, MemoryBanks, SceneBankPoolInstaller};
use prometeu_hal::AudioOpStatus;
use prometeu_hal::ComposerOpStatus;
use prometeu_hal::InputSignals;
use prometeu_hal::asset::{
AssetCodec, AssetEntry, AssetLoadError, AssetOpStatus, BankType, LoadStatus,
};
@ -22,6 +21,7 @@ use prometeu_hal::scene_layer::{ParallaxFactor, SceneLayer};
use prometeu_hal::syscalls::caps;
use prometeu_hal::tile::Tile;
use prometeu_hal::tilemap::TileMap;
use prometeu_hal::{InputSignals, RuntimePlatform};
use prometeu_vm::VmInitError;
use std::collections::HashMap;
use std::sync::Arc;
@ -247,7 +247,7 @@ fn tick_returns_error_when_vm_ends_slice_with_trap() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_BOOL 1\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -274,7 +274,7 @@ fn tick_returns_error_when_vm_ends_slice_with_trap() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
)
.expect("trap must surface as runtime error");
@ -298,7 +298,7 @@ fn tick_system_profile_rejects_gfx_game_surface() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -324,7 +324,7 @@ fn tick_system_profile_rejects_gfx_game_surface() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
)
.expect("system gfx call must trap");
@ -347,7 +347,7 @@ fn tick_system_profile_rejects_composer_game_surface() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -373,7 +373,7 @@ fn tick_system_profile_rejects_composer_game_surface() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
)
.expect("system composer call must trap");
@ -398,7 +398,7 @@ fn tick_game_profile_rejects_gfxui_shell_surface() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -424,7 +424,7 @@ fn tick_game_profile_rejects_gfxui_shell_surface() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
)
.expect("game gfxui call must trap");
@ -447,7 +447,7 @@ fn tick_shell_profile_closes_gfxui_commands_into_shell_packet() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 287454020\nHOSTCALL 0\nFRAME_SYNC\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -472,7 +472,7 @@ fn tick_shell_profile_closes_gfxui_commands_into_shell_packet() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none());
@ -483,7 +483,7 @@ fn tick_shell_profile_closes_gfxui_commands_into_shell_packet() {
};
assert_eq!(packet.commands.len(), 1);
assert!(matches!(packet.commands[0], prometeu_hal::GfxUiCommand::Clear { .. }));
assert_eq!(hardware.gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
assert_eq!(platform.local_hardware().gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
assert_eq!(runtime.frame_scheduler.completed_game_frames(), 0);
assert_eq!(runtime.frame_scheduler.active_game_frame_id(), None);
}
@ -498,7 +498,7 @@ fn tick_gfx2d_clear_buffers_without_immediate_pixel_mutation_before_frame_close(
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 287454020\nHOSTCALL 0\nJMP 0").expect("assemble");
let program = serialized_single_function_module(
@ -523,7 +523,7 @@ fn tick_gfx2d_clear_buffers_without_immediate_pixel_mutation_before_frame_close(
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none());
@ -533,7 +533,7 @@ fn tick_gfx2d_clear_buffers_without_immediate_pixel_mutation_before_frame_close(
Some(prometeu_hal::Gfx2dCommand::Clear { color })
if *color == Color::from_raw(0x11223344)
));
assert_ne!(hardware.gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
assert_ne!(platform.local_hardware().gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
}
#[test]
@ -546,7 +546,7 @@ fn tick_gfx2d_draw_text_buffers_without_immediate_pixel_mutation_before_frame_cl
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code =
assemble("PUSH_I32 0\nPUSH_I32 0\nPUSH_CONST 0\nPUSH_I32 287454020\nHOSTCALL 0\nJMP 0")
@ -574,7 +574,7 @@ fn tick_gfx2d_draw_text_buffers_without_immediate_pixel_mutation_before_frame_cl
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none());
@ -584,7 +584,7 @@ fn tick_gfx2d_draw_text_buffers_without_immediate_pixel_mutation_before_frame_cl
Some(prometeu_hal::Gfx2dCommand::DrawText { x: 0, y: 0, text, color })
if text == "I" && *color == Color::from_raw(0x11223344)
));
assert_ne!(hardware.gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
assert_ne!(platform.local_hardware().gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
}
#[test]
@ -597,7 +597,7 @@ fn tick_system_profile_rejects_bank_game_surface() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -623,7 +623,7 @@ fn tick_system_profile_rejects_bank_game_surface() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
)
.expect("system bank call must trap");
@ -646,7 +646,7 @@ fn tick_system_profile_can_use_shared_log_transport() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 2\nPUSH_CONST 0\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module_with_consts(
@ -672,7 +672,7 @@ fn tick_system_profile_can_use_shared_log_transport() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "system log transport must remain internally shared");
@ -689,7 +689,7 @@ fn tick_returns_panic_report_distinct_from_trap() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::new(assemble("HOSTCALL 0\nHALT").expect("assemble"), vec![]);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let report = runtime
@ -702,7 +702,7 @@ fn tick_returns_panic_report_distinct_from_trap() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
)
.expect("panic must surface as runtime error");
@ -734,12 +734,12 @@ fn tick_renders_bound_eight_pixel_scene_through_frame_composer_path() {
let banks = Arc::new(MemoryBanks::new());
banks.install_glyph_bank(0, Arc::new(runtime_test_glyph_bank(TileSize::Size8, 2, Color::BLUE)));
banks.install_scene_bank(0, Arc::new(runtime_test_scene(0, 2, TileSize::Size8)));
let mut hardware = Hardware::new_with_memory_banks(Arc::clone(&banks));
let glyph_slot_index = hardware.assets.glyph_asset_slot_index();
let mut platform = TestPlatform::new_with_memory_banks(Arc::clone(&banks));
let glyph_slot_index = platform.local_hardware().assets.glyph_asset_slot_index();
let mut slots = [None; 16];
slots[0] = Some(0);
glyph_slot_index.rebuild_from_slots(&slots);
assert!(hardware.frame_composer.bind_scene(0));
assert!(platform.local_hardware_mut().frame_composer.bind_scene(0));
runtime.initialize_vm(&mut log_service, &mut vm, &cartridge).expect("runtime must initialize");
let report = runtime.tick(
@ -751,11 +751,11 @@ fn tick_renders_bound_eight_pixel_scene_through_frame_composer_path() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "frame render path must not crash");
assert_eq!(hardware.gfx.front_buffer()[0], Color::BLUE.raw());
assert_eq!(platform.local_hardware().gfx.front_buffer()[0], Color::BLUE.raw());
}
#[test]
@ -807,8 +807,8 @@ fn tick_renders_scene_through_public_composer_syscalls() {
let banks = Arc::new(MemoryBanks::new());
banks.install_glyph_bank(0, Arc::new(runtime_test_glyph_bank(TileSize::Size8, 2, Color::BLUE)));
banks.install_scene_bank(0, Arc::new(runtime_test_scene(0, 2, TileSize::Size8)));
let mut hardware = Hardware::new_with_memory_banks(Arc::clone(&banks));
let glyph_slot_index = hardware.assets.glyph_asset_slot_index();
let mut platform = TestPlatform::new_with_memory_banks(Arc::clone(&banks));
let glyph_slot_index = platform.local_hardware().assets.glyph_asset_slot_index();
let mut slots = [None; 16];
slots[0] = Some(0);
glyph_slot_index.rebuild_from_slots(&slots);
@ -823,12 +823,12 @@ fn tick_renders_scene_through_public_composer_syscalls() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "public composer path must not crash");
assert_eq!(vm.operand_stack_top(1), vec![Value::Int64(ComposerOpStatus::Ok as i64)]);
assert_eq!(hardware.gfx.front_buffer()[0], Color::BLUE.raw());
assert_eq!(platform.local_hardware().gfx.front_buffer()[0], Color::BLUE.raw());
}
#[test]
@ -858,7 +858,7 @@ fn tick_draw_text_survives_no_scene_frame_path() {
}],
);
let cartridge = cartridge_with_program(program, caps::GFX);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
runtime.initialize_vm(&mut log_service, &mut vm, &cartridge).expect("runtime must initialize");
let report = runtime.tick(
@ -870,7 +870,7 @@ fn tick_draw_text_survives_no_scene_frame_path() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "no-scene overlay text must not crash");
@ -881,7 +881,7 @@ fn tick_draw_text_survives_no_scene_frame_path() {
};
assert_eq!(packet.gfx2d.len(), 1);
assert!(matches!(packet.gfx2d[0], prometeu_hal::Gfx2dCommand::DrawText { .. }));
assert_eq!(hardware.gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
assert_eq!(platform.local_hardware().gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
}
#[test]
@ -907,7 +907,7 @@ fn tick_game_submissions_are_immutable_and_latest_complete_wins() {
}],
);
let cartridge = cartridge_with_program(program, caps::GFX);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
runtime.initialize_vm(&mut log_service, &mut vm, &cartridge).expect("runtime must initialize");
let first_report = runtime.tick(
@ -919,7 +919,7 @@ fn tick_game_submissions_are_immutable_and_latest_complete_wins() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(first_report.is_none());
let first_submission =
@ -933,7 +933,7 @@ fn tick_game_submissions_are_immutable_and_latest_complete_wins() {
first_packet.gfx2d[0],
prometeu_hal::Gfx2dCommand::Clear { color } if color == Color::from_raw(0x11223344)
));
assert_eq!(hardware.gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
assert_eq!(platform.local_hardware().gfx.front_buffer()[0], Color::from_raw(0x11223344).raw());
assert_eq!(runtime.frame_scheduler.completed_game_frames(), 1);
let second_packet = prometeu_hal::Game2DFramePacket::new(
@ -957,9 +957,11 @@ fn tick_game_submissions_are_immutable_and_latest_complete_wins() {
first_packet.gfx2d[0],
prometeu_hal::Gfx2dCommand::Clear { color } if color == Color::from_raw(0x11223344)
));
prometeu_hal::RenderSubmissionSink::submit_render_submission(&mut hardware, latest.clone())
platform
.render_submission_sink()
.submit_render_submission(latest.clone())
.expect("local sink should publish latest submission");
assert_eq!(hardware.gfx.front_buffer()[0], Color::from_raw(0x55667788).raw());
assert_eq!(platform.local_hardware().gfx.front_buffer()[0], Color::from_raw(0x55667788).raw());
}
#[test]
@ -1061,7 +1063,7 @@ fn tick_numeric_happy_path_records_zero_internal_allocations() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code =
assemble("PUSH_I32 1\nPUSH_I32 2\nADD\nPOP_N 1\nFRAME_SYNC\nHALT").expect("assemble");
@ -1078,7 +1080,7 @@ fn tick_numeric_happy_path_records_zero_internal_allocations() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none());
@ -1097,7 +1099,7 @@ fn tick_already_materialized_string_path_records_zero_internal_allocations() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_CONST 0\nSET_GLOBAL 0\nGET_GLOBAL 0\nPOP_N 1\nFRAME_SYNC\nHALT")
.expect("assemble");
@ -1118,7 +1120,7 @@ fn tick_already_materialized_string_path_records_zero_internal_allocations() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none());
@ -1193,7 +1195,7 @@ fn tick_composer_bind_scene_operational_error_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 99\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -1218,7 +1220,7 @@ fn tick_composer_bind_scene_operational_error_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "operational error must not crash");
assert!(vm.is_halted());
@ -1238,7 +1240,7 @@ fn tick_composer_emit_sprite_operational_error_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_BOOL 0\nPUSH_BOOL 0\nPUSH_I32 0\nHOSTCALL 0\nHALT",
@ -1266,7 +1268,7 @@ fn tick_composer_emit_sprite_operational_error_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "operational error must not crash");
assert!(vm.is_halted());
@ -1283,7 +1285,7 @@ fn tick_composer_emit_sprite_invalid_layer_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 4\nPUSH_I32 0\nPUSH_BOOL 0\nPUSH_BOOL 0\nPUSH_I32 0\nHOSTCALL 0\nHALT",
@ -1311,7 +1313,7 @@ fn tick_composer_emit_sprite_invalid_layer_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "invalid layer must not crash");
assert!(vm.is_halted());
@ -1328,7 +1330,7 @@ fn tick_composer_emit_sprite_invalid_range_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_I32 0\nPUSH_I32 64\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_BOOL 0\nPUSH_BOOL 0\nPUSH_I32 0\nHOSTCALL 0\nHALT",
@ -1347,7 +1349,7 @@ fn tick_composer_emit_sprite_invalid_range_returns_status_not_crash() {
let cartridge = cartridge_with_program(program, caps::GFX);
let asset_data = test_glyph_asset_data();
hardware.assets.initialize_for_cartridge(
platform.local_hardware().assets.initialize_for_cartridge(
vec![test_glyph_asset_entry("tile_asset", asset_data.len())],
vec![prometeu_hal::asset::PreloadEntry { asset_id: 7, slot: 0 }],
AssetsPayloadSource::from_bytes(asset_data),
@ -1363,7 +1365,7 @@ fn tick_composer_emit_sprite_invalid_range_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "invalid composer parameter range must not crash");
assert!(vm.is_halted());
@ -1383,7 +1385,7 @@ fn tick_audio_play_sample_operational_error_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_I32 -1\nPUSH_I32 0\nPUSH_I32 255\nPUSH_I32 128\nPUSH_I32 1\nHOSTCALL 0\nHALT",
@ -1411,7 +1413,7 @@ fn tick_audio_play_sample_operational_error_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "operational error must not crash");
assert!(vm.is_halted());
@ -1428,7 +1430,7 @@ fn tick_audio_play_voice_invalid_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_I32 0\nPUSH_I32 0\nPUSH_I32 16\nPUSH_I32 255\nPUSH_I32 128\nPUSH_I32 1\nPUSH_I32 0\nHOSTCALL 0\nHALT",
@ -1456,7 +1458,7 @@ fn tick_audio_play_voice_invalid_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "invalid voice must not crash");
assert!(vm.is_halted());
@ -1473,7 +1475,7 @@ fn tick_audio_play_missing_asset_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 255\nPUSH_I32 128\nPUSH_I32 1\nPUSH_I32 0\nHOSTCALL 0\nHALT",
@ -1501,7 +1503,7 @@ fn tick_audio_play_missing_asset_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "missing audio asset must not crash");
assert!(vm.is_halted());
@ -1518,7 +1520,7 @@ fn tick_audio_play_type_mismatch_surfaces_trap_not_panic() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_BOOL 1\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 255\nPUSH_I32 128\nPUSH_I32 1\nPUSH_I32 0\nHOSTCALL 0\nHALT",
@ -1547,7 +1549,7 @@ fn tick_audio_play_type_mismatch_surfaces_trap_not_panic() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
)
.expect("type mismatch must surface as trap");
match report {
@ -1570,7 +1572,7 @@ fn tick_composer_emit_sprite_type_mismatch_surfaces_trap_not_panic() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_BOOL 1\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_BOOL 0\nPUSH_BOOL 0\nPUSH_I32 0\nHOSTCALL 0\nHALT",
@ -1599,7 +1601,7 @@ fn tick_composer_emit_sprite_type_mismatch_surfaces_trap_not_panic() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
)
.expect("type mismatch must surface as trap");
match report {

View File

@ -10,7 +10,7 @@ fn tick_asset_commit_operational_error_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 999\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -35,7 +35,7 @@ fn tick_asset_commit_operational_error_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "operational error must not crash");
assert!(vm.is_halted());
@ -52,7 +52,7 @@ fn tick_asset_load_missing_asset_returns_status_and_zero_handle() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 999\nPUSH_I32 0\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -77,7 +77,7 @@ fn tick_asset_load_missing_asset_returns_status_and_zero_handle() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "missing asset must not crash");
assert!(vm.is_halted());
@ -97,10 +97,10 @@ fn tick_asset_load_invalid_slot_returns_status_and_zero_handle() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let asset_data = test_glyph_asset_data();
hardware.assets.initialize_for_cartridge(
platform.local_hardware().assets.initialize_for_cartridge(
vec![test_glyph_asset_entry("tile_asset", asset_data.len())],
vec![],
AssetsPayloadSource::from_bytes(asset_data),
@ -128,7 +128,7 @@ fn tick_asset_load_invalid_slot_returns_status_and_zero_handle() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "invalid slot must not crash");
assert!(vm.is_halted());
@ -148,7 +148,7 @@ fn tick_asset_status_unknown_handle_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 999\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -173,7 +173,7 @@ fn tick_asset_status_unknown_handle_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "unknown asset handle must not crash");
assert!(vm.is_halted());
@ -190,10 +190,10 @@ fn tick_bank_info_returns_slot_summary_not_json() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let asset_data = test_glyph_asset_data();
hardware.assets.initialize_for_cartridge(
platform.local_hardware().assets.initialize_for_cartridge(
vec![test_glyph_asset_entry("tile_asset", asset_data.len())],
vec![prometeu_hal::asset::PreloadEntry { asset_id: 7, slot: 0 }],
AssetsPayloadSource::from_bytes(asset_data),
@ -221,7 +221,7 @@ fn tick_bank_info_returns_slot_summary_not_json() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "bank summary must not crash");
assert!(vm.is_halted());
@ -261,7 +261,7 @@ fn tick_asset_commit_invalid_transition_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 1\nHOSTCALL 0\nPOP_N 1\nPUSH_I32 1\nHOSTCALL 1\nHALT")
.expect("assemble");
@ -287,12 +287,13 @@ fn tick_asset_commit_invalid_transition_returns_status_not_crash() {
let cartridge = cartridge_with_program(program, caps::ASSET);
let asset_data = test_glyph_asset_data();
hardware.assets.initialize_for_cartridge(
platform.local_hardware().assets.initialize_for_cartridge(
vec![test_glyph_asset_entry("tile_asset", asset_data.len())],
vec![],
AssetsPayloadSource::from_bytes(asset_data),
);
let handle = hardware.assets.load(7, 0).expect("asset handle must be allocated");
let handle =
platform.local_hardware().assets.load(7, 0).expect("asset handle must be allocated");
runtime.initialize_vm(&mut log_service, &mut vm, &cartridge).expect("runtime must initialize");
let report = runtime.tick(
@ -304,7 +305,7 @@ fn tick_asset_commit_invalid_transition_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "invalid transition must not crash");
assert!(vm.is_halted());
@ -322,7 +323,7 @@ fn tick_asset_cancel_unknown_handle_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 999\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -347,7 +348,7 @@ fn tick_asset_cancel_unknown_handle_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "unknown handle cancel must not crash");
assert!(vm.is_halted());
@ -364,7 +365,7 @@ fn tick_asset_cancel_invalid_transition_returns_status_not_crash() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("PUSH_I32 1\nHOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -380,17 +381,18 @@ fn tick_asset_cancel_invalid_transition_returns_status_not_crash() {
let cartridge = cartridge_with_program(program, caps::ASSET);
let asset_data = test_glyph_asset_data();
hardware.assets.initialize_for_cartridge(
platform.local_hardware().assets.initialize_for_cartridge(
vec![test_glyph_asset_entry("tile_asset", asset_data.len())],
vec![],
AssetsPayloadSource::from_bytes(asset_data),
);
let handle = hardware.assets.load(7, 0).expect("asset handle must be allocated");
let handle =
platform.local_hardware().assets.load(7, 0).expect("asset handle must be allocated");
runtime.initialize_vm(&mut log_service, &mut vm, &cartridge).expect("runtime must initialize");
loop {
match hardware.assets.status(handle) {
match platform.local_hardware().assets.status(handle) {
LoadStatus::READY => break,
LoadStatus::PENDING | LoadStatus::LOADING => {
std::thread::sleep(std::time::Duration::from_millis(1));
@ -399,9 +401,9 @@ fn tick_asset_cancel_invalid_transition_returns_status_not_crash() {
}
}
assert_eq!(hardware.assets.commit(handle), AssetOpStatus::Ok);
hardware.assets.apply_commits();
assert_eq!(hardware.assets.status(handle), LoadStatus::COMMITTED);
assert_eq!(platform.local_hardware().assets.commit(handle), AssetOpStatus::Ok);
platform.local_hardware().assets.apply_commits();
assert_eq!(platform.local_hardware().assets.status(handle), LoadStatus::COMMITTED);
let report = runtime.tick(
&mut log_service,
@ -412,7 +414,7 @@ fn tick_asset_cancel_invalid_transition_returns_status_not_crash() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "cancel after commit must not crash");
assert!(vm.is_halted());
@ -429,7 +431,7 @@ fn tick_status_first_surface_smoke_across_composer_audio_and_asset() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 0\nPUSH_BOOL 0\nPUSH_BOOL 0\nPUSH_I32 0\nHOSTCALL 0\n\
@ -476,7 +478,7 @@ fn tick_status_first_surface_smoke_across_composer_audio_and_asset() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "mixed status-first surface must not crash");
assert!(vm.is_halted());

View File

@ -11,7 +11,7 @@ fn tick_memcard_slot_roundtrip_for_game_profile() {
let mut next_handle = 1;
runtime.mount_fs(&mut log_service, &mut fs, &mut fs_state, Box::new(MemFsBackend::default()));
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble(
"PUSH_I32 0\nPUSH_I32 0\nPUSH_CONST 0\nHOSTCALL 0\nPOP_N 2\nPUSH_I32 0\nHOSTCALL 1\nPOP_N 1\nPUSH_I32 0\nPUSH_I32 0\nPUSH_I32 10\nHOSTCALL 2\nHALT",
@ -66,7 +66,7 @@ fn tick_memcard_slot_roundtrip_for_game_profile() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "memcard roundtrip must not crash");
assert!(vm.is_halted());
@ -86,7 +86,7 @@ fn tick_memcard_access_is_denied_for_non_game_profile() {
let mut open_files: HashMap<u32, String> = HashMap::new();
let mut next_handle = 1;
let mut vm = VirtualMachine::default();
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
let signals = InputSignals::default();
let code = assemble("HOSTCALL 0\nHALT").expect("assemble");
let program = serialized_single_function_module(
@ -121,7 +121,7 @@ fn tick_memcard_access_is_denied_for_non_game_profile() {
&mut next_handle,
&mut vm,
&signals,
&mut hardware,
&mut platform,
);
assert!(report.is_none(), "non-game memcard call must return status");
assert!(vm.is_halted());

View File

@ -372,7 +372,7 @@ impl HostDebugger {
#[cfg(test)]
mod tests {
use super::*;
use prometeu_drivers::hardware::Hardware;
use prometeu_drivers::TestPlatform;
use prometeu_hal::debugger_protocol::DebugCommand;
#[test]
@ -396,15 +396,19 @@ mod tests {
fn handle_command_updates_pause_and_step_flags_without_host_io() {
let mut debugger = HostDebugger::new();
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
debugger.handle_command(DebugCommand::Pause, &mut firmware, &mut hardware);
debugger.handle_command(DebugCommand::Pause, &mut firmware, platform.local_hardware_mut());
assert!(firmware.os.vm().paused());
debugger.handle_command(DebugCommand::Resume, &mut firmware, &mut hardware);
debugger.handle_command(DebugCommand::Resume, &mut firmware, platform.local_hardware_mut());
assert!(!firmware.os.vm().paused());
debugger.handle_command(DebugCommand::StepFrame, &mut firmware, &mut hardware);
debugger.handle_command(
DebugCommand::StepFrame,
&mut firmware,
platform.local_hardware_mut(),
);
assert!(!firmware.os.vm().paused());
assert!(firmware.os.vm().debug_step_requested());
}
@ -413,12 +417,12 @@ mod tests {
fn handle_command_start_leaves_waiting_for_start_mode() {
let mut debugger = HostDebugger::new();
let mut firmware = Firmware::new(None);
let mut hardware = Hardware::new();
let mut platform = TestPlatform::new();
debugger.waiting_for_start = true;
firmware.os.vm().set_paused(true);
debugger.handle_command(DebugCommand::Start, &mut firmware, &mut hardware);
debugger.handle_command(DebugCommand::Start, &mut firmware, platform.local_hardware_mut());
assert!(!debugger.waiting_for_start);
assert!(!firmware.os.vm().paused());