xref: /plan9/sys/src/9/pc/vgacyber938x.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"
67dd7cddfSDavid 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 enum {
167dd7cddfSDavid du Colombier 	CursorON	= 0xC8,
177dd7cddfSDavid du Colombier 	CursorOFF	= 0x00,
187dd7cddfSDavid du Colombier };
197dd7cddfSDavid du Colombier 
207dd7cddfSDavid du Colombier static int
cyber938xpageset(VGAscr *,int page)217dd7cddfSDavid du Colombier cyber938xpageset(VGAscr*, int page)
227dd7cddfSDavid du Colombier {
237dd7cddfSDavid du Colombier 	int opage;
247dd7cddfSDavid du Colombier 
257dd7cddfSDavid du Colombier 	opage = inb(0x3D8);
267dd7cddfSDavid du Colombier 
277dd7cddfSDavid du Colombier 	outb(0x3D8, page);
287dd7cddfSDavid du Colombier 	outb(0x3D9, page);
297dd7cddfSDavid du Colombier 
307dd7cddfSDavid du Colombier 	return opage;
317dd7cddfSDavid du Colombier }
327dd7cddfSDavid du Colombier 
337dd7cddfSDavid du Colombier static void
cyber938xpage(VGAscr * scr,int page)347dd7cddfSDavid du Colombier cyber938xpage(VGAscr* scr, int page)
357dd7cddfSDavid du Colombier {
367dd7cddfSDavid du Colombier 	lock(&scr->devlock);
377dd7cddfSDavid du Colombier 	cyber938xpageset(scr, page);
387dd7cddfSDavid du Colombier 	unlock(&scr->devlock);
397dd7cddfSDavid du Colombier }
407dd7cddfSDavid du Colombier 
41*4de34a7eSDavid du Colombier static void
cyber938xlinear(VGAscr * scr,int,int)42*4de34a7eSDavid du Colombier cyber938xlinear(VGAscr* scr, int, int)
437dd7cddfSDavid du Colombier {
447dd7cddfSDavid du Colombier 	Pcidev *p;
457dd7cddfSDavid du Colombier 
46*4de34a7eSDavid du Colombier 	if(scr->vaddr)
47*4de34a7eSDavid du Colombier 		return;
487dd7cddfSDavid du Colombier 
49*4de34a7eSDavid du Colombier 	vgalinearpciid(scr, 0x1023, 0);
50*4de34a7eSDavid du Colombier 	p = scr->pci;
51*4de34a7eSDavid du Colombier 
529a747e4fSDavid du Colombier 	/*
539a747e4fSDavid du Colombier 	 * Heuristic to detect the MMIO space.  We're flying blind
549a747e4fSDavid du Colombier 	 * here, with only the XFree86 source to guide us.
559a747e4fSDavid du Colombier 	 */
569a747e4fSDavid du Colombier 	if(p->mem[1].size == 0x20000)
57*4de34a7eSDavid du Colombier 		scr->mmio = vmap(p->mem[1].bar & ~0x0F, p->mem[1].size);
587dd7cddfSDavid du Colombier 
59*4de34a7eSDavid du Colombier 	if(scr->apsize)
60*4de34a7eSDavid du Colombier 		addvgaseg("cyber938xscreen", scr->paddr, scr->apsize);
619a747e4fSDavid du Colombier 	if(scr->mmio)
62*4de34a7eSDavid du Colombier 		addvgaseg("cyber938xmmio", p->mem[1].bar&~0x0F, 0x20000);
637dd7cddfSDavid du Colombier }
647dd7cddfSDavid du Colombier 
657dd7cddfSDavid du Colombier static void
cyber938xcurdisable(VGAscr *)667dd7cddfSDavid du Colombier cyber938xcurdisable(VGAscr*)
677dd7cddfSDavid du Colombier {
687dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x50, CursorOFF);
697dd7cddfSDavid du Colombier }
707dd7cddfSDavid du Colombier 
717dd7cddfSDavid du Colombier static void
cyber938xcurload(VGAscr * scr,Cursor * curs)727dd7cddfSDavid du Colombier cyber938xcurload(VGAscr* scr, Cursor* curs)
737dd7cddfSDavid du Colombier {
747dd7cddfSDavid du Colombier 	uchar *p;
757dd7cddfSDavid du Colombier 	int islinear, opage, y;
767dd7cddfSDavid du Colombier 
777dd7cddfSDavid du Colombier 	cyber938xcurdisable(scr);
787dd7cddfSDavid du Colombier 
797dd7cddfSDavid du Colombier 	opage = 0;
80*4de34a7eSDavid du Colombier 	p = scr->vaddr;
817dd7cddfSDavid du Colombier 	islinear = vgaxi(Crtx, 0x21) & 0x20;
827dd7cddfSDavid du Colombier 	if(!islinear){
837dd7cddfSDavid du Colombier 		lock(&scr->devlock);
847dd7cddfSDavid du Colombier 		opage = cyber938xpageset(scr, scr->storage>>16);
857dd7cddfSDavid du Colombier 		p += (scr->storage & 0xFFFF);
867dd7cddfSDavid du Colombier 	}
877dd7cddfSDavid du Colombier 	else
887dd7cddfSDavid du Colombier 		p += scr->storage;
897dd7cddfSDavid du Colombier 
907dd7cddfSDavid du Colombier 	for(y = 0; y < 16; y++){
917dd7cddfSDavid du Colombier 		*p++ = curs->set[2*y]|curs->clr[2*y];
927dd7cddfSDavid du Colombier 		*p++ = curs->set[2*y + 1]|curs->clr[2*y + 1];
937dd7cddfSDavid du Colombier 		*p++ = 0x00;
947dd7cddfSDavid du Colombier 		*p++ = 0x00;
957dd7cddfSDavid du Colombier 		*p++ = curs->set[2*y];
967dd7cddfSDavid du Colombier 		*p++ = curs->set[2*y + 1];
977dd7cddfSDavid du Colombier 		*p++ = 0x00;
987dd7cddfSDavid du Colombier 		*p++ = 0x00;
997dd7cddfSDavid du Colombier 	}
1007dd7cddfSDavid du Colombier 	memset(p, 0, (32-y)*8);
1017dd7cddfSDavid du Colombier 
1027dd7cddfSDavid du Colombier 	if(!islinear){
1037dd7cddfSDavid du Colombier 		cyber938xpageset(scr, opage);
1047dd7cddfSDavid du Colombier 		unlock(&scr->devlock);
1057dd7cddfSDavid du Colombier 	}
1067dd7cddfSDavid du Colombier 
1077dd7cddfSDavid du Colombier 	/*
1087dd7cddfSDavid du Colombier 	 * Save the cursor hotpoint and enable the cursor.
1097dd7cddfSDavid du Colombier 	 */
1107dd7cddfSDavid du Colombier 	scr->offset = curs->offset;
1117dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x50, CursorON);
1127dd7cddfSDavid du Colombier }
1137dd7cddfSDavid du Colombier 
1147dd7cddfSDavid du Colombier static int
cyber938xcurmove(VGAscr * scr,Point p)1157dd7cddfSDavid du Colombier cyber938xcurmove(VGAscr* scr, Point p)
1167dd7cddfSDavid du Colombier {
1177dd7cddfSDavid du Colombier 	int x, xo, y, yo;
1187dd7cddfSDavid du Colombier 
1197dd7cddfSDavid du Colombier 	/*
1207dd7cddfSDavid du Colombier 	 * Mustn't position the cursor offscreen even partially,
1217dd7cddfSDavid du Colombier 	 * or it might disappear. Therefore, if x or y is -ve, adjust the
1227dd7cddfSDavid du Colombier 	 * cursor origins instead.
1237dd7cddfSDavid du Colombier 	 */
1247dd7cddfSDavid du Colombier 	if((x = p.x+scr->offset.x) < 0){
1257dd7cddfSDavid du Colombier 		xo = -x;
1267dd7cddfSDavid du Colombier 		x = 0;
1277dd7cddfSDavid du Colombier 	}
1287dd7cddfSDavid du Colombier 	else
1297dd7cddfSDavid du Colombier 		xo = 0;
1307dd7cddfSDavid du Colombier 	if((y = p.y+scr->offset.y) < 0){
1317dd7cddfSDavid du Colombier 		yo = -y;
1327dd7cddfSDavid du Colombier 		y = 0;
1337dd7cddfSDavid du Colombier 	}
1347dd7cddfSDavid du Colombier 	else
1357dd7cddfSDavid du Colombier 		yo = 0;
1367dd7cddfSDavid du Colombier 
1377dd7cddfSDavid du Colombier 	/*
1387dd7cddfSDavid du Colombier 	 * Load the new values.
1397dd7cddfSDavid du Colombier 	 */
1407dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x46, xo);
1417dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x47, yo);
1427dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x40, x & 0xFF);
1437dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x41, (x>>8) & 0xFF);
1447dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x42, y & 0xFF);
1457dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x43, (y>>8) & 0xFF);
1467dd7cddfSDavid du Colombier 
1477dd7cddfSDavid du Colombier 	return 0;
1487dd7cddfSDavid du Colombier }
1497dd7cddfSDavid du Colombier 
1507dd7cddfSDavid du Colombier static void
cyber938xcurenable(VGAscr * scr)1517dd7cddfSDavid du Colombier cyber938xcurenable(VGAscr* scr)
1527dd7cddfSDavid du Colombier {
1537dd7cddfSDavid du Colombier 	int i;
1547dd7cddfSDavid du Colombier 	ulong storage;
1557dd7cddfSDavid du Colombier 
1567dd7cddfSDavid du Colombier 	cyber938xcurdisable(scr);
1577dd7cddfSDavid du Colombier 
1587dd7cddfSDavid du Colombier 	/*
1597dd7cddfSDavid du Colombier 	 * Cursor colours.
1607dd7cddfSDavid du Colombier 	 */
1617dd7cddfSDavid du Colombier 	for(i = 0x48; i < 0x4C; i++)
1627dd7cddfSDavid du Colombier 		vgaxo(Crtx, i, 0x00);
1637dd7cddfSDavid du Colombier 	for(i = 0x4C; i < 0x50; i++)
1647dd7cddfSDavid du Colombier 		vgaxo(Crtx, i, 0xFF);
1657dd7cddfSDavid du Colombier 
1667dd7cddfSDavid du Colombier 	/*
1677dd7cddfSDavid du Colombier 	 * Find a place for the cursor data in display memory.
1687dd7cddfSDavid du Colombier 	 */
1697dd7cddfSDavid du Colombier 	storage = ((scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024);
1707dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x44, storage & 0xFF);
1717dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x45, (storage>>8) & 0xFF);
1727dd7cddfSDavid du Colombier 	storage *= 1024;
1737dd7cddfSDavid du Colombier 	scr->storage = storage;
1747dd7cddfSDavid du Colombier 
1757dd7cddfSDavid du Colombier 	/*
1767dd7cddfSDavid du Colombier 	 * Load, locate and enable the 32x32 cursor.
1777dd7cddfSDavid du Colombier 	 * (64x64 is bit 0, X11 format is bit 6 and cursor
1787dd7cddfSDavid du Colombier 	 * enable is bit 7). Bit 3 needs to be set on 9382
1797dd7cddfSDavid du Colombier 	 * chips otherwise even the white bits are black.
1807dd7cddfSDavid du Colombier 	 */
1817dd7cddfSDavid du Colombier 	cyber938xcurload(scr, &arrow);
1827dd7cddfSDavid du Colombier 	cyber938xcurmove(scr, ZP);
1837dd7cddfSDavid du Colombier 	vgaxo(Crtx, 0x50, CursorON);
1847dd7cddfSDavid du Colombier }
1857dd7cddfSDavid du Colombier 
1867dd7cddfSDavid du Colombier VGAdev vgacyber938xdev = {
1877dd7cddfSDavid du Colombier 	"cyber938x",
1887dd7cddfSDavid du Colombier 
1899a747e4fSDavid du Colombier 	nil,				/* enable */
1909a747e4fSDavid du Colombier 	nil,				/* disable */
1917dd7cddfSDavid du Colombier 	cyber938xpage,			/* page */
1927dd7cddfSDavid du Colombier 	cyber938xlinear,		/* linear */
1939a747e4fSDavid du Colombier 	nil,				/* drawinit */
1947dd7cddfSDavid du Colombier };
1957dd7cddfSDavid du Colombier 
1967dd7cddfSDavid du Colombier VGAcur vgacyber938xcur = {
1977dd7cddfSDavid du Colombier 	"cyber938xhwgc",
1987dd7cddfSDavid du Colombier 
1997dd7cddfSDavid du Colombier 	cyber938xcurenable,		/* enable */
2007dd7cddfSDavid du Colombier 	cyber938xcurdisable,		/* disable */
2017dd7cddfSDavid du Colombier 	cyber938xcurload,		/* load */
2027dd7cddfSDavid du Colombier 	cyber938xcurmove,		/* move */
2037dd7cddfSDavid du Colombier };
204