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
1559c21d95SDavid du Colombier typedef struct Cursor546x Cursor546x;
1659c21d95SDavid du Colombier struct Cursor546x {
177dd7cddfSDavid du Colombier ushort x;
187dd7cddfSDavid du Colombier ushort y;
197dd7cddfSDavid du Colombier ushort preset;
207dd7cddfSDavid du Colombier ushort enable;
217dd7cddfSDavid du Colombier ushort addr;
2259c21d95SDavid du Colombier };
237dd7cddfSDavid du Colombier
247dd7cddfSDavid du Colombier enum {
257dd7cddfSDavid du Colombier PaletteState = 0xB0,
267dd7cddfSDavid du Colombier CursorMMIO = 0xE0,
277dd7cddfSDavid du Colombier };
287dd7cddfSDavid du Colombier
29*4de34a7eSDavid du Colombier static void
clgd546xlinear(VGAscr * scr,int,int)30*4de34a7eSDavid du Colombier clgd546xlinear(VGAscr* scr, int, int)
317dd7cddfSDavid du Colombier {
32*4de34a7eSDavid du Colombier vgalinearpci(scr);
337dd7cddfSDavid du Colombier }
347dd7cddfSDavid du Colombier
357dd7cddfSDavid du Colombier static void
clgd546xenable(VGAscr * scr)367dd7cddfSDavid du Colombier clgd546xenable(VGAscr* scr)
377dd7cddfSDavid du Colombier {
387dd7cddfSDavid du Colombier Pcidev *p;
397dd7cddfSDavid du Colombier
40*4de34a7eSDavid du Colombier if(scr->mmio)
417dd7cddfSDavid du Colombier return;
42*4de34a7eSDavid du Colombier if((p = pcimatch(nil, 0x1013, 0)) == nil)
43*4de34a7eSDavid du Colombier return;
447dd7cddfSDavid du Colombier switch(p->did){
457dd7cddfSDavid du Colombier case 0xD0:
467dd7cddfSDavid du Colombier case 0xD4:
477dd7cddfSDavid du Colombier case 0xD6:
487dd7cddfSDavid du Colombier break;
497dd7cddfSDavid du Colombier default:
507dd7cddfSDavid du Colombier return;
517dd7cddfSDavid du Colombier }
527dd7cddfSDavid du Colombier
53*4de34a7eSDavid du Colombier scr->pci = p;
54*4de34a7eSDavid du Colombier scr->mmio = vmap(p->mem[1].bar&~0x0F, p->mem[1].size);
55*4de34a7eSDavid du Colombier if(scr->mmio == 0)
56*4de34a7eSDavid du Colombier return;
57*4de34a7eSDavid du Colombier addvgaseg("clgd546xmmio", p->mem[1].bar&~0x0F, p->mem[1].size);
587dd7cddfSDavid du Colombier }
597dd7cddfSDavid du Colombier
607dd7cddfSDavid du Colombier static void
clgd546xcurdisable(VGAscr * scr)617dd7cddfSDavid du Colombier clgd546xcurdisable(VGAscr* scr)
627dd7cddfSDavid du Colombier {
637dd7cddfSDavid du Colombier Cursor546x *cursor546x;
647dd7cddfSDavid du Colombier
65*4de34a7eSDavid du Colombier if(scr->mmio == 0)
667dd7cddfSDavid du Colombier return;
67*4de34a7eSDavid du Colombier cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
687dd7cddfSDavid du Colombier cursor546x->enable = 0;
697dd7cddfSDavid du Colombier }
707dd7cddfSDavid du Colombier
717dd7cddfSDavid du Colombier static void
clgd546xcurload(VGAscr * scr,Cursor * curs)727dd7cddfSDavid du Colombier clgd546xcurload(VGAscr* scr, Cursor* curs)
737dd7cddfSDavid du Colombier {
747dd7cddfSDavid du Colombier int c, i, m, y;
757dd7cddfSDavid du Colombier uchar *p;
767dd7cddfSDavid du Colombier Cursor546x *cursor546x;
777dd7cddfSDavid du Colombier
78*4de34a7eSDavid du Colombier if(scr->mmio == 0)
797dd7cddfSDavid du Colombier return;
80*4de34a7eSDavid du Colombier cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
817dd7cddfSDavid du Colombier
827dd7cddfSDavid du Colombier /*
837dd7cddfSDavid du Colombier * Disable the cursor then change only the bits
847dd7cddfSDavid du Colombier * that need it.
857dd7cddfSDavid du Colombier */
867dd7cddfSDavid du Colombier cursor546x->enable = 0;
87*4de34a7eSDavid du Colombier p = (uchar*)scr->vaddr + scr->storage;
887dd7cddfSDavid du Colombier for(y = 0; y < 16; y++){
897dd7cddfSDavid du Colombier c = curs->set[2*y];
907dd7cddfSDavid du Colombier m = 0;
917dd7cddfSDavid du Colombier for(i = 0; i < 8; i++){
927dd7cddfSDavid du Colombier if(c & (1<<(7-i)))
937dd7cddfSDavid du Colombier m |= 1<<i;
947dd7cddfSDavid du Colombier }
957dd7cddfSDavid du Colombier *p++ = m;
967dd7cddfSDavid du Colombier c = curs->set[2*y + 1];
977dd7cddfSDavid du Colombier m = 0;
987dd7cddfSDavid du Colombier for(i = 0; i < 8; i++){
997dd7cddfSDavid du Colombier if(c & (1<<(7-i)))
1007dd7cddfSDavid du Colombier m |= 1<<i;
1017dd7cddfSDavid du Colombier }
1027dd7cddfSDavid du Colombier *p++ = m;
1037dd7cddfSDavid du Colombier p += 6;
1047dd7cddfSDavid du Colombier c = curs->set[2*y]|curs->clr[2*y];
1057dd7cddfSDavid du Colombier m = 0;
1067dd7cddfSDavid du Colombier for(i = 0; i < 8; i++){
1077dd7cddfSDavid du Colombier if(c & (1<<(7-i)))
1087dd7cddfSDavid du Colombier m |= 1<<i;
1097dd7cddfSDavid du Colombier }
1107dd7cddfSDavid du Colombier *p++ = m;
1117dd7cddfSDavid du Colombier c = curs->set[2*y + 1]|curs->clr[2*y + 1];
1127dd7cddfSDavid du Colombier m = 0;
1137dd7cddfSDavid du Colombier for(i = 0; i < 8; i++){
1147dd7cddfSDavid du Colombier if(c & (1<<(7-i)))
1157dd7cddfSDavid du Colombier m |= 1<<i;
1167dd7cddfSDavid du Colombier }
1177dd7cddfSDavid du Colombier *p++ = m;
1187dd7cddfSDavid du Colombier p += 6;
1197dd7cddfSDavid du Colombier }
1207dd7cddfSDavid du Colombier
1217dd7cddfSDavid du Colombier /*
1227dd7cddfSDavid du Colombier * Save the cursor hotpoint and enable the cursor.
1237dd7cddfSDavid du Colombier */
1247dd7cddfSDavid du Colombier scr->offset = curs->offset;
1257dd7cddfSDavid du Colombier cursor546x->enable = 1;
1267dd7cddfSDavid du Colombier }
1277dd7cddfSDavid du Colombier
1287dd7cddfSDavid du Colombier static int
clgd546xcurmove(VGAscr * scr,Point p)1297dd7cddfSDavid du Colombier clgd546xcurmove(VGAscr* scr, Point p)
1307dd7cddfSDavid du Colombier {
1317dd7cddfSDavid du Colombier int x, xo, y, yo;
1327dd7cddfSDavid du Colombier Cursor546x *cursor546x;
1337dd7cddfSDavid du Colombier
134*4de34a7eSDavid du Colombier if(scr->mmio == 0)
1357dd7cddfSDavid du Colombier return 1;
136*4de34a7eSDavid du Colombier cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
1377dd7cddfSDavid du Colombier
1387dd7cddfSDavid du Colombier if((x = p.x+scr->offset.x) < 0){
1397dd7cddfSDavid du Colombier xo = -x;
1407dd7cddfSDavid du Colombier x = 0;
1417dd7cddfSDavid du Colombier }
1427dd7cddfSDavid du Colombier else
1437dd7cddfSDavid du Colombier xo = 0;
1447dd7cddfSDavid du Colombier if((y = p.y+scr->offset.y) < 0){
1457dd7cddfSDavid du Colombier yo = -y;
1467dd7cddfSDavid du Colombier y = 0;
1477dd7cddfSDavid du Colombier }
1487dd7cddfSDavid du Colombier else
1497dd7cddfSDavid du Colombier yo = 0;
1507dd7cddfSDavid du Colombier
1517dd7cddfSDavid du Colombier cursor546x->preset = (xo<<8)|yo;
1527dd7cddfSDavid du Colombier cursor546x->x = x;
1537dd7cddfSDavid du Colombier cursor546x->y = y;
1547dd7cddfSDavid du Colombier
1557dd7cddfSDavid du Colombier return 0;
1567dd7cddfSDavid du Colombier }
1577dd7cddfSDavid du Colombier
1587dd7cddfSDavid du Colombier static void
clgd546xcurenable(VGAscr * scr)1597dd7cddfSDavid du Colombier clgd546xcurenable(VGAscr* scr)
1607dd7cddfSDavid du Colombier {
1617dd7cddfSDavid du Colombier uchar *p;
1627dd7cddfSDavid du Colombier Cursor546x *cursor546x;
1637dd7cddfSDavid du Colombier
1647dd7cddfSDavid du Colombier clgd546xenable(scr);
165*4de34a7eSDavid du Colombier if(scr->mmio == 0)
1667dd7cddfSDavid du Colombier return;
167*4de34a7eSDavid du Colombier cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
1687dd7cddfSDavid du Colombier
1697dd7cddfSDavid du Colombier /*
1707dd7cddfSDavid du Colombier * Cursor colours.
1717dd7cddfSDavid du Colombier * Can't call setcolor here as cursor is already locked.
1727dd7cddfSDavid du Colombier */
173*4de34a7eSDavid du Colombier p = (uchar*)scr->mmio+PaletteState;
1747dd7cddfSDavid du Colombier *p |= 0x08;
1757dd7cddfSDavid du Colombier vgao(PaddrW, 0x00);
1767dd7cddfSDavid du Colombier vgao(Pdata, Pwhite);
1777dd7cddfSDavid du Colombier vgao(Pdata, Pwhite);
1787dd7cddfSDavid du Colombier vgao(Pdata, Pwhite);
1797dd7cddfSDavid du Colombier vgao(PaddrW, 0x0F);
1807dd7cddfSDavid du Colombier vgao(Pdata, Pblack);
1817dd7cddfSDavid du Colombier vgao(Pdata, Pblack);
1827dd7cddfSDavid du Colombier vgao(Pdata, Pblack);
1837dd7cddfSDavid du Colombier *p &= ~0x08;
1847dd7cddfSDavid du Colombier
1857dd7cddfSDavid du Colombier /*
1867dd7cddfSDavid du Colombier * Find a place for the cursor data in display memory.
1877dd7cddfSDavid du Colombier * 2 cursor images might be needed, 1KB each so use the last
1887dd7cddfSDavid du Colombier * 2KB of the framebuffer and initialise them to be
1897dd7cddfSDavid du Colombier * transparent.
1907dd7cddfSDavid du Colombier */
1917dd7cddfSDavid du Colombier scr->storage = ((vgaxi(Seqx, 0x14) & 0x07)+1)*1024*1022;
1927dd7cddfSDavid du Colombier cursor546x->addr = (scr->storage>>10)<<2;
193*4de34a7eSDavid du Colombier memset((uchar*)scr->vaddr + scr->storage, 0, 2*64*16);
1947dd7cddfSDavid du Colombier
1957dd7cddfSDavid du Colombier /*
1967dd7cddfSDavid du Colombier * Load, locate and enable the 64x64 cursor.
1977dd7cddfSDavid du Colombier */
1987dd7cddfSDavid du Colombier clgd546xcurload(scr, &arrow);
1997dd7cddfSDavid du Colombier clgd546xcurmove(scr, ZP);
2007dd7cddfSDavid du Colombier cursor546x->enable = 1;
2017dd7cddfSDavid du Colombier }
2027dd7cddfSDavid du Colombier
2037dd7cddfSDavid du Colombier VGAdev vgaclgd546xdev = {
2047dd7cddfSDavid du Colombier "clgd546x",
2057dd7cddfSDavid du Colombier
2067dd7cddfSDavid du Colombier clgd546xenable,
2077dd7cddfSDavid du Colombier nil,
2087dd7cddfSDavid du Colombier nil,
2097dd7cddfSDavid du Colombier clgd546xlinear,
2107dd7cddfSDavid du Colombier };
2117dd7cddfSDavid du Colombier
2127dd7cddfSDavid du Colombier VGAcur vgaclgd546xcur = {
2137dd7cddfSDavid du Colombier "clgd546xhwgc",
2147dd7cddfSDavid du Colombier
2157dd7cddfSDavid du Colombier clgd546xcurenable,
2167dd7cddfSDavid du Colombier clgd546xcurdisable,
2177dd7cddfSDavid du Colombier clgd546xcurload,
2187dd7cddfSDavid du Colombier clgd546xcurmove,
2197dd7cddfSDavid du Colombier };
220