Basic tests

This commit is contained in:
Ryan Kennedy 2020-03-14 22:55:48 -05:00
parent 0b3a12462d
commit d8c0b83575
6 changed files with 123 additions and 19 deletions

View file

@ -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)],
} }

View file

@ -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};

View file

@ -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,

View file

@ -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)
} }

View file

@ -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"

View file

@ -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
);
}
}