summaryrefslogtreecommitdiff
path: root/kernel/framebuffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/framebuffer.c')
-rw-r--r--kernel/framebuffer.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/kernel/framebuffer.c b/kernel/framebuffer.c
new file mode 100644
index 0000000..220d556
--- /dev/null
+++ b/kernel/framebuffer.c
@@ -0,0 +1,74 @@
+#include "framebuffer.h"
+#include "kernel.h"
+#include "portio.h"
+
+uint16_t framebuffer_color = 0x0700;
+uint8_t framebuffer_x;
+uint8_t framebuffer_y;
+
+void framebuffer_init() {
+ union {uint8_t b[2]; uint16_t w;} pos;
+
+ outb(0x3d4, 0x0f);
+ inb(0x3d5, pos.b[0]);
+
+ outb(0x3d4, 0x0e);
+ inb(0x3d5, pos.b[1]);
+
+ framebuffer_x = pos.w % 80;
+ framebuffer_y = pos.w / 80;
+}
+
+void framebuffer_putchar(char c) {
+ switch(c) {
+ case '\f':
+ framebuffer_clear();
+ break;
+ case '\r':
+ framebuffer_x = 0;
+ break;
+ case '\n':
+ framebuffer_x = 80;
+ break;
+ default:
+ framebuffer[framebuffer_y][framebuffer_x++] = framebuffer_color | c;
+ }
+ if(framebuffer_x == 80) {
+ framebuffer_x = 0;
+ if(framebuffer_y < 24) {
+ framebuffer_y++;
+ } else {
+ framebuffer_scroll();
+ }
+ }
+}
+
+void framebuffer_clear() {
+ for(int y = 0; y < 25; y++) {
+ for(int x = 0; x < 80; x++) {
+ framebuffer[y][x] = framebuffer_color;
+ }
+ }
+ framebuffer_x = framebuffer_y = 0;
+}
+
+void framebuffer_scroll() {
+ for(int y = 0; y < 24; y++) {
+ for(int x = 0; x < 80; x++) {
+ framebuffer[y][x] = framebuffer[y + 1][x];
+ }
+ }
+ for(int x = 0; x < 80; x++) {
+ framebuffer[24][x] = framebuffer_color;
+ }
+}
+
+void framebuffer_move_cursor() {
+ uint16_t pos = framebuffer_y * 80 + framebuffer_x;
+
+ outb(0x3d4, 0x0f);
+ outb(0x3d5, pos & 0xff);
+
+ outb(0x3d4, 0x0e);
+ outb(0x3d5, pos >> 8);
+}