]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/pc/vgargb524.c
sb16: return Blocksize instead of buffer size
[plan9front.git] / sys / src / 9 / pc / vgargb524.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 /*
16  * IBM RGB524.
17  * 170/220MHz High Performance Palette DAC.
18  *
19  * Assumes hooked up to an S3 Vision96[48].
20  */
21 enum {
22         IndexLo         = 0x00,
23         IndexHi         = 0x01,
24         Data            = 0x02,
25         IndexCtl        = 0x03,
26 };
27
28 enum {                                          /* index registers */
29         CursorCtl       = 0x30,
30         CursorXLo       = 0x31,
31         CursorXHi       = 0x32,
32         CursorYLo       = 0x33,
33         CursorYHi       = 0x34,
34         CursorHotX      = 0x35,
35         CursorHotY      = 0x36,
36
37         CursorR1        = 0x40,
38         CursorG1        = 0x41,
39         CursorB1        = 0x42,
40         CursorR2        = 0x43,
41         CursorG2        = 0x44,
42         CursorB2        = 0x45,
43         CursorR3        = 0x46,
44         CursorG3        = 0x47,
45         CursorB3        = 0x48,
46
47         CursorArray     = 0x100,
48 };
49
50 /*
51  * Lower 2-bits of indirect DAC register
52  * addressing.
53  */
54 static ushort dacxreg[4] = {
55         PaddrW, Pdata, Pixmask, PaddrR
56 };
57
58 static uchar
59 rgb524setrs2(void)
60 {
61         uchar rs2;
62
63         rs2 = vgaxi(Crtx, 0x55);
64         vgaxo(Crtx, 0x55, (rs2 & 0xFC)|0x01);
65
66         return rs2;
67 }
68
69 static void
70 rgb524xo(int index, uchar data)
71 {
72         vgao(dacxreg[IndexLo], index & 0xFF);
73         vgao(dacxreg[IndexHi], (index>>8) & 0xFF);
74         vgao(dacxreg[Data], data);
75 }
76
77 static void
78 rgb524disable(VGAscr*)
79 {
80         uchar rs2;
81
82         rs2 = rgb524setrs2();
83         rgb524xo(CursorCtl, 0x00);
84         vgaxo(Crtx, 0x55, rs2);
85 }
86
87 static void
88 rgb524enable(VGAscr*)
89 {
90         uchar rs2;
91
92         rs2 = rgb524setrs2();
93
94         /*
95          * Make sure cursor is off by initialising the cursor
96          * control to defaults.
97          */
98         rgb524xo(CursorCtl, 0x00);
99
100         /*
101          * Cursor colour 1 (white),
102          * cursor colour 2 (black).
103          */
104         rgb524xo(CursorR1, Pwhite); rgb524xo(CursorG1, Pwhite); rgb524xo(CursorB1, Pwhite);
105         rgb524xo(CursorR2, Pblack); rgb524xo(CursorG2, Pblack); rgb524xo(CursorB2, Pblack);
106
107         /*
108          * Enable the cursor, 32x32, mode 2.
109          */
110         rgb524xo(CursorCtl, 0x23);
111
112         vgaxo(Crtx, 0x55, rs2);
113 }
114
115 static void
116 rgb524load(VGAscr*, Cursor* curs)
117 {
118         uchar p, p0, p1, rs2;
119         int x, y;
120
121         rs2 = rgb524setrs2();
122
123         /*
124          * Make sure cursor is off by initialising the cursor
125          * control to defaults.
126          */
127         rgb524xo(CursorCtl, 0x00);
128
129         /*
130          * Set auto-increment mode for index-register addressing
131          * and initialise the cursor array index.
132          */
133         vgao(dacxreg[IndexCtl], 0x01);
134         vgao(dacxreg[IndexLo], CursorArray & 0xFF);
135         vgao(dacxreg[IndexHi], (CursorArray>>8) & 0xFF);
136
137         /*
138          * Initialise the 32x32 cursor RAM array. There are 2 planes,
139          * p0 and p1. Data is written 4 pixels per byte, with p1 the
140          * MS bit of each pixel.
141          * The cursor is set in X-Windows mode which gives the following
142          * truth table:
143          *      p1 p0   colour
144          *       0  0   underlying pixel colour
145          *       0  1   underlying pixel colour
146          *       1  0   cursor colour 1
147          *       1  1   cursor colour 2
148          * Put the cursor into the top-left of the 32x32 array.
149          */
150         for(y = 0; y < 32; y++){
151                 for(x = 0; x < 32/8; x++){
152                         if(x < 16/8 && y < 16){
153                                 p0 = curs->clr[x+y*2];
154                                 p1 = curs->set[x+y*2];
155
156                                 p = 0x00;
157                                 if(p1 & 0x80)
158                                         p |= 0xC0;
159                                 else if(p0 & 0x80)
160                                         p |= 0x80;
161                                 if(p1 & 0x40)
162                                         p |= 0x30;
163                                 else if(p0 & 0x40)
164                                         p |= 0x20;
165                                 if(p1 & 0x20)
166                                         p |= 0x0C;
167                                 else if(p0 & 0x20)
168                                         p |= 0x08;
169                                 if(p1 & 0x10)
170                                         p |= 0x03;
171                                 else if(p0 & 0x10)
172                                         p |= 0x02;
173                                 vgao(dacxreg[Data], p);
174
175                                 p = 0x00;
176                                 if(p1 & 0x08)
177                                         p |= 0xC0;
178                                 else if(p0 & 0x08)
179                                         p |= 0x80;
180                                 if(p1 & 0x04)
181                                         p |= 0x30;
182                                 else if(p0 & 0x04)
183                                         p |= 0x20;
184                                 if(p1 & 0x02)
185                                         p |= 0x0C;
186                                 else if(p0 & 0x02)
187                                         p |= 0x08;
188                                 if(p1 & 0x01)
189                                         p |= 0x03;
190                                 else if(p0 & 0x01)
191                                         p |= 0x02;
192                                 vgao(dacxreg[Data], p);
193                         }
194                         else{
195                                 vgao(dacxreg[Data], 0x00);
196                                 vgao(dacxreg[Data], 0x00);
197                         }
198                 }
199         }
200
201         /*
202          * Initialise the cursor hotpoint,
203          * enable the cursor and restore state.
204          */
205         rgb524xo(CursorHotX, -curs->offset.x);
206         rgb524xo(CursorHotY, -curs->offset.y);
207
208         rgb524xo(CursorCtl, 0x23);
209
210         vgaxo(Crtx, 0x55, rs2);
211 }
212
213 static int
214 rgb524move(VGAscr*, Point p)
215 {
216         uchar rs2;
217
218         rs2 = rgb524setrs2();
219
220         rgb524xo(CursorXLo, p.x & 0xFF);
221         rgb524xo(CursorXHi, (p.x>>8) & 0x0F);
222         rgb524xo(CursorYLo, p.y & 0xFF);
223         rgb524xo(CursorYHi, (p.y>>8) & 0x0F);
224
225         vgaxo(Crtx, 0x55, rs2);
226
227         return 0;
228 }
229
230 VGAcur vgargb524cur = {
231         "rgb524hwgc",
232
233         rgb524enable,
234         rgb524disable,
235         rgb524load,
236         rgb524move,
237 };