b964be191cf894ced3b1ea5286d2dfa28de38340
[reactos.git] / reactos / drivers / dd / vga / miniport / vgavideo.c
1 #include "vgavideo.h"
2
3 #define VIDMEM_BASE 0xa0000
4 char* vidmem = (char *)(VIDMEM_BASE);
5
6 div_t div(int num, int denom)
7 {
8 div_t r;
9 if (num > 0 && denom < 0) {
10 num = -num;
11 denom = -denom;
12 }
13 r.quot = num / denom;
14 r.rem = num % denom;
15 if (num < 0 && denom > 0)
16 {
17 if (r.rem > 0)
18 {
19 r.quot++;
20 r.rem -= denom;
21 }
22 }
23 return r;
24 }
25
26 int mod(int num, int denom)
27 {
28 div_t dvt = div(num, denom);
29 return dvt.rem;
30 }
31
32 VOID vgaPreCalc()
33 {
34 ULONG j;
35
36 startmasks[1] = 127;
37 startmasks[2] = 63;
38 startmasks[3] = 31;
39 startmasks[4] = 15;
40 startmasks[5] = 7;
41 startmasks[6] = 3;
42 startmasks[7] = 1;
43 startmasks[8] = 255;
44
45 endmasks[0] = 128;
46 endmasks[1] = 192;
47 endmasks[2] = 224;
48 endmasks[3] = 240;
49 endmasks[4] = 248;
50 endmasks[5] = 252;
51 endmasks[6] = 254;
52 endmasks[7] = 255;
53 endmasks[8] = 255;
54
55 for(j=0; j<80; j++)
56 {
57 maskbit[j*8] = 128;
58 maskbit[j*8+1] = 64;
59 maskbit[j*8+2] = 32;
60 maskbit[j*8+3] = 16;
61 maskbit[j*8+4] = 8;
62 maskbit[j*8+5] = 4;
63 maskbit[j*8+6] = 2;
64 maskbit[j*8+7] = 1;
65
66 bit8[j*8] = 7;
67 bit8[j*8+1] = 6;
68 bit8[j*8+2] = 5;
69 bit8[j*8+3] = 4;
70 bit8[j*8+4] = 3;
71 bit8[j*8+5] = 2;
72 bit8[j*8+6] = 1;
73 bit8[j*8+7] = 0;
74 }
75 for(j=0; j<480; j++)
76 {
77 y80[j] = j*80;
78 }
79 for(j=0; j<640; j++)
80 {
81 xconv[j] = j >> 3;
82 }
83 }
84
85 void vgaSetWriteMode(char mode)
86 {
87 VideoPortWritePortUchar((PUCHAR)0x03ce, 0x03);
88 VideoPortWritePortUchar((PUCHAR)0x03cf, mode);
89 }
90
91 void vgaSetColor(int cindex, int red, int green, int blue)
92 {
93 VideoPortWritePortUchar((PUCHAR)0x03c8, cindex);
94 VideoPortWritePortUchar((PUCHAR)0x03c9, red);
95 VideoPortWritePortUchar((PUCHAR)0x03c9, green);
96 VideoPortWritePortUchar((PUCHAR)0x03c9, blue);
97 }
98
99 void vgaPutPixel(int x, int y, unsigned char c)
100 {
101 unsigned offset;
102 unsigned char a;
103
104 offset = xconv[x]+y80[y];
105
106 VideoPortWritePortUchar((PUCHAR)0x3ce,0x08); // Set
107 VideoPortWritePortUchar((PUCHAR)0x3cf,maskbit[x]); // the MASK
108 VideoPortWritePortUshort((PUSHORT)0x3ce,0x0205); // write mode = 2 (bits 0,1)
109 // read mode = 0 (bit 3
110 a = vidmem[offset]; // Update bit buffer
111 vidmem[offset] = c; // Write the pixel
112 }
113
114 void vgaPutByte(int x, int y, unsigned char c)
115 {
116 unsigned offset;
117
118 offset = xconv[x]+y80[y];
119
120 // Set mask to all pixels in byte
121 VideoPortWritePortUchar((PUCHAR)0x3ce,0x08);
122 VideoPortWritePortUchar((PUCHAR)0x3cf,0xff);
123
124 vidmem[offset]=c;
125 }
126
127 void vgaGetByte(unsigned offset,
128 unsigned char *b, unsigned char *g,
129 unsigned char *r, unsigned char *i)
130 {
131 VideoPortWritePortUshort((PUSHORT)0x03ce, 0x0304);
132 *i = vidmem[offset];
133 VideoPortWritePortUshort((PUSHORT)0x03ce, 0x0204);
134 *r = vidmem[offset];
135 VideoPortWritePortUshort((PUSHORT)0x03ce, 0x0104);
136 *g = vidmem[offset];
137 VideoPortWritePortUshort((PUSHORT)0x03ce, 0x0004);
138 *b = vidmem[offset];
139 }
140
141 int vgaGetPixel(int x, int y)
142 {
143 unsigned char mask, b, g, r, i;
144 unsigned offset;
145
146 offset = xconv[x]+y80[y];
147 mask=maskbit[x];
148 vgaGetByte(offset, &b, &g, &r, &i);
149 b=b&mask;
150 g=g&mask;
151 r=r&mask;
152 i=i&mask;
153
154 mask=bit8[x];
155 g=g>>mask;
156 b=b>>mask;
157 r=r>>mask;
158 i=i>>mask;
159
160 return(b+2*g+4*r+8*i);
161 }
162
163 BOOL vgaHLine(int x, int y, int len, unsigned char c)
164 {
165 unsigned char a;
166 unsigned int pre1, i;
167 unsigned int orgpre1, orgx, midpre1;
168 unsigned long leftpixs, midpixs, rightpixs, temp;
169
170 orgx=x;
171
172 if(len<8)
173 {
174 for (i=x; i<x+len; i++)
175 vgaPutPixel(i, y, c);
176 } else {
177
178 leftpixs=x;
179 while(leftpixs>8) leftpixs-=8;
180 temp = len;
181 midpixs = 0;
182
183 while(temp>7)
184 {
185 temp-=8;
186 midpixs++;
187 }
188 if((temp>=0) && (midpixs>0)) midpixs--;
189
190 pre1=xconv[x]+y80[y];
191 orgpre1=pre1;
192
193 // Left
194 if(leftpixs==8) {
195 // Left edge should be an entire middle bar
196 x=orgx;
197 leftpixs=0;
198 }
199 else if(leftpixs>0)
200 {
201 VideoPortWritePortUchar((PUCHAR)0x3ce,0x08); // Set
202 VideoPortWritePortUchar((PUCHAR)0x3cf,startmasks[leftpixs]); // the MASK
203 VideoPortWritePortUshort((PUSHORT)0x3ce,0x0205); // write mode = 2 (bits 0,1)
204 // read mode = 0 (bit 3
205 a = vidmem[pre1]; // Update bit buffer
206 vidmem[pre1] = c; // Write the pixel
207
208 // Middle
209 x=orgx+(8-leftpixs)+leftpixs;
210
211 } else {
212 // leftpixs == 0
213 midpixs+=1;
214 }
215
216 if(midpixs>0)
217 {
218 midpre1=xconv[x]+y80[y];
219
220 // Set mask to all pixels in byte
221 VideoPortWritePortUchar((PUCHAR)0x3ce, 0x08);
222 VideoPortWritePortUchar((PUCHAR)0x3cf, 0xff);
223 memset(vidmem+midpre1, c, midpixs);
224 }
225
226 rightpixs = len - ((midpixs*8) + leftpixs);
227
228 if((rightpixs>0))
229 {
230 x=(orgx+len)-rightpixs;
231
232 // Go backwards till we reach the 8-byte boundary
233 while(mod(x, 8)!=0) { x--; rightpixs++; }
234
235 while(rightpixs>7)
236 {
237 // This is a BAD case as this should have been a midpixs
238
239 vgaPutByte(x, y, c);
240 rightpixs-=8;
241 x+=8;
242 }
243
244 pre1=xconv[x]+y80[y];
245 VideoPortWritePortUchar((PUCHAR)0x3ce,0x08); // Set
246 VideoPortWritePortUchar((PUCHAR)0x3cf,endmasks[rightpixs]); // the MASK
247 VideoPortWritePortUshort((PUSHORT)0x3ce,0x0205); // write mode = 2 (bits 0,1)
248 // read mode = 0 (bit 3
249 a = vidmem[pre1]; // Update bit buffer
250 vidmem[pre1] = c; // Write the pixel
251 }
252 }
253
254 return TRUE;
255 }
256
257 BOOL vgaVLine(int x, int y, int len, unsigned char c)
258 {
259 unsigned offset, i;
260 unsigned char a;
261
262 offset = xconv[x]+y80[y];
263
264 VideoPortWritePortUchar((PUCHAR)0x3ce,0x08); // Set
265 VideoPortWritePortUchar((PUCHAR)0x3cf,maskbit[x]); // the MASK
266 VideoPortWritePortUshort((PUSHORT)0x3ce,0x0205); // write mode = 2 (bits 0,1)
267 // read mode = 0 (bit 3)
268 len++;
269
270 for(i=y; i<y+len; i++)
271 {
272 a = vidmem[offset]; // Update bit buffer
273 vidmem[offset] = c; // Write the pixel
274 offset+=80;
275 }
276
277 return TRUE;
278 }