--- /dev/null
+#include <conio.h>\r
+#include <dos.h>\r
+#include <mem.h>\r
+#include <stdio.h>\r
+\r
+#include "modex.hpp"\r
+#include "xprim.hpp"\r
+\r
+#define SEQU_ADDR 0x3C4\r
+#define GRACON_ADDR 0x3CE\r
+#define CRTC_ADDR 0x3D4\r
+#define STATUS_ADDR 0x3DA\r
+\r
+BYTE Xfont[2048];\r
+\r
+\r
+void\r
+wait_for_retrace(void)\r
+{\r
+ while (!(inp(STATUS_ADDR) & 0x08));\r
+}\r
+\r
+\r
+void\r
+setDrawPage(unsigned int page)\r
+{\r
+ activeStart = page_offset[page];\r
+}\r
+\r
+\r
+void\r
+setVisiblePage(unsigned int page)\r
+{\r
+ // setVisibleStart() tells the VGA from which byte to fetch the first\r
+ // pixel when starting refresh at the top of the screen.\r
+ visibleStart = page_offset[page];\r
+\r
+ // set high byte\r
+ outpw(CRTC_ADDR, page_mask_high[page]);\r
+\r
+ // set low byte\r
+ outpw(CRTC_ADDR, page_mask_low[page]);\r
+}\r
+\r
+\r
+void\r
+clearX(BYTE color)\r
+{\r
+ outpw(SEQU_ADDR, 0x0F02);\r
+ memset((unsigned char *)(0xA000 << 4) + activeStart, color, 0x00010000);\r
+}\r
+\r
+\r
+void\r
+putpixelX(COORD x, COORD y, BYTE color)\r
+{\r
+ BYTE temp;\r
+\r
+ if (write_plane != (temp = (x & 3))) {\r
+ write_plane = temp;\r
+ outpw(SEQU_ADDR, plane_mask[temp]);\r
+ }\r
+\r
+ *(RowsX[y] + (x >> 2) + activeStart) = color;\r
+}\r
+\r
+\r
+BYTE\r
+getpixelX(COORD x, COORD y)\r
+{\r
+ BYTE temp;\r
+\r
+ if (read_plane != (temp = (x & 3))) {\r
+ read_plane = temp;\r
+ outpw(GRACON_ADDR, read_mask[temp]);\r
+ }\r
+\r
+ return (*(RowsX[y] + (x >> 2) + activeStart));\r
+}\r
+\r
+\r
+void\r
+internal_vert_lineX(COORD x, COORD top_y, int len, BYTE color)\r
+{\r
+ BYTE *ptr;\r
+ BYTE temp;\r
+\r
+ if (write_plane != (temp = (x & 3))) {\r
+ write_plane = temp;\r
+ outpw(SEQU_ADDR, plane_mask[temp]);\r
+ }\r
+\r
+ ptr = RowsX[top_y] + (x >> 2) + activeStart;\r
+\r
+ while (len--) {\r
+ *ptr = color;\r
+ ptr += widthBytes;\r
+ }\r
+}\r
+\r
+\r
+void\r
+internal_horiz_lineX(COORD left_x, COORD y, int len, BYTE color)\r
+{\r
+ BYTE *ptr;\r
+ BYTE temp;\r
+\r
+ ptr = RowsX[y] + (left_x >> 2) + activeStart;\r
+\r
+ // Set current plane to invalid value\r
+ write_plane = -1;\r
+\r
+ if (temp = (left_x & 3)) {\r
+ outp(SEQU_ADDR, 0x02);\r
+ outp(0x3C5, line_head[temp]);\r
+ *ptr++ = color;\r
+ len -= (4 - temp);\r
+ }\r
+\r
+ if (temp = (len >> 2)) {\r
+ outpw(SEQU_ADDR, 0x0F02);\r
+\r
+ len &= 3;\r
+\r
+ memset(ptr, color, temp);\r
+ ptr += temp;\r
+ }\r
+\r
+ if (len) {\r
+ outp(SEQU_ADDR, 0x02);\r
+ outp(0x3C5, line_tail[len]);\r
+ *ptr = color;\r
+ }\r
+}\r
+\r
+\r
+void\r
+boxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)\r
+{\r
+ int xsize, ysize;\r
+\r
+ xsize = (x2 - x1) + 1;\r
+ internal_horiz_lineX(x1, y1, xsize, color);\r
+ internal_horiz_lineX(x1, y2, xsize, color);\r
+\r
+ y1++;\r
+ ysize = (y2 - y1);\r
+\r
+ internal_vert_lineX(x1, y1, ysize, color);\r
+ internal_vert_lineX(x2, y1, ysize, color);\r
+}\r
+\r
+\r
+void\r
+filledboxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)\r
+{\r
+ BYTE *base_ptr;\r
+ BYTE *ptr;\r
+ BYTE temp;\r
+ short int i, xsize, ysize;\r
+\r
+ // Set current plane to invalid value\r
+ write_plane = -1;\r
+\r
+ xsize = (x2 - x1) + 1;\r
+ ysize = (y2 - y1) + 1;\r
+\r
+ if (ysize == 1) {\r
+ internal_horiz_lineX(x1, y1, xsize, color);\r
+ return;\r
+ }\r
+\r
+ base_ptr = RowsX[y1] + (x1 >> 2) + activeStart;\r
+\r
+ if (temp = (x1 & 3)) {\r
+ outp(SEQU_ADDR, 0x02);\r
+ outp(0x3C5, line_head[temp]);\r
+ ptr = base_ptr;\r
+ i=ysize;\r
+ while (i--) {\r
+ *ptr = color;\r
+ ptr += widthBytes;\r
+ }\r
+ xsize -= (4 - temp);\r
+ base_ptr++;\r
+ }\r
+\r
+ if (temp = (xsize >> 2)) {\r
+ outpw(SEQU_ADDR, 0x0F02);\r
+\r
+ xsize &= 3;\r
+ ptr = base_ptr;\r
+ i=ysize;\r
+ while (i--) {\r
+ memset(ptr, color, temp);\r
+ ptr += widthBytes;\r
+ }\r
+ base_ptr += temp;\r
+ }\r
+\r
+ if (xsize) {\r
+ outp(SEQU_ADDR, 0x02);\r
+ outp(0x3C5, line_tail[xsize]);\r
+ while (ysize--) {\r
+ *base_ptr = color;\r
+ base_ptr += widthBytes;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+void\r
+circleX(COORD x, COORD y, DIST r, BYTE color)\r
+{\r
+ int ix, iy, d, deltaE, deltaSE;\r
+\r
+ ix = 0;\r
+ iy = r;\r
+ d = 1 - r;\r
+ deltaE = 3;\r
+ deltaSE = (-2 * r) + 5;\r
+\r
+ putpixelX(x + ix, y + iy, color);\r
+ putpixelX(x + ix, y - iy, color);\r
+ putpixelX(x + iy, y + ix, color);\r
+ putpixelX(x + iy, y - ix, color);\r
+ putpixelX(x - ix, y + iy, color);\r
+ putpixelX(x - ix, y - iy, color);\r
+ putpixelX(x - iy, y + ix, color);\r
+ putpixelX(x - iy, y - ix, color);\r
+\r
+ while (iy > ix++) {\r
+ if (d < 0) {\r
+ d += deltaE;\r
+ deltaE += 2;\r
+ deltaSE += 2;\r
+ } else {\r
+ d += deltaSE;\r
+ deltaE += 2;\r
+ deltaSE += 4;\r
+ iy--;\r
+ }\r
+\r
+ putpixelX(x + ix, y + iy, color);\r
+ putpixelX(x + ix, y - iy, color);\r
+ putpixelX(x + iy, y + ix, color);\r
+ putpixelX(x + iy, y - ix, color);\r
+ putpixelX(x - ix, y + iy, color);\r
+ putpixelX(x - ix, y - iy, color);\r
+ putpixelX(x - iy, y + ix, color);\r
+ putpixelX(x - iy, y - ix, color);\r
+ }\r
+}\r
+\r
+\r
+void\r
+filledcircleX(COORD x, COORD y, DIST r, BYTE color)\r
+{\r
+ int ix, iy, d, deltaE, deltaSE;\r
+\r
+ ix = 0;\r
+ iy = r;\r
+ d = 1 - r;\r
+ deltaE = 3;\r
+ deltaSE = (-2 * r) + 5;\r
+\r
+ internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color);\r
+ internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color);\r
+ internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color);\r
+ internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color);\r
+\r
+ while (iy > ix++) {\r
+ if (d < 0) {\r
+ d += deltaE;\r
+ deltaE += 2;\r
+ deltaSE += 2;\r
+ } else {\r
+ d += deltaSE;\r
+ deltaE += 2;\r
+ deltaSE += 4;\r
+ iy--;\r
+ }\r
+\r
+ internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color);\r
+ internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color);\r
+ internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color);\r
+ internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color);\r
+ }\r
+}\r
+\r
+\r
+void\r
+internal_xmajor(BYTE *vga_ptr, short int len, short int yskip,\r
+ unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)\r
+{\r
+ if (len) {\r
+ len--;\r
+ while (len--) {\r
+ *vga_ptr++ = color;\r
+ ErrorAcc += ErrorAdj;\r
+\r
+ if (ErrorAcc & ~0xFFFFL) {\r
+ ErrorAcc &= 0xFFFFL;\r
+ vga_ptr += yskip;\r
+ }\r
+ }\r
+ *vga_ptr = color;\r
+ }\r
+}\r
+\r
+\r
+void\r
+internal_middle(BYTE *vga_ptr, short int len, short int yskip,\r
+ unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)\r
+{\r
+ if (len) {\r
+ len--;\r
+ while (len--) {\r
+ *vga_ptr++ = color;\r
+ ErrorAcc += ErrorAdj;\r
+ vga_ptr += (yskip * (ErrorAcc >> 16));\r
+ ErrorAcc &= 0xFFFFL;\r
+ }\r
+ *vga_ptr = color;\r
+ }\r
+}\r
+\r
+\r
+void\r
+internal_ymajor(BYTE *vga_ptr, short int len, short int yskip,\r
+ unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)\r
+{\r
+ unsigned long TinyAdj;\r
+ short int i;\r
+\r
+ if (len) {\r
+ TinyAdj = (ErrorAdj >> 2);\r
+ ErrorAdj -= TinyAdj;\r
+\r
+ len--;\r
+ while (len--) {\r
+ ErrorAcc += TinyAdj;\r
+ i = (ErrorAcc >> 16);\r
+ ErrorAcc &= 0xFFFFL;\r
+\r
+ while (i--) {\r
+ *vga_ptr = color;\r
+ vga_ptr += yskip;\r
+ }\r
+\r
+ ErrorAcc += ErrorAdj;\r
+ vga_ptr += (yskip * (ErrorAcc >> 16)) + 1;\r
+ ErrorAcc &= 0xFFFFL;\r
+ }\r
+ ErrorAcc += TinyAdj;\r
+ i = (ErrorAcc >> 16);\r
+ while (i--) {\r
+ *vga_ptr = color;\r
+ vga_ptr += yskip;\r
+ }\r
+ }\r
+}\r
+\r
+\r
+void\r
+lineX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)\r
+{\r
+ unsigned long ErrorAcc, ErrorAdj, TinyAdj;\r
+ short int i, DeltaX, DeltaY, yskip;\r
+ short int len[4];\r
+ BYTE *vga_ptr;\r
+ COORD temp;\r
+\r
+ // Mode X 4-way folded Bresenham line function - by David Boeren\r
+\r
+ // Set invalid plane, because we're screwing with the plane mask\r
+ write_plane = -1;\r
+\r
+ // Make sure the line runs left to right\r
+ if (x1 > x2) {\r
+ temp = x1; x1 = x2; x2 = temp;\r
+ temp = y1; y1 = y2; y2 = temp;\r
+ }\r
+\r
+ DeltaX = (x2 - x1);\r
+ DeltaY = (y2 - y1);\r
+\r
+ if (DeltaY >= 0) {\r
+ yskip = widthBytes;\r
+ } else {\r
+ DeltaY = -DeltaY; // Make DeltaY positive\r
+ yskip = -widthBytes;\r
+ }\r
+\r
+ if (DeltaX == 0) {\r
+ // Vertical Line (and one pixel lines)\r
+ if (yskip > 0) {\r
+ internal_vert_lineX(x1, y1, (DeltaY + 1), color);\r
+ } else {\r
+ internal_vert_lineX(x1, y2, (DeltaY + 1), color);\r
+ }\r
+ return;\r
+ }\r
+\r
+ if (DeltaY == 0) {\r
+ // Horizontal Line\r
+ internal_horiz_lineX(x1, y1, (DeltaX + 1), color);\r
+ return;\r
+ }\r
+\r
+ vga_ptr = RowsX[y1] + (x1 >> 2) + activeStart;\r
+ ErrorAcc = 0x8000;\r
+\r
+ // Length of sub-line in each plane\r
+ temp = (x1 & 3);\r
+ i = DeltaX + temp;\r
+ len[0] = ((i--) >> 2);\r
+ len[1] = ((i--) >> 2);\r
+ len[2] = ((i--) >> 2);\r
+ len[3] = (i >> 2) + 1;\r
+\r
+ for (i=temp; i < 3; i++) {\r
+ len[i]++;\r
+ }\r
+\r
+ if ((DeltaX >> 2) >= DeltaY) {\r
+ // X-Major line (0.00 < slope <= 0.25)\r
+ ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));\r
+ TinyAdj = (ErrorAdj >> 2);\r
+ while (i--) {\r
+ outpw(SEQU_ADDR, plane_mask[temp]);\r
+ internal_xmajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);\r
+ if (temp == 4) {\r
+ temp = 0;\r
+ vga_ptr++;\r
+ }\r
+ ErrorAcc += TinyAdj;\r
+ if (ErrorAcc & ~0xFFFFL) {\r
+ ErrorAcc &= 0xFFFFL;\r
+ vga_ptr += yskip;\r
+ }\r
+ }\r
+ outpw(SEQU_ADDR, plane_mask[temp]);\r
+ internal_xmajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);\r
+ } else if (DeltaX >= DeltaY) {\r
+ // Middle line (0.25 < slope <= 1.00)\r
+ ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));\r
+ TinyAdj = (ErrorAdj >> 2);\r
+ while (i--) {\r
+ outpw(SEQU_ADDR, plane_mask[temp]);\r
+ internal_middle(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);\r
+ if (temp == 4) {\r
+ temp = 0;\r
+ vga_ptr++;\r
+ }\r
+ ErrorAcc += TinyAdj;\r
+ if (ErrorAcc & ~0xFFFFL) {\r
+ vga_ptr += yskip;\r
+ ErrorAcc &= 0xFFFFL;\r
+ }\r
+ }\r
+ outpw(SEQU_ADDR, plane_mask[temp]);\r
+ internal_middle(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);\r
+ } else {\r
+ // Y-Major line (slope > 1)\r
+ ErrorAdj = ((((unsigned long)(DeltaY+1) << 18) /\r
+ (unsigned long)(DeltaX+1)));\r
+ TinyAdj = (ErrorAdj >> 2);\r
+ while (i--) {\r
+ outpw(SEQU_ADDR, plane_mask[temp]);\r
+ internal_ymajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);\r
+ if (temp == 4) {\r
+ temp = 0;\r
+ vga_ptr++;\r
+ }\r
+ ErrorAcc += TinyAdj;\r
+ vga_ptr += (yskip * (ErrorAcc >> 16));\r
+ ErrorAcc &= 0xFFFFL;\r
+ }\r
+ outpw(SEQU_ADDR, plane_mask[temp]);\r
+ internal_ymajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);\r
+ }\r
+}\r
+\r
+\r
+int\r
+loadfontX(char *fname)\r
+{\r
+ FILE *fp;\r
+\r
+ fp = fopen(fname, "rb");\r
+\r
+ if (fp == NULL) {\r
+ return 0;\r
+ } else {\r
+ fread(Xfont, 8, 256, fp);\r
+ fclose(fp);\r
+ return 1;\r
+ }\r
+}\r
+\r
+\r
+void\r
+putchX(COORD x, COORD y, char c, BYTE color)\r
+{\r
+ int i;\r
+ BYTE *vga_ptr;\r
+ BYTE *font_ptr;\r
+ BYTE temp;\r
+\r
+ // 8x8 font\r
+ vga_ptr = RowsX[y << 3] + (x << 1) + activeStart;\r
+ write_plane = -1;\r
+\r
+ font_ptr = Xfont + (c << 3);\r
+\r
+ i=8;\r
+ while (i--) {\r
+ temp = *font_ptr++;\r
+ outpw(SEQU_ADDR, text_mask[temp & 0x0F]);\r
+ *vga_ptr++ = color;\r
+\r
+ outpw(SEQU_ADDR, text_mask[temp >> 4]);\r
+ *vga_ptr-- = color;\r
+ vga_ptr += widthBytes;\r
+ }\r
+}\r
+\r
+\r
+void\r
+putstringX(COORD x, COORD y, char *str, BYTE color)\r
+{\r
+ int i, skip;\r
+ BYTE *vga_ptr;\r
+ BYTE *font_ptr;\r
+ BYTE c, temp;\r
+\r
+ // 8x8 font\r
+ vga_ptr = RowsX[y << 3] + (x << 1) + activeStart;\r
+ write_plane = -1;\r
+\r
+ skip = 2 - (widthBytes << 3);\r
+\r
+ while (c = *str++) {\r
+ font_ptr = Xfont + (c << 3);\r
+\r
+ i=8;\r
+ while (i--) {\r
+ temp = *font_ptr++;\r
+ outpw(SEQU_ADDR, text_mask[temp & 0x0F]);\r
+ *vga_ptr++ = color;\r
+\r
+ outpw(SEQU_ADDR, text_mask[temp >> 4]);\r
+ *vga_ptr-- = color;\r
+ vga_ptr += widthBytes;\r
+ }\r
+\r
+ vga_ptr += skip;\r
+ }\r
+}\r
+\r