diff --git a/src/main.rs b/src/main.rs index 8931dde..8518721 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,51 @@ use anyhow::{anyhow, Result}; use minifb::{Key, Window, WindowOptions}; use wasmtime::{GlobalType, MemoryType, Mutability, ValType}; +struct Loader { + store: wasmtime::Store<()>, + memory: wasmtime::Memory, + instance: wasmtime::Instance, +} + +impl Loader { + fn new(engine: &wasmtime::Engine) -> Result { + let module = wasmtime::Module::new(engine, include_bytes!("../platform/loader.wasm"))?; + let mut store = wasmtime::Store::new(engine, ()); + + let mut linker = wasmtime::Linker::new(engine); + let memory = wasmtime::Memory::new(&mut store, MemoryType::new(9, Some(9)))?; + linker.define("env", "memory", memory.clone())?; + + let instance = linker.instantiate(&mut store, &module)?; + Ok(Loader { + store, + memory, + instance, + }) + } + + fn load(&mut self, module_data: &[u8]) -> Result> { + let memory = self.memory.data_mut(&mut self.store); + + let base_start = module_data.len(); + memory[..base_start].copy_from_slice(module_data); + + let base_module = include_bytes!("../uw8-tool/base1.wasm"); + let base_end = base_start + base_module.len(); + memory[base_start..base_end].copy_from_slice(base_module); + + let load_uw8 = self + .instance + .get_typed_func::<(i32, i32, i32, i32), i32, _>(&mut self.store, "load_uw8")?; + let end_offset = load_uw8.call( + &mut self.store, + (0, base_start as i32, base_start as i32, base_end as i32), + )? as u32 as usize; + + Ok(self.memory.data(&self.store)[base_end..end_offset].to_vec()) + } +} + fn main() -> Result<()> { let filename = std::env::args() .nth(1) @@ -13,22 +58,43 @@ fn main() -> Result<()> { File::open(filename)?.read_to_end(&mut uw8_module)?; let engine = wasmtime::Engine::default(); - let module = wasmtime::Module::new(&engine, uw8_module)?; + + let mut loader = Loader::new(&engine)?; + + let module = wasmtime::Module::new(&engine, loader.load(&uw8_module)?)?; let mut store = wasmtime::Store::new(&engine, ()); - let time_global = wasmtime::Global::new( - &mut store, - GlobalType::new(ValType::I32, Mutability::Var), - 0.into(), - )?; - let memory = wasmtime::Memory::new(&mut store, MemoryType::new(2, Some(2)))?; + let memory = wasmtime::Memory::new(&mut store, MemoryType::new(4, Some(4)))?; let mut linker = wasmtime::Linker::new(&engine); - linker.define("uw8", "time", time_global.clone())?; - linker.define("uw8", "ram", memory.clone())?; + linker.define("env", "memory", memory.clone())?; + linker.func_wrap("env", "acos", |v: f32| v.acos())?; + linker.func_wrap("env", "asin", |v: f32| v.asin())?; + linker.func_wrap("env", "atan", |v: f32| v.atan())?; + linker.func_wrap("env", "atan2", |x: f32, y: f32| x.atan2(y))?; + linker.func_wrap("env", "cos", |v: f32| v.cos())?; + linker.func_wrap("env", "exp", |v: f32| v.exp())?; + linker.func_wrap("env", "log", |v: f32| v.ln())?; + linker.func_wrap("env", "sin", |v: f32| v.sin())?; + linker.func_wrap("env", "tan", |v: f32| v.tan())?; + linker.func_wrap("env", "pow", |a: f32, b: f32| a.powf(b))?; + for i in 9..64 { + linker.func_wrap("env", &format!("reserved{}", i), || {})?; + } + for i in 0..16 { + linker.define( + "env", + &format!("g_reserved{}", i), + wasmtime::Global::new( + &mut store, + GlobalType::new(ValType::I32, Mutability::Const), + 0.into(), + )?, + )?; + } let instance = linker.instantiate(&mut store, &module)?; - let tic = instance.get_typed_func::<(), (), _>(&mut store, "tic")?; + let tic = instance.get_typed_func::(&mut store, "tic")?; let mut buffer = vec![0u32; 320 * 256]; let mut window = Window::new("MicroW8", 320, 256, WindowOptions::default())?; @@ -37,12 +103,7 @@ fn main() -> Result<()> { let start_time = Instant::now(); while window.is_open() && !window.is_key_down(Key::Escape) { - time_global.set( - &mut store, - wasmtime::Val::I32(start_time.elapsed().as_millis() as i32), - )?; - - tic.call(&mut store, ())?; + tic.call(&mut store, start_time.elapsed().as_millis() as i32)?; let framebuffer = &memory.data(&store)[120..]; for i in 0..320 * 256 { diff --git a/web/src/main.js b/web/src/main.js index 6196398..0233d4a 100644 --- a/web/src/main.js +++ b/web/src/main.js @@ -59,7 +59,7 @@ async function runModule(data) { let loaderImport = { env: { - memory: new WebAssembly.Memory({ initial: 8 }) + memory: new WebAssembly.Memory({ initial: 9 }) } }; let loadMem = loaderImport.env.memory.buffer;