From a05f2cc8261ea3923df7208c2811fe8e9c7db7d1 Mon Sep 17 00:00:00 2001 From: Ryan Kennedy Date: Sun, 22 Mar 2020 18:49:30 -0500 Subject: [PATCH] public registers and plane mask --- src/registers/attribute_controller.rs | 2 +- src/registers/color_palette.rs | 2 +- src/registers/crtc_controller.rs | 2 +- src/registers/general.rs | 2 +- src/registers/graphics_controller.rs | 2 +- src/registers/mod.rs | 2 +- src/registers/sequencer.rs | 47 +++++++++++++++++++- src/vga.rs | 62 ++++----------------------- src/writers/graphics_640x480x16.rs | 9 ++-- 9 files changed, 67 insertions(+), 63 deletions(-) diff --git a/src/registers/attribute_controller.rs b/src/registers/attribute_controller.rs index 63554e9..7fdd0b3 100644 --- a/src/registers/attribute_controller.rs +++ b/src/registers/attribute_controller.rs @@ -67,7 +67,7 @@ pub struct AttributeControllerRegisters { } impl AttributeControllerRegisters { - pub fn new() -> AttributeControllerRegisters { + pub(crate) fn new() -> AttributeControllerRegisters { AttributeControllerRegisters { arx_index: Port::new(ARX_INDEX_ADDRESS), arx_data: Port::new(ARX_DATA_ADDRESS), diff --git a/src/registers/color_palette.rs b/src/registers/color_palette.rs index 8f49f2f..83a595d 100644 --- a/src/registers/color_palette.rs +++ b/src/registers/color_palette.rs @@ -12,7 +12,7 @@ pub struct ColorPaletteRegisters { } impl ColorPaletteRegisters { - pub fn new() -> ColorPaletteRegisters { + pub(crate) fn new() -> ColorPaletteRegisters { ColorPaletteRegisters { data_port: Port::new(COLOR_PALETTE_DATA_ADDRESS), index_read_port: Port::new(COLOR_PALETTE_INDEX_READ_ADDRESS), diff --git a/src/registers/crtc_controller.rs b/src/registers/crtc_controller.rs index 8c16388..d9df5d4 100644 --- a/src/registers/crtc_controller.rs +++ b/src/registers/crtc_controller.rs @@ -79,7 +79,7 @@ pub struct CrtcControllerRegisters { } impl CrtcControllerRegisters { - pub fn new() -> CrtcControllerRegisters { + pub(crate) fn new() -> CrtcControllerRegisters { CrtcControllerRegisters { crx_index_cga: Port::new(CRX_INDEX_CGA_ADDRESS), crx_index_mda: Port::new(CRX_INDEX_MDA_ADDRESS), diff --git a/src/registers/general.rs b/src/registers/general.rs index 323f5f5..6f4ddca 100644 --- a/src/registers/general.rs +++ b/src/registers/general.rs @@ -17,7 +17,7 @@ pub struct GeneralRegisters { } impl GeneralRegisters { - pub fn new() -> GeneralRegisters { + pub(crate) fn new() -> GeneralRegisters { GeneralRegisters { st00_read: PortReadOnly::new(ST00_READ_ADDRESS), st01_read_cga: PortReadOnly::new(ST01_READ_CGA_ADDRESS), diff --git a/src/registers/graphics_controller.rs b/src/registers/graphics_controller.rs index 289e508..1aca93b 100644 --- a/src/registers/graphics_controller.rs +++ b/src/registers/graphics_controller.rs @@ -44,7 +44,7 @@ pub struct GraphicsControllerRegisters { } impl GraphicsControllerRegisters { - pub fn new() -> GraphicsControllerRegisters { + pub(crate) fn new() -> GraphicsControllerRegisters { GraphicsControllerRegisters { grx_index: Port::new(GRX_INDEX_ADDRESS), grx_data: Port::new(GRX_DATA_ADDRESS), diff --git a/src/registers/mod.rs b/src/registers/mod.rs index a51901c..5c582c6 100644 --- a/src/registers/mod.rs +++ b/src/registers/mod.rs @@ -14,7 +14,7 @@ pub use color_palette::ColorPaletteRegisters; pub use crtc_controller::{CrtcControllerIndex, CrtcControllerRegisters}; pub use general::GeneralRegisters; pub use graphics_controller::{GraphicsControllerIndex, GraphicsControllerRegisters}; -pub use sequencer::{SequencerIndex, SequencerRegisters}; +pub use sequencer::{PlaneMask, SequencerIndex, SequencerRegisters}; const ST00_READ_ADDRESS: u16 = 0x3C2; const ST01_READ_CGA_ADDRESS: u16 = 0x3DA; diff --git a/src/registers/sequencer.rs b/src/registers/sequencer.rs index 29938c1..097cdeb 100644 --- a/src/registers/sequencer.rs +++ b/src/registers/sequencer.rs @@ -1,6 +1,46 @@ use super::{SRX_DATA_ADDRESS, SRX_INDEX_ADDRESS}; +use bitflags::bitflags; +use core::convert::TryFrom; use x86_64::instructions::port::Port; +bitflags! { + /// Represents the plane masks of the `SequencerIndex::PlaneMask` register. + pub struct PlaneMask: u8 { + /// Represents none of the plane masks of vga memory. + const NONE = 0b0000_0000; + /// Represents `Plane0` of vga memory. + const PLANE0 = 0b0000_0001; + /// Represents `Plane1` of vga memory. + const PLANE1 = 0b0000_0010; + /// Represents `Plane2` of vga memory. + const PLANE2 = 0b0000_0100; + /// Represents `Plane3` of vga memory. + const PLANE3 = 0b0000_1000; + /// Represents all of the plane masks of vga memory. + const ALL_PLANES = Self::PLANE0.bits() | Self::PLANE1.bits() | Self::PLANE2.bits() | Self::PLANE3.bits(); + } +} + +impl TryFrom for PlaneMask { + type Error = &'static str; + + fn try_from(value: u8) -> Result { + match value { + 0 => Ok(PlaneMask::PLANE0), + 1 => Ok(PlaneMask::PLANE1), + 2 => Ok(PlaneMask::PLANE2), + 3 => Ok(PlaneMask::PLANE3), + _ => Err("PlaneMask only accepts values between 0-3!"), + } + } +} + +impl From for u8 { + fn from(value: PlaneMask) -> u8 { + value.bits() + } +} + /// Represents an index for the seqeuncer registers. #[derive(Debug, Clone, Copy)] #[repr(u8)] @@ -32,7 +72,7 @@ pub struct SequencerRegisters { } impl SequencerRegisters { - pub fn new() -> SequencerRegisters { + pub(crate) fn new() -> SequencerRegisters { SequencerRegisters { srx_index: Port::new(SRX_INDEX_ADDRESS), srx_data: Port::new(SRX_DATA_ADDRESS), @@ -51,6 +91,11 @@ impl SequencerRegisters { } } + /// Sets the plane mask of the sequencer controller, as specified by `plane_mask`. + pub fn set_plane_mask(&mut self, plane_mask: PlaneMask) { + self.write(SequencerIndex::PlaneMask, u8::from(plane_mask)); + } + fn set_index(&mut self, index: SequencerIndex) { unsafe { self.srx_index.write(u8::from(index)); diff --git a/src/vga.rs b/src/vga.rs index 5e32437..6f8955c 100644 --- a/src/vga.rs +++ b/src/vga.rs @@ -10,10 +10,10 @@ use super::{ registers::{ AttributeControllerIndex, AttributeControllerRegisters, ColorPaletteRegisters, CrtcControllerIndex, CrtcControllerRegisters, EmulationMode, GeneralRegisters, - GraphicsControllerIndex, GraphicsControllerRegisters, SequencerIndex, SequencerRegisters, + GraphicsControllerIndex, GraphicsControllerRegisters, PlaneMask, SequencerIndex, + SequencerRegisters, }, }; -use bitflags::bitflags; use conquer_once::spin::Lazy; use core::convert::TryFrom; use spinning_top::Spinlock; @@ -86,44 +86,6 @@ impl From for u8 { } } -bitflags! { - /// Represents the plane masks of the `SequencerIndex::PlaneMask` register. - pub struct PlaneMask: u8 { - /// Represents none of the plane masks of vga memory. - const NONE = 0b0000_0000; - /// Represents `Plane0` of vga memory. - const PLANE0 = 0b0000_0001; - /// Represents `Plane1` of vga memory. - const PLANE1 = 0b0000_0010; - /// Represents `Plane2` of vga memory. - const PLANE2 = 0b0000_0100; - /// Represents `Plane3` of vga memory. - const PLANE3 = 0b0000_1000; - /// Represents all of the plane masks of vga memory. - const ALL_PLANES = Self::PLANE0.bits() | Self::PLANE1.bits() | Self::PLANE2.bits() | Self::PLANE3.bits(); - } -} - -impl TryFrom for PlaneMask { - type Error = &'static str; - - fn try_from(value: u8) -> Result { - match value { - 0 => Ok(PlaneMask::PLANE0), - 1 => Ok(PlaneMask::PLANE1), - 2 => Ok(PlaneMask::PLANE2), - 3 => Ok(PlaneMask::PLANE3), - _ => Err("PlaneMask only accepts values between 0-3!"), - } - } -} - -impl From for u8 { - fn from(value: PlaneMask) -> u8 { - value.bits() - } -} - /// Represents a specified vga video mode. #[derive(Debug, Clone, Copy)] pub enum VideoMode { @@ -140,12 +102,12 @@ pub enum VideoMode { /// Represents a vga graphics card with it's common registers, /// as well as the most recent video mode. pub struct Vga { - general_registers: GeneralRegisters, - sequencer_registers: SequencerRegisters, - graphics_controller_registers: GraphicsControllerRegisters, - attribute_controller_registers: AttributeControllerRegisters, - crtc_controller_registers: CrtcControllerRegisters, - color_palette_registers: ColorPaletteRegisters, + pub general_registers: GeneralRegisters, + pub sequencer_registers: SequencerRegisters, + pub graphics_controller_registers: GraphicsControllerRegisters, + pub attribute_controller_registers: AttributeControllerRegisters, + pub crtc_controller_registers: CrtcControllerRegisters, + pub color_palette_registers: ColorPaletteRegisters, most_recent_video_mode: Option, } @@ -280,7 +242,7 @@ impl Vga { ); // Write font to plane - self.set_plane_mask(PlaneMask::PLANE2); + self.sequencer_registers.set_plane_mask(PlaneMask::PLANE2); let frame_buffer = u32::from(self.get_frame_buffer()) as *mut u8; @@ -340,12 +302,6 @@ impl Vga { ) } - /// Sets the plane mask of the sequencer controller, as specified by `plane_mask`. - pub fn set_plane_mask(&mut self, plane_mask: PlaneMask) { - self.sequencer_registers - .write(SequencerIndex::PlaneMask, u8::from(plane_mask)); - } - /// Sets the read plane of the graphics controller, as specified by `read_plane`. pub fn set_read_plane(&mut self, read_plane: ReadPlane) { let read_plane = u8::from(read_plane) & 0x3; diff --git a/src/writers/graphics_640x480x16.rs b/src/writers/graphics_640x480x16.rs index e471cd4..7a186ef 100644 --- a/src/writers/graphics_640x480x16.rs +++ b/src/writers/graphics_640x480x16.rs @@ -1,6 +1,7 @@ use crate::{ colors::{Color16Bit, DEFAULT_PALETTE}, - vga::{PlaneMask, Vga, VideoMode, VGA}, + registers::PlaneMask, + vga::{Vga, VideoMode, VGA}, }; use core::convert::TryInto; use spinning_top::SpinlockGuard; @@ -35,7 +36,8 @@ impl Graphics640x480x16 { /// Clears the screen by setting all pixels to `Color16Bit::Black`. pub fn clear_screen(&self) { let (mut vga, frame_buffer) = self.get_frame_buffer(); - vga.set_plane_mask(PlaneMask::ALL_PLANES); + vga.sequencer_registers + .set_plane_mask(PlaneMask::ALL_PLANES); vga.set_graphics_enable_set_reset(PlaneMask::NONE); for offset in 0..ALL_PLANES_SCREEN_SIZE { unsafe { @@ -58,7 +60,8 @@ impl Graphics640x480x16 { for plane in 0u8..4u8 { vga.set_read_plane(plane.try_into().unwrap()); - vga.set_plane_mask(plane.try_into().unwrap()); + vga.sequencer_registers + .set_plane_mask(plane.try_into().unwrap()); let current_value = unsafe { frame_buffer.add(offset).read_volatile() }; let new_value = if plane_mask & color as u8 != 0 { current_value | mask