]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgaclgd546x.c
syscallfmt: use up->syserrstr instead of up->errstr (import from sources)
[plan9front.git] / sys / src / 9 / pc / vgaclgd546x.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 typedef struct Cursor546x Cursor546x;
16 struct Cursor546x {
17         ushort  x;
18         ushort  y;
19         ushort  preset;
20         ushort  enable;
21         ushort  addr;
22 };
23
24 enum {
25         PaletteState    = 0xB0,
26         CursorMMIO      = 0xE0,
27 };
28
29 static void
30 clgd546xlinear(VGAscr* scr, int, int)
31 {
32         vgalinearpci(scr);
33 }
34
35 static void
36 clgd546xenable(VGAscr* scr)
37 {
38         Pcidev *p;
39
40         if(scr->mmio)
41                 return;
42         if((p = pcimatch(nil, 0x1013, 0)) == nil)
43                 return;
44         switch(p->did){
45         case 0xD0:
46         case 0xD4:
47         case 0xD6:
48                 break;
49         default:
50                 return;
51         }
52
53         scr->pci = p;
54         scr->mmio = vmap(p->mem[1].bar&~0x0F, p->mem[1].size);
55         if(scr->mmio == 0)
56                 return;
57         addvgaseg("clgd546xmmio", p->mem[1].bar&~0x0F, p->mem[1].size);
58 }
59
60 static void
61 clgd546xcurdisable(VGAscr* scr)
62 {
63         Cursor546x *cursor546x;
64
65         if(scr->mmio == 0)
66                 return;
67         cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
68         cursor546x->enable = 0;
69 }
70
71 static void
72 clgd546xcurload(VGAscr* scr, Cursor* curs)
73 {
74         int c, i, m, y;
75         uchar *p;
76         Cursor546x *cursor546x;
77
78         if(scr->mmio == 0)
79                 return;
80         cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
81
82         /*
83          * Disable the cursor then change only the bits
84          * that need it.
85          */
86         cursor546x->enable = 0;
87         p = (uchar*)scr->vaddr + scr->storage;
88         for(y = 0; y < 16; y++){
89                 c = curs->set[2*y];
90                 m = 0;
91                 for(i = 0; i < 8; i++){
92                         if(c & (1<<(7-i)))
93                                 m |= 1<<i;
94                 }
95                 *p++ = m;
96                 c = curs->set[2*y + 1];
97                 m = 0;
98                 for(i = 0; i < 8; i++){
99                         if(c & (1<<(7-i)))
100                                 m |= 1<<i;
101                 }
102                 *p++ = m;
103                 p += 6;
104                 c = curs->set[2*y]|curs->clr[2*y];
105                 m = 0;
106                 for(i = 0; i < 8; i++){
107                         if(c & (1<<(7-i)))
108                                 m |= 1<<i;
109                 }
110                 *p++ = m;
111                 c = curs->set[2*y + 1]|curs->clr[2*y + 1];
112                 m = 0;
113                 for(i = 0; i < 8; i++){
114                         if(c & (1<<(7-i)))
115                                 m |= 1<<i;
116                 }
117                 *p++ = m;
118                 p += 6;
119         }
120
121         /*
122          * Save the cursor hotpoint and enable the cursor.
123          */
124         scr->offset = curs->offset;
125         cursor546x->enable = 1;
126 }
127
128 static int
129 clgd546xcurmove(VGAscr* scr, Point p)
130 {
131         int x, xo, y, yo;
132         Cursor546x *cursor546x;
133
134         if(scr->mmio == 0)
135                 return 1;
136         cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
137
138         if((x = p.x+scr->offset.x) < 0){
139                 xo = -x;
140                 x = 0;
141         }
142         else
143                 xo = 0;
144         if((y = p.y+scr->offset.y) < 0){
145                 yo = -y;
146                 y = 0;
147         }
148         else
149                 yo = 0;
150
151         cursor546x->preset = (xo<<8)|yo;
152         cursor546x->x = x;
153         cursor546x->y = y;
154
155         return 0;
156 }
157
158 static void
159 clgd546xcurenable(VGAscr* scr)
160 {
161         uchar *p;
162         Cursor546x *cursor546x;
163
164         clgd546xenable(scr);
165         if(scr->mmio == 0)
166                 return;
167         cursor546x = (Cursor546x*)((uchar*)scr->mmio+CursorMMIO);
168
169         /*
170          * Cursor colours.
171          * Can't call setcolor here as cursor is already locked.
172          */
173         p = (uchar*)scr->mmio+PaletteState;
174         *p |= 0x08;
175         vgao(PaddrW, 0x00);
176         vgao(Pdata, Pwhite);
177         vgao(Pdata, Pwhite);
178         vgao(Pdata, Pwhite);
179         vgao(PaddrW, 0x0F);
180         vgao(Pdata, Pblack);
181         vgao(Pdata, Pblack);
182         vgao(Pdata, Pblack);
183         *p &= ~0x08;
184
185         /*
186          * Find a place for the cursor data in display memory.
187          * 2 cursor images might be needed, 1KB each so use the last
188          * 2KB of the framebuffer and initialise them to be
189          * transparent.
190          */
191         scr->storage = ((vgaxi(Seqx, 0x14) & 0x07)+1)*1024*1022;
192         cursor546x->addr = (scr->storage>>10)<<2;
193         memset((uchar*)scr->vaddr + scr->storage, 0, 2*64*16);
194
195         /*
196          * Load, locate and enable the 64x64 cursor.
197          */
198         clgd546xcurload(scr, &arrow);
199         clgd546xcurmove(scr, ZP);
200         cursor546x->enable = 1;
201 }
202
203 VGAdev vgaclgd546xdev = {
204         "clgd546x",
205
206         clgd546xenable,
207         nil,
208         nil,
209         clgd546xlinear,
210 };
211
212 VGAcur vgaclgd546xcur = {
213         "clgd546xhwgc",
214
215         clgd546xcurenable,
216         clgd546xcurdisable,
217         clgd546xcurload,
218         clgd546xcurmove,
219 };