public registers and plane mask
This commit is contained in:
parent
3eae6fb32d
commit
a05f2cc826
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<u8> for PlaneMask {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
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<PlaneMask> 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));
|
||||
|
|
62
src/vga.rs
62
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<ReadPlane> 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<u8> for PlaneMask {
|
||||
type Error = &'static str;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self, Self::Error> {
|
||||
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<PlaneMask> 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<VideoMode>,
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue