diff options
author | Joursoir <chat@joursoir.net> | 2021-08-30 12:48:24 +0000 |
---|---|---|
committer | Joursoir <chat@joursoir.net> | 2021-08-30 12:48:24 +0000 |
commit | d835cae0968ea5d6e9989dac637449b8d403ac5e (patch) | |
tree | 4d9e9cbea5ac763207e6c5c17a3ad55638b2f13e | |
parent | 347bc7de0dc25891f1ad0356fbd95ce54843a8f2 (diff) | |
download | mfsos-d835cae0968ea5d6e9989dac637449b8d403ac5e.tar.gz mfsos-d835cae0968ea5d6e9989dac637449b8d403ac5e.tar.bz2 mfsos-d835cae0968ea5d6e9989dac637449b8d403ac5e.zip |
move interaction with VGA to driver
-rw-r--r-- | drivers/video/console/vgacon.c | 101 | ||||
-rw-r--r-- | drivers/video/console/vgacon.h | 15 | ||||
-rw-r--r-- | kernel/video-vga.c | 98 | ||||
-rw-r--r-- | kernel/video-vga.h | 36 |
4 files changed, 116 insertions, 134 deletions
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c new file mode 100644 index 0000000..cad384a --- /dev/null +++ b/drivers/video/console/vgacon.c @@ -0,0 +1,101 @@ +/* + Low level VGA based console driver +*/ + +#include "string.h" +#include "video/vga.h" +#include "asm/io.h" + +#define LIGHT_GREY_ON_BLACK \ + VGA_ENTRY_COLOR(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK) + +static uint16_t *vga_vram_base; +static size_t vga_vram_size; +static size_t vga_cols; +static size_t vga_rows; +static uint8_t vga_attr; + +static size_t cursor_x; +static size_t cursor_y; + +void vgacon_init(void) +{ + vga_vram_base = (uint16_t *) VGA_VRAM_BC; + vga_cols = 80; + vga_rows = 25; + vga_vram_size = vga_cols * vga_rows; + vga_attr = LIGHT_GREY_ON_BLACK; + + cursor_x = 0; + cursor_y = 0; +} + +void vgacon_setattr(uint8_t attr) +{ + vga_attr = attr; +} + +void vgacon_scroll(size_t lines) +{ + uint16_t vga_char = VGA_ENTRY(' ', vga_attr); + size_t count = (vga_rows - lines) * vga_cols; + memmove(vga_vram_base, vga_vram_base + vga_cols * lines, count * 2); + for(; count < vga_vram_size; count++) + vga_vram_base[count] = vga_char; +} + +void vgacon_cls(void) +{ + vgacon_scroll(vga_rows); +} + +static void putchar(char c) +{ + if(c == '\n') { + cursor_x = 0; + if(++cursor_y >= vga_rows) { + vgacon_scroll(1); + cursor_y--; + } + } + else { + const size_t index = cursor_y * vga_cols + cursor_x; + vga_vram_base[index] = VGA_ENTRY(c, vga_attr); + + if(++cursor_x >= vga_cols) { + cursor_x = 0; + if(++cursor_y >= vga_rows) { + vgacon_scroll(1); + cursor_y--; + } + } + } +} + +static void update_cursor() +{ + uint16_t pos = cursor_y * vga_cols + cursor_x; + outb(VGA_CRTC_IC, VGA_CRTC_CURSOR_H); + outb(VGA_CRTC_DC, (uint8_t) ((pos >> 8) & 0xFF)); + outb(VGA_CRTC_IC, VGA_CRTC_CURSOR_L); + outb(VGA_CRTC_DC, (uint8_t) (pos & 0xFF)); +} + +void vgacon_putchar(char c) +{ + putchar(c); + update_cursor(); +} + +void vgacon_write(const char *str, size_t size) +{ + size_t i; + for(i = 0; i < size; i++) + putchar(str[i]); + update_cursor(); +} + +void vgacon_print(const char *str) +{ + vgacon_write(str, strlen(str)); +} diff --git a/drivers/video/console/vgacon.h b/drivers/video/console/vgacon.h new file mode 100644 index 0000000..ac2e9e3 --- /dev/null +++ b/drivers/video/console/vgacon.h @@ -0,0 +1,15 @@ +#ifndef DRIVERS_VIDEO_CONSOLE_VGA_H +#define DRIVERS_VIDEO_CONSOLE_VGA_H + +#include <stddef.h> +#include <stdint.h> + +void vgacon_init(void); +void vgacon_setattr(uint8_t attr); +void vgacon_scroll(size_t lines); +void vgacon_cls(void); +void vgacon_putchar(char c); +void vgacon_write(const char *str, size_t size); +void vgacon_print(const char *str); + +#endif /* DRIVERS_VIDEO_CONSOLE_VGA_H */ diff --git a/kernel/video-vga.c b/kernel/video-vga.c deleted file mode 100644 index 4a7a14c..0000000 --- a/kernel/video-vga.c +++ /dev/null @@ -1,98 +0,0 @@ -#include "video-vga.h" -#include "string.h" -#include "i386.h" - -#define VGA_BASE 0xB8000 -#define CRTC_PORT 0x3D4 - -#define VGA_WIDTH 80 -#define VGA_HEIGHT 25 - -static size_t vga_row, vga_column; -static uint8_t vga_color; -static uint16_t *vga_buffer; - -uint8_t vga_entry_color(enum vga_colors fg, enum vga_colors bg) -{ - return fg | bg << 4; -} - -uint16_t vga_entry(uint8_t uc, uint8_t color) -{ - return (uint16_t) uc | (uint16_t) color << 8; -} - -void vga_init(void) -{ - size_t x, y; - size_t vga_char; - vga_row = 0, vga_column = 0; - vga_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); - vga_char = vga_entry(' ', vga_color); - vga_buffer = (uint16_t *) VGA_BASE; - for(y = 0; y < VGA_HEIGHT; y++) { - for(x = 0; x < VGA_WIDTH; x++) { - const size_t index = y * VGA_WIDTH + x; - vga_buffer[index] = vga_char; - } - } -} - -void vga_setcolor(uint8_t color) -{ - vga_color = color; -} - -void vga_scroll(size_t lines) -{ - size_t count = (VGA_HEIGHT - lines) * VGA_WIDTH; - size_t vga_char = vga_entry(' ', vga_color); - - memmove(vga_buffer, vga_buffer + VGA_WIDTH * lines, count * 2); - for(; count < (vga_row + 1) * VGA_WIDTH; count++) - vga_buffer[count] = vga_char; -} - -void vga_putchar(char c) -{ - uint16_t pos; - if(c == '\n') { - vga_column = 0; - if(++vga_row >= VGA_HEIGHT) { - vga_scroll(1); - vga_row--; - } - } - else { - const size_t index = vga_row * VGA_WIDTH + vga_column; - vga_buffer[index] = vga_entry(c, vga_color); - - if(++vga_column >= VGA_WIDTH) { - vga_column = 0; - if(++vga_row >= VGA_HEIGHT) { - vga_scroll(1); - vga_row--; - } - } - } - - /* Update cursor position */ - pos = vga_row * VGA_WIDTH + vga_column; - outb(CRTC_PORT, 0x0E); - outb(CRTC_PORT+1, (uint8_t) ((pos >> 8) & 0xFF)); - outb(CRTC_PORT, 0x0F); - outb(CRTC_PORT+1, (uint8_t) (pos & 0xFF)); -} - - -void vga_write(const char *str, size_t size) -{ - size_t i; - for(i = 0; i < size; i++) - vga_putchar(str[i]); -} - -void vga_print(const char *str) -{ - vga_write(str, strlen(str)); -} diff --git a/kernel/video-vga.h b/kernel/video-vga.h deleted file mode 100644 index ddcfc31..0000000 --- a/kernel/video-vga.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef KERNEL_VIDEO_VGA -#define KERNEL_VIDEO_VGA - -#include <stddef.h> -#include <stdint.h> - -/* Hardware text mode color constants. */ -enum vga_colors { - VGA_COLOR_BLACK = 0, - VGA_COLOR_BLUE = 1, - VGA_COLOR_GREEN = 2, - VGA_COLOR_CYAN = 3, - VGA_COLOR_RED = 4, - VGA_COLOR_MAGENTA = 5, - VGA_COLOR_BROWN = 6, - VGA_COLOR_LIGHT_GREY = 7, - VGA_COLOR_DARK_GREY = 8, - VGA_COLOR_LIGHT_BLUE = 9, - VGA_COLOR_LIGHT_GREEN = 10, - VGA_COLOR_LIGHT_CYAN = 11, - VGA_COLOR_LIGHT_RED = 12, - VGA_COLOR_LIGHT_MAGENTA = 13, - VGA_COLOR_LIGHT_BROWN = 14, - VGA_COLOR_WHITE = 15 -}; - -uint8_t vga_entry_color(enum vga_colors fg, enum vga_colors bg); -uint16_t vga_entry(uint8_t uc, uint8_t color); -void vga_init(void); -void vga_setcolor(uint8_t color); -void vga_scroll(size_t lines); -void vga_putchar(char c); -void vga_write(const char *str, size_t size); -void vga_print(const char *str); - -#endif /* KERNEL_VIDEO_VGA */ |