summaryrefslogtreecommitdiff
path: root/src/kernel/vga.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/vga.c')
-rw-r--r--src/kernel/vga.c71
1 files changed, 71 insertions, 0 deletions
diff --git a/src/kernel/vga.c b/src/kernel/vga.c
new file mode 100644
index 0000000..046dda7
--- /dev/null
+++ b/src/kernel/vga.c
@@ -0,0 +1,71 @@
+/*
+Copyright 2019 Benji Dial
+
+Permission to use, copy, modify, and/or distribute this
+software for any purpose with or without fee is hereby
+granted, provided that the above copyright notice and this
+permission notice appear in all copies.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS
+ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
+EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
+ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+OF THIS SOFTWARE.
+*/
+
+#include "vga.h"
+
+uint16_t cursor_pos = 0;
+uint8_t color = 0xf0;
+#define cols 80
+#define rows 25
+
+void scroll(void) {
+ cursor_pos -= cols * 2;
+ uint32_t *limit = (uint32_t *)(VGA_BUFFER + cols * (rows - 1));
+ for (uint32_t *i = (uint32_t *)VGA_BUFFER; i < limit; ++i)
+ *i = *(i + cols / 2);
+ limit += cols / 2;
+ uint32_t fill = (color * 0x0100 + (uint8_t)' ') * 0x00010001;
+ for (uint32_t *i = limit - cols / 2; i < limit; ++i)
+ *i = fill;
+}
+
+void put_char(uint8_t ch) {
+ switch (ch) {
+ case '\b':
+ if (cursor_pos)
+ VGA_BUFFER[cursor_pos -= 2] = (uint8_t)' ';
+ break;
+ case '\t':
+ while ((cursor_pos % (cols * 2)) % 20)
+ put_char(' ');
+ break;
+ case '\n':
+ if ((cursor_pos = (cursor_pos / (cols * 2) + 1) * (cols * 2)) >= cols * rows * 2)
+ scroll();
+ break;
+ default:
+ VGA_BUFFER[cursor_pos++] = ch;
+ VGA_BUFFER[cursor_pos++] = color;
+ if (cursor_pos == (cols * rows * 2))
+ scroll();
+ }
+}
+
+void put_sz(uint8_t *sz) {
+ while (*sz)
+ put_char(*(sz++));
+}
+
+void move_cursor(uint8_t col, uint8_t row) {
+ cursor_pos = (col + row * cols) * 2;
+}
+
+void set_color(uint8_t c) {
+ color = c;
+}