Skip to content

Commit e6838f9

Browse files
committed
Printing ASCII character by accessing VGA buffer
1 parent 248ed4d commit e6838f9

File tree

4 files changed

+116
-8
lines changed

4 files changed

+116
-8
lines changed

.cargo/config.toml

+4
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,7 @@ build-std-features = ["compiler-builtins-mem"]
55

66
[build]
77
target = "llvm_target_descp.json"
8+
9+
#using cargo run (add .exe extension)
10+
[target.'cfg(target_os="none")']
11+
runner = "bootimage runner"

readme.md

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
<h2>To Run the generated .bin in Qemu emulator.</h2>
2-
<i>qemu-system-x86_64.exe -drive format=raw,file=bootimage-OS-With-Rust.bin</i>
2+
<i><span>**RUN:** </span>cargo bootimage<i>
3+
<br>
4+
<i><span>**RUN:** </span>qemu-system-x86_64.exe -drive format=raw,file=target\llvm_target_descp\debug\bootimage-OS-With-Rust.bin</i>

src/main.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![no_std]
22
#![no_main]
33

4+
mod vga_buffer;
5+
46
//we will not be using main function as the entrypoint
57
use core::panic::PanicInfo;
68

@@ -15,13 +17,14 @@ static HELLO: &[u8] = b"hello world!";
1517
// no_mangle prevents from function name prined as a crytic
1618
#[no_mangle]
1719
pub extern "C" fn _start() -> ! {
18-
let vga_buffer = 0xb8000 as *mut u8;
19-
for (i, &byte) in HELLO.iter().enumerate() {
20-
unsafe {
21-
*vga_buffer.offset(i as isize * 2) = byte;
22-
*vga_buffer.offset(i as isize * 2 + 1) = 0xb;
23-
}
24-
}
20+
// let vga_buffer = 0xb8000 as *mut u8;
21+
// for (i, &byte) in HELLO.iter().enumerate() {
22+
// unsafe {
23+
// *vga_buffer.offset(i as isize * 2) = byte;
24+
// *vga_buffer.offset(i as isize * 2 + 1) = 0xb;
25+
// }
26+
// }
27+
vga_buffer::print_something();
2528
loop {}
2629
}
2730

src/vga_buffer.rs

+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#[allow(dead_code)]
2+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
3+
#[repr(u8)] //each enum variant would be stored as a u8.
4+
pub enum Color {
5+
Black = 0,
6+
Blue = 1,
7+
Green = 2,
8+
Cyan = 3,
9+
Red = 4,
10+
Magenta = 5,
11+
Brown = 6,
12+
LightGray = 7,
13+
DarkGray = 8,
14+
LightBlue = 9,
15+
LightGreen = 10,
16+
LightCyan = 11,
17+
LightRed = 12,
18+
Pink = 13,
19+
Yellow = 14,
20+
White = 15,
21+
}
22+
23+
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
24+
#[repr(transparent)]
25+
struct ColorCode(u8);
26+
27+
impl ColorCode {
28+
fn new(foreground: Color, background: Color) -> ColorCode {
29+
ColorCode((background as u8) << 4 | (foreground as u8))
30+
}
31+
}
32+
33+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
34+
#[repr(C)]
35+
struct ScreenChar {
36+
ascii_character: u8,
37+
color_code: ColorCode,
38+
}
39+
40+
const BUFFER_HEIGHT: usize = 25;
41+
const BUFFER_WIDTH: usize = 80;
42+
43+
#[repr(transparent)]
44+
struct Buffer {
45+
chars: [[ScreenChar; BUFFER_WIDTH]; BUFFER_HEIGHT],
46+
}
47+
48+
pub struct Writer {
49+
column_position: usize,
50+
color_code: ColorCode,
51+
buffer: &'static mut Buffer,
52+
}
53+
54+
impl Writer {
55+
pub fn write_byte(&mut self, byte: u8) {
56+
match byte {
57+
b'\n' => self.new_line(),
58+
byte => {
59+
if self.column_position >= BUFFER_WIDTH {
60+
self.new_line()
61+
}
62+
let row = BUFFER_HEIGHT - 1;
63+
let col = self.column_position;
64+
let color_code = self.color_code;
65+
66+
self.buffer.chars[row][col] = ScreenChar {
67+
ascii_character: byte,
68+
color_code,
69+
};
70+
self.column_position += 1;
71+
}
72+
}
73+
}
74+
fn new_line(&mut self) {}
75+
}
76+
77+
impl Writer {
78+
pub fn write_string(&mut self, s: &str) {
79+
for byte in s.bytes() {
80+
match byte {
81+
// printable ASCII byte or newline
82+
0x20..=0x7e | b'\n' => self.write_byte(byte),
83+
// not part of printable ASCII range
84+
_ => self.write_byte(0xfe)
85+
}
86+
}
87+
}
88+
}
89+
90+
pub fn print_something() {
91+
let mut writer = Writer {
92+
column_position: 0,
93+
color_code: ColorCode::new(Color::Yellow, Color::Black),
94+
buffer: unsafe { &mut *(0xb8000 as *mut Buffer) },
95+
};
96+
writer.write_byte(b'H');
97+
writer.write_string("ello ");
98+
writer.write_string("Wörld!");
99+
}

0 commit comments

Comments
 (0)