Faster clear screen

This commit is contained in:
Ryan Kennedy 2020-03-21 22:26:59 -05:00
parent 86c575e7bc
commit 700d657e25
2 changed files with 15 additions and 13 deletions

View file

@ -90,13 +90,15 @@ bitflags! {
/// Represents the plane masks of the `SequencerIndex::PlaneMask` register.
pub struct PlaneMask: u8 {
/// Represents `Plane0` of vga memory.
const PLANE0 = 0b00000001;
const PLANE0 = 0b0000_0001;
/// Represents `Plane1` of vga memory.
const PLANE1 = 0b00000010;
const PLANE1 = 0b0000_0010;
/// Represents `Plane2` of vga memory.
const PLANE2 = 0b00000100;
const PLANE2 = 0b0000_0100;
/// Represents `Plane3` of vga memory.
const PLANE3 = 0b00001000;
const PLANE3 = 0b0000_1000;
/// Represents a combination of all the plane masks.
const ALL_PLANES = Self::PLANE0.bits() | Self::PLANE1.bits() | Self::PLANE2.bits() | Self::PLANE3.bits();
}
}

View file

@ -1,12 +1,13 @@
use crate::{
colors::{Color16Bit, DEFAULT_PALETTE},
vga::{Vga, VideoMode, VGA},
vga::{PlaneMask, Vga, VideoMode, VGA},
};
use core::convert::TryInto;
use spinning_top::SpinlockGuard;
const WIDTH: usize = 640;
const HEIGHT: usize = 480;
const ALL_PLANES_SCREEN_SIZE: usize = (WIDTH * HEIGHT) / 4;
/// A basic interface for interacting with vga graphics mode 640x480x16
///
@ -33,20 +34,19 @@ impl Graphics640x480x16 {
/// Clears the screen by setting all pixels to `Color16Bit::Black`.
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 y in 0..HEIGHT {
self.set_pixel(x, y, Color16Bit::Black);
let (mut vga, frame_buffer) = self.get_frame_buffer();
vga.set_plane_mask(PlaneMask::ALL_PLANES);
for offset in 0..ALL_PLANES_SCREEN_SIZE {
unsafe {
frame_buffer
.add(offset)
.write_volatile(Color16Bit::Black as u8);
}
}
}
/// Sets the given pixel at `(x, y)` to the given `color`.
///
/// Panics if `x >= 640` or `y >= 480`.
pub fn set_pixel(&self, x: usize, y: usize, color: Color16Bit) {
assert!(x < WIDTH, "x >= {}", WIDTH);
assert!(y < HEIGHT, "y >= {}", HEIGHT);
let (mut vga, frame_buffer) = self.get_frame_buffer();
let offset = x / 8 + (WIDTH / 8) * y;