]> git.lizzy.rs Git - loadnothing.git/blob - stage2/src/vga.rs
d0527246245bdf33903714e6cb717ac266c514a0
[loadnothing.git] / stage2 / src / vga.rs
1 use core::ops::{AddAssign, Shl};
2
3 #[allow(dead_code)]
4 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
5 #[repr(u8)]
6 pub enum Color {
7     Black = 0,
8     Blue = 1,
9     Green = 2,
10     Cyan = 3,
11     Red = 4,
12     Magenta = 5,
13     Brown = 6,
14     LightGray = 7,
15     DarkGray = 8,
16     LightBlue = 9,
17     LightGreen = 10,
18     LightCyan = 11,
19     LightRed = 12,
20     Pink = 13,
21     Yellow = 14,
22     White = 15,
23 }
24
25 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
26 #[repr(transparent)]
27 pub struct ColorCode(u8);
28
29 impl ColorCode {
30     pub fn new(foreground: Color, background: Color) -> ColorCode {
31         ColorCode((background as u8).shl(4) | (foreground as u8))
32     }
33 }
34
35 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
36 #[repr(C)]
37 struct ScreenChar {
38     ascii_character: u8,
39     color_code: ColorCode,
40 }
41
42 const BUFFER_WIDTH: usize = 80;
43 const BUFFER_HEIGHT: usize = 25;
44
45 #[repr(transparent)]
46 struct Buffer {
47     chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
48 }
49
50 pub struct Writer {
51     row_position: usize,
52     column_position: usize,
53     color_code: ColorCode,
54     buffer: &'static mut Buffer,
55 }
56
57 impl Writer {
58     pub fn write_byte(&mut self, byte: u8) {
59         match byte {
60             b'\n' => self.new_line(),
61             byte => {
62                 if self.column_position >= BUFFER_WIDTH {
63                     self.new_line();
64                 }
65
66                 let row = self.row_position;
67                 let col = self.column_position;
68
69                 let color_code = self.color_code;
70                 self.buffer.chars[row][col] = ScreenChar {
71                     ascii_character: byte,
72                     color_code,
73                 };
74
75                 self.column_position.add_assign(1);
76             },
77         }
78     }
79
80     pub fn write_string(&mut self, s: &str) {
81         for byte in s.bytes() {
82             match byte {
83                 // Printable ASCII character or \n
84                 0x20..=0x7e | b'\n' => self.write_byte(byte),
85                 // Not printable, write error char instead
86                 _ => self.write_byte(0xfe),
87             }
88         }
89     }
90
91     fn new_line(&mut self) {
92
93     }
94 }
95
96 pub fn test_print() {
97     let mut writer = Writer {
98         row_position: 1,
99         column_position: 0,
100         color_code: ColorCode::new(Color::Yellow, Color::Black),
101         buffer: unsafe { &mut *(0xb8000 as *mut Buffer) },
102     };
103
104     writer.write_string("Hello Stage2!");
105 }