9 #define SEQU_ADDR 0x3C4
\r
10 #define GRACON_ADDR 0x3CE
\r
11 #define CRTC_ADDR 0x3D4
\r
12 #define STATUS_ADDR 0x3DA
\r
18 wait_for_retrace(void)
\r
20 while (!(inp(STATUS_ADDR) & 0x08));
\r
25 setDrawPage(unsigned int page)
\r
27 activeStart = page_offset[page];
\r
32 setVisiblePage(unsigned int page)
\r
34 // setVisibleStart() tells the VGA from which byte to fetch the first
\r
35 // pixel when starting refresh at the top of the screen.
\r
36 visibleStart = page_offset[page];
\r
39 outpw(CRTC_ADDR, page_mask_high[page]);
\r
42 outpw(CRTC_ADDR, page_mask_low[page]);
\r
49 outpw(SEQU_ADDR, 0x0F02);
\r
50 memset((unsigned char *)(0xA000 << 4) + activeStart, color, 0x00010000);
\r
55 putpixelX(COORD x, COORD y, BYTE color)
\r
59 if (write_plane != (temp = (x & 3))) {
\r
61 outpw(SEQU_ADDR, plane_mask[temp]);
\r
64 *(RowsX[y] + (x >> 2) + activeStart) = color;
\r
69 getpixelX(COORD x, COORD y)
\r
73 if (read_plane != (temp = (x & 3))) {
\r
75 outpw(GRACON_ADDR, read_mask[temp]);
\r
78 return (*(RowsX[y] + (x >> 2) + activeStart));
\r
83 internal_vert_lineX(COORD x, COORD top_y, int len, BYTE color)
\r
88 if (write_plane != (temp = (x & 3))) {
\r
90 outpw(SEQU_ADDR, plane_mask[temp]);
\r
93 ptr = RowsX[top_y] + (x >> 2) + activeStart;
\r
103 internal_horiz_lineX(COORD left_x, COORD y, int len, BYTE color)
\r
108 ptr = RowsX[y] + (left_x >> 2) + activeStart;
\r
110 // Set current plane to invalid value
\r
113 if (temp = (left_x & 3)) {
\r
114 outp(SEQU_ADDR, 0x02);
\r
115 outp(0x3C5, line_head[temp]);
\r
120 if (temp = (len >> 2)) {
\r
121 outpw(SEQU_ADDR, 0x0F02);
\r
125 memset(ptr, color, temp);
\r
130 outp(SEQU_ADDR, 0x02);
\r
131 outp(0x3C5, line_tail[len]);
\r
138 boxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)
\r
142 xsize = (x2 - x1) + 1;
\r
143 internal_horiz_lineX(x1, y1, xsize, color);
\r
144 internal_horiz_lineX(x1, y2, xsize, color);
\r
149 internal_vert_lineX(x1, y1, ysize, color);
\r
150 internal_vert_lineX(x2, y1, ysize, color);
\r
155 filledboxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)
\r
160 short int i, xsize, ysize;
\r
162 // Set current plane to invalid value
\r
165 xsize = (x2 - x1) + 1;
\r
166 ysize = (y2 - y1) + 1;
\r
169 internal_horiz_lineX(x1, y1, xsize, color);
\r
173 base_ptr = RowsX[y1] + (x1 >> 2) + activeStart;
\r
175 if (temp = (x1 & 3)) {
\r
176 outp(SEQU_ADDR, 0x02);
\r
177 outp(0x3C5, line_head[temp]);
\r
184 xsize -= (4 - temp);
\r
188 if (temp = (xsize >> 2)) {
\r
189 outpw(SEQU_ADDR, 0x0F02);
\r
195 memset(ptr, color, temp);
\r
202 outp(SEQU_ADDR, 0x02);
\r
203 outp(0x3C5, line_tail[xsize]);
\r
206 base_ptr += widthBytes;
\r
213 circleX(COORD x, COORD y, DIST r, BYTE color)
\r
215 int ix, iy, d, deltaE, deltaSE;
\r
221 deltaSE = (-2 * r) + 5;
\r
223 putpixelX(x + ix, y + iy, color);
\r
224 putpixelX(x + ix, y - iy, color);
\r
225 putpixelX(x + iy, y + ix, color);
\r
226 putpixelX(x + iy, y - ix, color);
\r
227 putpixelX(x - ix, y + iy, color);
\r
228 putpixelX(x - ix, y - iy, color);
\r
229 putpixelX(x - iy, y + ix, color);
\r
230 putpixelX(x - iy, y - ix, color);
\r
232 while (iy > ix++) {
\r
244 putpixelX(x + ix, y + iy, color);
\r
245 putpixelX(x + ix, y - iy, color);
\r
246 putpixelX(x + iy, y + ix, color);
\r
247 putpixelX(x + iy, y - ix, color);
\r
248 putpixelX(x - ix, y + iy, color);
\r
249 putpixelX(x - ix, y - iy, color);
\r
250 putpixelX(x - iy, y + ix, color);
\r
251 putpixelX(x - iy, y - ix, color);
\r
257 filledcircleX(COORD x, COORD y, DIST r, BYTE color)
\r
259 int ix, iy, d, deltaE, deltaSE;
\r
265 deltaSE = (-2 * r) + 5;
\r
267 internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color);
\r
268 internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color);
\r
269 internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color);
\r
270 internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color);
\r
272 while (iy > ix++) {
\r
284 internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color);
\r
285 internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color);
\r
286 internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color);
\r
287 internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color);
\r
293 internal_xmajor(BYTE *vga_ptr, short int len, short int yskip,
\r
294 unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)
\r
299 *vga_ptr++ = color;
\r
300 ErrorAcc += ErrorAdj;
\r
302 if (ErrorAcc & ~0xFFFFL) {
\r
303 ErrorAcc &= 0xFFFFL;
\r
313 internal_middle(BYTE *vga_ptr, short int len, short int yskip,
\r
314 unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)
\r
319 *vga_ptr++ = color;
\r
320 ErrorAcc += ErrorAdj;
\r
321 vga_ptr += (yskip * (ErrorAcc >> 16));
\r
322 ErrorAcc &= 0xFFFFL;
\r
330 internal_ymajor(BYTE *vga_ptr, short int len, short int yskip,
\r
331 unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)
\r
333 unsigned long TinyAdj;
\r
337 TinyAdj = (ErrorAdj >> 2);
\r
338 ErrorAdj -= TinyAdj;
\r
342 ErrorAcc += TinyAdj;
\r
343 i = (ErrorAcc >> 16);
\r
344 ErrorAcc &= 0xFFFFL;
\r
351 ErrorAcc += ErrorAdj;
\r
352 vga_ptr += (yskip * (ErrorAcc >> 16)) + 1;
\r
353 ErrorAcc &= 0xFFFFL;
\r
355 ErrorAcc += TinyAdj;
\r
356 i = (ErrorAcc >> 16);
\r
366 lineX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)
\r
368 unsigned long ErrorAcc, ErrorAdj, TinyAdj;
\r
369 short int i, DeltaX, DeltaY, yskip;
\r
374 // Mode X 4-way folded Bresenham line function - by David Boeren
\r
376 // Set invalid plane, because we're screwing with the plane mask
\r
379 // Make sure the line runs left to right
\r
381 temp = x1; x1 = x2; x2 = temp;
\r
382 temp = y1; y1 = y2; y2 = temp;
\r
385 DeltaX = (x2 - x1);
\r
386 DeltaY = (y2 - y1);
\r
389 yskip = widthBytes;
\r
391 DeltaY = -DeltaY; // Make DeltaY positive
\r
392 yskip = -widthBytes;
\r
396 // Vertical Line (and one pixel lines)
\r
398 internal_vert_lineX(x1, y1, (DeltaY + 1), color);
\r
400 internal_vert_lineX(x1, y2, (DeltaY + 1), color);
\r
407 internal_horiz_lineX(x1, y1, (DeltaX + 1), color);
\r
411 vga_ptr = RowsX[y1] + (x1 >> 2) + activeStart;
\r
414 // Length of sub-line in each plane
\r
417 len[0] = ((i--) >> 2);
\r
418 len[1] = ((i--) >> 2);
\r
419 len[2] = ((i--) >> 2);
\r
420 len[3] = (i >> 2) + 1;
\r
422 for (i=temp; i < 3; i++) {
\r
426 if ((DeltaX >> 2) >= DeltaY) {
\r
427 // X-Major line (0.00 < slope <= 0.25)
\r
428 ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));
\r
429 TinyAdj = (ErrorAdj >> 2);
\r
431 outpw(SEQU_ADDR, plane_mask[temp]);
\r
432 internal_xmajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);
\r
437 ErrorAcc += TinyAdj;
\r
438 if (ErrorAcc & ~0xFFFFL) {
\r
439 ErrorAcc &= 0xFFFFL;
\r
443 outpw(SEQU_ADDR, plane_mask[temp]);
\r
444 internal_xmajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);
\r
445 } else if (DeltaX >= DeltaY) {
\r
446 // Middle line (0.25 < slope <= 1.00)
\r
447 ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));
\r
448 TinyAdj = (ErrorAdj >> 2);
\r
450 outpw(SEQU_ADDR, plane_mask[temp]);
\r
451 internal_middle(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);
\r
456 ErrorAcc += TinyAdj;
\r
457 if (ErrorAcc & ~0xFFFFL) {
\r
459 ErrorAcc &= 0xFFFFL;
\r
462 outpw(SEQU_ADDR, plane_mask[temp]);
\r
463 internal_middle(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);
\r
465 // Y-Major line (slope > 1)
\r
466 ErrorAdj = ((((unsigned long)(DeltaY+1) << 18) /
\r
467 (unsigned long)(DeltaX+1)));
\r
468 TinyAdj = (ErrorAdj >> 2);
\r
470 outpw(SEQU_ADDR, plane_mask[temp]);
\r
471 internal_ymajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);
\r
476 ErrorAcc += TinyAdj;
\r
477 vga_ptr += (yskip * (ErrorAcc >> 16));
\r
478 ErrorAcc &= 0xFFFFL;
\r
480 outpw(SEQU_ADDR, plane_mask[temp]);
\r
481 internal_ymajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);
\r
487 loadfontX(char *fname)
\r
491 fp = fopen(fname, "rb");
\r
496 fread(Xfont, 8, 256, fp);
\r
504 putchX(COORD x, COORD y, char c, BYTE color)
\r
512 vga_ptr = RowsX[y << 3] + (x << 1) + activeStart;
\r
515 font_ptr = Xfont + (c << 3);
\r
519 temp = *font_ptr++;
\r
520 outpw(SEQU_ADDR, text_mask[temp & 0x0F]);
\r
521 *vga_ptr++ = color;
\r
523 outpw(SEQU_ADDR, text_mask[temp >> 4]);
\r
524 *vga_ptr-- = color;
\r
525 vga_ptr += widthBytes;
\r
531 putstringX(COORD x, COORD y, char *str, BYTE color)
\r
539 vga_ptr = RowsX[y << 3] + (x << 1) + activeStart;
\r
542 skip = 2 - (widthBytes << 3);
\r
544 while (c = *str++) {
\r
545 font_ptr = Xfont + (c << 3);
\r
549 temp = *font_ptr++;
\r
550 outpw(SEQU_ADDR, text_mask[temp & 0x0F]);
\r
551 *vga_ptr++ = color;
\r
553 outpw(SEQU_ADDR, text_mask[temp >> 4]);
\r
554 *vga_ptr-- = color;
\r
555 vga_ptr += widthBytes;
\r