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