Skip to content

Commit ccc24ef

Browse files
committed
added print! and println! macro
1 parent 08d5ec5 commit ccc24ef

6 files changed

Lines changed: 181 additions & 9 deletions

File tree

.cargo/config.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,6 @@ build-std-features = ["compiler-builtins-mem"]
44
build-std = ["core", "compiler_builtins"]
55
[build]
66
target = "x86_64-ShabbOS.json"
7+
8+
[target.'cfg(target_os="none")']
9+
runner = "bootimage runner"

Cargo.lock

Lines changed: 30 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,11 @@ panic = "abort"
1010

1111
[dependencies]
1212
bootloader = "0.9"
13-
13+
volatile = "0.2.6"
14+
spin = "0.5.2"
15+
[dependencies.lazy_static]
16+
version = "1.0"
17+
features = ["spin_no_std"]
1418
[[bin]]
1519
name ="ShabbOS"
1620
test = false

src/macros.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
2+
use core::fmt;
3+
4+
5+
#[macro_export]
6+
macro_rules! println {
7+
() => ($crate::print!("\n"));
8+
($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)));
9+
}
10+
#[macro_export]
11+
macro_rules! print{
12+
($($arg:tt)*)=> ($crate::macros::print(format_args!($($arg)*)))
13+
}
14+
15+
pub fn print(args: fmt::Arguments) {
16+
use core::fmt::Write;
17+
crate::vga_buffer::WRITER.lock().write_fmt(args).unwrap();
18+
}

src/main.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,19 @@
22
#![no_std]
33
#![no_main]
44

5+
mod vga_buffer;
6+
mod macros;
7+
58
use core::panic::PanicInfo;
69

710

811

9-
static hello: &[u8] = b"hello world";
12+
1013

1114
#[unsafe(no_mangle)]
1215
pub extern "C" fn _start()->!{
13-
let vga_buffer = 0xb8000 as *mut u8;
14-
for(i,&byte) in hello.iter().enumerate(){
15-
unsafe {
16-
*vga_buffer.offset(i as isize *2) = byte;//char
17-
*vga_buffer.offset(i as isize *2+1) = 0xb;//color
18-
}
19-
}
16+
println!("hello number {}",3);
17+
2018
loop{}
2119
}
2220

src/vga_buffer.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
2+
use volatile::Volatile;
3+
use core::fmt;
4+
use spin::Mutex;
5+
use lazy_static::lazy_static;
6+
const BUFFER_WIDTH:usize = 80;
7+
const BUFFER_HEIGHT:usize = 25;
8+
const VGA_BUFFER_ADDR:u64 = 0xb8000;
9+
#[derive(Debug,Clone,Copy,PartialEq,Eq)]
10+
#[repr(u8)]
11+
12+
pub enum Color{
13+
Black = 0,
14+
Blue=1,
15+
Green=2,
16+
Cyan=3,
17+
Red=4,
18+
Magenta=5,
19+
Brown=6,
20+
LightGray=7,
21+
DarkGray=8,
22+
LightBlue=9,
23+
LightGreen=10,
24+
LightCyan=11,
25+
LightRed=12,
26+
Pink=13,
27+
Yellow=14,
28+
White=15,
29+
}
30+
31+
#[derive(Debug,Clone,Copy,PartialEq,Eq)]
32+
#[repr(transparent)]
33+
struct ColorCode(u8);
34+
impl ColorCode{
35+
pub fn new(foreground:Color, background : Color)-> ColorCode{
36+
ColorCode((foreground as u8) | (background as u8) <<4)
37+
}
38+
}
39+
40+
41+
42+
#[derive(Debug,Clone,Copy,PartialEq,Eq)]
43+
#[repr(C)]
44+
struct ScreenChar{
45+
ascii_character:u8,
46+
color_code:ColorCode,
47+
}
48+
49+
#[repr(transparent)]
50+
struct Buffer{
51+
chars:[[Volatile<ScreenChar>;BUFFER_WIDTH];BUFFER_HEIGHT],
52+
}
53+
54+
pub struct Writer {
55+
column_position:usize,
56+
color_code:ColorCode,
57+
buffer: &'static mut Buffer,
58+
}
59+
impl Writer{
60+
fn write_byte(&mut self,byte:u8){
61+
match byte{
62+
b'\n'=>{self.new_line()}
63+
byte=>{
64+
if(self.column_position >=BUFFER_WIDTH){
65+
self.new_line();
66+
}
67+
let row=BUFFER_HEIGHT-1;
68+
let col = self.column_position;
69+
self.buffer.chars[row][col].write(ScreenChar{
70+
ascii_character:byte,
71+
color_code:self.color_code,
72+
});
73+
self.column_position+=1;
74+
}
75+
}
76+
}
77+
fn write_string(&mut self,string:&str){
78+
for byte in string.bytes(){
79+
match byte{
80+
0x20..=0x7e | b'\n'=> self.write_byte(byte),
81+
_=>self.write_byte(0xfe)//blank square
82+
}
83+
}
84+
}
85+
fn new_line(&mut self){
86+
for row in 1..BUFFER_HEIGHT{
87+
for col in 0..BUFFER_WIDTH{
88+
let char = self.buffer.chars[row][col].read();
89+
self.buffer.chars[row-1][col].write(char);
90+
}
91+
}
92+
self.clear_row(BUFFER_HEIGHT-1);
93+
self.column_position = 0;
94+
}
95+
fn clear_row(&mut self,row: usize){
96+
let blank = ScreenChar{
97+
ascii_character:b' ',
98+
color_code:self.color_code
99+
};
100+
for col in 0..BUFFER_WIDTH{
101+
self.buffer.chars[row][col].write(blank);
102+
}
103+
}
104+
}
105+
106+
impl fmt::Write for Writer{
107+
fn write_str(&mut self, s: &str) -> fmt::Result {
108+
self.write_string(s);
109+
Ok(())
110+
}
111+
}
112+
113+
lazy_static! {
114+
pub static ref WRITER:Mutex<Writer> = Mutex::new(Writer{
115+
column_position:0,
116+
color_code:ColorCode::new(Color::LightCyan,Color::Black),
117+
buffer:unsafe{&mut *(0xb8000 as *mut Buffer)}
118+
});
119+
}

0 commit comments

Comments
 (0)