From da84fd0b91fce827d24e3dc27739dbf80c4b2072 Mon Sep 17 00:00:00 2001
From: Sascha Wildner <saw@online.de>
Date: Tue, 8 Jul 2014 23:59:51 +0200
Subject: [PATCH] WIP vga

---
 sys/dev/video/fb/vga.c    | 48 ++++++++++++++---------------------------------
 sys/dev/video/fb/vgareg.h | 41 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 34 deletions(-)

diff --git a/sys/dev/video/fb/vga.c b/sys/dev/video/fb/vga.c
index a0e5035..ce41eda 100644
--- a/sys/dev/video/fb/vga.c
+++ b/sys/dev/video/fb/vga.c
@@ -43,8 +43,6 @@
 #include <sys/fbio.h>
 #include <sys/thread2.h>
 
-#include <bus/isa/isareg.h>
-
 #include <machine/clock.h>
 #include <machine/md_var.h>
 #ifdef __i386__
@@ -651,10 +649,8 @@ probe_adapters(void)
      * memory.
      * This must be done before vga_save_state() for VGA.
      */
-    outb(CRTC, 12);
-    outb(CRTC + 1, 0);
-    outb(CRTC, 13);
-    outb(CRTC + 1, 0);
+    vga_crtc_reg_set(START_ADDRESS_HIGH, 0);
+    vga_crtc_reg_set(START_ADDRESS_LOW, 0);
 
     /* the video mode parameter table in VGA BIOS */
     /* NOTE: there can be only one VGA recognized by the video BIOS.
@@ -755,8 +751,7 @@ set_line_length(video_adapter_t *adp, int pixel)
 
     if (mp[10 + 0x17] & 0x40)			/* CRTC mode control reg */
 	count *= 2;				/* byte mode */
-    outb(CRTC, 0x13);
-    outb(CRTC + 1, count);
+    vga_crtc_reg_set(OFFSET, count);
     adp->va_line_width = bpl;
 
     return 0;
@@ -790,11 +785,8 @@ set_display_start(video_adapter_t *adp, int x, int y)
 	    poff = (x + 8)%ppb;
     }
 
-    /* start address */
-    outb(CRTC, 0xc);		/* high */
-    outb(CRTC + 1, off >> 8);
-    outb(CRTC, 0xd);		/* low */
-    outb(CRTC + 1, off & 0xff);
+    vga_crtc_reg_set(START_ADDRESS_HIGH, off >> 8);
+    vga_crtc_reg_set(START_ADDRESS_LOW, off & 0xff);
 
     /* horizontal pel pan */
     inb(CRTC + 6);
@@ -803,9 +795,7 @@ set_display_start(video_adapter_t *adp, int x, int y)
     inb(CRTC + 6);
     outb(ATC, 0x20);
 
-    /* preset row scan */
-    outb(CRTC, 8);
-    outb(CRTC + 1, roff);
+    vga_crtc_reg_set(PRESET_ROW_SCAN, roff);
 
     adp->va_disp_start.x = x;
     adp->va_disp_start.y = y;
@@ -1638,10 +1628,8 @@ vga_set_hw_cursor(video_adapter_t *adp, int col, int row)
     }
 
     crit_enter();
-    outb(CRTC, 14);
-    outb(CRTC + 1, off >> 8);
-    outb(CRTC, 15);
-    outb(CRTC + 1, off & 0x00ff);
+    vga_crtc_reg_set(CURSOR_LOCATION_HIGH, off >> 8);
+    vga_crtc_reg_set(CURSOR_LOCATION_LOW, off & 0xff);
     crit_exit();
 
     return 0;
@@ -1662,15 +1650,11 @@ vga_set_hw_cursor_shape(video_adapter_t *adp, int base, int height,
     crit_enter();
     if (height <= 0) {
 	/* make the cursor invisible */
-	outb(CRTC, 10);
-	outb(CRTC + 1, 32);
-	outb(CRTC, 11);
-	outb(CRTC + 1, 0);
+	vga_crtc_reg_set(CURSOR_START, 32);
+	vga_crtc_reg_set(CURSOR_END, 0);
     } else {
-	outb(CRTC, 10);
-	outb(CRTC + 1, celsize - base - height);
-	outb(CRTC, 11);
-	outb(CRTC + 1, celsize - base - 1);
+	vga_crtc_reg_set(CURSOR_START, celsize - base - height);
+	vga_crtc_reg_set(CURSOR_END, celsize - base - 1);
     }
     crit_exit();
 
@@ -1694,9 +1678,7 @@ vga_blank_display(video_adapter_t *adp, int mode)
 	val = inb(TSREG);
 	outb(TSIDX, 0x01);
 	outb(TSREG, val | 0x20);
-	outb(CRTC, 0x17);
-	val = inb(CRTC + 1);
-	outb(CRTC + 1, val & ~0x80);
+	vga_crtc_reg_and(CRT_MODE_CONTROL, 0x7f);
 	break;
     case V_DISPLAY_OFF:
 	outb(TSIDX, 0x01);
@@ -1709,9 +1691,7 @@ vga_blank_display(video_adapter_t *adp, int mode)
 	val = inb(TSREG);
 	outb(TSIDX, 0x01);
 	outb(TSREG, val & 0xDF);
-	outb(CRTC, 0x17);
-	val = inb(CRTC + 1);
-	outb(CRTC + 1, val | 0x80);
+	vga_crtc_reg_or(CRT_MODE_CONTROL, 0x80);
 	break;
     }
     crit_exit();
diff --git a/sys/dev/video/fb/vgareg.h b/sys/dev/video/fb/vgareg.h
index 6f4a0ca..f0a0438 100644
--- a/sys/dev/video/fb/vgareg.h
+++ b/sys/dev/video/fb/vgareg.h
@@ -30,6 +30,8 @@
 #ifndef _DEV_FB_VGAREG_H_
 #define _DEV_FB_VGAREG_H_
 
+#include <bus/isa/isareg.h>
+
 /* physical addresses */
 #define MDA_BUF_BASE		0xb0000
 #define MDA_BUF_SIZE		0x08000
@@ -60,6 +62,45 @@
 #define GDCIDX		(IO_VGA + 0x0E)		/* graph data controller idx */
 #define GDCREG		(IO_VGA + 0x0F)		/* graph data controller data */
 
+enum vga_crtc_register {		/*  7 | 6 | 5 | 4 | 3 | 2 | 1 | 0   */
+	PRESET_ROW_SCAN		= 0x08, /*  - | BP|          SRS            */
+	CURSOR_START		= 0x0a, /*  - | - | CO|        RSCB         */
+	CURSOR_END		= 0x0b, /*  - |  CSK  |        RSCE         */
+	START_ADDRESS_HIGH	= 0x0c, /*        Start Address High        */
+	START_ADDRESS_LOW	= 0x0d, /*        Start Address Low         */
+	CURSOR_LOCATION_HIGH	= 0x0e, /*      Cursor Location High        */
+	CURSOR_LOCATION_LOW	= 0x0f, /*      Cursor Location Low         */
+	OFFSET			= 0x13, /*             Offset               */
+	CRT_MODE_CONTROL	= 0x17	/* RST| WB|ADW| - |CB2|HRS|SRC|CMS0 */
+};
+
+static inline void
+vga_crtc_reg_set(enum vga_crtc_register reg, uint8_t val)
+{
+	outb(CRTC, reg);
+	outb(CRTC + 1, val);
+}
+
+static inline void
+vga_crtc_reg_and(enum vga_crtc_register reg, uint8_t val)
+{
+	uint8_t oldval;
+
+	outb(CRTC, reg);
+	oldval = inb(CRTC + 1);
+	outb(CRTC + 1, oldval & val);
+}
+
+static inline void
+vga_crtc_reg_or(enum vga_crtc_register reg, uint8_t val)
+{
+	uint8_t oldval;
+
+	outb(CRTC, reg);
+	oldval = inb(CRTC + 1);
+	outb(CRTC + 1, oldval | val);
+}
+
 #define VGA_DRIVER_NAME		"vga"
 #define VGA_UNIT(dev)		minor(dev)
 #define VGA_MKMINOR(unit)	(unit & 0xff)
-- 
1.9.3

