aboutsummaryrefslogtreecommitdiff
path: root/src/graphics/vga.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/graphics/vga.c')
-rw-r--r--src/graphics/vga.c28
1 files changed, 23 insertions, 5 deletions
diff --git a/src/graphics/vga.c b/src/graphics/vga.c
index 54527e1..7efa014 100644
--- a/src/graphics/vga.c
+++ b/src/graphics/vga.c
@@ -1,5 +1,6 @@
#include <stddef.h>
#include <stdint.h>
+#include <stdbool.h>
// Hardware text mode color constants
enum vga_color {
@@ -66,16 +67,33 @@ void terminal_put_entry_at(char c, uint8_t color, size_t x, size_t y) {
terminal_buffer[index] = vga_entry(c, color);
}
+void terminal_clear() {
+ for (size_t x = 0; x < VGA_WIDTH; x++)
+ for (size_t y = 0; y < VGA_HEIGHT; y++)
+ terminal_put_entry_at(' ', terminal_color, x, y);
+}
+
void terminal_put_char(char c) {
- if (c == '\n' || c == '\r') {
+ bool new_line = c == '\n' || c == '\r';
+
+ if (new_line) {
terminal_row += 1;
terminal_column = 0;
} else {
terminal_put_entry_at(c, terminal_color, terminal_column, terminal_row);
- if (++terminal_column == VGA_WIDTH) {
- terminal_column = 0;
- if (++terminal_row == VGA_HEIGHT)
- terminal_row = 0;
+ }
+
+ // Scroll content up
+ if (++terminal_column >= VGA_WIDTH || new_line) {
+ terminal_column = 0;
+ if (++terminal_row >= VGA_HEIGHT) {
+ terminal_row = VGA_HEIGHT - 1;
+ for (size_t x = 0; x < VGA_WIDTH; x++)
+ for (size_t y = 0; y < VGA_HEIGHT; y++) {
+ uint16_t c = terminal_buffer[y * VGA_WIDTH + x];
+ terminal_buffer[(y - 1) * VGA_WIDTH + x] = c;
+ terminal_buffer[y * VGA_WIDTH + x] = vga_entry(' ', terminal_color);
+ }
}
}
}