diff --git a/src/sys/vga/mod.rs b/src/sys/vga/mod.rs index f354cdec..da5a6033 100644 --- a/src/sys/vga/mod.rs +++ b/src/sys/vga/mod.rs @@ -27,6 +27,7 @@ const ATTR_READ_REG: u16 = 0x3C1; const MISC_WRITE_REG: u16 = 0x3C2; const SEQUENCER_ADDR_REG: u16 = 0x3C4; const SEQUENCER_DATA_REG: u16 = 0x3C5; +const DAC_ADDR_READ_MODE_REG: u16 = 0x3C7; const DAC_ADDR_WRITE_MODE_REG: u16 = 0x3C8; const DAC_DATA_REG: u16 = 0x3C9; const GRAPHICS_ADDR_REG: u16 = 0x3CE; @@ -75,11 +76,6 @@ struct ScreenBuffer { chars: [[ScreenChar; SCREEN_WIDTH]; SCREEN_HEIGHT], } -// Convert 8-bit to 6-bit color -fn vga_color(color: u8) -> u8 { - color >> 2 -} - // TODO: Remove this fn parse_palette(palette: &str) -> Result<(usize, u8, u8, u8), ParseIntError> { debug_assert!(palette.len() == 8); diff --git a/src/sys/vga/palette.rs b/src/sys/vga/palette.rs index 5ccb73ce..a92f610c 100644 --- a/src/sys/vga/palette.rs +++ b/src/sys/vga/palette.rs @@ -42,12 +42,30 @@ impl Palette { palette } + pub fn get() -> Self { + let mut palette = Palette::new(); + for i in 0..256 { + palette.colors[i] = get_palette(i); + } + palette + } + pub fn set(&self) { for (i, (r, g, b)) in self.colors.iter().enumerate() { set_palette(i, *r, *g, *b); } } + pub fn to_bytes(&self) -> [u8; 256 * 3] { + let mut buf = [0; 256 * 3]; + for (i, (r, g, b)) in self.colors.iter().enumerate() { + buf[i * 3 + 0] = *r; + buf[i * 3 + 1] = *g; + buf[i * 3 + 2] = *b; + } + buf + } + pub fn size() -> usize { 256 * 3 } @@ -70,8 +88,13 @@ impl TryFrom<&[u8]> for Palette { } impl FileIO for VgaPalette { - fn read(&mut self, _buf: &mut [u8]) -> Result { - Err(()) // TODO + fn read(&mut self, buf: &mut [u8]) -> Result { + let res = Palette::get().to_bytes(); + if buf.len() < res.len() { + return Err(()); + } + buf.clone_from_slice(&res); + Ok(res.len()) } fn write(&mut self, buf: &[u8]) -> Result { @@ -84,14 +107,22 @@ impl FileIO for VgaPalette { fn poll(&mut self, event: IO) -> bool { match event { - IO::Read => false, // TODO - IO::Write => true, // TODO + IO::Read => true, + IO::Write => true, } } } -pub fn set_palette(i: usize, r: u8, g: u8, b: u8) { +// TODO: Rename to `write_palette_index` +fn set_palette(i: usize, r: u8, g: u8, b: u8) { interrupts::without_interrupts(|| WRITER.lock().set_palette(i, r, g, b) ) } + +// TODO: Rename to `read_palette_index` +fn get_palette(i: usize) -> (u8, u8, u8) { + interrupts::without_interrupts(|| + WRITER.lock().palette(i) + ) +} diff --git a/src/sys/vga/writer.rs b/src/sys/vga/writer.rs index a1cbc5d2..3140cf9f 100644 --- a/src/sys/vga/writer.rs +++ b/src/sys/vga/writer.rs @@ -272,9 +272,21 @@ impl Writer { let mut data: Port = Port::new(DAC_DATA_REG); unsafe { addr.write(i as u8); - data.write(vga_color(r)); - data.write(vga_color(g)); - data.write(vga_color(b)); + data.write(r >> 2); // Convert 8-bit to 6-bit color + data.write(g >> 2); + data.write(b >> 2); + } + } + + pub fn palette(&mut self, i: usize) -> (u8, u8, u8) { + let mut addr: Port = Port::new(DAC_ADDR_READ_MODE_REG); + let mut data: Port = Port::new(DAC_DATA_REG); + unsafe { + addr.write(i as u8); + let r = data.read() << 2; // Convert 6-bit to 8-bit color + let g = data.read() << 2; + let b = data.read() << 2; + (r, g, b) } }