progress: new assembler works, instruction set fully implemented with call/ret and push/pop, bf.dsa works which means the dsa assembly language works reliably. still a few bugs to fix. might be able to squeeze out a tiny bit more performance
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
use std::sync::{
|
||||
Arc,
|
||||
atomic::{AtomicBool, AtomicU8, Ordering},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
io::{IoAccess, IoDevice},
|
||||
processor::interrupts::Interrupt,
|
||||
};
|
||||
|
||||
pub struct DisplayDevice {
|
||||
buffer: Arc<Box<[AtomicU8]>>,
|
||||
dirty: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl DisplayDevice {
|
||||
pub fn new(width: usize, height: usize) -> (Self, DisplayHandle) {
|
||||
let buffer = Arc::new(
|
||||
(0..width * height)
|
||||
.map(|_| AtomicU8::new(0))
|
||||
.collect::<Vec<_>>()
|
||||
.into_boxed_slice(),
|
||||
);
|
||||
let dirty = Arc::new(AtomicBool::new(false));
|
||||
|
||||
let handle = DisplayHandle {
|
||||
buffer: Arc::clone(&buffer),
|
||||
dirty: Arc::clone(&dirty),
|
||||
};
|
||||
|
||||
(Self { buffer, dirty }, handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl IoDevice for DisplayDevice {
|
||||
fn size(&self) -> u32 {
|
||||
(self.buffer.len()) as u32
|
||||
}
|
||||
fn access(&self) -> IoAccess {
|
||||
IoAccess::WRITE
|
||||
}
|
||||
|
||||
fn id(&self) -> super::DeviceId {
|
||||
super::DeviceId::Display
|
||||
}
|
||||
|
||||
fn write_word(&mut self, offset: u32, val: u32) -> Result<(), Interrupt> {
|
||||
let bytes = val.to_le_bytes();
|
||||
self.buffer[offset as usize].store(bytes[0], Ordering::Relaxed);
|
||||
self.buffer[offset as usize + 1].store(bytes[1], Ordering::Relaxed);
|
||||
self.buffer[offset as usize + 2].store(bytes[2], Ordering::Relaxed);
|
||||
self.buffer[offset as usize + 3].store(bytes[3], Ordering::Relaxed);
|
||||
self.dirty.store(true, Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_byte(&mut self, offset: u32, val: u8) -> Result<(), Interrupt> {
|
||||
self.buffer[offset as usize].store(val, Ordering::Relaxed);
|
||||
self.dirty.store(true, Ordering::Relaxed);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DisplayHandle {
|
||||
pub buffer: Arc<Box<[AtomicU8]>>,
|
||||
pub dirty: Arc<AtomicBool>,
|
||||
}
|
||||
|
||||
impl DisplayHandle {
|
||||
pub fn is_dirty(&self) -> bool {
|
||||
self.dirty.swap(false, Ordering::Relaxed)
|
||||
}
|
||||
|
||||
pub fn read_all(&self) -> Vec<u8> {
|
||||
self.buffer
|
||||
.iter()
|
||||
.map(|b| b.load(Ordering::Relaxed))
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user