summaryrefslogtreecommitdiffhomepage
path: root/src/loader/vga.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/loader/vga.c')
-rw-r--r--src/loader/vga.c64
1 files changed, 64 insertions, 0 deletions
diff --git a/src/loader/vga.c b/src/loader/vga.c
new file mode 100644
index 0000000..6cc9bfa
--- /dev/null
+++ b/src/loader/vga.c
@@ -0,0 +1,64 @@
+// MIT License, Copyright (c) 2021 Marvin Borner
+
+#include <log.h>
+
+#define VGA_WIDTH 80
+#define VGA_HEIGHT 25
+#define VGA_ADDRESS 0xb8000
+
+void vga_clear(void)
+{
+ u16 *out = (u16 *)VGA_ADDRESS;
+ for (u16 i = 0; i < 80 * 25; i++)
+ out[i] = 0;
+}
+
+void vga_put_at(char ch, u8 x, u8 y, u8 color)
+{
+ u8 *out = (u8 *)(VGA_ADDRESS + 2 * (x + y * VGA_WIDTH));
+ *out++ = ch;
+ *out++ = color;
+}
+
+static void vga_put(char ch)
+{
+ static u8 x = 0;
+ static u8 y = 0;
+
+ if (ch == '\n') {
+ x = 0;
+ y++;
+ return;
+ } else if (x + 1 == VGA_WIDTH) {
+ x = 0;
+ y++;
+ } else if (y + 1 == VGA_HEIGHT) {
+ x = 0;
+ y = 0;
+ vga_clear();
+ }
+
+ u8 *out = (u8 *)(VGA_ADDRESS + 2 * (x + y * VGA_WIDTH));
+ *out++ = ch;
+ *out++ = 0x07;
+
+ x++;
+}
+
+static void vga_print(const char *data)
+{
+ for (const char *p = data; *p; p++)
+ vga_put(*p);
+}
+
+void vga_log(const char *format, ...)
+{
+ char buf[1024] = { 0 };
+
+ va_list ap;
+ va_start(ap, format);
+ vsnprintf(buf, sizeof(buf), format, ap);
+ va_end(ap);
+
+ vga_print(buf);
+}