Interuptions

This commit is contained in:
Mwa
2026-03-15 23:32:13 +01:00
parent aead858727
commit c38bb22e88
6 changed files with 575 additions and 195 deletions

View File

@@ -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 {