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