xref: /plan9/sys/src/9/pc/vgact65545.c (revision 4de34a7edde43207e841ec91ecd12e6cf5f5ebe7)
17dd7cddfSDavid du Colombier #include "u.h"
27dd7cddfSDavid du Colombier #include "../port/lib.h"
37dd7cddfSDavid du Colombier #include "mem.h"
47dd7cddfSDavid du Colombier #include "dat.h"
57dd7cddfSDavid du Colombier #include "fns.h"
6*4de34a7eSDavid du Colombier #include "io.h"
77dd7cddfSDavid du Colombier #include "../port/error.h"
87dd7cddfSDavid du Colombier 
97dd7cddfSDavid du Colombier #define	Image	IMAGE
107dd7cddfSDavid du Colombier #include <draw.h>
117dd7cddfSDavid du Colombier #include <memdraw.h>
127dd7cddfSDavid du Colombier #include <cursor.h>
137dd7cddfSDavid du Colombier #include "screen.h"
147dd7cddfSDavid du Colombier 
157dd7cddfSDavid du Colombier static void
ct65545page(VGAscr *,int page)167dd7cddfSDavid du Colombier ct65545page(VGAscr*, int page)
177dd7cddfSDavid du Colombier {
187dd7cddfSDavid du Colombier 	outb(0x3D6, 0x10);
197dd7cddfSDavid du Colombier 	outb(0x3D7, page<<6);
207dd7cddfSDavid du Colombier }
217dd7cddfSDavid du Colombier 
227dd7cddfSDavid du Colombier static void
ct65545disable(VGAscr *)237dd7cddfSDavid du Colombier ct65545disable(VGAscr*)
247dd7cddfSDavid du Colombier {
257dd7cddfSDavid du Colombier 	outl(0xA3D0, 0);
267dd7cddfSDavid du Colombier }
277dd7cddfSDavid du Colombier 
287dd7cddfSDavid du Colombier static void
ct65545enable(VGAscr * scr)297dd7cddfSDavid du Colombier ct65545enable(VGAscr* scr)
307dd7cddfSDavid du Colombier {
317dd7cddfSDavid du Colombier 	ulong storage;
327dd7cddfSDavid du Colombier 
337dd7cddfSDavid du Colombier 	/*
347dd7cddfSDavid du Colombier 	 * Find a place for the cursor data in display memory.
357dd7cddfSDavid du Colombier 	 * Must be on a 1024-byte boundary.
367dd7cddfSDavid du Colombier 	 */
377dd7cddfSDavid du Colombier 	storage = ROUND(scr->gscreen->width*BY2WD*scr->gscreen->r.max.y, 1024);
387dd7cddfSDavid du Colombier 	outl(0xB3D0, storage);
397dd7cddfSDavid du Colombier 	scr->storage = storage;
407dd7cddfSDavid du Colombier 
417dd7cddfSDavid du Colombier 	/*
427dd7cddfSDavid du Colombier 	 * Set the colours.
437dd7cddfSDavid du Colombier 	 * Enable the cursor.
447dd7cddfSDavid du Colombier 	 */
457dd7cddfSDavid du Colombier 	outl(0xA7D0, 0xFFFF0000);
467dd7cddfSDavid du Colombier 	outl(0xA3D0, 2);
477dd7cddfSDavid du Colombier }
487dd7cddfSDavid du Colombier 
497dd7cddfSDavid du Colombier static void
ct65545initcursor(VGAscr * scr,int xo,int yo,int index)507dd7cddfSDavid du Colombier ct65545initcursor(VGAscr* scr, int xo, int yo, int index)
517dd7cddfSDavid du Colombier {
527dd7cddfSDavid du Colombier 	uchar *mem;
537dd7cddfSDavid du Colombier 	uint and, clr, set, xor;
547dd7cddfSDavid du Colombier 	int i, x, y;
557dd7cddfSDavid du Colombier 
56*4de34a7eSDavid du Colombier 	mem = scr->vaddr;
577dd7cddfSDavid du Colombier 	mem += scr->storage + index*1024;
587dd7cddfSDavid du Colombier 
597dd7cddfSDavid du Colombier 	for(y = yo; y < 16; y++){
607dd7cddfSDavid du Colombier 		clr = (scr->clr[2*y]<<8)|scr->clr[2*y+1];
617dd7cddfSDavid du Colombier 		set = (scr->set[2*y]<<8)|scr->set[2*y+1];
627dd7cddfSDavid du Colombier 		if(xo){
637dd7cddfSDavid du Colombier 			clr <<= xo;
647dd7cddfSDavid du Colombier 			set <<= xo;
657dd7cddfSDavid du Colombier 		}
667dd7cddfSDavid du Colombier 
677dd7cddfSDavid du Colombier 		and = 0;
687dd7cddfSDavid du Colombier 		xor = 0;
697dd7cddfSDavid du Colombier 		for(i = 0; i < 16; i++){
709a747e4fSDavid du Colombier 			if(set & (1<<i)){
719a747e4fSDavid du Colombier 				/* nothing to do */
729a747e4fSDavid du Colombier 			}
737dd7cddfSDavid du Colombier 			else if(clr & (1<<i))
747dd7cddfSDavid du Colombier 				xor |= 1<<i;
757dd7cddfSDavid du Colombier 			else
767dd7cddfSDavid du Colombier 				and |= 1<<i;
777dd7cddfSDavid du Colombier 		}
787dd7cddfSDavid du Colombier 		*mem++ = and>>8;
797dd7cddfSDavid du Colombier 		*mem++ = xor>>8;
807dd7cddfSDavid du Colombier 		*mem++ = and;
817dd7cddfSDavid du Colombier 		*mem++ = xor;
827dd7cddfSDavid du Colombier 
837dd7cddfSDavid du Colombier 		for(x = 16; x < 64; x += 8){
847dd7cddfSDavid du Colombier 			*mem++ = 0xFF;
857dd7cddfSDavid du Colombier 			*mem++ = 0x00;
867dd7cddfSDavid du Colombier 		}
877dd7cddfSDavid du Colombier 	}
887dd7cddfSDavid du Colombier 	while(y < 64+yo){
897dd7cddfSDavid du Colombier 		for(x = 0; x < 64; x += 8){
907dd7cddfSDavid du Colombier 			*mem++ = 0xFF;
917dd7cddfSDavid du Colombier 			*mem++ = 0x00;
927dd7cddfSDavid du Colombier 		}
937dd7cddfSDavid du Colombier 		y++;
947dd7cddfSDavid du Colombier 	}
957dd7cddfSDavid du Colombier }
967dd7cddfSDavid du Colombier 
977dd7cddfSDavid du Colombier static void
ct65545load(VGAscr * scr,Cursor * curs)987dd7cddfSDavid du Colombier ct65545load(VGAscr* scr, Cursor* curs)
997dd7cddfSDavid du Colombier {
1007dd7cddfSDavid du Colombier 	memmove(&scr->Cursor, curs, sizeof(Cursor));
1017dd7cddfSDavid du Colombier 	ct65545initcursor(scr, 0, 0, 0);
1027dd7cddfSDavid du Colombier }
1037dd7cddfSDavid du Colombier 
1047dd7cddfSDavid du Colombier static int
ct65545move(VGAscr * scr,Point p)1057dd7cddfSDavid du Colombier ct65545move(VGAscr* scr, Point p)
1067dd7cddfSDavid du Colombier {
1077dd7cddfSDavid du Colombier 	int index, x, xo, y, yo;
1087dd7cddfSDavid du Colombier 
1097dd7cddfSDavid du Colombier 	index = 0;
1107dd7cddfSDavid du Colombier 	if((x = p.x+scr->offset.x) < 0){
1117dd7cddfSDavid du Colombier 		xo = -x;
1127dd7cddfSDavid du Colombier 		x = 0;
1137dd7cddfSDavid du Colombier 	}
1147dd7cddfSDavid du Colombier 	else
1157dd7cddfSDavid du Colombier 		xo = 0;
1167dd7cddfSDavid du Colombier 	if((y = p.y+scr->offset.y) < 0){
1177dd7cddfSDavid du Colombier 		yo = -y;
1187dd7cddfSDavid du Colombier 		y = 0;
1197dd7cddfSDavid du Colombier 	}
1207dd7cddfSDavid du Colombier 	else
1217dd7cddfSDavid du Colombier 		yo = 0;
1227dd7cddfSDavid du Colombier 
1237dd7cddfSDavid du Colombier 	if(xo || yo){
1247dd7cddfSDavid du Colombier 		ct65545initcursor(scr, xo, yo, 1);
1257dd7cddfSDavid du Colombier 		index = 1;
1267dd7cddfSDavid du Colombier 	}
1277dd7cddfSDavid du Colombier 	outl(0xB3D0, scr->storage + index*1024);
1287dd7cddfSDavid du Colombier 
1297dd7cddfSDavid du Colombier 	outl(0xAFD0, (y<<16)|x);
1307dd7cddfSDavid du Colombier 
1317dd7cddfSDavid du Colombier 	return 0;
1327dd7cddfSDavid du Colombier }
1337dd7cddfSDavid du Colombier 
1347dd7cddfSDavid du Colombier VGAdev vgact65545dev = {
1357dd7cddfSDavid du Colombier 	"ct65540",				/* BUG: really 65545 */
1367dd7cddfSDavid du Colombier 
1377dd7cddfSDavid du Colombier 	0,
1387dd7cddfSDavid du Colombier 	0,
1397dd7cddfSDavid du Colombier 	ct65545page,
1407dd7cddfSDavid du Colombier 	0,
1417dd7cddfSDavid du Colombier };
1427dd7cddfSDavid du Colombier 
1437dd7cddfSDavid du Colombier VGAcur vgact65545cur = {
1447dd7cddfSDavid du Colombier 	"ct65545hwgc",
1457dd7cddfSDavid du Colombier 
1467dd7cddfSDavid du Colombier 	ct65545enable,
1477dd7cddfSDavid du Colombier 	ct65545disable,
1487dd7cddfSDavid du Colombier 	ct65545load,
1497dd7cddfSDavid du Colombier 	ct65545move,
1507dd7cddfSDavid du Colombier };
151