use crate::vm::{Value, VirtualMachine}; use crate::Machine; pub trait NativeInterface { fn syscall(&mut self, id: u32, vm: &mut VirtualMachine) -> Result; } impl NativeInterface for Machine { fn syscall(&mut self, id: u32, vm: &mut VirtualMachine) -> Result { match id { // system.has_cart() -> bool 0x0001 => { vm.push(Value::Boolean(self.cartridge.is_some())); Ok(10) } // system.run_cart() 0x0002 => { if let Some(cart) = self.cartridge.as_ref() { vm.program = cart.program.clone(); vm.pc = 0; vm.operand_stack.clear(); vm.call_stack.clear(); vm.globals.clear(); vm.heap.clear(); vm.halted = false; } else { return Err("No cartridge inserted".into()); } Ok(100) } // gfx.clear(color_index) 0x1001 => { let color_idx = vm.pop_integer()? as usize; let color = self.get_color(color_idx); self.gfx.clear(color); Ok(100) } // gfx.draw_rect(x, y, w, h, color_index) 0x1002 => { let color_idx = vm.pop_integer()? as usize; let h = vm.pop_integer()? as i32; let w = vm.pop_integer()? as i32; let y = vm.pop_integer()? as i32; let x = vm.pop_integer()? as i32; let color = self.get_color(color_idx); self.gfx.fill_rect(x, y, w, h, color); Ok(200) } // input.get_pad(button_id) -> bool 0x2001 => { let button_id = vm.pop_integer()? as u32; let is_down = self.is_button_down(button_id); vm.push(Value::Boolean(is_down)); Ok(50) } // audio.play_sample(sample_id, voice_id, volume, pan, pitch) // sample_id: 0=square, 1=kick, 2=snare 0x3001 => { let pitch = vm.pop_number()?; let pan = vm.pop_integer()? as u8; let volume = vm.pop_integer()? as u8; let voice_id = vm.pop_integer()? as usize; let sample_id = vm.pop_integer()? as u32; let sample = match sample_id { 0 => self.sample_square.clone(), 1 => self.sample_kick.clone(), 2 => self.sample_snare.clone(), _ => None, }; if let Some(s) = sample { self.audio.play(s, voice_id, volume, pan, pitch, 0, crate::peripherals::LoopMode::Off); } Ok(300) } _ => Err(format!("Unknown syscall: 0x{:08X}", id)), } } }