81 lines
2.1 KiB
Rust
81 lines
2.1 KiB
Rust
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()
|
|
}
|
|
}
|