Interuptions
This commit is contained in:
149
simu/src/main.rs
149
simu/src/main.rs
@@ -1,10 +1,19 @@
|
||||
#![feature(likely_unlikely, widening_mul, sync_unsafe_cell)]
|
||||
#![feature(
|
||||
likely_unlikely,
|
||||
widening_mul,
|
||||
sync_unsafe_cell,
|
||||
int_lowest_highest_one
|
||||
)]
|
||||
#![deny(clippy::all)]
|
||||
|
||||
use std::env::args;
|
||||
use std::hint::unlikely;
|
||||
use std::process::exit;
|
||||
use std::sync::Arc;
|
||||
use std::thread::{scope, sleep};
|
||||
use std::sync::{
|
||||
Arc,
|
||||
atomic::Ordering::{Relaxed, Release},
|
||||
};
|
||||
use std::thread::scope;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
use pixels::{Error, Pixels, SurfaceTexture};
|
||||
@@ -16,11 +25,20 @@ use winit::platform::scancode::PhysicalKeyExtScancode;
|
||||
use winit::window::Window;
|
||||
// use winit_input_helper::WinitInputHelper;
|
||||
|
||||
use crate::cpu::Computer;
|
||||
use crate::cpu::{Computer, MMIOInterupt};
|
||||
|
||||
mod cpu;
|
||||
use cpu::SHARED;
|
||||
|
||||
fn wait_int() {
|
||||
let mut v = (&SHARED.external_interupts).load(Relaxed);
|
||||
while unlikely(v != 0) {
|
||||
println!("wating for interupt clear {v}");
|
||||
atomic_wait::wait(&SHARED.external_interupts, v);
|
||||
v = (&SHARED.external_interupts).load(std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
|
||||
const WIDTH: u32 = 640;
|
||||
const HEIGHT: u32 = 480;
|
||||
|
||||
@@ -58,42 +76,107 @@ impl<'a> ApplicationHandler for App<'a> {
|
||||
) {
|
||||
// Draw the current frame
|
||||
match event {
|
||||
WindowEvent::KeyboardInput { event, .. } => match event.state {
|
||||
winit::event::ElementState::Pressed => {
|
||||
if let Some(val) = event.physical_key.to_scancode() {
|
||||
cpu::SHARED
|
||||
.keyboard
|
||||
.store(val + 8, std::sync::atomic::Ordering::Relaxed);
|
||||
WindowEvent::KeyboardInput { event, .. } => {
|
||||
let enabled = (&SHARED.external_enabled_interupts).load(Relaxed)
|
||||
& Into::<u32>::into(MMIOInterupt::Keyboard)
|
||||
!= 0;
|
||||
|
||||
if enabled {
|
||||
wait_int();
|
||||
}
|
||||
match event.state {
|
||||
winit::event::ElementState::Pressed => {
|
||||
if let Some(val) = event.physical_key.to_scancode() {
|
||||
cpu::SHARED
|
||||
.keyboard
|
||||
.store(val + 8, std::sync::atomic::Ordering::Relaxed);
|
||||
}
|
||||
}
|
||||
winit::event::ElementState::Released => SHARED
|
||||
.keyboard
|
||||
.store(0, std::sync::atomic::Ordering::Relaxed),
|
||||
}
|
||||
if enabled {
|
||||
(&SHARED.external_interupts).store(MMIOInterupt::Keyboard.into(), Release);
|
||||
atomic_wait::wake_all(&SHARED.external_interupts);
|
||||
}
|
||||
}
|
||||
WindowEvent::CursorMoved { position, .. } => {
|
||||
let enabled = (&SHARED.external_enabled_interupts).load(Relaxed)
|
||||
& Into::<u32>::into(MMIOInterupt::MouseMove)
|
||||
!= 0;
|
||||
if enabled {wait_int();}
|
||||
match self
|
||||
.pixels
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.window_pos_to_pixel((position.x as f32, position.y as f32))
|
||||
{
|
||||
Ok((x, y)) => {
|
||||
(&cpu::SHARED.mouse[1])
|
||||
.store(x as u32, Relaxed);
|
||||
(&cpu::SHARED.mouse[2])
|
||||
.store(y as u32, Relaxed);
|
||||
}
|
||||
Err(_) => {
|
||||
(&SHARED.mouse[1]).store(u32::MAX, Relaxed);
|
||||
(&SHARED.mouse[2]).store(u32::MAX, Relaxed);
|
||||
}
|
||||
}
|
||||
winit::event::ElementState::Released => SHARED
|
||||
.keyboard
|
||||
.store(0, std::sync::atomic::Ordering::Relaxed),
|
||||
},
|
||||
WindowEvent::CursorMoved {
|
||||
device_id,
|
||||
position,
|
||||
} => {}
|
||||
WindowEvent::MouseWheel {
|
||||
device_id,
|
||||
delta,
|
||||
phase,
|
||||
} => {}
|
||||
WindowEvent::MouseInput {
|
||||
device_id,
|
||||
state,
|
||||
button,
|
||||
} => {}
|
||||
WindowEvent::ScaleFactorChanged {
|
||||
scale_factor,
|
||||
inner_size_writer,
|
||||
} => {}
|
||||
if enabled {
|
||||
(&SHARED.external_interupts).store(MMIOInterupt::MouseMove.into(), Release);
|
||||
println!("wake mouse move");
|
||||
atomic_wait::wake_all(&SHARED.external_interupts);
|
||||
}
|
||||
}
|
||||
// WindowEvent::MouseWheel {
|
||||
// delta,
|
||||
// ..
|
||||
// } => {}
|
||||
WindowEvent::MouseInput { state, button, .. } => {
|
||||
let enabled = (&SHARED.external_enabled_interupts).load(Relaxed)
|
||||
& Into::<u32>::into(MMIOInterupt::MouseClick)
|
||||
!= 0;
|
||||
if enabled {wait_int();}
|
||||
let but = 1
|
||||
<< match button {
|
||||
winit::event::MouseButton::Left => 0,
|
||||
winit::event::MouseButton::Right => 1,
|
||||
winit::event::MouseButton::Middle => 2,
|
||||
winit::event::MouseButton::Back => 3,
|
||||
winit::event::MouseButton::Forward => 4,
|
||||
winit::event::MouseButton::Other(i) => i & 31,
|
||||
};
|
||||
match state {
|
||||
winit::event::ElementState::Pressed => {
|
||||
(&cpu::SHARED.mouse[0]).fetch_or(but, std::sync::atomic::Ordering::Relaxed)
|
||||
}
|
||||
winit::event::ElementState::Released => (&cpu::SHARED.mouse[0])
|
||||
.fetch_and(!but, std::sync::atomic::Ordering::Relaxed),
|
||||
};
|
||||
if enabled {
|
||||
(&SHARED.external_interupts).store(MMIOInterupt::MouseClick.into(), Release);
|
||||
println!("wake mouse click");
|
||||
atomic_wait::wake_all(&SHARED.external_interupts);
|
||||
}
|
||||
}
|
||||
WindowEvent::ScaleFactorChanged { .. } => {
|
||||
self.w.as_ref().unwrap().request_redraw();
|
||||
}
|
||||
//handling redraws and other graphical events
|
||||
WindowEvent::RedrawRequested => {
|
||||
let enabled = (&SHARED.external_enabled_interupts).load(Relaxed)
|
||||
& Into::<u32>::into(MMIOInterupt::VSync)
|
||||
!= 0;
|
||||
if enabled {
|
||||
(&SHARED.external_interupts).store(MMIOInterupt::VSync.into(), Relaxed);
|
||||
atomic_wait::wake_all(&SHARED.external_interupts);
|
||||
wait_int();
|
||||
}
|
||||
let pix = self.pixels.as_mut().unwrap();
|
||||
|
||||
let screen = pix.frame_mut();
|
||||
for (addr, ubgr) in { cpu::SHARED.screen_buf.iter().enumerate() } {
|
||||
for (addr, ubgr) in cpu::SHARED.screen_buf.iter().enumerate() {
|
||||
let ubgr = ubgr.load(std::sync::atomic::Ordering::Relaxed);
|
||||
let rgba = [ubgr as u8, (ubgr >> 8) as u8, (ubgr >> 16) as u8, 0xff];
|
||||
for i in 0..4 {
|
||||
|
||||
Reference in New Issue
Block a user