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 85c237d

Browse filesBrowse files
authored
Merge pull request #10 from rust-osdev/develop
Develop
2 parents 6f8e2b3 + 1a1823b commit 85c237d
Copy full SHA for 85c237d

File tree

Expand file treeCollapse file tree

7 files changed

+228
-10
lines changed
Filter options
Expand file treeCollapse file tree

7 files changed

+228
-10
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.0"
3+
version = "0.2.1"
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.1
2+
3+
- Added `Graphics320x200x256` mode.
4+
- Implemented `Screen` for `Graphics640x480x16`.
5+
16
# 0.2.0
27

38
## Breaking

‎src/configurations.rs

Copy file name to clipboardExpand all lines: src/configurations.rs
+74Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,77 @@ pub const MODE_640X480X16_CONFIGURATION: VgaConfiguration = VgaConfiguration {
315315
(AttributeControllerIndex::ColorSelect, 0x00),
316316
],
317317
};
318+
319+
/// Register values for Vga mode 640x480x16 Graphics.
320+
pub const MODE_320X200X256_CONFIGURATION: VgaConfiguration = VgaConfiguration {
321+
// Configuration values acquired from https://www.singlix.com/trdos/archive/vga/Graphics%20in%20pmode.pdf
322+
miscellaneous_output: 0x63,
323+
sequencer_registers: &[
324+
(SequencerIndex::SequencerReset, 0x03),
325+
(SequencerIndex::ClockingMode, 0x01),
326+
(SequencerIndex::PlaneMask, 0x0F),
327+
(SequencerIndex::CharacterFont, 0x00),
328+
(SequencerIndex::MemoryMode, 0x0E),
329+
],
330+
crtc_controller_registers: &[
331+
(CrtcControllerIndex::HorizontalTotal, 0x5F),
332+
(CrtcControllerIndex::HorizontalDisplayEnableEnd, 0x4F),
333+
(CrtcControllerIndex::HorizontalBlankingStart, 0x50),
334+
(CrtcControllerIndex::HorizontalBlankingEnd, 0x82),
335+
(CrtcControllerIndex::HorizontalSyncStart, 0x54),
336+
(CrtcControllerIndex::HorizontalSyncEnd, 0x80),
337+
(CrtcControllerIndex::VeritcalTotal, 0xBF),
338+
(CrtcControllerIndex::Overflow, 0x1F),
339+
(CrtcControllerIndex::PresetRowScan, 0x00),
340+
(CrtcControllerIndex::MaximumScanLine, 0x41),
341+
(CrtcControllerIndex::TextCursorStart, 0x00),
342+
(CrtcControllerIndex::TextCursorEnd, 0x00),
343+
(CrtcControllerIndex::StartAddressHigh, 0x00),
344+
(CrtcControllerIndex::StartAddressLow, 0x00),
345+
(CrtcControllerIndex::TextCursorLocationHigh, 0x00),
346+
(CrtcControllerIndex::TextCursorLocationLow, 0x00),
347+
(CrtcControllerIndex::VerticalSyncStart, 0x9C),
348+
(CrtcControllerIndex::VerticalSyncEnd, 0x0E),
349+
(CrtcControllerIndex::VerticalDisplayEnableEnd, 0x8F),
350+
(CrtcControllerIndex::Offset, 0x28),
351+
(CrtcControllerIndex::UnderlineLocation, 0x40),
352+
(CrtcControllerIndex::VerticalBlankingStart, 0x96),
353+
(CrtcControllerIndex::VerticalBlankingEnd, 0xB9),
354+
(CrtcControllerIndex::ModeControl, 0xA3),
355+
(CrtcControllerIndex::LineCompare, 0xFF),
356+
],
357+
graphics_controller_registers: &[
358+
(GraphicsControllerIndex::SetReset, 0x00),
359+
(GraphicsControllerIndex::EnableSetReset, 0x00),
360+
(GraphicsControllerIndex::ColorCompare, 0x00),
361+
(GraphicsControllerIndex::DataRotate, 0x00),
362+
(GraphicsControllerIndex::ReadPlaneSelect, 0x00),
363+
(GraphicsControllerIndex::GraphicsMode, 0x40),
364+
(GraphicsControllerIndex::Miscellaneous, 0x05),
365+
(GraphicsControllerIndex::ColorDontCare, 0x0F),
366+
(GraphicsControllerIndex::BitMask, 0xFF),
367+
],
368+
attribute_controller_registers: &[
369+
(AttributeControllerIndex::PaletteRegister0, 0x00),
370+
(AttributeControllerIndex::PaletteRegister1, 0x01),
371+
(AttributeControllerIndex::PaletteRegister2, 0x02),
372+
(AttributeControllerIndex::PaletteRegister3, 0x03),
373+
(AttributeControllerIndex::PaletteRegister4, 0x04),
374+
(AttributeControllerIndex::PaletteRegister5, 0x05),
375+
(AttributeControllerIndex::PaletteRegister6, 0x06),
376+
(AttributeControllerIndex::PaletteRegister7, 0x07),
377+
(AttributeControllerIndex::PaletteRegister8, 0x08),
378+
(AttributeControllerIndex::PaletteRegister9, 0x09),
379+
(AttributeControllerIndex::PaletteRegisterA, 0x0A),
380+
(AttributeControllerIndex::PaletteRegisterB, 0x0B),
381+
(AttributeControllerIndex::PaletteRegisterC, 0x0C),
382+
(AttributeControllerIndex::PaletteRegisterD, 0x0D),
383+
(AttributeControllerIndex::PaletteRegisterE, 0x0E),
384+
(AttributeControllerIndex::PaletteRegisterF, 0x0F),
385+
(AttributeControllerIndex::ModeControl, 0x41),
386+
(AttributeControllerIndex::OverscanColor, 0x00),
387+
(AttributeControllerIndex::MemoryPlaneEnable, 0x0F),
388+
(AttributeControllerIndex::HorizontalPixelPanning, 0x00),
389+
(AttributeControllerIndex::ColorSelect, 0x00),
390+
],
391+
};

‎src/vga.rs

Copy file name to clipboardExpand all lines: src/vga.rs
+11-2Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
33
use super::{
44
configurations::{
5-
VgaConfiguration, MODE_40X25_CONFIGURATION, MODE_40X50_CONFIGURATION,
6-
MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
5+
VgaConfiguration, MODE_320X200X256_CONFIGURATION, MODE_40X25_CONFIGURATION,
6+
MODE_40X50_CONFIGURATION, MODE_640X480X16_CONFIGURATION, MODE_80X25_CONFIGURATION,
77
},
88
fonts::VgaFont,
99
registers::{
@@ -57,6 +57,8 @@ pub enum VideoMode {
5757
Mode40x50,
5858
/// Represents text mode 80x25.
5959
Mode80x25,
60+
/// Represents graphics mode 320x200x256.
61+
Mode320x200x256,
6062
/// Represents graphics mode 640x480x16.
6163
Mode640x480x16,
6264
}
@@ -98,6 +100,7 @@ impl Vga {
98100
VideoMode::Mode40x25 => self.set_video_mode_40x25(),
99101
VideoMode::Mode40x50 => self.set_video_mode_40x50(),
100102
VideoMode::Mode80x25 => self.set_video_mode_80x25(),
103+
VideoMode::Mode320x200x256 => self.set_video_mode_320x200x256(),
101104
VideoMode::Mode640x480x16 => self.set_video_mode_640x480x16(),
102105
}
103106
}
@@ -266,6 +269,12 @@ impl Vga {
266269
self.most_recent_video_mode = Some(VideoMode::Mode80x25);
267270
}
268271

272+
/// Sets the video card to Mode 320x200x256.
273+
fn set_video_mode_320x200x256(&mut self) {
274+
self.set_registers(&MODE_320X200X256_CONFIGURATION);
275+
self.most_recent_video_mode = Some(VideoMode::Mode320x200x256);
276+
}
277+
269278
/// Sets the video card to Mode 640x480x16.
270279
fn set_video_mode_640x480x16(&mut self) {
271280
self.set_registers(&MODE_640X480X16_CONFIGURATION);

‎src/writers/graphics_320x200x256.rs

Copy file name to clipboard
+116Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
use super::{GraphicsWriter, Screen};
2+
use crate::{
3+
colors::DEFAULT_PALETTE,
4+
drawing::{Bresenham, Point},
5+
vga::{Vga, VideoMode, VGA},
6+
};
7+
use font8x8::UnicodeFonts;
8+
use spinning_top::SpinlockGuard;
9+
10+
const WIDTH: usize = 320;
11+
const HEIGHT: usize = 200;
12+
const SIZE: usize = WIDTH * HEIGHT;
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::{Graphics320x200x256, GraphicsWriter};
23+
24+
/// let mode = Graphics320x200x256::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(Default)]
37+
pub struct Graphics320x200x256 {}
38+
39+
impl Screen for Graphics320x200x256 {
40+
#[inline]
41+
fn get_width(&self) -> usize {
42+
WIDTH
43+
}
44+
45+
#[inline]
46+
fn get_height(&self) -> usize {
47+
HEIGHT
48+
}
49+
50+
#[inline]
51+
fn get_size(&self) -> usize {
52+
SIZE
53+
}
54+
}
55+
56+
impl GraphicsWriter<u8> for Graphics320x200x256 {
57+
fn clear_screen(&self, color: u8) {
58+
for x in 0..WIDTH {
59+
for y in 0..HEIGHT {
60+
self.set_pixel(x, y, color);
61+
}
62+
}
63+
}
64+
fn draw_line(&self, start: Point<isize>, end: Point<isize>, color: u8) {
65+
for (x, y) in Bresenham::new(start, end) {
66+
self.set_pixel(x as usize, y as usize, color);
67+
}
68+
}
69+
fn set_pixel(&self, x: usize, y: usize, color: u8) {
70+
let (_vga, frame_buffer) = self.get_frame_buffer();
71+
let offset = (y * WIDTH) + x;
72+
unsafe {
73+
frame_buffer.add(offset).write_volatile(color);
74+
}
75+
}
76+
fn draw_character(&self, x: usize, y: usize, character: char, color: u8) {
77+
let character = match font8x8::BASIC_FONTS.get(character) {
78+
Some(character) => character,
79+
// Default to a filled block if the character isn't found
80+
None => font8x8::unicode::BLOCK_UNICODE[8].byte_array(),
81+
};
82+
83+
for (row, byte) in character.iter().enumerate() {
84+
for bit in 0..8 {
85+
match *byte & 1 << bit {
86+
0 => (),
87+
_ => self.set_pixel(x + bit, y + row, color),
88+
}
89+
}
90+
}
91+
}
92+
fn set_mode(&self) {
93+
let mut vga = VGA.lock();
94+
vga.set_video_mode(VideoMode::Mode320x200x256);
95+
96+
// Some bios mess up the palette when switching modes,
97+
// so explicitly set it.
98+
vga.color_palette_registers.load_palette(&DEFAULT_PALETTE);
99+
}
100+
}
101+
102+
impl Graphics320x200x256 {
103+
/// Creates a new `Graphics320x200x256`.
104+
pub fn new() -> Graphics320x200x256 {
105+
Graphics320x200x256 {}
106+
}
107+
108+
/// Returns the start of the `FrameBuffer` as `*mut u8` as
109+
/// well as a lock to the vga driver. This ensures the vga
110+
/// driver stays locked while the frame buffer is in use.
111+
fn get_frame_buffer(&self) -> (SpinlockGuard<Vga>, *mut u8) {
112+
let mut vga = VGA.lock();
113+
let frame_buffer = vga.get_frame_buffer();
114+
(vga, u32::from(frame_buffer) as *mut u8)
115+
}
116+
}

‎src/writers/graphics_640x480x16.rs

Copy file name to clipboardExpand all lines: src/writers/graphics_640x480x16.rs
+18-1Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use super::GraphicsWriter;
1+
use super::{GraphicsWriter, Screen};
22
use crate::{
33
colors::{Color16, DEFAULT_PALETTE},
44
drawing::{Bresenham, Point},
@@ -10,6 +10,7 @@ use spinning_top::SpinlockGuard;
1010

1111
const WIDTH: usize = 640;
1212
const HEIGHT: usize = 480;
13+
const SIZE: usize = WIDTH * HEIGHT;
1314
const ALL_PLANES_SCREEN_SIZE: usize = (WIDTH * HEIGHT) / 8;
1415
const WIDTH_IN_BYTES: usize = WIDTH / 8;
1516

@@ -38,6 +39,18 @@ const WIDTH_IN_BYTES: usize = WIDTH / 8;
3839
#[derive(Default)]
3940
pub struct Graphics640x480x16;
4041

42+
impl Screen for Graphics640x480x16 {
43+
fn get_width(&self) -> usize {
44+
WIDTH
45+
}
46+
fn get_height(&self) -> usize {
47+
HEIGHT
48+
}
49+
fn get_size(&self) -> usize {
50+
SIZE
51+
}
52+
}
53+
4154
impl GraphicsWriter<Color16> for Graphics640x480x16 {
4255
fn clear_screen(&self, color: Color16) {
4356
self.set_write_mode_2();
@@ -74,6 +87,10 @@ impl GraphicsWriter<Color16> for Graphics640x480x16 {
7487
}
7588
}
7689

90+
/// **Note:** This method is provided for convenience, but has terrible
91+
/// performance since it needs to ensure the correct `WriteMode` per pixel
92+
/// drawn. If you need to draw more then one pixel, consider using a method
93+
/// such as `draw_line`.
7794
fn set_pixel(&self, x: usize, y: usize, color: Color16) {
7895
self.set_write_mode_2();
7996
self._set_pixel(x, y, color);

‎src/writers/mod.rs

Copy file name to clipboardExpand all lines: src/writers/mod.rs
+3-6Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
//! Writers for common vga modes.
2+
mod graphics_320x200x256;
23
mod graphics_640x480x16;
34
mod text_40x25;
45
mod text_40x50;
@@ -12,6 +13,7 @@ use super::{
1213
};
1314
use spinning_top::SpinlockGuard;
1415

16+
pub use graphics_320x200x256::Graphics320x200x256;
1517
pub use graphics_640x480x16::Graphics640x480x16;
1618
pub use text_40x25::Text40x25;
1719
pub use text_40x50::Text40x50;
@@ -183,16 +185,11 @@ pub trait TextWriter: Screen {
183185
pub trait GraphicsWriter<Color> {
184186
/// Clears the screen by setting all pixels to the specified `color`.
185187
fn clear_screen(&self, color: Color);
186-
/// /// Draws a line from `start` to `end` with the specified `color`.
188+
/// Draws a line from `start` to `end` with the specified `color`.
187189
fn draw_line(&self, start: Point<isize>, end: Point<isize>, color: Color);
188190
/// Draws a character at the given `(x, y)` coordinant to the specified `color`.
189191
fn draw_character(&self, x: usize, y: usize, character: char, color: Color);
190192
/// Sets the given pixel at `(x, y)` to the given `color`.
191-
///
192-
/// **Note:** This method is provided for convenience, but has terrible
193-
/// performance since it needs to ensure the correct `WriteMode` per pixel
194-
/// drawn. If you need to draw more then one pixel, consider using a method
195-
/// such as `draw_line`.
196193
fn set_pixel(&self, x: usize, y: usize, color: Color);
197194
/// Sets the graphics device to a `VideoMode`.
198195
fn set_mode(&self);

0 commit comments

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