diff options
Diffstat (limited to 'kernel/framebuffer.c')
-rw-r--r-- | kernel/framebuffer.c | 74 |
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); +} |