Ability to manipulate palettes
This commit is contained in:
parent
27ee8090ff
commit
ac6b76b4d1
|
@ -1,5 +1,7 @@
|
||||||
//! Common color structures used in vga.
|
//! Common color structures used in vga.
|
||||||
|
|
||||||
|
pub const PALETTE_SIZE: usize = 768;
|
||||||
|
|
||||||
/// Represents a 16 bit color used for vga display.
|
/// Represents a 16 bit color used for vga display.
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
|
@ -50,3 +52,55 @@ impl TextModeColor {
|
||||||
TextModeColor((background as u8) << 4 | (foreground as u8))
|
TextModeColor((background as u8) << 4 | (foreground as u8))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents the default vga 256 color palette.
|
||||||
|
pub const DEFAULT_PALETTE: [u8; PALETTE_SIZE] = [
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x2A, 0x0, 0x2A, 0x0, 0x0, 0x2A, 0x2A, 0x2A, 0x0, 0x0, 0x2A, 0x0,
|
||||||
|
0x2A, 0x2A, 0x2A, 0x0, 0x2A, 0x2A, 0x2A, 0x0, 0x0, 0x15, 0x0, 0x0, 0x3F, 0x0, 0x2A, 0x15, 0x0,
|
||||||
|
0x2A, 0x3F, 0x2A, 0x0, 0x15, 0x2A, 0x0, 0x3F, 0x2A, 0x2A, 0x15, 0x2A, 0x2A, 0x3F, 0x0, 0x15,
|
||||||
|
0x0, 0x0, 0x15, 0x2A, 0x0, 0x3F, 0x0, 0x0, 0x3F, 0x2A, 0x2A, 0x15, 0x0, 0x2A, 0x15, 0x2A, 0x2A,
|
||||||
|
0x3F, 0x0, 0x2A, 0x3F, 0x2A, 0x0, 0x15, 0x15, 0x0, 0x15, 0x3F, 0x0, 0x3F, 0x15, 0x0, 0x3F,
|
||||||
|
0x3F, 0x2A, 0x15, 0x15, 0x2A, 0x15, 0x3F, 0x2A, 0x3F, 0x15, 0x2A, 0x3F, 0x3F, 0x15, 0x0, 0x0,
|
||||||
|
0x15, 0x0, 0x2A, 0x15, 0x2A, 0x0, 0x15, 0x2A, 0x2A, 0x3F, 0x0, 0x0, 0x3F, 0x0, 0x2A, 0x3F,
|
||||||
|
0x2A, 0x0, 0x3F, 0x2A, 0x2A, 0x15, 0x0, 0x15, 0x15, 0x0, 0x3F, 0x15, 0x2A, 0x15, 0x15, 0x2A,
|
||||||
|
0x3F, 0x3F, 0x0, 0x15, 0x3F, 0x0, 0x3F, 0x3F, 0x2A, 0x15, 0x3F, 0x2A, 0x3F, 0x15, 0x15, 0x0,
|
||||||
|
0x15, 0x15, 0x2A, 0x15, 0x3F, 0x0, 0x15, 0x3F, 0x2A, 0x3F, 0x15, 0x0, 0x3F, 0x15, 0x2A, 0x3F,
|
||||||
|
0x3F, 0x0, 0x3F, 0x3F, 0x2A, 0x15, 0x15, 0x15, 0x15, 0x15, 0x3F, 0x15, 0x3F, 0x15, 0x15, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x15, 0x15, 0x3F, 0x15, 0x3F, 0x3F, 0x3F, 0x15, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
|
||||||
|
];
|
||||||
|
|
|
@ -14,6 +14,7 @@ mod registers;
|
||||||
mod vga;
|
mod vga;
|
||||||
mod writers;
|
mod writers;
|
||||||
|
|
||||||
|
pub use self::colors::{Color16Bit, TextModeColor, DEFAULT_PALETTE, PALETTE_SIZE};
|
||||||
pub use self::configurations::{
|
pub use self::configurations::{
|
||||||
VgaConfiguration, MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION,
|
VgaConfiguration, MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION,
|
||||||
MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
|
MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use crate::colors::PALETTE_SIZE;
|
||||||
use x86_64::instructions::port::{Port, PortReadOnly, PortWriteOnly};
|
use x86_64::instructions::port::{Port, PortReadOnly, PortWriteOnly};
|
||||||
|
|
||||||
const ST00_READ_ADDRESS: u16 = 0x3C2;
|
const ST00_READ_ADDRESS: u16 = 0x3C2;
|
||||||
|
@ -23,6 +24,10 @@ const CRX_INDEX_MDA_ADDRESS: u16 = 0x3B4;
|
||||||
const CRX_DATA_CGA_ADDRESS: u16 = 0x3D5;
|
const CRX_DATA_CGA_ADDRESS: u16 = 0x3D5;
|
||||||
const CRX_DATA_MDA_ADDRESS: u16 = 0x3B5;
|
const CRX_DATA_MDA_ADDRESS: u16 = 0x3B5;
|
||||||
|
|
||||||
|
const COLOR_PALETTE_DATA_ADDRESS: u16 = 0x3C9;
|
||||||
|
const COLOR_PALETTE_INDEX_READ_ADDRESS: u16 = 0x3C7;
|
||||||
|
const COLOR_PALETTE_INDEX_WRITE_ADDRESSS: u16 = 0x3C8;
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum EmulationMode {
|
pub enum EmulationMode {
|
||||||
|
@ -389,3 +394,42 @@ impl CrtcControllerRegisters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct ColorPaletteRegisters {
|
||||||
|
data_port: Port<u8>,
|
||||||
|
index_read_port: Port<u8>,
|
||||||
|
index_write_port: Port<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ColorPaletteRegisters {
|
||||||
|
pub fn new() -> ColorPaletteRegisters {
|
||||||
|
ColorPaletteRegisters {
|
||||||
|
data_port: Port::new(COLOR_PALETTE_DATA_ADDRESS),
|
||||||
|
index_read_port: Port::new(COLOR_PALETTE_INDEX_READ_ADDRESS),
|
||||||
|
index_write_port: Port::new(COLOR_PALETTE_INDEX_WRITE_ADDRESSS),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn load_palette(&mut self, palette: &[u8; PALETTE_SIZE]) {
|
||||||
|
unsafe {
|
||||||
|
self.index_write_port.write(0);
|
||||||
|
}
|
||||||
|
for i in palette.iter() {
|
||||||
|
unsafe {
|
||||||
|
self.data_port.write(*i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn read_palette(&mut self, palette: &mut [u8; PALETTE_SIZE]) {
|
||||||
|
unsafe {
|
||||||
|
self.index_read_port.write(0);
|
||||||
|
}
|
||||||
|
for i in 0..PALETTE_SIZE {
|
||||||
|
unsafe {
|
||||||
|
palette[i] = self.data_port.read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
src/vga.rs
25
src/vga.rs
|
@ -1,15 +1,16 @@
|
||||||
//! Provides access to the vga graphics card.
|
//! Provides access to the vga graphics card.
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
colors::PALETTE_SIZE,
|
||||||
configurations::{
|
configurations::{
|
||||||
VgaConfiguration, MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION,
|
VgaConfiguration, MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION,
|
||||||
MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
|
MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
|
||||||
},
|
},
|
||||||
fonts::{VgaFont, TEXT_8X16_FONT, TEXT_8X8_FONT},
|
fonts::{VgaFont, TEXT_8X16_FONT, TEXT_8X8_FONT},
|
||||||
registers::{
|
registers::{
|
||||||
AttributeControllerIndex, AttributeControllerRegisters, CrtcControllerIndex,
|
AttributeControllerIndex, AttributeControllerRegisters, ColorPaletteRegisters,
|
||||||
CrtcControllerRegisters, EmulationMode, GeneralRegisters, GraphicsControllerIndex,
|
CrtcControllerIndex, CrtcControllerRegisters, EmulationMode, GeneralRegisters,
|
||||||
GraphicsControllerRegisters, SequencerIndex, SequencerRegisters,
|
GraphicsControllerIndex, GraphicsControllerRegisters, SequencerIndex, SequencerRegisters,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use conquer_once::spin::Lazy;
|
use conquer_once::spin::Lazy;
|
||||||
|
@ -90,6 +91,7 @@ pub struct Vga {
|
||||||
graphics_controller_registers: GraphicsControllerRegisters,
|
graphics_controller_registers: GraphicsControllerRegisters,
|
||||||
attribute_controller_registers: AttributeControllerRegisters,
|
attribute_controller_registers: AttributeControllerRegisters,
|
||||||
crtc_controller_registers: CrtcControllerRegisters,
|
crtc_controller_registers: CrtcControllerRegisters,
|
||||||
|
color_palette_registers: ColorPaletteRegisters,
|
||||||
most_recent_video_mode: Option<VideoMode>,
|
most_recent_video_mode: Option<VideoMode>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +103,7 @@ impl Vga {
|
||||||
graphics_controller_registers: GraphicsControllerRegisters::new(),
|
graphics_controller_registers: GraphicsControllerRegisters::new(),
|
||||||
attribute_controller_registers: AttributeControllerRegisters::new(),
|
attribute_controller_registers: AttributeControllerRegisters::new(),
|
||||||
crtc_controller_registers: CrtcControllerRegisters::new(),
|
crtc_controller_registers: CrtcControllerRegisters::new(),
|
||||||
|
color_palette_registers: ColorPaletteRegisters::new(),
|
||||||
most_recent_video_mode: None,
|
most_recent_video_mode: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -172,6 +175,22 @@ impl Vga {
|
||||||
EmulationMode::from(self.general_registers.read_msr() & 0x1)
|
EmulationMode::from(self.general_registers.read_msr() & 0x1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Loads a new palette into the vga, as specified by `palette`.
|
||||||
|
///
|
||||||
|
/// Each palette must be `PALETTE_SIZE` bytes long, with every 3
|
||||||
|
/// bytes representing one color `(R, G, B)`.
|
||||||
|
pub fn load_palette(&mut self, palette: &[u8; PALETTE_SIZE]) {
|
||||||
|
self.color_palette_registers.load_palette(palette);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Reads the current vga palette into `palette`.
|
||||||
|
///
|
||||||
|
/// Each palette must be `PALETTE_SIZE` bytes long, with every 3
|
||||||
|
/// bytes representing one color `(R, G, B)`.
|
||||||
|
pub fn read_palette(&mut self, palette: &mut [u8; PALETTE_SIZE]) {
|
||||||
|
self.color_palette_registers.read_palette(palette);
|
||||||
|
}
|
||||||
|
|
||||||
fn load_font(&mut self, vga_font: &VgaFont) {
|
fn load_font(&mut self, vga_font: &VgaFont) {
|
||||||
// Save registers
|
// Save registers
|
||||||
let (
|
let (
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
colors::Color16Bit,
|
colors::{Color16Bit, DEFAULT_PALETTE},
|
||||||
vga::{Plane, Vga, VideoMode, VGA},
|
vga::{Plane, Vga, VideoMode, VGA},
|
||||||
};
|
};
|
||||||
use spinning_top::SpinlockGuard;
|
use spinning_top::SpinlockGuard;
|
||||||
|
@ -34,6 +34,7 @@ impl Graphics640x480x16 {
|
||||||
|
|
||||||
/// Clears the screen by setting all pixels to `Color16Bit::Black`.
|
/// Clears the screen by setting all pixels to `Color16Bit::Black`.
|
||||||
pub fn clear_screen(&self) {
|
pub fn clear_screen(&self) {
|
||||||
|
// TODO: Clear the screen by using 4-plane mode instead of slow `set_pixel`.
|
||||||
for x in 0..WIDTH {
|
for x in 0..WIDTH {
|
||||||
for y in 0..HEIGHT {
|
for y in 0..HEIGHT {
|
||||||
self.set_pixel(x, y, Color16Bit::Yellow);
|
self.set_pixel(x, y, Color16Bit::Yellow);
|
||||||
|
@ -72,7 +73,12 @@ impl Graphics640x480x16 {
|
||||||
|
|
||||||
/// Sets the graphics device to `VideoMode::Mode640x480x16`.
|
/// Sets the graphics device to `VideoMode::Mode640x480x16`.
|
||||||
pub fn set_mode(&self) {
|
pub fn set_mode(&self) {
|
||||||
VGA.lock().set_video_mode(VideoMode::Mode640x480x16);
|
let mut vga = VGA.lock();
|
||||||
|
vga.set_video_mode(VideoMode::Mode640x480x16);
|
||||||
|
|
||||||
|
// Some bios mess up the palette when switching modes,
|
||||||
|
// so explicitly set it.
|
||||||
|
vga.load_palette(&DEFAULT_PALETTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the start of the `FrameBuffer` as `*mut u8` as
|
/// Returns the start of the `FrameBuffer` as `*mut u8` as
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::ScreenCharacter;
|
use super::ScreenCharacter;
|
||||||
use crate::{
|
use crate::{
|
||||||
colors::{Color16Bit, TextModeColor},
|
colors::{Color16Bit, TextModeColor, DEFAULT_PALETTE},
|
||||||
vga::{Vga, VideoMode, VGA},
|
vga::{Vga, VideoMode, VGA},
|
||||||
};
|
};
|
||||||
use spinning_top::SpinlockGuard;
|
use spinning_top::SpinlockGuard;
|
||||||
|
@ -66,7 +66,12 @@ impl Text40x25 {
|
||||||
|
|
||||||
/// Sets the graphics device to `VideoMode::Mode40x25`.
|
/// Sets the graphics device to `VideoMode::Mode40x25`.
|
||||||
pub fn set_mode(&self) {
|
pub fn set_mode(&self) {
|
||||||
VGA.lock().set_video_mode(VideoMode::Mode40x25);
|
let mut vga = VGA.lock();
|
||||||
|
vga.set_video_mode(VideoMode::Mode40x25);
|
||||||
|
|
||||||
|
// Some bios mess up the palette when switching modes,
|
||||||
|
// so explicitly set it.
|
||||||
|
vga.load_palette(&DEFAULT_PALETTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::ScreenCharacter;
|
use super::ScreenCharacter;
|
||||||
use crate::{
|
use crate::{
|
||||||
colors::{Color16Bit, TextModeColor},
|
colors::{Color16Bit, TextModeColor, DEFAULT_PALETTE},
|
||||||
vga::{Vga, VideoMode, VGA},
|
vga::{Vga, VideoMode, VGA},
|
||||||
};
|
};
|
||||||
use spinning_top::SpinlockGuard;
|
use spinning_top::SpinlockGuard;
|
||||||
|
@ -66,7 +66,12 @@ impl Text40x50 {
|
||||||
|
|
||||||
/// Sets the graphics device to `VideoMode::Mode40x50`.
|
/// Sets the graphics device to `VideoMode::Mode40x50`.
|
||||||
pub fn set_mode(&self) {
|
pub fn set_mode(&self) {
|
||||||
VGA.lock().set_video_mode(VideoMode::Mode40x50);
|
let mut vga = VGA.lock();
|
||||||
|
vga.set_video_mode(VideoMode::Mode40x50);
|
||||||
|
|
||||||
|
// Some bios mess up the palette when switching modes,
|
||||||
|
// so explicitly set it.
|
||||||
|
vga.load_palette(&DEFAULT_PALETTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use super::ScreenCharacter;
|
use super::ScreenCharacter;
|
||||||
use crate::{
|
use crate::{
|
||||||
colors::{Color16Bit, TextModeColor},
|
colors::{Color16Bit, TextModeColor, DEFAULT_PALETTE},
|
||||||
vga::{Vga, VideoMode, VGA},
|
vga::{Vga, VideoMode, VGA},
|
||||||
};
|
};
|
||||||
use spinning_top::SpinlockGuard;
|
use spinning_top::SpinlockGuard;
|
||||||
|
@ -66,7 +66,12 @@ impl Text80x25 {
|
||||||
|
|
||||||
/// Sets the graphics device to `VideoMode::Mode80x25`.
|
/// Sets the graphics device to `VideoMode::Mode80x25`.
|
||||||
pub fn set_mode(&self) {
|
pub fn set_mode(&self) {
|
||||||
VGA.lock().set_video_mode(VideoMode::Mode80x25);
|
let mut vga = VGA.lock();
|
||||||
|
vga.set_video_mode(VideoMode::Mode80x25);
|
||||||
|
|
||||||
|
// Some bios mess up the palette when switching modes,
|
||||||
|
// so explicitly set it.
|
||||||
|
vga.load_palette(&DEFAULT_PALETTE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
||||||
|
|
|
@ -7,8 +7,9 @@
|
||||||
use core::panic::PanicInfo;
|
use core::panic::PanicInfo;
|
||||||
use testing::{gdt, interrupts, serial_print, serial_println};
|
use testing::{gdt, interrupts, serial_print, serial_println};
|
||||||
use vga::{
|
use vga::{
|
||||||
Vga, VgaConfiguration, VideoMode, MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION,
|
Vga, VgaConfiguration, VideoMode, DEFAULT_PALETTE, MODE_40X25_CONFIGURATION,
|
||||||
MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION, VGA,
|
MODE_40X50_CONFIGURATION, MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
|
||||||
|
PALETTE_SIZE, VGA,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[no_mangle] // don't mangle the name of this function
|
#[no_mangle] // don't mangle the name of this function
|
||||||
|
@ -75,6 +76,22 @@ fn set_mode_640x480x16() {
|
||||||
serial_println!("[ok]");
|
serial_println!("[ok]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn load_palette() {
|
||||||
|
serial_print!("load palette... ");
|
||||||
|
|
||||||
|
let mut palette = [0u8; PALETTE_SIZE];
|
||||||
|
let mut vga = VGA.lock();
|
||||||
|
vga.load_palette(&DEFAULT_PALETTE);
|
||||||
|
vga.read_palette(&mut palette);
|
||||||
|
|
||||||
|
for i in 0..PALETTE_SIZE {
|
||||||
|
assert_eq!(palette[i], DEFAULT_PALETTE[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_println!("[ok]");
|
||||||
|
}
|
||||||
|
|
||||||
fn check_registers(vga: &mut Vga, configuration: &VgaConfiguration) {
|
fn check_registers(vga: &mut Vga, configuration: &VgaConfiguration) {
|
||||||
let emulation_mode = vga.get_emulation_mode();
|
let emulation_mode = vga.get_emulation_mode();
|
||||||
assert_eq!(vga.read_msr(), configuration.miscellaneous_output);
|
assert_eq!(vga.read_msr(), configuration.miscellaneous_output);
|
||||||
|
|
Loading…
Reference in a new issue