Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 4236884

Browse filesBrowse files
authored
Merge pull request #14 from rust-osdev/develop
Develop
2 parents 8b68414 + 817023c commit 4236884
Copy full SHA for 4236884

File tree

Expand file treeCollapse file tree

9 files changed

+218
-45
lines changed
Filter options
Expand file treeCollapse file tree

9 files changed

+218
-45
lines changed

‎Cargo.toml

Copy file name to clipboardExpand all lines: Cargo.toml
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "vga"
3-
version = "0.2.2"
3+
version = "0.2.3"
44
authors = ["Ryan Kennedy <rkennedy9064@gmail.com>"]
55
edition = "2018"
66
description = "Support for vga specific functions, data structures, and registers."

‎Changelog.md

Copy file name to clipboardExpand all lines: Changelog.md
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
# 0.2.3
2+
3+
- Added support for 320x240x256 mode via `Graphics320x240x256`.
4+
- Added the ability to easily get a pointer to the modes frame buffer via `GraphicsWriter::get_frame_buffer`.
5+
16
# 0.2.2
27

38
## Breaking

‎src/configurations.rs

Copy file name to clipboardExpand all lines: src/configurations.rs
+75-1Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ pub const MODE_640X480X16_CONFIGURATION: VgaConfiguration = VgaConfiguration {
316316
],
317317
};
318318

