From d835cae0968ea5d6e9989dac637449b8d403ac5e Mon Sep 17 00:00:00 2001
From: Joursoir <chat@joursoir.net>
Date: Mon, 30 Aug 2021 12:48:24 +0000
Subject: move interaction with VGA to driver

---
 drivers/video/console/vgacon.c | 101 +++++++++++++++++++++++++++++++++++++++++
 drivers/video/console/vgacon.h |  15 ++++++
 kernel/video-vga.c             |  98 ---------------------------------------
 kernel/video-vga.h             |  36 ---------------
 4 files changed, 116 insertions(+), 134 deletions(-)
 create mode 100644 drivers/video/console/vgacon.c
 create mode 100644 drivers/video/console/vgacon.h
 delete mode 100644 kernel/video-vga.c
 delete mode 100644 kernel/video-vga.h

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 */
-- 
cgit v1.2.3-18-g5258