]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgageode.c
pc, pc64: more conservative pcirouting
[plan9front.git] / sys / src / 9 / pc / vgageode.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "io.h"
7 #include "../port/error.h"
8
9 #define Image   IMAGE
10 #include <draw.h>
11 #include <memdraw.h>
12 #include <cursor.h>
13 #include "screen.h"
14
15 enum {
16         DC_UNLOCK = 0,
17         DC_UNLOCKVALUE = 0x4758,
18         DC_GENERAL_CFG = 1,
19         CURE = 2,
20         DC_CURS_ST_OFFSET = 6,
21         DC_CURSOR_X = 24,
22         DC_CURSOR_Y = 25,
23         DC_PAL_ADDRESS = 28,
24         DC_PAL_DATA
25 };
26
27 static void
28 geodeenable(VGAscr* scr)
29 {
30         Pcidev *p;
31         
32         if(scr->mmio)
33                 return;
34         p = scr->pci;
35         if(!p) return;
36         scr->mmio = vmap(p->mem[2].bar&~0x0F, p->mem[2].size);
37         if(!scr->mmio) return;
38         addvgaseg("geodegp", p->mem[1].bar&~0x0F, p->mem[1].size);
39         addvgaseg("geodemmio", p->mem[2].bar&~0x0F, p->mem[2].size);
40         addvgaseg("geodevid", p->mem[3].bar&~0x0F, p->mem[3].size);
41         vgalinearpci(scr);
42         if(scr->apsize)
43                 addvgaseg("geodescreen", scr->paddr, scr->apsize);
44         scr->storage = 0x800000;
45 }
46
47 static void
48 geodelinear(VGAscr*, int, int)
49 {
50 }
51
52 static void
53 geodecurload(VGAscr* scr, Cursor* curs)
54 {
55         uvlong *p, and1, xor1, and2, xor2;
56         int i;
57         uchar *c, *s;
58
59         if(!scr->mmio) return;
60         p = (uvlong*)((uchar*)scr->vaddr + scr->storage);
61         c = curs->clr;
62         s = curs->set;
63         for(i=0;i<16;i++) {
64                 and1 = 0xFF ^ (*s ^ *c++);
65                 xor1 = *s++;
66                 and1 &= ~xor1;
67                 and2 = 0xFF ^ (*s ^ *c++);
68                 xor2 = *s++;
69                 and2 &= ~xor2;
70                 *p++ = (and1 << 56) | (and2 << 48) | 0xFFFFFFFFFFFFLL;
71                 *p++ = (xor1 << 56) | (xor2 << 48);
72         }
73         for(;i<128;i++) {
74                 *p++ = -1;
75                 *p++ = 0;
76         }
77         scr->offset = curs->offset;
78 }
79
80 static int
81 geodecurmove(VGAscr* scr, Point p) {
82         if(!scr->mmio) return 1;
83         ((ulong*)scr->mmio)[DC_UNLOCK] = DC_UNLOCKVALUE;
84         ((ulong*)scr->mmio)[DC_CURSOR_X] = p.x + scr->offset.x;
85         ((ulong*)scr->mmio)[DC_CURSOR_Y] = p.y + scr->offset.y;
86         return 0;
87 }
88
89 static void
90 geodecurenable(VGAscr* scr)
91 {
92         geodeenable(scr);
93         if(!scr->mmio) return;
94         geodecurload(scr, &arrow);
95         geodecurmove(scr, ZP);
96         ((ulong*)scr->mmio)[DC_UNLOCK] = DC_UNLOCKVALUE;
97         ((ulong*)scr->mmio)[DC_CURS_ST_OFFSET] = scr->storage;
98         ((ulong*)scr->mmio)[DC_GENERAL_CFG] |= CURE;
99         /* set cursor colours */
100         ((ulong*)scr->mmio)[DC_PAL_ADDRESS] = 0x100;
101         ((ulong*)scr->mmio)[DC_PAL_DATA] = -1;
102         ((ulong*)scr->mmio)[DC_PAL_DATA] = 0;
103 }
104
105 static void
106 geodecurdisable(VGAscr* scr)
107 {
108         if(!scr->mmio) return;
109         ((ulong*)scr->mmio)[DC_UNLOCK] = DC_UNLOCKVALUE;
110         ((ulong*)scr->mmio)[DC_GENERAL_CFG] &= ~CURE;
111 }
112
113 VGAdev vgageodedev = {
114         "geode",
115         geodeenable,
116         .linear = geodelinear,
117 };
118
119
120 VGAcur vgageodecur = {
121         "geodehwgc",
122         geodecurenable,
123         geodecurdisable,
124         geodecurload,
125         geodecurmove,
126 };