319-
/// Register values for Vga mode 640x480x16 Graphics.
319+
/// Register values for Vga mode 320x200x256 Graphics.
320320
pub const MODE_320X200X256_CONFIGURATION: VgaConfiguration = VgaConfiguration {
321321
// Configuration values acquired from https://www.singlix.com/trdos/archive/vga/Graphics%20in%20pmode.pdf
322322
miscellaneous_output: 0x63,
@@ -389,3 +389,77 @@ pub const MODE_320X200X256_CONFIGURATION: VgaConfiguration = VgaConfiguration {
389389
(AttributeControllerIndex::ColorSelect, 0x00),
390390
],
391391
};
392+
393+
/// Register values for Vga mode 320x200x256x Graphics.
394+
pub const MODE_320X240X256_CONFIGURATION: VgaConfiguration = VgaConfiguration {
395+
// Configuration values acquired from https://www.singlix.com/trdos/archive/vga/Graphics%20in%20pmode.pdf
396+
miscellaneous_output: 0x63,
397+
sequencer_registers: &[
398+
(SequencerIndex::SequencerReset, 0x03),
399+
(SequencerIndex::ClockingMode, 0x01),
400+
(SequencerIndex::PlaneMask, 0x0F),
401+
(SequencerIndex::CharacterFont, 0x00),
402+
(SequencerIndex::MemoryMode, 0x06),
403+
],
404+
crtc_controller_registers: &[
405+
(CrtcControllerIndex::HorizontalTotal, 0x5F),
406+
(CrtcControllerIndex::HorizontalDisplayEnableEnd, 0x4F),
407+
(CrtcControllerIndex::HorizontalBlankingStart, 0x50),
408+
(CrtcControllerIndex::HorizontalBlankingEnd, 0x82),
409+
(CrtcControllerIndex::HorizontalSyncStart, 0x54),
410+
(CrtcControllerIndex::HorizontalSyncEnd, 0x80),
411+
(CrtcControllerIndex::VeritcalTotal, 0x0D),
412+
(CrtcControllerIndex::Overflow, 0x3E),
413+
(CrtcControllerIndex::PresetRowScan, 0x00),
414+
(CrtcControllerIndex::MaximumScanLine, 0x41),
415+
(CrtcControllerIndex::TextCursorStart, 0x00),
416+
(CrtcControllerIndex::TextCursorEnd, 0x00),
417+
(CrtcControllerIndex::StartAddressHigh, 0x00),
418+
(CrtcControllerIndex::StartAddressLow, 0x00),
419+
(CrtcControllerIndex::TextCursorLocationHigh, 0x00),
420+
(CrtcControllerIndex::TextCursorLocationLow, 0x00),
421+
(CrtcControllerIndex::VerticalSyncStart, 0xEA),
422+
(CrtcControllerIndex::VerticalSyncEnd, 0xAC),
423+
(CrtcControllerIndex::VerticalDisplayEnableEnd, 0xDF),
424+
(CrtcControllerIndex::Offset, 0x28),
425+
(CrtcControllerIndex::UnderlineLocation, 0x00),
426+
(CrtcControllerIndex::VerticalBlankingStart, 0xE7),
427+
(CrtcControllerIndex::VerticalBlankingEnd, 0x06),
428+
(CrtcControllerIndex::ModeControl, 0xE3),
429+
(CrtcControllerIndex::LineCompare, 0xFF),
430+
],
431+
graphics_controller_registers: &[
432+
(GraphicsControllerIndex::SetReset, 0x00),
433+
(GraphicsControllerIndex::EnableSetReset, 0x00),
434+
(GraphicsControllerIndex::ColorCompare, 0x00),
435+
(GraphicsControllerIndex::DataRotate, 0x00),
436+
(GraphicsControllerIndex::ReadPlaneSelect, 0x00),
437+
(GraphicsControllerIndex::GraphicsMode, 0x40),
438+
(GraphicsControllerIndex::Miscellaneous, 0x05),
439+
(GraphicsControllerIndex::ColorDontCare, 0x0F),
440+
(GraphicsControllerIndex::BitMask, 0xFF),
441+
],
442+
attribute_controller_registers: &[
443+
(AttributeControllerIndex::PaletteRegister0, 0x00),
444+
(AttributeControllerIndex::PaletteRegister1, 0x01),
445+
(AttributeControllerIndex::PaletteRegister2, 0x02),
446+
(AttributeControllerIndex::PaletteRegister3, 0x03),
447+
(AttributeControllerIndex::PaletteRegister4, 0x04),
448+
(AttributeControllerIndex::PaletteRegister5, 0x05),
449+
(AttributeControllerIndex::PaletteRegister6, 0x06),
450+
(AttributeControllerIndex::PaletteRegister7, 0x07),
451+
(AttributeControllerIndex::PaletteRegister8, 0x08),
452+
(AttributeControllerIndex::PaletteRegister9, 0x09),
453+
(AttributeControllerIndex::PaletteRegisterA, 0x0A),
454+
(AttributeControllerIndex::PaletteRegisterB, 0x0B),
455+
(AttributeControllerIndex::PaletteRegisterC, 0x0C),
456+
(AttributeControllerIndex::PaletteRegisterD, 0x0D),
457+
(AttributeControllerIndex::PaletteRegisterE, 0x0E),
458+
(AttributeControllerIndex::PaletteRegisterF, 0x0F),
459+
(AttributeControllerIndex::ModeControl, 0x41),
460+
(AttributeControllerIndex::OverscanColor, 0x00),
461+
(AttributeControllerIndex::MemoryPlaneEnable, 0x0F),
462+
(AttributeControllerIndex::HorizontalPixelPanning, 0x00),
463+
(AttributeControllerIndex::ColorSelect, 0x00),
464+
],
465+
};

‎src/registers/sequencer.rs

