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