summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClément Sibille <claymeuns@protonmail.com>2021-10-05 21:03:09 +0200
committerClément Sibille <claymeuns@protonmail.com>2021-10-05 21:03:09 +0200
commit58a7b22c3ec60380f6efdfd1493b8823fe0c17bc (patch)
tree0e3103415574ad6e7336e00e8d43d7d41a0a7fe8
parenta16a4dc9ed895c3a2934c2e14e1ab515f4899971 (diff)
Add terminal scrolling
This closes #2.
-rw-r--r--Makefile4
-rw-r--r--kernel/Cargo.toml2
-rw-r--r--kernel/src/io.rs12
-rw-r--r--kernel/src/lib.rs28
-rw-r--r--kernel/src/terminal.rs58
5 files changed, 81 insertions, 23 deletions
diff --git a/Makefile b/Makefile
index cb64d5e..f248f46 100644
--- a/Makefile
+++ b/Makefile
@@ -13,9 +13,9 @@ target/kernel.o: target/boot.o target/i686-lisibleos/release/libkernel.a
target/i686-lisibleos/release/libkernel.a:
mkdir -p target
- xargo build -p kernel --target i686-lisibleos --release
+ RUST_TARGET_PATH=$(shell pwd) xargo build -p kernel --target i686-lisibleos --release
clean:
- xargo clean --target i686-lisibleos
+ RUST_TARGET_PATH=$(shell pwd) xargo clean --target i686-lisibleos
rm target/kernel.o target/boot.o target/i686-lisibleos/debug/libkernel.a
rm target/kernel.o target/boot.o target/i686-lisibleos/release/libkernel.a
diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml
index 1ca49e6..e5b9b67 100644
--- a/kernel/Cargo.toml
+++ b/kernel/Cargo.toml
@@ -10,3 +10,5 @@ edition = "2018"
[lib]
crate-type = ["staticlib"]
+[dependencies]
+compiler_builtins = { version = "0.1.50", features = ["mem"] }
diff --git a/kernel/src/io.rs b/kernel/src/io.rs
index b6b4cc7..def8665 100644
--- a/kernel/src/io.rs
+++ b/kernel/src/io.rs
@@ -1,7 +1,5 @@
-pub fn out8(address: u16, value: u8) {
- unsafe {
- asm!(
- "out dx, al", in("dx") address, in("al") value
- )
- }
-} \ No newline at end of file
+pub unsafe fn out8(address: u16, value: u8) {
+ asm!(
+ "out dx, al", in("dx") address, in("al") value
+ )
+}
diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs
index b6bc55f..edb5704 100644
--- a/kernel/src/lib.rs
+++ b/kernel/src/lib.rs
@@ -12,8 +12,32 @@ mod terminal;
pub extern "C" fn kmain() -> ! {
let mut terminal = Terminal::new();
terminal.clear();
- terminal.put_string(b"LisibleOS\n");
- terminal.put_string(b"> ");
+ terminal.put_string(b"1 LisibleOS\n");
+ terminal.put_string(b"2 > \n");
+ terminal.put_string(b"3\n");
+ terminal.put_string(b"4\n");
+ terminal.put_string(b"5\n");
+ terminal.put_string(b"6\n");
+ terminal.put_string(b"7\n");
+ terminal.put_string(b"8\n");
+ terminal.put_string(b"9\n");
+ terminal.put_string(b"10\n");
+ terminal.put_string(b"11\n");
+ terminal.put_string(b"12\n");
+ terminal.put_string(b"13\n");
+ terminal.put_string(b"14\n");
+ terminal.put_string(b"15\n");
+ terminal.put_string(b"16\n");
+ terminal.put_string(b"17\n");
+ terminal.put_string(b"18\n");
+ terminal.put_string(b"19\n");
+ terminal.put_string(b"20\n");
+ terminal.put_string(b"21\n");
+ terminal.put_string(b"22\n");
+ terminal.put_string(b"23\n");
+ terminal.put_string(b"24\n");
+ terminal.put_string(b"25\n");
+ terminal.put_string(b"26");
loop {}
}
diff --git a/kernel/src/terminal.rs b/kernel/src/terminal.rs
index 2a5cf1a..9e3eec1 100644
--- a/kernel/src/terminal.rs
+++ b/kernel/src/terminal.rs
@@ -1,4 +1,5 @@
use crate::io;
+use compiler_builtins::mem::memcpy;
const VGA_BUFFER_POINTER: *mut u8 = 0xb8000 as *mut u8;
const VGA_BUFFER_SIZE: u16 = 4000;
@@ -28,15 +29,17 @@ impl Terminal {
pub fn put_char(&mut self, c: u8) {
if c == b'\n' {
- self.current_row += 1;
- if self.current_row == ROW_COUNT {
- self.current_row = 0;
+ if self.current_row < ROW_COUNT - 1 {
+ self.current_row += 1;
+ } else {
+ self.scroll_y(-1);
}
self.current_col = 0;
return;
}
+ /// Safety: This is safe because VGA_BUFFER_POINTER points toward the VGA character buffer
unsafe {
*VGA_BUFFER_POINTER.offset(
((self.current_col as isize + self.current_row as isize * COL_COUNT as isize)
@@ -48,32 +51,63 @@ impl Terminal {
fn compute_current_position(&mut self) {
if self.current_col == COL_COUNT - 1 {
- if self.current_row == ROW_COUNT - 1 {
- self.current_col = 0;
- self.current_row = 0;
- } else {
+ if self.current_row != ROW_COUNT - 1 {
self.current_row = (self.current_row + 1) % ROW_COUNT;
+ } else {
+ self.scroll_y(-1);
}
+ self.current_col = 0;
+ } else {
+ self.current_col = (self.current_col + 1) % COL_COUNT;
}
- self.current_col = (self.current_col + 1) % COL_COUNT;
+ }
+
+ fn scroll_y(&mut self, y: i8) {
+ // Safety:
+ // The starting pointer is in bound because it's the VGA character buffer pointer
+ // The end pointer isn't past the VGA character buffer pointer
+ // The offset doesn't overflow isize
+ // The offset doesn't rely on wrapping around the address space
+ let src = unsafe { VGA_BUFFER_POINTER.offset(COL_COUNT as isize * VALUE_SIZE as isize) };
+ let dest = VGA_BUFFER_POINTER;
+ let size = (VGA_BUFFER_SIZE as usize - COL_COUNT as usize) * VALUE_SIZE as usize;
+
+ // Safety:
+ // dest and src are valid pointer to the same object being the VGA character buffer
+ // This copy will not go past the VGA character buffer
+ unsafe { memcpy(dest, src, size) };
+
+ self.clear_line(ROW_COUNT - 1);
}
pub fn put_char_at(&mut self, c: u8, row: u8, col: u8) {
self.current_row = row;
self.current_col = col;
- self.put_char(c);
+ unsafe {
+ *VGA_BUFFER_POINTER.offset(
+ ((self.current_col as isize + self.current_row as isize * COL_COUNT as isize)
+ * VALUE_SIZE as isize),
+ ) = c;
+ }
}
pub fn clear(&mut self) {
for row in 0..ROW_COUNT {
- for col in 0..COL_COUNT {
- self.put_char_at(b' ', row, col);
- }
+ self.clear_line(row)
}
self.current_col = 0;
self.current_row = 0;
}
+ fn clear_line(&mut self, row: u8) {
+ for col in 0..COL_COUNT {
+ self.put_char_at(b' ', row, col);
+ }
+
+ self.current_row = row;
+ self.current_col = 0;
+ }
+
pub fn set_cursor_position(&mut self, row: u8, col: u8) {
let cursor_position: u16 = (row * COL_COUNT + col) as u16;
let address_register = 0x3D4;
Go back to lisible.xyz