Skip to content

Commit

Permalink
Add display backend implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
1whatleytay committed Sep 10, 2024
1 parent 109100f commit a3388fa
Show file tree
Hide file tree
Showing 14 changed files with 156 additions and 51 deletions.
10 changes: 5 additions & 5 deletions src-backend/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-backend/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ base64 = "0.21.7"
rand = "0.8.5"
rand_chacha = "0.3.1"
async-trait = "0.1.77"
log = "0.4.22"

titan = { git = "https://github.com/1whatleytay/titan.git", branch = "main" }
log = "0.4.22"
4 changes: 4 additions & 0 deletions src-backend/src/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ pub trait ExecutionRewindable {

pub trait RewindableDevice: ExecutionDevice + ExecutionRewindable { }

#[derive(Debug, Clone)]
pub struct BatchOptions {
pub count: usize,
// if true, the cancelled flag for syscall delegates will be cleared
Expand Down Expand Up @@ -199,9 +200,12 @@ impl<Mem: Memory + Send, Track: Tracker<Mem> + Send> ExecutionDevice for Executi
let state = self.delegate.clone();
let finished_pcs = self.finished_pcs.clone();

log::info!("Resuming with batch options: {:?}", options.batch);

if let Some(breakpoints) = options.breakpoints {
let breakpoints_set = HashSet::from_iter(breakpoints.iter().copied());

log::info!("Overriding breakpoints: {:?}", breakpoints_set);
debugger.set_breakpoints(breakpoints_set);
}

Expand Down
27 changes: 18 additions & 9 deletions src-backend/src/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use std::io::{Read, Write};
use std::pin::{Pin, pin};
use std::sync::{Arc, Mutex};
use std::time::{Duration, SystemTime, UNIX_EPOCH};
use async_trait::async_trait;
use futures::future::FusedFuture;
use titan::cpu::error::Error;
use titan::cpu::error::Error::{CpuSyscall, CpuTrap};
Expand All @@ -32,6 +33,7 @@ pub struct MidiRequest {
pub volume: u32, // 0 - 127
}

#[derive(Debug)]
pub enum SyscallResult {
Completed, // Syscall completed successfully.
Failure(String), // Failed to complete with message.
Expand All @@ -52,9 +54,10 @@ pub trait MidiHandler {
fn installed(&mut self, instrument: u32) -> bool;
}

#[async_trait]
pub trait TimeHandler {
fn time(&self) -> Option<Duration>;
fn sleep(&self, duration: Duration) -> oneshot::Receiver<()>;
async fn sleep(&self, duration: Duration);
}

// Sync problems probably require something like this.
Expand All @@ -71,7 +74,7 @@ pub struct SyscallState {
heap_start: u32,
console: Box<dyn ConsoleHandler + Send + Sync>,
midi: Box<dyn MidiHandler + Send + Sync>,
time: Box<dyn TimeHandler + Send + Sync>,
time: Arc<dyn TimeHandler + Send + Sync>,
generators: HashMap<u32, ChaCha8Rng>,
next_file: u32,
file_map: HashMap<u32, File>,
Expand All @@ -81,7 +84,7 @@ impl SyscallState {
pub fn new(
console: Box<dyn ConsoleHandler + Send + Sync>,
midi: Box<dyn MidiHandler + Send + Sync>,
time: Box<dyn TimeHandler + Send + Sync>,
time: Arc<dyn TimeHandler + Send + Sync>,
) -> SyscallState {
SyscallState {
cancel_token: CancelToken::None,
Expand Down Expand Up @@ -159,9 +162,9 @@ impl SyscallDelegate {
async fn send_print(&self, text: &str) {
self.state.lock().unwrap().console.print(text, false);

let future = self.state.lock().unwrap().time.sleep(PRINT_BUFFER_TIME);
let time = self.state.lock().unwrap().time.clone();

future.await.ok();
time.sleep(PRINT_BUFFER_TIME).await;
}

fn play_installed(&self, request: &MidiRequest, sync: bool) -> bool {
Expand Down Expand Up @@ -604,9 +607,9 @@ impl SyscallDelegate {
async fn sleep_for_duration(&self, time: u64) {
let duration = Duration::from_millis(time);

let future = self.state.lock().unwrap().time.sleep(duration);
let time = self.state.lock().unwrap().time.clone();

future.await.ok();
time.sleep(duration).await;
}

async fn sleep<Mem: Memory, Track: Tracker<Mem>>(&self, debugger: &Executor<Mem, Track>) -> SyscallResult {
Expand Down Expand Up @@ -806,11 +809,15 @@ impl SyscallDelegate {
pub async fn run_batch<Mem: Memory, Track: Tracker<Mem>>(
&self, debugger: &Executor<Mem, Track>, batch: usize, should_skip_first: bool, allow_interrupt: bool
) -> Option<(DebugFrame, Option<SyscallResult>)> {
if !debugger.run_batched(batch, should_skip_first, allow_interrupt) {
log::info!("Running batch (size: {batch}, should_skip_first: {should_skip_first}, allow_interrupt: {allow_interrupt})");

if !debugger.run_batched(batch, should_skip_first, allow_interrupt).interrupted {
return None // no interruption, batch completed successfully
}

let (frame, result) = self.handle_frame(debugger, debugger.frame()).await;
let frame_in = debugger.frame();

let (frame, result) = self.handle_frame(debugger, frame_in).await;

if let Some(frame) = frame {
return Some((frame, result));
Expand All @@ -819,6 +826,8 @@ impl SyscallDelegate {
// Need to re-check.
let frame = debugger.frame();

log::info!("Resulting debugger frame handled with output mode: {:?}, result: {:?}", frame.mode, result);

if frame.mode != Recovered {
return Some((frame, None))
}
Expand Down
39 changes: 32 additions & 7 deletions src-wasm/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src-wasm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,12 @@ futures = "0.3.29"
wasm-bindgen = "0.2.91"
wasm-bindgen-futures = "0.4.41"
serde-wasm-bindgen = "0.6.4"
async-trait = "0.1.82"
js-sys = "0.3.70"
gloo-timers = "0.3.0"

log = "0.4.22"
wasm-logger = "0.2.0"
console_error_panic_hook = { version = "0.1.7", optional = true }

getrandom = { version = "0.2.12", features = ["js"] }
Expand Down
26 changes: 20 additions & 6 deletions src-wasm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ use crate::console::WasmConsole;
use crate::midi::WasmMidi;
use crate::time::WasmTime;

#[wasm_bindgen]
pub fn initialize() {
wasm_logger::init(wasm_logger::Config::default());

console_error_panic_hook::set_once();
}

#[wasm_bindgen]
pub fn assemble_regions(text: &str, options: JsValue) -> JsValue {
let result = saturn_backend::regions::assemble_regions(
Expand Down Expand Up @@ -86,7 +93,7 @@ impl Runner {
keyboard: Arc<Mutex<KeyboardState>>,
console: Box<dyn ConsoleHandler + Send + Sync>,
midi: Box<dyn MidiHandler + Send + Sync>,
time: Box<dyn TimeHandler + Send + Sync>,
time: Arc<dyn TimeHandler + Send + Sync>,
) {
if let Some(device) = &self.device {
device.pause()
Expand All @@ -110,7 +117,7 @@ impl Runner {
keyboard: Arc<Mutex<KeyboardState>>,
console: Box<dyn ConsoleHandler + Send + Sync>,
midi: Box<dyn MidiHandler + Send + Sync>,
time: Box<dyn TimeHandler + Send + Sync>,
time: Arc<dyn TimeHandler + Send + Sync>,
) {
if let Some(device) = &self.device {
device.pause()
Expand Down Expand Up @@ -167,7 +174,7 @@ impl Runner {

let console = Box::new(WasmConsole { });
let midi = Box::new(WasmMidi { });
let time = Box::new(WasmTime { });
let time = Arc::new(WasmTime { });
let history = HistoryTracker::new(TIME_TRAVEL_HISTORY_SIZE);

let mut memory = SectionMemory::new();
Expand Down Expand Up @@ -221,7 +228,7 @@ impl Runner {

let console = Box::new(WasmConsole { });
let midi = Box::new(WasmMidi { });
let time = Box::new(WasmTime { });
let time = Arc::new(WasmTime { });
let history = HistoryTracker::new(TIME_TRAVEL_HISTORY_SIZE);

let mut memory = SectionMemory::new();
Expand Down Expand Up @@ -300,12 +307,19 @@ impl Runner {
}
}

pub fn read_display(&self, address: u32, width: u32, height: u32) -> Option<Vec<u8>> {
if let Some(device) = &self.device {
device.read_display(address, width, height)
} else {
None
}
}

pub async fn resume(&mut self, batch_size: usize, breakpoints: Option<Vec<u32>>, first_batch: bool, is_step: bool) -> JsValue {
let Some(device) = &mut self.device else {
return JsValue::NULL
};

// Some(batch_size), breakpoints, Some(self.display.clone()), set_running
let result = device.resume(ResumeOptions {
batch: Some(BatchOptions {
count: batch_size,
Expand Down Expand Up @@ -347,4 +361,4 @@ impl Runner {

serde_wasm_bindgen::to_value(&result).unwrap()
}
}
}
15 changes: 13 additions & 2 deletions src-wasm/src/time.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,26 @@
use std::time::Duration;
use saturn_backend::syscall::TimeHandler;
use futures::channel::oneshot;
use async_trait::async_trait;

pub struct WasmTime { }

#[async_trait]
impl TimeHandler for WasmTime {
fn time(&self) -> Option<Duration> {
Some(Duration::from_millis(js_sys::Date::now() as u64))
}

fn sleep(&self, duration: Duration) -> oneshot::Receiver<()> {

async fn sleep(&self, duration: Duration) {
let (sender, receiver) = oneshot::channel::<()>();

{
// Is this going to panic?
gloo_timers::callback::Timeout::new(duration.as_millis() as u32, move || {
sender.send(()).ok();
}).forget();
}

receiver.await.ok();
}
}
Loading

0 comments on commit a3388fa

Please sign in to comment.