aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarvin Borner2019-09-15 22:00:40 +0200
committerMarvin Borner2019-09-15 22:00:40 +0200
commitee0d964302299633fd1f3dd99f61119ae5bedaaa (patch)
treeb1c7783608b8bfaaa895b8c7638896b7c42ce2e6 /src
parent9e802f11a673c63d3fac395f151c80d6cfc4caf4 (diff)
Added terminal scrolling and moving cursor
Diffstat (limited to 'src')
-rw-r--r--src/graphics/vga.c77
1 files changed, 49 insertions, 28 deletions
diff --git a/src/graphics/vga.c b/src/graphics/vga.c
index 7efa014..22e1255 100644
--- a/src/graphics/vga.c
+++ b/src/graphics/vga.c
@@ -1,6 +1,6 @@
#include <stddef.h>
#include <stdint.h>
-#include <stdbool.h>
+#include "../io/io.h"
// Hardware text mode color constants
enum vga_color {
@@ -45,11 +45,7 @@ size_t terminal_column;
uint8_t terminal_color;
uint16_t *terminal_buffer;
-void terminal_initialize(void) {
- terminal_row = 0;
- terminal_column = 0;
- terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
- terminal_buffer = (uint16_t *) 0xB8000;
+void terminal_clear() {
for (size_t y = 0; y < VGA_HEIGHT; y++) {
for (size_t x = 0; x < VGA_WIDTH; x++) {
const size_t index = y * VGA_WIDTH + x;
@@ -58,6 +54,34 @@ void terminal_initialize(void) {
}
}
+void terminal_initialize(void) {
+ terminal_row = 0;
+ terminal_column = 0;
+ terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK);
+ terminal_buffer = (uint16_t *) 0xB8000;
+ terminal_clear();
+}
+
+void terminal_scroll(void) {
+ 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);
+ }
+ }
+}
+
+void terminal_update_cursor(void) {
+ unsigned temp = terminal_row * VGA_WIDTH + terminal_column;
+ send(0x3D4, 14);
+ send(0x3D5, temp >> 8);
+ send(0x3D4, 15);
+ send(0x3D5, temp);
+}
+
void terminal_set_color(uint8_t color) {
terminal_color = color;
}
@@ -67,35 +91,32 @@ 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) {
- bool new_line = c == '\n' || c == '\r';
-
- if (new_line) {
- terminal_row += 1;
+ if (c == 0x08) {
+ if (terminal_column != 0) terminal_column--;
+ } else if (c == 0x09) {
+ terminal_column = (terminal_column + 8) & ~(8 - 1);
+ } else if (c == '\r') {
terminal_column = 0;
- } else {
+ } else if (c == '\n') {
+ terminal_column = 0;
+ terminal_row++;
+ terminal_scroll();
+ terminal_put_entry_at('$', terminal_color, terminal_column, terminal_row);
+ terminal_column = 2;
+ } else if (c >= ' ') { // Any printable character
terminal_put_entry_at(c, terminal_color, terminal_column, terminal_row);
+ terminal_column++;
}
- // Scroll content up
- if (++terminal_column >= VGA_WIDTH || new_line) {
+ // Add new line on overflow
+ if (terminal_column >= VGA_WIDTH) {
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);
- }
- }
+ terminal_row++;
}
+
+ terminal_scroll();
+ terminal_update_cursor();
}
void terminal_write(const char *data, size_t size) {