--- /dev/null
+#include <string.h>
+#include "vga.h"
+#include "asmutil.h"
+
+#define CRTC_ADDR_PORT 0x3d4
+#define CRTC_DATA_PORT 0x3d5
+
+/* CRTC registers */
+#define CRTC_START_H 0x0c
+#define CRTC_START_L 0x0d
+#define CRTC_CURPOS_H 0x0e
+#define CRTC_CURPOS_L 0x0f
+
+static void crtc_write(int reg, unsigned char val);
+
+static uint16_t attr = 0x0700;
+static int yoffs;
+
+void vga_setcolor(int fg, int bg)
+{
+ attr = ((bg & 7) << 12) | ((fg & 0xf) << 8);
+}
+
+void vga_setcursor(int x, int y)
+{
+ int loc = (y + yoffs) * 80 + x;
+ crtc_write(CRTC_CURPOS_H, loc >> 8);
+ crtc_write(CRTC_CURPOS_L, loc);
+}
+
+void vga_setstart(int start)
+{
+ yoffs = start;
+ crtc_write(CRTC_START_H, start >> 8);
+ crtc_write(CRTC_START_L, start);
+}
+
+void vga_reset(void)
+{
+ vga_setcolor(VGA_WHITE, VGA_BLACK);
+ vga_setstart(0);
+ vga_setcursor(0, 0);
+ memset((void*)0xb8000, 0, 80 * 25 * 2);
+}
+
+void vga_drawchar(int x, int y, int c)
+{
+ uint16_t *ptr = (uint16_t*)0xb8000 + (y + yoffs) * 80 + x;
+ *ptr = (c & 0xff) | attr;
+}
+
+static void crtc_write(int reg, unsigned char val)
+{
+ outp(CRTC_ADDR_PORT, reg);
+ outp(CRTC_DATA_PORT, val);
+}