Copy file name to clipboardExpand all lines: src/registers/sequencer.rs
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl SequencerRegisters {
9696

9797
/// Sets the plane mask of the sequencer controller, as specified by `plane_mask`.
9898
pub fn set_plane_mask(&mut self, plane_mask: PlaneMask) {
99-
let original_value = self.read(SequencerIndex::PlaneMask);
99+
let original_value = self.read(SequencerIndex::PlaneMask) & 0xF0;
100100
self.write(
101101
SequencerIndex::PlaneMask,
102102
original_value | u8::from(plane_mask),

‎src/vga.rs

Copy file name to clipboardExpand all lines: src/vga.rs
+12-2Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
33
use super::{
44
configurations::{
5-
VgaConfiguration, MODE_320X200X256_CONFIGURATION, MODE_40X25_CONFIGURATION,
6-
MODE_40X50_CONFIGURATION, MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
5+
VgaConfiguration, MODE_320X200X256_CONFIGURATION, MODE_320X240X256_CONFIGURATION,
6+
MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION, MODE_640X480X16_CONFIGURATION,
7+
MODE_80X25_CONFIGURATION,
78
},
89
fonts::VgaFont,
910
registers::{
@@ -59,6 +60,8 @@ pub enum VideoMode {
5960
Mode80x25,
6061
/// Represents graphics mode 320x200x256.
6162
Mode320x200x256,
63+
/// Represents graphics mode 320x240x256.
64+
Mode320x240x256,
6265
/// Represents graphics mode 640x480x16.
6366
Mode640x480x16,
6467
}
@@ -101,6 +104,7 @@ impl Vga {
101104
VideoMode::Mode40x50 => self.set_video_mode_40x50(),
102105
VideoMode::Mode80x25 => self.set_video_mode_80x25(),
103106
VideoMode::Mode320x200x256 => self.set_video_mode_320x200x256(),
107+
VideoMode::Mode320x240x256 => self.set_video_mode_320x240x256(),
104108
VideoMode::Mode640x480x16 => self.set_video_mode_640x480x16(),
105109
}
106110
}
@@ -275,6 +279,12 @@ impl Vga {
275279
self.most_recent_video_mode = Some(VideoMode::Mode320x200x256);
276280
}
277281

282+
/// Sets the video card to Mode 320x200x256x.
283+
fn set_video_mode_320x240x256(&mut self) {
284+
self.set_registers(&MODE_320X240X256_CONFIGURATION);
285+
self.most_recent_video_mode = Some(VideoMode::Mode320x240x256);
286+
}
287+
278288
/// Sets the video card to Mode 640x480x16.
279289
fn set_video_mode_640x480x16(&mut self) {
280290
self.set_registers(&MODE_640X480X16_CONFIGURATION);

‎src/writers/graphics_320x200x256.rs

Copy file name to clipboardExpand all lines: src/writers/graphics_320x200x256.rs
+5-18Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ use super::{GraphicsWriter, Screen};
22
use crate::{
33
colors::DEFAULT_PALETTE,
44
drawing::{Bresenham, Point},
5-
vga::{Vga, VideoMode, VGA},
5+
vga::{VideoMode, VGA},
66
};
77
use font8x8::UnicodeFonts;
8-
use spinning_top::SpinlockGuard;
98

109
const WIDTH: usize = 320;
1110
const HEIGHT: usize = 200;
@@ -20,7 +19,7 @@ const SIZE: usize = WIDTH * HEIGHT;
2019
/// ```no_run
2120
/// use vga::colors::Color16;
2221
/// use vga::writers::{Graphics320x200x256, GraphicsWriter};
23-
22+
///
2423
/// let mode = Graphics320x200x256::new();
2524
/// mode.set_mode();
2625
/// mode.clear_screen(0);
@@ -44,10 +43,8 @@ impl Screen for Graphics320x200x256 {
4443

4544
impl GraphicsWriter<u8> for Graphics320x200x256 {
4645
fn clear_screen(&self, color: u8) {
47-
for x in 0..WIDTH {
48-
for y in 0..HEIGHT {
49-
self.set_pixel(x, y, color);
50-
}
46+
unsafe {
47+
self.get_frame_buffer().write_bytes(color, Self::SIZE);
5148
}
5249
}
5350
fn draw_line(&self, start: Point<isize>, end: Point<isize>, color: u8) {
@@ -56,10 +53,9 @@ impl GraphicsWriter<u8> for Graphics320x200x256 {
5653
}
5754
}
5855
fn set_pixel(&self, x: usize, y: usize, color: u8) {
59-
let (_vga, frame_buffer) = self.get_frame_buffer();
6056
let offset = (y * WIDTH) + x;
6157
unsafe {
62-
frame_buffer.add(offset).write_volatile(color);
58+
self.get_frame_buffer().add(offset).write_volatile(color);
6359
}
6460
}
6561
fn draw_character(&self, x: usize, y: usize, character: char, color: u8) {
@@ -93,13 +89,4 @@ impl Graphics320x200x256 {
9389
pub const fn new() -> Graphics320x200x256 {
9490
Graphics320x200x256
9591
}
96-
97-
/// Returns the start of the `FrameBuffer` as `*mut u8` as
98-
/// well as a lock to the vga driver. This ensures the vga
99-
/// driver stays locked while the frame buffer is in use.
100-
fn get_frame_buffer(self) -> (SpinlockGuard<'static, Vga>, *mut u8) {
101-
let mut vga = VGA.lock();
102-
let frame_buffer = vga.get_frame_buffer();
103-
(vga, u32::from(frame_buffer) as *mut u8)
104-
}
10592
}

‎src/writers/graphics_320x240x256.rs

Copy file name to clipboard
+102Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
use super::{GraphicsWriter, Screen};
2+
use crate::{
3+
colors::DEFAULT_PALETTE,
4+
drawing::{Bresenham, Point},
5+
registers::PlaneMask,
6+
vga::{VideoMode, VGA},
7+
};
8+
use font8x8::UnicodeFonts;
9+
10+
const WIDTH: usize = 320;
11+
const HEIGHT: usize = 240;
12+
const SIZE: usize = (WIDTH * HEIGHT) / 4;
13+
14+
/// A basic interface for interacting with vga graphics mode 320x200x256.
15+
///
16+
/// # Examples
17+
///
18+
/// Basic usage:
19+
///
20+
/// ```no_run
21+
/// use vga::colors::Color16;
22+
/// use vga::writers::{Graphics320x240x256, GraphicsWriter};
23+
///
24+
/// let mode = Graphics320x240x256::new();
25+
/// mode.set_mode();
26+
/// mode.clear_screen(0);
27+
/// mode.draw_line((60, 20), (260, 20), 255);
28+
/// mode.draw_line((60, 20), (60, 180), 255);
29+
/// mode.draw_line((60, 180), (260, 180), 255);
30+
/// mode.draw_line((260, 180), (260, 20), 255);
31+
/// mode.draw_line((60, 40), (260, 40), 255);
32+
/// for (offset, character) in "Hello World!".chars().enumerate() {
33+
/// mode.draw_character(118 + offset * 8, 27, character, 255);
34+
/// }
35+
/// ```
36+
#[derive(Debug, Clone, Copy, Default)]
37+
pub struct Graphics320x240x256;
38+
39+
impl Screen for Graphics320x240x256 {
40+
const WIDTH: usize = WIDTH;
41+
const HEIGHT: usize = HEIGHT;
42+
const SIZE: usize = SIZE;
43+
}
44+
45+
impl GraphicsWriter<u8> for Graphics320x240x256 {
46+
fn clear_screen(&self, color: u8) {
47+
let frame_buffer = self.get_frame_buffer();
48+
VGA.lock()
49+
.sequencer_registers
50+
.set_plane_mask(PlaneMask::ALL_PLANES);
51+
unsafe {
52+
frame_buffer.write_bytes(color, Self::SIZE);
53+
}
54+
}
55+
fn draw_line(&self, start: Point<isize>, end: Point<isize>, color: u8) {
56+
for (x, y) in Bresenham::new(start, end) {
57+
self.set_pixel(x as usize, y as usize, color);
58+
}
59+
}
60+
fn set_pixel(&self, x: usize, y: usize, color: u8) {
61+
let frame_buffer = self.get_frame_buffer();
62+
unsafe {
63+
let offset = (WIDTH * y + x) / 4;
64+
let plane_mask = 0x1 << (x & 3);
65+
VGA.lock()
66+
.sequencer_registers
67+
.set_plane_mask(PlaneMask::from_bits(plane_mask).unwrap());
68+
frame_buffer.add(offset).write_volatile(color);
69+
}
70+
}
71+
fn draw_character(&self, x: usize, y: usize, character: char, color: u8) {
72+
let character = match font8x8::BASIC_FONTS.get(character) {
73+
Some(character) => character,
74+
// Default to a filled block if the character isn't found
75+
None => font8x8::unicode::BLOCK_UNICODE[8].byte_array(),
76+
};
77+
78+
for (row, byte) in character.iter().enumerate() {
79+
for bit in 0..8 {
80+
match *byte & 1 << bit {
81+
0 => (),
82+
_ => self.set_pixel(x + bit, y + row, color),
83+
}
84+
}
85+
}
86+
}
87+
fn set_mode(&self) {
88+
let mut vga = VGA.lock();
89+
vga.set_video_mode(VideoMode::Mode320x240x256);
90+
91+
// Some bios mess up the palette when switching modes,
92+
// so explicitly set it.
93+
vga.color_palette_registers.load_palette(&DEFAULT_PALETTE);
94+
}
95+
}
96+
97+
impl Graphics320x240x256 {
98+
/// Creates a new `Graphics320x240x256`.
99+
pub const fn new() -> Graphics320x240x256 {
100+
Graphics320x240x256
101+
}
102+
}

‎src/writers/graphics_640x480x16.rs

Copy file name to clipboardExpand all lines: src/writers/graphics_640x480x16.rs
+11-22Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,13 @@ use crate::{
33
colors::{Color16, DEFAULT_PALETTE},
44
drawing::{Bresenham, Point},
55
registers::{PlaneMask, WriteMode},
6-
vga::{Vga, VideoMode, VGA},
6+
vga::{VideoMode, VGA},
77
};
88
use font8x8::UnicodeFonts;
9-
use spinning_top::SpinlockGuard;
109

1110
const WIDTH: usize = 640;
1211
const HEIGHT: usize = 480;
13-
const SIZE: usize = WIDTH * HEIGHT;
14-
const ALL_PLANES_SCREEN_SIZE: usize = (WIDTH * HEIGHT) / 8;
12+
const SIZE: usize = (WIDTH * HEIGHT) / 8;
1513
const WIDTH_IN_BYTES: usize = WIDTH / 8;
1614

1715
/// A basic interface for interacting with vga graphics mode 640x480x16
@@ -48,11 +46,9 @@ impl Screen for Graphics640x480x16 {
4846
impl GraphicsWriter<Color16> for Graphics640x480x16 {
4947
fn clear_screen(&self, color: Color16) {
5048
self.set_write_mode_2();
51-
let (_vga, frame_buffer) = self.get_frame_buffer();
52-
for offset in 0..ALL_PLANES_SCREEN_SIZE {
53-
unsafe {
54-
frame_buffer.add(offset).write_volatile(u8::from(color));
55-
}
49+
unsafe {
50+
self.get_frame_buffer()
51+
.write_bytes(u8::from(color), Self::SIZE);
5652
}
5753
}
5854

@@ -107,7 +103,7 @@ impl Graphics640x480x16 {
107103
}
108104

109105
fn set_write_mode_0(self, color: Color16) {
110-
let (mut vga, _frame_buffer) = self.get_frame_buffer();
106+
let mut vga = VGA.lock();
111107
vga.graphics_controller_registers.write_set_reset(color);
112108
vga.graphics_controller_registers
113109
.write_enable_set_reset(0xF);
@@ -116,29 +112,22 @@ impl Graphics640x480x16 {
116112
}
117113

118114
fn set_write_mode_2(self) {
119-
let (mut vga, _frame_buffer) = self.get_frame_buffer();
115+
let mut vga = VGA.lock();
120116
vga.graphics_controller_registers
121117
.set_write_mode(WriteMode::Mode2);
122118
vga.graphics_controller_registers.set_bit_mask(0xFF);
123119
vga.sequencer_registers
124120
.set_plane_mask(PlaneMask::ALL_PLANES);
125121
}
126122

127-
/// Returns the start of the `FrameBuffer` as `*mut u8` as
128-
/// well as a lock to the vga driver. This ensures the vga
129-
/// driver stays locked while the frame buffer is in use.
130-
fn get_frame_buffer(self) -> (SpinlockGuard<'static, Vga>, *mut u8) {
131-
let mut vga = VGA.lock();
132-
let frame_buffer = vga.get_frame_buffer();
133-
(vga, u32::from(frame_buffer) as *mut u8)
134-
}
135-
136123
#[inline]
137124
fn _set_pixel(self, x: usize, y: usize, color: Color16) {
138-
let (mut vga, frame_buffer) = self.get_frame_buffer();
125+
let frame_buffer = self.get_frame_buffer();
139126
let offset = x / 8 + y * WIDTH_IN_BYTES;
140127
let pixel_mask = 0x80 >> (x & 0x07);
141-
vga.graphics_controller_registers.set_bit_mask(pixel_mask);
128+
VGA.lock()
129+
.graphics_controller_registers
130+
.set_bit_mask(pixel_mask);
142131
unsafe {
143132
frame_buffer.add(offset).read_volatile();
144133
frame_buffer.add(offset).write_volatile(u8::from(color));

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.