summaryrefslogtreecommitdiff
path: root/os/pc/vgact65545.c
diff options
context:
space:
mode:
authorCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
committerCharles.Forsyth <devnull@localhost>2006-12-22 21:39:35 +0000
commit74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a (patch)
treec6e220ba61db3a6ea4052e6841296d829654e664 /os/pc/vgact65545.c
parent46439007cf417cbd9ac8049bb4122c890097a0fa (diff)
20060303
Diffstat (limited to 'os/pc/vgact65545.c')
-rw-r--r--os/pc/vgact65545.c149
1 files changed, 149 insertions, 0 deletions
diff --git a/os/pc/vgact65545.c b/os/pc/vgact65545.c
new file mode 100644
index 00000000..9a1467ac
--- /dev/null
+++ b/os/pc/vgact65545.c
@@ -0,0 +1,149 @@
+#include "u.h"
+#include "../port/lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "../port/error.h"
+
+#define Image IMAGE
+#include <draw.h>
+#include <memdraw.h>
+#include <cursor.h>
+#include "screen.h"
+
+static void
+ct65545page(VGAscr*, int page)
+{
+ outb(0x3D6, 0x10);
+ outb(0x3D7, page<<6);
+}
+
+static void
+ct65545disable(VGAscr*)
+{
+ outl(0xA3D0, 0);
+}
+
+static void
+ct65545enable(VGAscr* scr)
+{
+ ulong storage;
+
+ /*
+ * Find a place for the cursor data in display memory.
+ * Must be on a 1024-byte boundary.
+ */
+ storage = ROUND(scr->gscreen->width*BY2WD*scr->gscreen->r.max.y, 1024);
+ outl(0xB3D0, storage);
+ scr->storage = storage;
+
+ /*
+ * Set the colours.
+ * Enable the cursor.
+ */
+ outl(0xA7D0, 0xFFFF0000);
+ outl(0xA3D0, 2);
+}
+
+static void
+ct65545initcursor(VGAscr* scr, int xo, int yo, int index)
+{
+ uchar *mem;
+ uint and, clr, set, xor;
+ int i, x, y;
+
+ mem = KADDR(scr->aperture);
+ mem += scr->storage + index*1024;
+
+ for(y = yo; y < 16; y++){
+ clr = (scr->clr[2*y]<<8)|scr->clr[2*y+1];
+ set = (scr->set[2*y]<<8)|scr->set[2*y+1];
+ if(xo){
+ clr <<= xo;
+ set <<= xo;
+ }
+
+ and = 0;
+ xor = 0;
+ for(i = 0; i < 16; i++){
+ if(set & (1<<i)){
+ /* nothing to do */
+ }
+ else if(clr & (1<<i))
+ xor |= 1<<i;
+ else
+ and |= 1<<i;
+ }
+ *mem++ = and>>8;
+ *mem++ = xor>>8;
+ *mem++ = and;
+ *mem++ = xor;
+
+ for(x = 16; x < 64; x += 8){
+ *mem++ = 0xFF;
+ *mem++ = 0x00;
+ }
+ }
+ while(y < 64+yo){
+ for(x = 0; x < 64; x += 8){
+ *mem++ = 0xFF;
+ *mem++ = 0x00;
+ }
+ y++;
+ }
+}
+
+static void
+ct65545load(VGAscr* scr, Cursor* curs)
+{
+ memmove(&scr->Cursor, curs, sizeof(Cursor));
+ ct65545initcursor(scr, 0, 0, 0);
+}
+
+static int
+ct65545move(VGAscr* scr, Point p)
+{
+ int index, x, xo, y, yo;
+
+ index = 0;
+ 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;
+
+ if(xo || yo){
+ ct65545initcursor(scr, xo, yo, 1);
+ index = 1;
+ }
+ outl(0xB3D0, scr->storage + index*1024);
+
+ outl(0xAFD0, (y<<16)|x);
+
+ return 0;
+}
+
+VGAdev vgact65545dev = {
+ "ct65540", /* BUG: really 65545 */
+
+ 0,
+ 0,
+ ct65545page,
+ 0,
+};
+
+VGAcur vgact65545cur = {
+ "ct65545hwgc",
+
+ ct65545enable,
+ ct65545disable,
+ ct65545load,
+ ct65545move,
+};