Code cleanup
This commit is contained in:
parent
855c6b8658
commit
ac8da132e5
|
@ -4,16 +4,112 @@ mod text_40x25;
|
||||||
mod text_40x50;
|
mod text_40x50;
|
||||||
mod text_80x25;
|
mod text_80x25;
|
||||||
|
|
||||||
use super::colors::TextModeColor;
|
use super::{
|
||||||
|
colors::{Color16Bit, TextModeColor},
|
||||||
|
registers::CrtcControllerIndex,
|
||||||
|
vga::{Vga, VGA},
|
||||||
|
};
|
||||||
|
use spinning_top::SpinlockGuard;
|
||||||
|
|
||||||
pub use graphics_640x480x16::Graphics640x480x16;
|
pub use graphics_640x480x16::Graphics640x480x16;
|
||||||
pub use text_40x25::Text40x25;
|
pub use text_40x25::Text40x25;
|
||||||
pub use text_40x50::Text40x50;
|
pub use text_40x50::Text40x50;
|
||||||
pub use text_80x25::Text80x25;
|
pub use text_80x25::Text80x25;
|
||||||
|
|
||||||
|
/// Represents a `ScreenCharacter` in vga text modes.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct ScreenCharacter {
|
pub struct ScreenCharacter {
|
||||||
character: u8,
|
character: u8,
|
||||||
color: TextModeColor,
|
color: TextModeColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ScreenCharacter {
|
||||||
|
/// Creates a new `ScreenCharacter` with the specified `character`
|
||||||
|
/// and a `TextModeColor` with the specified `foreground` and `background`.
|
||||||
|
pub fn new(character: u8, foreground: Color16Bit, background: Color16Bit) -> ScreenCharacter {
|
||||||
|
let color = TextModeColor::new(foreground, background);
|
||||||
|
ScreenCharacter { character, color }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
||||||
|
character: b' ',
|
||||||
|
color: TextModeColor::new(Color16Bit::Yellow, Color16Bit::Black),
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A helper trait used to interact with various vga text modes.
|
||||||
|
pub trait TextWriter {
|
||||||
|
/// Returns the width of the `TextWriter`.
|
||||||
|
fn get_width(&self) -> usize;
|
||||||
|
|
||||||
|
/// Returns the height of the `TextWriter`.
|
||||||
|
fn get_height(&self) -> usize;
|
||||||
|
|
||||||
|
/// Sets the graphics device to a video mode as determined by
|
||||||
|
/// the `TextWriter` implementation.
|
||||||
|
fn set_mode(&self);
|
||||||
|
|
||||||
|
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
||||||
|
/// as well as a lock to the vga driver. This ensures the vga
|
||||||
|
/// driver stays locked while the frame buffer is in use.
|
||||||
|
fn get_frame_buffer(&self) -> (SpinlockGuard<Vga>, *mut ScreenCharacter) {
|
||||||
|
let mut vga = VGA.lock();
|
||||||
|
let frame_buffer = vga.get_frame_buffer();
|
||||||
|
(vga, u32::from(frame_buffer) as *mut ScreenCharacter)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clears the screen by setting all cells to `b' '` with
|
||||||
|
/// a background color of `Color16Bit::Black` and a foreground
|
||||||
|
/// color of `Color16Bit::Yellow`.
|
||||||
|
fn clear_screen(&self) {
|
||||||
|
let (_vga, frame_buffer) = self.get_frame_buffer();
|
||||||
|
let screen_size = self.get_width() * self.get_height();
|
||||||
|
for i in 0..screen_size {
|
||||||
|
unsafe {
|
||||||
|
frame_buffer.add(i).write_volatile(BLANK_CHARACTER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets the current text cursor to the position specified by
|
||||||
|
/// `x` and `y`.
|
||||||
|
///
|
||||||
|
/// Panics if `x >= se.lf.get_width()` or `y >= self.get_height()`.
|
||||||
|
fn set_cursor_position(&self, x: usize, y: usize) {
|
||||||
|
let width = self.get_width();
|
||||||
|
let height = self.get_height();
|
||||||
|
assert!(x < width, "x >= {}", width);
|
||||||
|
assert!(y < height, "y >= {}", height);
|
||||||
|
let offset = width * y + x;
|
||||||
|
let (mut vga, _frame_buffer) = self.get_frame_buffer();
|
||||||
|
let emulation_mode = vga.get_emulation_mode();
|
||||||
|
let cursor_start = offset & 0xFF;
|
||||||
|
let cursor_end = (offset >> 8) & 0xFF;
|
||||||
|
vga.write_crtc_controller(
|
||||||
|
emulation_mode,
|
||||||
|
CrtcControllerIndex::TextCursorLocationLow,
|
||||||
|
cursor_start as u8,
|
||||||
|
);
|
||||||
|
vga.write_crtc_controller(
|
||||||
|
emulation_mode,
|
||||||
|
CrtcControllerIndex::TextCursorLocationHigh,
|
||||||
|
cursor_end as u8,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints the given `character` and `color` at `(x, y)`.
|
||||||
|
///
|
||||||
|
/// Panics if `x >= self.get_width()` or `y >= self.get_height()`.
|
||||||
|
fn write_character(&self, x: usize, y: usize, screen_character: ScreenCharacter) {
|
||||||
|
let width = self.get_width();
|
||||||
|
let height = self.get_height();
|
||||||
|
assert!(x < width, "x >= {}", width);
|
||||||
|
assert!(y < height, "y >= {}", height);
|
||||||
|
let (_vga, frame_buffer) = self.get_frame_buffer();
|
||||||
|
let offset = width * y + x;
|
||||||
|
unsafe {
|
||||||
|
frame_buffer.add(offset).write_volatile(screen_character);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,20 +1,12 @@
|
||||||
use super::ScreenCharacter;
|
use super::TextWriter;
|
||||||
use crate::{
|
use crate::{
|
||||||
colors::{Color16Bit, TextModeColor, DEFAULT_PALETTE},
|
colors::DEFAULT_PALETTE,
|
||||||
fonts::TEXT_8X16_FONT,
|
fonts::TEXT_8X16_FONT,
|
||||||
registers::CrtcControllerIndex,
|
vga::{VideoMode, VGA},
|
||||||
vga::{Vga, VideoMode, VGA},
|
|
||||||
};
|
};
|
||||||
use spinning_top::SpinlockGuard;
|
|
||||||
|
|
||||||
const WIDTH: usize = 40;
|
const WIDTH: usize = 40;
|
||||||
const HEIGHT: usize = 25;
|
const HEIGHT: usize = 25;
|
||||||
const SCREEN_SIZE: usize = WIDTH * HEIGHT;
|
|
||||||
|
|
||||||
static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
|
||||||
character: b' ',
|
|
||||||
color: TextModeColor::new(Color16Bit::Yellow, Color16Bit::Black),
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A basic interface for interacting with vga text mode 40x25
|
/// A basic interface for interacting with vga text mode 40x25
|
||||||
///
|
///
|
||||||
|
@ -23,7 +15,7 @@ static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use vga::writers::Text40x25;
|
/// use vga::writers::{TextWriter, Text40x25};
|
||||||
///
|
///
|
||||||
/// let text_mode = Text40x25::new();
|
/// let text_mode = Text40x25::new();
|
||||||
///
|
///
|
||||||
|
@ -33,41 +25,17 @@ static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Text40x25;
|
pub struct Text40x25;
|
||||||
|
|
||||||
impl Text40x25 {
|
impl TextWriter for Text40x25 {
|
||||||
/// Creates a new `Text40x25`.
|
fn get_width(&self) -> usize {
|
||||||
pub fn new() -> Text40x25 {
|
WIDTH
|
||||||
Text40x25 {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the screen by setting all cells to `b' '` with
|
fn get_height(&self) -> usize {
|
||||||
/// a background color of `Color16Bit::Black` and a foreground
|
HEIGHT
|
||||||
/// color of `Color16Bit::Yellow`.
|
|
||||||
pub fn clear_screen(&self) {
|
|
||||||
let (_vga, frame_buffer) = self.get_frame_buffer();
|
|
||||||
for i in 0..SCREEN_SIZE {
|
|
||||||
unsafe {
|
|
||||||
frame_buffer.add(i).write_volatile(BLANK_CHARACTER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prints the given `character` and `color` at `(x, y)`.
|
|
||||||
///
|
|
||||||
/// Panics if `x >= 40` or `y >= 25`.
|
|
||||||
pub fn write_character(&self, x: usize, y: usize, character: u8, color: TextModeColor) {
|
|
||||||
assert!(x < WIDTH, "x >= {}", WIDTH);
|
|
||||||
assert!(y < HEIGHT, "y >= {}", HEIGHT);
|
|
||||||
let (_vga, frame_buffer) = self.get_frame_buffer();
|
|
||||||
let offset = WIDTH * y + x;
|
|
||||||
unsafe {
|
|
||||||
frame_buffer
|
|
||||||
.add(offset)
|
|
||||||
.write_volatile(ScreenCharacter { character, color });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the graphics device to `VideoMode::Mode40x25`.
|
/// Sets the graphics device to `VideoMode::Mode40x25`.
|
||||||
pub fn set_mode(&self) {
|
fn set_mode(&self) {
|
||||||
let mut vga = VGA.lock();
|
let mut vga = VGA.lock();
|
||||||
vga.set_video_mode(VideoMode::Mode40x25);
|
vga.set_video_mode(VideoMode::Mode40x25);
|
||||||
|
|
||||||
|
@ -76,37 +44,11 @@ impl Text40x25 {
|
||||||
vga.load_palette(&DEFAULT_PALETTE);
|
vga.load_palette(&DEFAULT_PALETTE);
|
||||||
vga.load_font(&TEXT_8X16_FONT);
|
vga.load_font(&TEXT_8X16_FONT);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the current text cursor to the position specified by
|
impl Text40x25 {
|
||||||
/// `x` and `y`.
|
/// Creates a new `Text40x25`.
|
||||||
///
|
pub fn new() -> Text40x25 {
|
||||||
/// Panics if `x >= 40` or `y >= 25`.
|
Text40x25 {}
|
||||||
pub fn set_cursor_position(&self, x: usize, y: usize) {
|
|
||||||
assert!(x < WIDTH, "x >= {}", WIDTH);
|
|
||||||
assert!(y < HEIGHT, "y >= {}", HEIGHT);
|
|
||||||
let offset = WIDTH * y + x;
|
|
||||||
let (mut vga, _frame_buffer) = self.get_frame_buffer();
|
|
||||||
let emulation_mode = vga.get_emulation_mode();
|
|
||||||
let cursor_start = offset & 0xFF;
|
|
||||||
let cursor_end = (offset >> 8) & 0xFF;
|
|
||||||
vga.write_crtc_controller(
|
|
||||||
emulation_mode,
|
|
||||||
CrtcControllerIndex::TextCursorLocationLow,
|
|
||||||
cursor_start as u8,
|
|
||||||
);
|
|
||||||
vga.write_crtc_controller(
|
|
||||||
emulation_mode,
|
|
||||||
CrtcControllerIndex::TextCursorLocationHigh,
|
|
||||||
cursor_end as u8,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
|
||||||
/// as well as a lock to the vga driver. This ensures the vga
|
|
||||||
/// driver stays locked while the frame buffer is in use.
|
|
||||||
fn get_frame_buffer(&self) -> (SpinlockGuard<Vga>, *mut ScreenCharacter) {
|
|
||||||
let mut vga = VGA.lock();
|
|
||||||
let frame_buffer = vga.get_frame_buffer();
|
|
||||||
(vga, u32::from(frame_buffer) as *mut ScreenCharacter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,12 @@
|
||||||
use super::ScreenCharacter;
|
use super::TextWriter;
|
||||||
use crate::{
|
use crate::{
|
||||||
colors::{Color16Bit, TextModeColor, DEFAULT_PALETTE},
|
colors::DEFAULT_PALETTE,
|
||||||
fonts::TEXT_8X8_FONT,
|
fonts::TEXT_8X8_FONT,
|
||||||
registers::CrtcControllerIndex,
|
vga::{VideoMode, VGA},
|
||||||
vga::{Vga, VideoMode, VGA},
|
|
||||||
};
|
};
|
||||||
use spinning_top::SpinlockGuard;
|
|
||||||
|
|
||||||
const WIDTH: usize = 40;
|
const WIDTH: usize = 40;
|
||||||
const HEIGHT: usize = 50;
|
const HEIGHT: usize = 50;
|
||||||
const SCREEN_SIZE: usize = WIDTH * HEIGHT;
|
|
||||||
|
|
||||||
static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
|
||||||
character: b' ',
|
|
||||||
color: TextModeColor::new(Color16Bit::Yellow, Color16Bit::Black),
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A basic interface for interacting with vga text mode 40x50
|
/// A basic interface for interacting with vga text mode 40x50
|
||||||
///
|
///
|
||||||
|
@ -23,7 +15,7 @@ static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use vga::writers::Text40x50;
|
/// use vga::writers::{TextWriter, Text40x50};
|
||||||
///
|
///
|
||||||
/// let text_mode = Text40x50::new();
|
/// let text_mode = Text40x50::new();
|
||||||
///
|
///
|
||||||
|
@ -33,41 +25,17 @@ static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Text40x50;
|
pub struct Text40x50;
|
||||||
|
|
||||||
impl Text40x50 {
|
impl TextWriter for Text40x50 {
|
||||||
/// Creates a new `Text40x50`.
|
fn get_width(&self) -> usize {
|
||||||
pub fn new() -> Text40x50 {
|
WIDTH
|
||||||
Text40x50 {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the screen by setting all cells to `b' '` with
|
fn get_height(&self) -> usize {
|
||||||
/// a background color of `Color16Bit::Black` and a foreground
|
HEIGHT
|
||||||
/// color of `Color16Bit::Yellow`.
|
|
||||||
pub fn clear_screen(&self) {
|
|
||||||
let (_vga, frame_buffer) = self.get_frame_buffer();
|
|
||||||
for i in 0..SCREEN_SIZE {
|
|
||||||
unsafe {
|
|
||||||
frame_buffer.add(i).write_volatile(BLANK_CHARACTER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prints the given `character` and `color` at `(x, y)`.
|
|
||||||
///
|
|
||||||
/// Panics if `x >= 40` or `y >= 50`.
|
|
||||||
pub fn write_character(&self, x: usize, y: usize, character: u8, color: TextModeColor) {
|
|
||||||
assert!(x < WIDTH, "x >= {}", WIDTH);
|
|
||||||
assert!(y < HEIGHT, "y >= {}", HEIGHT);
|
|
||||||
let (_vga, frame_buffer) = self.get_frame_buffer();
|
|
||||||
let offset = WIDTH * y + x;
|
|
||||||
unsafe {
|
|
||||||
frame_buffer
|
|
||||||
.add(offset)
|
|
||||||
.write_volatile(ScreenCharacter { character, color });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the graphics device to `VideoMode::Mode40x50`.
|
/// Sets the graphics device to `VideoMode::Mode40x50`.
|
||||||
pub fn set_mode(&self) {
|
fn set_mode(&self) {
|
||||||
let mut vga = VGA.lock();
|
let mut vga = VGA.lock();
|
||||||
vga.set_video_mode(VideoMode::Mode40x50);
|
vga.set_video_mode(VideoMode::Mode40x50);
|
||||||
|
|
||||||
|
@ -76,37 +44,11 @@ impl Text40x50 {
|
||||||
vga.load_palette(&DEFAULT_PALETTE);
|
vga.load_palette(&DEFAULT_PALETTE);
|
||||||
vga.load_font(&TEXT_8X8_FONT);
|
vga.load_font(&TEXT_8X8_FONT);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the current text cursor to the position specified by
|
impl Text40x50 {
|
||||||
/// `x` and `y`.
|
/// Creates a new `Text40x50`.
|
||||||
///
|
pub fn new() -> Text40x50 {
|
||||||
/// Panics if `x >= 40` or `y >= 50`.
|
Text40x50 {}
|
||||||
pub fn set_cursor_position(&self, x: usize, y: usize) {
|
|
||||||
assert!(x < WIDTH, "x >= {}", WIDTH);
|
|
||||||
assert!(y < HEIGHT, "y >= {}", HEIGHT);
|
|
||||||
let offset = WIDTH * y + x;
|
|
||||||
let (mut vga, _frame_buffer) = self.get_frame_buffer();
|
|
||||||
let emulation_mode = vga.get_emulation_mode();
|
|
||||||
let cursor_start = offset & 0xFF;
|
|
||||||
let cursor_end = (offset >> 8) & 0xFF;
|
|
||||||
vga.write_crtc_controller(
|
|
||||||
emulation_mode,
|
|
||||||
CrtcControllerIndex::TextCursorLocationLow,
|
|
||||||
cursor_start as u8,
|
|
||||||
);
|
|
||||||
vga.write_crtc_controller(
|
|
||||||
emulation_mode,
|
|
||||||
CrtcControllerIndex::TextCursorLocationHigh,
|
|
||||||
cursor_end as u8,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
|
||||||
/// as well as a lock to the vga driver. This ensures the vga
|
|
||||||
/// driver stays locked while the frame buffer is in use.
|
|
||||||
fn get_frame_buffer(&self) -> (SpinlockGuard<Vga>, *mut ScreenCharacter) {
|
|
||||||
let mut vga = VGA.lock();
|
|
||||||
let frame_buffer = vga.get_frame_buffer();
|
|
||||||
(vga, u32::from(frame_buffer) as *mut ScreenCharacter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,12 @@
|
||||||
use super::ScreenCharacter;
|
use super::TextWriter;
|
||||||
use crate::{
|
use crate::{
|
||||||
colors::{Color16Bit, TextModeColor, DEFAULT_PALETTE},
|
colors::DEFAULT_PALETTE,
|
||||||
fonts::TEXT_8X16_FONT,
|
fonts::TEXT_8X16_FONT,
|
||||||
registers::CrtcControllerIndex,
|
vga::{VideoMode, VGA},
|
||||||
vga::{Vga, VideoMode, VGA},
|
|
||||||
};
|
};
|
||||||
use spinning_top::SpinlockGuard;
|
|
||||||
|
|
||||||
const WIDTH: usize = 80;
|
const WIDTH: usize = 80;
|
||||||
const HEIGHT: usize = 25;
|
const HEIGHT: usize = 25;
|
||||||
const SCREEN_SIZE: usize = WIDTH * HEIGHT;
|
|
||||||
|
|
||||||
static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
|
||||||
character: b' ',
|
|
||||||
color: TextModeColor::new(Color16Bit::Yellow, Color16Bit::Black),
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A basic interface for interacting with vga text mode 80x25
|
/// A basic interface for interacting with vga text mode 80x25
|
||||||
///
|
///
|
||||||
|
@ -23,7 +15,7 @@ static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
||||||
/// Basic usage:
|
/// Basic usage:
|
||||||
///
|
///
|
||||||
/// ```no_run
|
/// ```no_run
|
||||||
/// use vga::writers::Text80x25;
|
/// use vga::writers::{TextWriter, Text80x25};
|
||||||
///
|
///
|
||||||
/// let text_mode = Text80x25::new();
|
/// let text_mode = Text80x25::new();
|
||||||
///
|
///
|
||||||
|
@ -33,41 +25,16 @@ static BLANK_CHARACTER: ScreenCharacter = ScreenCharacter {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
pub struct Text80x25;
|
pub struct Text80x25;
|
||||||
|
|
||||||
impl Text80x25 {
|
impl TextWriter for Text80x25 {
|
||||||
/// Creates a new `Text80x25`.
|
fn get_width(&self) -> usize {
|
||||||
pub fn new() -> Text80x25 {
|
WIDTH
|
||||||
Text80x25 {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clears the screen by setting all cells to `b' '` with
|
fn get_height(&self) -> usize {
|
||||||
/// a background color of `Color16Bit::Black` and a foreground
|
HEIGHT
|
||||||
/// color of `Color16Bit::Yellow`.
|
|
||||||
pub fn clear_screen(&self) {
|
|
||||||
let (_vga, frame_buffer) = self.get_frame_buffer();
|
|
||||||
for i in 0..SCREEN_SIZE {
|
|
||||||
unsafe {
|
|
||||||
frame_buffer.add(i).write_volatile(BLANK_CHARACTER);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints the given `character` and `color` at `(x, y)`.
|
fn set_mode(&self) {
|
||||||
///
|
|
||||||
/// Panics if `x >= 80` or `y >= 25`.
|
|
||||||
pub fn write_character(&self, x: usize, y: usize, character: u8, color: TextModeColor) {
|
|
||||||
assert!(x < WIDTH, "x >= {}", WIDTH);
|
|
||||||
assert!(y < HEIGHT, "y >= {}", HEIGHT);
|
|
||||||
let (_vga, frame_buffer) = self.get_frame_buffer();
|
|
||||||
let offset = WIDTH * y + x;
|
|
||||||
unsafe {
|
|
||||||
frame_buffer
|
|
||||||
.add(offset)
|
|
||||||
.write_volatile(ScreenCharacter { character, color });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Sets the graphics device to `VideoMode::Mode80x25`.
|
|
||||||
pub fn set_mode(&self) {
|
|
||||||
let mut vga = VGA.lock();
|
let mut vga = VGA.lock();
|
||||||
vga.set_video_mode(VideoMode::Mode80x25);
|
vga.set_video_mode(VideoMode::Mode80x25);
|
||||||
|
|
||||||
|
@ -76,37 +43,11 @@ impl Text80x25 {
|
||||||
vga.load_palette(&DEFAULT_PALETTE);
|
vga.load_palette(&DEFAULT_PALETTE);
|
||||||
vga.load_font(&TEXT_8X16_FONT);
|
vga.load_font(&TEXT_8X16_FONT);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the current text cursor to the position specified by
|
impl Text80x25 {
|
||||||
/// `x` and `y`.
|
/// Creates a new `Text80x25`.
|
||||||
///
|
pub fn new() -> Text80x25 {
|
||||||
/// Panics if `x >= 80` or `y >= 25`.
|
Text80x25 {}
|
||||||
pub fn set_cursor_position(&self, x: usize, y: usize) {
|
|
||||||
assert!(x < WIDTH, "x >= {}", WIDTH);
|
|
||||||
assert!(y < HEIGHT, "y >= {}", HEIGHT);
|
|
||||||
let offset = WIDTH * y + x;
|
|
||||||
let (mut vga, _frame_buffer) = self.get_frame_buffer();
|
|
||||||
let emulation_mode = vga.get_emulation_mode();
|
|
||||||
let cursor_start = offset & 0xFF;
|
|
||||||
let cursor_end = (offset >> 8) & 0xFF;
|
|
||||||
vga.write_crtc_controller(
|
|
||||||
emulation_mode,
|
|
||||||
CrtcControllerIndex::TextCursorLocationLow,
|
|
||||||
cursor_start as u8,
|
|
||||||
);
|
|
||||||
vga.write_crtc_controller(
|
|
||||||
emulation_mode,
|
|
||||||
CrtcControllerIndex::TextCursorLocationHigh,
|
|
||||||
cursor_end as u8,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the start of the `FrameBuffer` as `*mut ScreenCharacter`
|
|
||||||
/// as well as a lock to the vga driver. This ensures the vga
|
|
||||||
/// driver stays locked while the frame buffer is in use.
|
|
||||||
fn get_frame_buffer(&self) -> (SpinlockGuard<Vga>, *mut ScreenCharacter) {
|
|
||||||
let mut vga = VGA.lock();
|
|
||||||
let frame_buffer = vga.get_frame_buffer();
|
|
||||||
(vga, u32::from(frame_buffer) as *mut ScreenCharacter)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue