summaryrefslogtreecommitdiff
path: root/sys/src/9/pc/vgaark2000pv.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/9/pc/vgaark2000pv.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/9/pc/vgaark2000pv.c')
-rwxr-xr-xsys/src/9/pc/vgaark2000pv.c191
1 files changed, 191 insertions, 0 deletions
diff --git a/sys/src/9/pc/vgaark2000pv.c b/sys/src/9/pc/vgaark2000pv.c
new file mode 100755
index 000000000..542a7b3a2
--- /dev/null
+++ b/sys/src/9/pc/vgaark2000pv.c
@@ -0,0 +1,191 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+#include "../port/error.h"
+
+#define Image IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+
+static int
+ark2000pvpageset(VGAscr*, int page)
+{
+ uchar seq15;
+
+ seq15 = vgaxi(Seqx, 0x15);
+ vgaxo(Seqx, 0x15, page);
+ vgaxo(Seqx, 0x16, page);
+
+ return seq15;
+}
+
+static void
+ark2000pvpage(VGAscr* scr, int page)
+{
+ lock(&scr->devlock);
+ ark2000pvpageset(scr, page);
+ unlock(&scr->devlock);
+}
+
+static void
+ark2000pvdisable(VGAscr*)
+{
+ uchar seq20;
+
+ seq20 = vgaxi(Seqx, 0x20) & ~0x08;
+ vgaxo(Seqx, 0x20, seq20);
+}
+
+static void
+ark2000pvenable(VGAscr* scr)
+{
+ uchar seq20;
+ ulong storage;
+
+ /*
+ * Disable the cursor then configure for X-Windows style,
+ * 32x32 and 4/8-bit colour depth.
+ * Set cursor colours for 4/8-bit.
+ */
+ seq20 = vgaxi(Seqx, 0x20) & ~0x1F;
+ vgaxo(Seqx, 0x20, seq20);
+ seq20 |= 0x18;
+
+ vgaxo(Seqx, 0x26, 0x00);
+ vgaxo(Seqx, 0x27, 0x00);
+ vgaxo(Seqx, 0x28, 0x00);
+ vgaxo(Seqx, 0x29, 0xFF);
+ vgaxo(Seqx, 0x2A, 0xFF);
+ vgaxo(Seqx, 0x2B, 0xFF);
+
+ /*
+ * Cursor storage is a 256 byte or 1Kb block located in the last
+ * 16Kb of video memory. Crt25 is the index of which block.
+ */
+ storage = (vgaxi(Seqx, 0x10)>>6) & 0x03;
+ storage = (1024*1024)<<storage;
+ storage -= 256;
+ scr->storage = storage;
+ vgaxo(Seqx, 0x25, 0x3F);
+
+ /*
+ * Enable the cursor.
+ */
+ vgaxo(Seqx, 0x20, seq20);
+}
+
+static void
+ark2000pvload(VGAscr* scr, Cursor* curs)
+{
+ uchar *p, seq10;
+ int opage, x, y;
+
+ /*
+ * Is linear addressing turned on? This will determine
+ * how we access the cursor storage.
+ */
+ seq10 = vgaxi(Seqx, 0x10);
+ opage = 0;
+ p = scr->vaddr;
+ if(!(seq10 & 0x10)){
+ lock(&scr->devlock);
+ opage = ark2000pvpageset(scr, scr->storage>>16);
+ p += (scr->storage & 0xFFFF);
+ }
+ else
+ p += scr->storage;
+
+ /*
+ * The cursor is set in X11 mode which gives the following
+ * truth table:
+ * and xor colour
+ * 0 0 underlying pixel colour
+ * 0 1 underlying pixel colour
+ * 1 0 background colour
+ * 1 1 foreground colour
+ * Put the cursor into the top-left of the 32x32 array.
+ * The manual doesn't say what the data layout in memory is -
+ * this worked out by trial and error.
+ */
+ for(y = 0; y < 32; y++){
+ for(x = 0; x < 32/8; x++){
+ if(x < 16/8 && y < 16){
+ *p++ = curs->clr[2*y + x]|curs->set[2*y + x];
+ *p++ = curs->set[2*y + x];
+ }
+ else {
+ *p++ = 0x00;
+ *p++ = 0x00;
+ }
+ }
+ }
+
+ if(!(seq10 & 0x10)){
+ ark2000pvpageset(scr, opage);
+ unlock(&scr->devlock);
+ }
+
+ /*
+ * Save the cursor hotpoint.
+ */
+ scr->offset = curs->offset;
+}
+
+static int
+ark2000pvmove(VGAscr* scr, Point p)
+{
+ int x, xo, y, yo;
+
+ /*
+ * Mustn't position the cursor offscreen even partially,
+ * or it might disappear. Therefore, if x or y is -ve, adjust the
+ * cursor origins instead.
+ */
+ if((x = p.x+scr->offset.x) < 0){
+ xo = -x;
+ x = 0;
+ }
+ else
+ xo = 0;
+ if((y = p.y+scr->offset.y) < 0){
+ yo = -y;
+ y = 0;
+ }
+ else
+ yo = 0;
+
+ /*
+ * Load the new values.
+ */
+ vgaxo(Seqx, 0x2C, xo);
+ vgaxo(Seqx, 0x2D, yo);
+ vgaxo(Seqx, 0x21, (x>>8) & 0x0F);
+ vgaxo(Seqx, 0x22, x & 0xFF);
+ vgaxo(Seqx, 0x23, (y>>8) & 0x0F);
+ vgaxo(Seqx, 0x24, y & 0xFF);
+
+ return 0;
+}
+
+VGAdev vgaark2000pvdev = {
+ "ark2000pv",
+
+ 0,
+ 0,
+ ark2000pvpage,
+ 0,
+};
+
+VGAcur vgaark2000pvcur = {
+ "ark2000pvhwgc",
+
+ ark2000pvenable,
+ ark2000pvdisable,
+ ark2000pvload,
+ ark2000pvmove,
+};