Basic tests
This commit is contained in:
parent
0b3a12462d
commit
d8c0b83575
|
@ -5,10 +5,15 @@ use super::registers::{
|
||||||
/// Represents a set of vga registers for a given mode.
|
/// Represents a set of vga registers for a given mode.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct VgaConfiguration {
|
pub struct VgaConfiguration {
|
||||||
|
/// Represents the configuration value for the miscellaneous output register.
|
||||||
pub miscellaneous_output: u8,
|
pub miscellaneous_output: u8,
|
||||||
|
/// Represents the configuration values for the sequencer registers.
|
||||||
pub sequencer_registers: &'static [(SequencerIndex, u8)],
|
pub sequencer_registers: &'static [(SequencerIndex, u8)],
|
||||||
|
/// Represents the configuration values for the crtc controller registers.
|
||||||
pub crtc_controller_registers: &'static [(CrtcControllerIndex, u8)],
|
pub crtc_controller_registers: &'static [(CrtcControllerIndex, u8)],
|
||||||
|
/// Represents the configuration values for the graphics controller registers.
|
||||||
pub graphics_controller_registers: &'static [(GraphicsControllerIndex, u8)],
|
pub graphics_controller_registers: &'static [(GraphicsControllerIndex, u8)],
|
||||||
|
/// Represents the configuration values for the attribute controller registers.
|
||||||
pub attribute_controller_registers: &'static [(AttributeControllerIndex, u8)],
|
pub attribute_controller_registers: &'static [(AttributeControllerIndex, u8)],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/lib.rs
10
src/lib.rs
|
@ -7,12 +7,16 @@
|
||||||
#![no_std]
|
#![no_std]
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
pub mod colors;
|
mod colors;
|
||||||
mod configurations;
|
mod configurations;
|
||||||
mod fonts;
|
mod fonts;
|
||||||
mod registers;
|
mod registers;
|
||||||
pub mod vga;
|
mod vga;
|
||||||
mod writers;
|
mod writers;
|
||||||
|
|
||||||
pub use self::vga::{VideoMode, VGA};
|
pub use self::configurations::{
|
||||||
|
VgaConfiguration, MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION,
|
||||||
|
MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
|
||||||
|
};
|
||||||
|
pub use self::vga::{Vga, VideoMode, VGA};
|
||||||
pub use self::writers::{Graphics640x480x16, Text40x25, Text40x50, Text80x25};
|
pub use self::writers::{Graphics640x480x16, Text40x25, Text40x50, Text80x25};
|
||||||
|
|
|
@ -271,6 +271,12 @@ impl AttributeControllerRegisters {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read(&mut self, emulation_mode: EmulationMode, index: AttributeControllerIndex) -> u8 {
|
||||||
|
self.toggle_index(emulation_mode);
|
||||||
|
self.set_index(index);
|
||||||
|
unsafe { self.arx_data.read() }
|
||||||
|
}
|
||||||
|
|
||||||
pub fn write(
|
pub fn write(
|
||||||
&mut self,
|
&mut self,
|
||||||
emulation_mode: EmulationMode,
|
emulation_mode: EmulationMode,
|
||||||
|
|
55
src/vga.rs
55
src/vga.rs
|
@ -7,9 +7,9 @@ use super::{
|
||||||
},
|
},
|
||||||
fonts::{VgaFont, TEXT_8X16_FONT, TEXT_8X8_FONT},
|
fonts::{VgaFont, TEXT_8X16_FONT, TEXT_8X8_FONT},
|
||||||
registers::{
|
registers::{
|
||||||
AttributeControllerRegisters, CrtcControllerIndex, CrtcControllerRegisters, EmulationMode,
|
AttributeControllerIndex, AttributeControllerRegisters, CrtcControllerIndex,
|
||||||
GeneralRegisters, GraphicsControllerIndex, GraphicsControllerRegisters, SequencerIndex,
|
CrtcControllerRegisters, EmulationMode, GeneralRegisters, GraphicsControllerIndex,
|
||||||
SequencerRegisters,
|
GraphicsControllerRegisters, SequencerIndex, SequencerRegisters,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use conquer_once::spin::Lazy;
|
use conquer_once::spin::Lazy;
|
||||||
|
@ -131,17 +131,44 @@ impl Vga {
|
||||||
self.most_recent_video_mode
|
self.most_recent_video_mode
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `I/O Address Select` Bit 0 `(value & 0x1)` of MSR selects 3Bxh or 3Dxh as the I/O address for the CRT Controller
|
/// Returns the current value of the miscellaneous output register.
|
||||||
/// registers, the Feature Control Register (FCR), and Input Status Register 1 (ST01). Presently
|
pub fn read_msr(&mut self) -> u8 {
|
||||||
/// ignored (whole range is claimed), but will "ignore" 3Bx for color configuration or 3Dx for
|
self.general_registers.read_msr()
|
||||||
/// monochrome.
|
}
|
||||||
/// Note that it is typical in AGP chipsets to shadow this bit and properly steer I/O cycles to the
|
|
||||||
/// proper bus for operation where a MDA exists on another bus such as ISA.
|
/// Returns the current value of the sequencer register, as determined by `index`.
|
||||||
///
|
pub fn read_sequencer(&mut self, index: SequencerIndex) -> u8 {
|
||||||
/// 0 = Select 3Bxh I/O address `(EmulationMode::Mda)`
|
self.sequencer_registers.read(index)
|
||||||
///
|
}
|
||||||
/// 1 = Select 3Dxh I/O address `(EmulationMode:Cga)`
|
|
||||||
fn get_emulation_mode(&mut self) -> EmulationMode {
|
/// Returns the current value of the graphics controller register, as determined by `index`.
|
||||||
|
pub fn read_graphics_controller(&mut self, index: GraphicsControllerIndex) -> u8 {
|
||||||
|
self.graphics_controller_registers.read(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the current value of the attribute controller register, as determined by `emulation_mode`
|
||||||
|
/// and `index`.
|
||||||
|
pub fn read_attribute_controller(
|
||||||
|
&mut self,
|
||||||
|
emulation_mode: EmulationMode,
|
||||||
|
index: AttributeControllerIndex,
|
||||||
|
) -> u8 {
|
||||||
|
self.attribute_controller_registers
|
||||||
|
.read(emulation_mode, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the current value of the crtc controller, as determined by `emulation_mode`
|
||||||
|
/// and `index`.
|
||||||
|
pub fn read_crtc_controller(
|
||||||
|
&mut self,
|
||||||
|
emulation_mode: EmulationMode,
|
||||||
|
index: CrtcControllerIndex,
|
||||||
|
) -> u8 {
|
||||||
|
self.crtc_controller_registers.read(emulation_mode, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the current `EmulationMode` as determined by the miscellaneous output register.
|
||||||
|
pub fn get_emulation_mode(&mut self) -> EmulationMode {
|
||||||
EmulationMode::from(self.general_registers.read_msr() & 0x1)
|
EmulationMode::from(self.general_registers.read_msr() & 0x1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@ authors = ["Ryan Kennedy <rkennedy9064@gmail.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bootloader = { version = "0.8.9", features = ["map_physical_memory"] }
|
# TODO: Move back to crate when vga mapping is merged in.
|
||||||
|
bootloader = { git = "https://github.com/RKennedy9064/bootloader", branch = "vga-mappings", features = ["map_physical_memory"] }
|
||||||
conquer-once = { version = "0.2.0", default-features = false }
|
conquer-once = { version = "0.2.0", default-features = false }
|
||||||
spinning_top = { version = "0.1.0", features = ["nightly"] }
|
spinning_top = { version = "0.1.0", features = ["nightly"] }
|
||||||
pic8259_simple = "0.1.1"
|
pic8259_simple = "0.1.1"
|
||||||
|
|
|
@ -6,7 +6,10 @@
|
||||||
|
|
||||||
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::{VideoMode, VGA};
|
use vga::{
|
||||||
|
Vga, VgaConfiguration, VideoMode, MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION,
|
||||||
|
MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION, VGA,
|
||||||
|
};
|
||||||
|
|
||||||
#[no_mangle] // don't mangle the name of this function
|
#[no_mangle] // don't mangle the name of this function
|
||||||
pub extern "C" fn _start() -> ! {
|
pub extern "C" fn _start() -> ! {
|
||||||
|
@ -28,12 +31,70 @@ fn panic(info: &PanicInfo) -> ! {
|
||||||
testing::test_panic_handler(info)
|
testing::test_panic_handler(info)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn set_mode_40x25() {
|
||||||
|
serial_print!("mode 40x25... ");
|
||||||
|
|
||||||
|
let mut vga = VGA.lock();
|
||||||
|
vga.set_video_mode(VideoMode::Mode40x25);
|
||||||
|
check_registers(&mut vga, &MODE_40X25_CONFIGURATION);
|
||||||
|
|
||||||
|
serial_println!("[ok]");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn set_mode_40x50() {
|
||||||
|
serial_print!("mode 40x50... ");
|
||||||
|
|
||||||
|
let mut vga = VGA.lock();
|
||||||
|
vga.set_video_mode(VideoMode::Mode40x50);
|
||||||
|
check_registers(&mut vga, &MODE_40X50_CONFIGURATION);
|
||||||
|
|
||||||
|
serial_println!("[ok]");
|
||||||
|
}
|
||||||
|
|
||||||
#[test_case]
|
#[test_case]
|
||||||
fn set_mode_80x25() {
|
fn set_mode_80x25() {
|
||||||
serial_print!("mode 80x25... ");
|
serial_print!("mode 80x25... ");
|
||||||
|
|
||||||
let mut vga = VGA.lock();
|
let mut vga = VGA.lock();
|
||||||
vga.set_video_mode(VideoMode::Mode80x25);
|
vga.set_video_mode(VideoMode::Mode80x25);
|
||||||
|
check_registers(&mut vga, &MODE_80X25_CONFIGURATION);
|
||||||
|
|
||||||
serial_println!("[ok]");
|
serial_println!("[ok]");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test_case]
|
||||||
|
fn set_mode_640x480x16() {
|
||||||
|
serial_print!("mode 640x480x16... ");
|
||||||
|
|
||||||
|
let mut vga = VGA.lock();
|
||||||
|
vga.set_video_mode(VideoMode::Mode640x480x16);
|
||||||
|
check_registers(&mut vga, &MODE_640X480X16_CONFIGURATION);
|
||||||
|
|
||||||
|
serial_println!("[ok]");
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_registers(vga: &mut Vga, configuration: &VgaConfiguration) {
|
||||||
|
let emulation_mode = vga.get_emulation_mode();
|
||||||
|
assert_eq!(vga.read_msr(), configuration.miscellaneous_output);
|
||||||
|
|
||||||
|
for (index, value) in configuration.sequencer_registers {
|
||||||
|
assert_eq!(vga.read_sequencer(*index), *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index, value) in configuration.crtc_controller_registers {
|
||||||
|
assert_eq!(vga.read_crtc_controller(emulation_mode, *index), *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index, value) in configuration.graphics_controller_registers {
|
||||||
|
assert_eq!(vga.read_graphics_controller(*index), *value);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (index, value) in configuration.attribute_controller_registers {
|
||||||
|
assert_eq!(
|
||||||
|
vga.read_attribute_controller(emulation_mode, *index),
|
||||||
|
*value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue