latest DOS updates (Daniel Borca)
diff --git a/docs/README.DJ b/docs/README.DJ
index 6589f52..1316761 100644
--- a/docs/README.DJ
+++ b/docs/README.DJ
@@ -32,8 +32,9 @@
      Environment variables:

 	CPU		optimize for the given processor.

 			default = k6

-	SGI_GLU=1	build SGI's GLU instead of Mesa's.

-			default = no

+	GLU=[src|si]	specify GLU directory; can be `src' (src-glu = Mesa)

+			or `si' (si-glu = SGI's GLU -- requires GNU/C++).

+			default = src

 	GLIDE		path to Glide3 SDK include files; used with FX.

 			default = $(TOP)/include/glide3

 	FX=1		build for 3dfx Glide3. Note that this disables

@@ -41,6 +42,9 @@
 			As a consequence, you'll need the DJGPP Glide3

 			library to build any application.

 			default = no

+	MATROX=1	build for Matrox Millennium I (MGA2064W) cards.

+			This is experimental and not intensively tested.

+			default = no

 	HAVE_X86=1	optimize for i386.

 			default = no

 	HAVE_MMX=1	allow MMX specializations, provided your assembler

@@ -81,6 +85,15 @@
    A) You need LFN support.

    A) When compiling for Glide (FX=1), pay attention to Glide path.

 

+   Q) Libraries built OK, but linker complains about `vsnprintf' every time I

+      compile some demo.

+   A) Upgrade to DJGPP 2.04.

+   A) Add `vsnprintf.c' to the CORE_SOURCES in `src/Makefile.DJ' (untested!).

+   A) The following hack should be safe in 90% of the cases, but if anything

+      goes wrong, don't come back to me crying. Anyway, patch `src/imports.c'

+      with the following line:

+	#define vsnprintf(buf, max, fmt, arg) vsprintf(buf, fmt, arg)

+

 2. Dynamic modules

 

    Q) What are you mumbling about dynamic modules?

@@ -103,9 +116,10 @@
 3. Using Mesa for DJGPP

 

    Q) DMesa is so SLOOOW! The Win32 OpenGL performs so much better...

-   A) Is that a question? If you have a Voodoo3/Banshee card, you're lucky. The

-      Glide port is on my web page. If you haven't, sorry; everything is done

-      in software. Suggestions?

+   A) Is that a question? If you have a Voodoo3/Banshee card, you're lucky (the

+      Glide port is on my web page). If you have a Matrox Millennium I card,

+      you just MIGHT be lucky... If you haven't, sorry; everything is done in

+      software. Suggestions?

 

    Q) I tried to set refresh rate w/ DMesa, but without success.

    A) Refresh rate control works only for VESA 3.0. If you were compiling for

@@ -113,15 +127,12 @@
 

    Q) I made a simple application and it does nothing. It exits right away. Not

       even a blank screen.

-   A) Only DMesa+FX supports single-buffered. The standard VESA/VGA drivers

-      will always work in double-buffered modes. If/When I will find a way to

-      use *REAL* hardware acceleration for a specific card, it might or might

-      not support single-buffered modes.

+   A) The pure software drivers (VESA/VGA) support only double-buffered modes.

    A) Another weird "feature" is that buffer width must be multiple of 8 (I'm a

       lazy programmer and I found that the easiest way to keep buffer handling

       at peak performance ;-).

 

-   Q) My demo doesn't display text. I know I used the glut font routines!

+   Q) My demo doesn't display text. I know I used the GLUT font routines!

    A) Then you probably use GLUT as a DXE. Well, there is no direct access to

       variables due to the way DXE works. Read the documentation. The author of

       GLUT took this into account for _WIN32 DLL's only; I don't want to modify

@@ -196,15 +207,17 @@
 	* synced w/ Mesa-4.1

 	- removed dmesadxe.h

 

-v1.3 (jan-2003)

+v1.3 (feb-2003)

 	+ enabled OpenGL 1.4 support

 	+ added MMX clear/blit routines

 	+ enabled SGI's GLU compilation

+	+ added samples makefile

 	+ added new GLUT functions

 	+ added color-index modes

+	+ added Matrox Millennium MGA2064W driver

 	+ added 8bit FakeColor (thanks to Neil Funk)

 	+ added VGA support (to keep Ben Decker happy)

-	* fixed GLUT compilation error (reported by Chan Kar Heng)

+	! fixed GLUT compilation error (reported by Chan Kar Heng)

 	* overhauled virtual buffer and internal video drivers

 	* better fxMesa integration

 	* revamped GLUT

diff --git a/include/GL/dmesa.h b/include/GL/dmesa.h
index 16f6bff..2c0ef81 100644
--- a/include/GL/dmesa.h
+++ b/include/GL/dmesa.h
@@ -87,6 +87,11 @@
  */

 void DMesaDestroyContext (DMesaContext c);

 

+/*

+ * Return a handle to the current context.

+ */

+DMesaContext DMesaGetCurrentContext (void);

+

 

 

 /*

@@ -101,21 +106,17 @@
  */

 void DMesaDestroyBuffer (DMesaBuffer b);

 

-

-

-/*

- * Bind Buffer to Context and make the Context the current one.

- */

-GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b);

-

-

-

 /*

  * Swap the front and back buffers for the given Buffer.

  * No action is taken if the buffer is not double buffered.

  */

 void DMesaSwapBuffers (DMesaBuffer b);

 

+/*

+ * Bind Buffer to Context and make the Context the current one.

+ */

+GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b);

+

 

 

 /*

@@ -132,10 +133,12 @@
 /*

  * DMesa state retrieval.

  */

-#define DMESA_Y_ORIGIN    0x0100

-#define DMESA_SCREEN_SIZE 0x0101

-#define DMESA_ARGB_ORDER  0x0200

-void DMesaGetIntegerv (GLenum pname, GLint *params);

+#define DMESA_GET_SCREEN_SIZE 0x0100

+#define DMESA_GET_DRIVER_CAPS 0x0200

+

+#define DMESA_DRIVER_SWDB_BIT 0x1 /* software double-buffered */

+#define DMESA_DRIVER_LLWO_BIT 0x2 /* lower-left window origin */

+int DMesaGetIntegerv (GLenum pname, GLint *params);

 

 #ifdef __cplusplus

 }

diff --git a/progs/samples/Makefile.DJ b/progs/samples/Makefile.DJ
index b5724f4..3d679eb 100644
--- a/progs/samples/Makefile.DJ
+++ b/progs/samples/Makefile.DJ
@@ -65,16 +65,12 @@
 

 LDFLAGS = -s -L$(TOP)/lib

 

-ifdef DXE

+ifeq ($(DXE),1)

 DMESADXE = $(TOP)/lib/dmesadxe.o

-LDLIBS += -liglut -liglu -ligl

-ifdef FX

-LDFLAGS += -L$(GLIDE)

-endif

-LDLIBS += -ldl

+LDLIBS += -liglut -liglu -ligl -ldl

 else

 LDLIBS = -lglut -lglu -lgl

-ifdef FX

+ifeq ($(FX),1)

 LDFLAGS += -L$(GLIDE)

 LDLIBS += -lglid3

 endif

diff --git a/src/glut/dos/glutint.h b/src/glut/dos/glutint.h
index 77a8322..bbabf0f 100644
--- a/src/glut/dos/glutint.h
+++ b/src/glut/dos/glutint.h
@@ -105,6 +105,9 @@
 extern GLuint g_bpp;                  /* HW: bits per pixel */

 extern GLuint g_refresh;              /* HW: vertical refresh rate */

 extern GLuint g_screen_w, g_screen_h; /* HW: physical screen size */

+extern GLint g_driver_caps;

+

+extern GLuint g_fps;

 

 extern GLuint g_display_mode;         /* display bits */

 extern int g_init_x, g_init_y;        /* initial window position */

@@ -132,7 +135,7 @@
 

 

 

-#define MAX_WINDOWS    2

+#define MAX_WINDOWS 2

 

 #define DEFAULT_WIDTH  300

 #define DEFAULT_HEIGHT 300

diff --git a/src/glut/dos/init.c b/src/glut/dos/init.c
index 0f848f6..6c034ff 100644
--- a/src/glut/dos/init.c
+++ b/src/glut/dos/init.c
@@ -38,6 +38,9 @@
 GLuint g_bpp = DEFAULT_BPP;

 GLuint g_refresh = 0;

 GLuint g_screen_w, g_screen_h;

+GLint g_driver_caps;

+

+GLuint g_fps = 0;

 

 GLuint g_display_mode = 0;

 int g_init_x = 0, g_init_y = 0;

@@ -68,6 +71,13 @@
  }

  __glutProgramName = __glutStrdup(str);

 

+ /* check if GLUT_FPS env var is set */

+ if ((env = getenv("GLUT_FPS")) != NULL) {

+    if ((g_fps = atoi(env)) <= 0) {

+       g_fps = 5000; /* 5000 milliseconds */

+    }

+ }

+

  /* Initialize timer */

  glutGet(GLUT_ELAPSED_TIME);

 }

@@ -106,9 +116,10 @@
 

  {

   GLint screen_size[2];

-  DMesaGetIntegerv(DMESA_SCREEN_SIZE, screen_size);

+  DMesaGetIntegerv(DMESA_GET_SCREEN_SIZE, screen_size);

   g_screen_w = screen_size[0];

   g_screen_h = screen_size[1];

+  DMesaGetIntegerv(DMESA_GET_DRIVER_CAPS, &g_driver_caps);

  }

 

  pc_install_keyb();

diff --git a/src/glut/dos/mouse.c b/src/glut/dos/mouse.c
index c67f809..d82f5e8 100644
--- a/src/glut/dos/mouse.c
+++ b/src/glut/dos/mouse.c
@@ -39,19 +39,7 @@
 void __glutInitMouse (void)

 {

  if ((g_mouse = pc_install_mouse())) {

-    GLint yorg;

-    GLint rect[4];

-

-    DMesaGetIntegerv(DMESA_Y_ORIGIN, &yorg);

-    if (yorg) {

-       rect[1] = g_screen_h - g_curwin->height;

-    } else {

-       rect[1] = g_curwin->ypos;

-    }

-    rect[0] = g_curwin->xpos;

-    rect[2] = rect[0] + g_curwin->width - 1;

-    rect[3] = rect[1] + g_curwin->height - 1;

-    pc_mouse_area(rect[0], rect[1], rect[2], rect[3]);

+    pc_mouse_area(g_curwin->xpos, g_curwin->ypos, g_curwin->xpos + g_curwin->width - 1, g_curwin->ypos + g_curwin->height - 1);

 

     g_curwin->show_mouse = (g_curwin->mouse || g_curwin->motion || g_curwin->passive);

  }

diff --git a/src/glut/dos/window.c b/src/glut/dos/window.c
index a7a7d9c..cad4726 100644
--- a/src/glut/dos/window.c
+++ b/src/glut/dos/window.c
@@ -27,12 +27,15 @@
  */

 

 

+#include <stdio.h>

+

 #include "glutint.h"

 #include "GL/dmesa.h"

 

 

 

 GLUTwindow *g_curwin;

+static GLuint swaptime, swapcount;

 

 static DMesaVisual  visual  = NULL;

 static DMesaContext context = NULL;

@@ -59,7 +62,6 @@
 int APIENTRY glutCreateWindow (const char *title)

 {

  int i;

- GLint screen_size[2];

  int m8width = (g_init_w + 7) & ~7;

 

  if (!visual) {

@@ -154,6 +156,20 @@
  } else {

     DMesaSwapBuffers(g_curwin->buffer);

  }

+

+ if (g_fps) {

+    GLint t = glutGet(GLUT_ELAPSED_TIME);

+    swapcount++;

+    if (swaptime == 0)

+       swaptime = t;

+    else if (t - swaptime > g_fps) {

+       double time = 0.001 * (t - swaptime);

+       double fps = (double)swapcount / time;

+       fprintf(stderr, "GLUT: %d frames in %.2f seconds = %.2f FPS\n", swapcount, time, fps);

+       swaptime = t;

+       swapcount = 0;

+    }

+ }

 }

 

 

diff --git a/src/mesa/drivers/dos/vesa/blit.S b/src/mesa/drivers/dos/blit.S
similarity index 100%
rename from src/mesa/drivers/dos/vesa/blit.S
rename to src/mesa/drivers/dos/blit.S
diff --git a/src/mesa/drivers/dos/dmesa.c b/src/mesa/drivers/dos/dmesa.c
index ec9f3b2..a729738 100644
--- a/src/mesa/drivers/dos/dmesa.c
+++ b/src/mesa/drivers/dos/dmesa.c
@@ -54,14 +54,22 @@
 #include "tnl/t_context.h"

 #include "tnl/t_pipeline.h"

 

+#ifndef MATROX

+

 #include "video.h"

 

-#else

+#else  /* MATROX */

+

+#include "mga/mga.h"

+

+#endif /* MATROX */

+

+#else  /* FX */

 

 #include "../FX/fxdrv.h"

 #include "GL/dmesa.h"

 

-#endif

+#endif /* FX */

 

 

 

@@ -74,6 +82,10 @@
    GLboolean db_flag;           /* double buffered? */

    GLboolean rgb_flag;          /* RGB mode? */

    GLuint depth;                /* bits per pixel (1, 8, 24, etc) */

+#ifdef MATROX

+   int stride_in_pixels;

+#endif

+   int zbuffer;                 /* Z=buffer: 0=no, 1=SW, -1=HW */

 };

 

 /*

@@ -107,8 +119,21 @@
 /****************************************************************************

  * Read/Write pixels

  ***************************************************************************/

-#define FLIP(y)  (c->Buffer->height - (y) - 1)

-#define FLIP2(y) (b - (y))

+#define FLIP(y)  (dmesa->Buffer->height - (y) - 1)

+#define FLIP2(y) (_b_ - (y))

+

+

+#ifndef MATROX

+#define DSTRIDE dmesa->Buffer->width

+#else

+#define DSTRIDE dmesa->visual->stride_in_pixels

+#define vl_putpixel mga_putpixel

+#define vl_mixrgba  mga_mixrgb

+#define vl_mixrgb   mga_mixrgb

+#define vl_getrgba  mga_getrgba

+#define vl_setz     mga_setz

+#define vl_getz     mga_getz

+#endif

 

 /****************************************************************************

  * RGB[A]

@@ -116,10 +141,11 @@
 static void write_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,

                              const GLubyte rgba[][4], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

  GLuint i, offset;

 

- offset = c->Buffer->width * FLIP(y) + x;

+#ifndef MATROX

+ offset = DSTRIDE * FLIP(y) + x;

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++, offset++) {

@@ -133,6 +159,29 @@
         vl_putpixel(offset, vl_mixrgba(rgba[i]));

     }

  }

+#else  /* MATROX */

+ y = FLIP(y);

+ if (mask) {

+    /* draw some pixels */

+    offset = 0;

+    for (i = 0; i < n; i++) {

+        if (mask[i]) {

+           ++offset;

+        } else {

+           if (offset != 0) {

+              mga_draw_span_rgb_tx32(x + i - offset, y, offset, (const unsigned long *)(&rgba[i-offset]));

+              offset = 0;

+           }

+        }

+    }

+    if (offset != 0) {

+       mga_draw_span_rgb_tx32(x + n - offset, y, offset, (const unsigned long *)(&rgba[n-offset]));

+    }

+ } else {

+    /* draw all pixels */

+    mga_draw_span_rgb_tx32(x, y, n, (const unsigned long *)rgba);

+ }

+#endif /* MATROX */

 }

 

 

@@ -140,10 +189,10 @@
 static void write_rgb_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,

                             const GLubyte rgb[][3], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

  GLuint i, offset;

 

- offset = c->Buffer->width * FLIP(y) + x;

+ offset = DSTRIDE * FLIP(y) + x;

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++, offset++) {

@@ -165,10 +214,10 @@
                                   GLuint n, GLint x, GLint y,

                                   const GLchan color[4], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

  GLuint i, offset, rgba = vl_mixrgba(color);

 

- offset = c->Buffer->width * FLIP(y) + x;

+ offset = DSTRIDE * FLIP(y) + x;

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++, offset++) {

@@ -189,10 +238,10 @@
 static void read_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,

                             GLubyte rgba[][4])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

  GLuint i, offset;

 

- offset = c->Buffer->width * FLIP(y) + x;

+ offset = DSTRIDE * FLIP(y) + x;

  /* read all pixels */

  for (i=0; i<n; i++, offset++) {

      vl_getrgba(offset, rgba[i]);

@@ -205,20 +254,20 @@
                                GLuint n, const GLint x[], const GLint y[],

                                const GLubyte rgba[][4], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint i, w = c->Buffer->width, b = c->Buffer->height - 1;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;

 

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++) {

         if (mask[i]) {

-           vl_putpixel(FLIP2(y[i])*w + x[i], vl_mixrgba(rgba[i]));

+           vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i]));

         }

     }

  } else {

     /* draw all pixels */

     for (i=0; i<n; i++) {

-        vl_putpixel(FLIP2(y[i])*w + x[i], vl_mixrgba(rgba[i]));

+        vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i]));

     }

  }

 }

@@ -229,20 +278,20 @@
                                     GLuint n, const GLint x[], const GLint y[],

                                     const GLchan color[4], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint i, w = c->Buffer->width, b = c->Buffer->height - 1, rgba = vl_mixrgba(color);

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1, rgba = vl_mixrgba(color);

 

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++) {

         if (mask[i]) {

-           vl_putpixel(FLIP2(y[i])*w + x[i], rgba);

+           vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba);

         }

     }

  } else {

     /* draw all pixels */

     for (i=0; i<n; i++) {

-        vl_putpixel(FLIP2(y[i])*w + x[i], rgba);

+        vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba);

     }

  }

 }

@@ -253,34 +302,37 @@
                               GLuint n, const GLint x[], const GLint y[],

                               GLubyte rgba[][4], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint i, w = c->Buffer->width, b = c->Buffer->height - 1;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;

 

  if (mask) {

     /* read some pixels */

     for (i=0; i<n; i++) {

         if (mask[i]) {

-           vl_getrgba(FLIP2(y[i])*w + x[i], rgba[i]);

+           vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]);

         }

     }

  } else {

     /* read all pixels */

     for (i=0; i<n; i++) {

-        vl_getrgba(FLIP2(y[i])*w + x[i], rgba[i]);

+        vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]);

     }

  }

 }

 

+

+

 /****************************************************************************

  * Index

  ***************************************************************************/

+#ifndef MATROX

 static void write_index_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,

                               const GLuint index[], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

  GLuint i, offset;

 

- offset = c->Buffer->width * FLIP(y) + x;

+ offset = DSTRIDE * FLIP(y) + x;

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++, offset++) {

@@ -301,10 +353,10 @@
 static void write_index8_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,

                                const GLubyte index[], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

  GLuint i, offset;

 

- offset = c->Buffer->width * FLIP(y) + x;

+ offset = DSTRIDE * FLIP(y) + x;

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++, offset++) {

@@ -326,10 +378,10 @@
                                    GLuint n, GLint x, GLint y,

                                    GLuint colorIndex, const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

  GLuint i, offset;

 

- offset = c->Buffer->width * FLIP(y) + x;

+ offset = DSTRIDE * FLIP(y) + x;

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++, offset++) {

@@ -350,10 +402,10 @@
 static void read_index_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,

                              GLuint index[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

  GLuint i, offset;

 

- offset = c->Buffer->width * FLIP(y) + x;

+ offset = DSTRIDE * FLIP(y) + x;

  /* read all pixels */

  for (i=0; i<n; i++, offset++) {

      index[i] = vl_getpixel(offset);

@@ -366,20 +418,20 @@
                                 GLuint n, const GLint x[], const GLint y[],

                                 const GLuint index[], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint i, w = c->Buffer->width, b = c->Buffer->height - 1;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;

 

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++) {

         if (mask[i]) {

-           vl_putpixel(FLIP2(y[i])*w + x[i], index[i]);

+           vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]);

         }

     }

  } else {

     /* draw all pixels */

     for (i=0; i<n; i++) {

-        vl_putpixel(FLIP2(y[i])*w + x[i], index[i]);

+        vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]);

     }

  }

 }

@@ -390,20 +442,20 @@
                                      GLuint n, const GLint x[], const GLint y[],

                                      GLuint colorIndex, const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint i, w = c->Buffer->width, b = c->Buffer->height - 1;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;

 

  if (mask) {

     /* draw some pixels */

     for (i=0; i<n; i++) {

         if (mask[i]) {

-           vl_putpixel(FLIP2(y[i])*w + x[i], colorIndex);

+           vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex);

         }

     }

  } else {

     /* draw all pixels */

     for (i=0; i<n; i++) {

-        vl_putpixel(FLIP2(y[i])*w + x[i], colorIndex);

+        vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex);

     }

  }

 }

@@ -414,23 +466,107 @@
                                GLuint n, const GLint x[], const GLint y[],

                                GLuint index[], const GLubyte mask[])

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint i, w = c->Buffer->width, b = c->Buffer->height - 1;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;

 

  if (mask) {

     /* read some pixels */

     for (i=0; i<n; i++) {

         if (mask[i]) {

-           index[i] = vl_getpixel(FLIP2(y[i])*w + x[i]);

+           index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]);

         }

     }

  } else {

     /* read all pixels */

     for (i=0; i<n; i++) {

-        index[i] = vl_getpixel(FLIP2(y[i])*w + x[i]);

+        index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]);

     }

  }

 }

+#endif /* !MATROX */

+

+

+

+/****************************************************************************

+ * Z-buffer

+ ***************************************************************************/

+#ifdef MATROX

+static void write_depth_span (GLcontext *ctx, GLuint n, GLint x, GLint y,

+                              const GLdepth depth[], const GLubyte mask[])

+{

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, offset;

+

+ offset = DSTRIDE * FLIP(y) + x;

+ if (mask) {

+    /* draw some values */

+    for (i=0; i<n; i++, offset++) {

+        if (mask[i]) {

+           vl_setz(offset, depth[i]);

+        }

+    }

+ } else {

+    /* draw all values */

+    for (i=0; i<n; i++, offset++) {

+        vl_setz(offset, depth[i]);

+    }

+ }

+}

+

+

+

+static void read_depth_span (GLcontext *ctx, GLuint n, GLint x, GLint y,

+                             GLdepth depth[])

+{

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, offset;

+

+ offset = DSTRIDE * FLIP(y) + x;

+ /* read all values */

+ for (i=0; i<n; i++, offset++) {

+     depth[i] = vl_getz(offset);

+ }

+}

+

+

+

+static void write_depth_pixels (GLcontext *ctx, GLuint n,

+                                const GLint x[], const GLint y[],

+                                const GLdepth depth[], const GLubyte mask[])

+{

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;

+

+ if (mask) {

+    /* draw some values */

+    for (i=0; i<n; i++) {

+        if (mask[i]) {

+           vl_setz(FLIP2(y[i])*_w_ + x[i], depth[i]);

+        }

+    }

+ } else {

+    /* draw all values */

+    for (i=0; i<n; i++) {

+        vl_setz(FLIP2(y[i])*_w_ + x[i], depth[i]);

+    }

+ }

+}

+

+

+

+static void read_depth_pixels (GLcontext *ctx, GLuint n,

+                               const GLint x[], const GLint y[],

+                               GLdepth depth[])

+{

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;

+

+ /* read all values */

+ for (i=0; i<n; i++) {

+     depth[i] = vl_getz(FLIP2(y[i])*_w_ + x[i]);

+ }

+}

+#endif /* MATROX */

 

 

 

@@ -439,74 +575,105 @@
  ***************************************************************************/

 

 /*

- * flat, NON-depth-buffered, triangle.

+ * NON-depth-buffered flat triangle.

  */

 static void tri_rgb_flat (GLcontext *ctx,

                           const SWvertex *v0,

                           const SWvertex *v1,

                           const SWvertex *v2)

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint w = c->Buffer->width, b = c->Buffer->height - 1;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint _b_ = dmesa->Buffer->height - 1;

+#ifndef MATROX

+ GLuint _w_ = dmesa->Buffer->width;

 

 #define SETUP_CODE GLuint rgb = vl_mixrgb(v2->color);

 

-#define RENDER_SPAN(span)					\

- GLuint i, offset = FLIP2(span.y)*w + span.x;			\

- for (i = 0; i < span.end; i++, offset++) {			\

-     vl_putpixel(offset, rgb);					\

+#define RENDER_SPAN(span) \

+ GLuint i, offset = FLIP2(span.y)*_w_ + span.x;	\

+ for (i = 0; i < span.end; i++, offset++) {	\

+     vl_putpixel(offset, rgb);			\

  }

 

 #include "swrast/s_tritemp.h"

+#else  /* MATROX */

+ MGAvertex m0, m1, m2;

+ m0.win[0] = v0->win[0];

+ m0.win[1] = FLIP2(v0->win[1]);

+ m1.win[0] = v1->win[0];

+ m1.win[1] = FLIP2(v1->win[1]);

+ m2.win[0] = v2->win[0];

+ m2.win[1] = FLIP2(v2->win[1]);

+ *(unsigned long *)m2.color = *(unsigned long *)v2->color;

+ mga_draw_tri_rgb_flat((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);

+#endif /* MATROX */

 }

 

 

 

 /*

- * flat, depth-buffered, triangle.

+ * Z-less flat triangle.

  */

-static void tri_rgb_flat_z (GLcontext *ctx,

-                            const SWvertex *v0,

-                            const SWvertex *v1,

-                            const SWvertex *v2)

+static void tri_rgb_flat_zless (GLcontext *ctx,

+                                const SWvertex *v0,

+                                const SWvertex *v1,

+                                const SWvertex *v2)

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint w = c->Buffer->width, b = c->Buffer->height - 1;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint _b_ = dmesa->Buffer->height - 1;

+#ifndef MATROX

+ GLuint _w_ = dmesa->Buffer->width;

 

 #define INTERP_Z 1

 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE

 #define SETUP_CODE GLuint rgb = vl_mixrgb(v2->color);

 

-#define RENDER_SPAN(span)					\

- GLuint i, offset = FLIP2(span.y)*w + span.x;			\

- for (i = 0; i < span.end; i++, offset++) {			\

-     const DEPTH_TYPE z = FixedToDepth(span.z);			\

-     if (z < zRow[i]) {						\

-        vl_putpixel(offset, rgb);				\

-        zRow[i] = z;						\

-     }								\

-     span.z += span.zStep;					\

+#define RENDER_SPAN(span) \

+ GLuint i, offset = FLIP2(span.y)*_w_ + span.x;	\

+ for (i = 0; i < span.end; i++, offset++) {	\

+     const DEPTH_TYPE z = FixedToDepth(span.z);	\

+     if (z < zRow[i]) {				\

+        vl_putpixel(offset, rgb);		\

+        zRow[i] = z;				\

+     }						\

+     span.z += span.zStep;			\

  }

 

 #include "swrast/s_tritemp.h"

+#else  /* MATROX */

+ MGAvertex m0, m1, m2;

+ m0.win[0] = v0->win[0];

+ m0.win[1] = FLIP2(v0->win[1]);

+ m0.win[2] = v0->win[2];

+ m1.win[0] = v1->win[0];

+ m1.win[1] = FLIP2(v1->win[1]);

+ m1.win[2] = v1->win[2];

+ m2.win[0] = v2->win[0];

+ m2.win[1] = FLIP2(v2->win[1]);

+ m2.win[2] = v2->win[2];

+ *(unsigned long *)m2.color = *(unsigned long *)v2->color;

+ mga_draw_tri_rgb_flat_zless((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);

+#endif /* MATROX */

 }

 

 

 

 /*

- * smooth, NON-depth-buffered, triangle.

+ * NON-depth-buffered iterated triangle.

  */

-static void tri_rgb_smooth (GLcontext *ctx,

-                            const SWvertex *v0,

-                            const SWvertex *v1,

-                            const SWvertex *v2)

+static void tri_rgb_iter (GLcontext *ctx,

+                          const SWvertex *v0,

+                          const SWvertex *v1,

+                          const SWvertex *v2)

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint w = c->Buffer->width, b = c->Buffer->height - 1;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint _b_ = dmesa->Buffer->height - 1;

+#ifndef MATROX

+ GLuint _w_ = dmesa->Buffer->width;

 

 #define INTERP_RGB 1

-#define RENDER_SPAN(span)						\

- GLuint i, offset = FLIP2(span.y)*w + span.x;				\

+#define RENDER_SPAN(span) \

+ GLuint i, offset = FLIP2(span.y)*_w_ + span.x;				\

  for (i = 0; i < span.end; i++, offset++) {				\

      vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));	\

      span.red += span.redStep;						\

@@ -515,27 +682,42 @@
  }

 

 #include "swrast/s_tritemp.h"

+#else  /* MATROX */

+ MGAvertex m0, m1, m2;

+ m0.win[0] = v0->win[0];

+ m0.win[1] = FLIP2(v0->win[1]);

+ m1.win[0] = v1->win[0];

+ m1.win[1] = FLIP2(v1->win[1]);

+ m2.win[0] = v2->win[0];

+ m2.win[1] = FLIP2(v2->win[1]);

+ *(unsigned long *)m0.color = *(unsigned long *)v0->color;

+ *(unsigned long *)m1.color = *(unsigned long *)v1->color;

+ *(unsigned long *)m2.color = *(unsigned long *)v2->color;

+ mga_draw_tri_rgb_iter((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);

+#endif /* MATROX */

 }

 

 

 

 /*

- * smooth, depth-buffered, triangle.

+ * Z-less iterated triangle.

  */

-static void tri_rgb_smooth_z (GLcontext *ctx,

-                              const SWvertex *v0,

-                              const SWvertex *v1,

-                              const SWvertex *v2)

+static void tri_rgb_iter_zless (GLcontext *ctx,

+                                const SWvertex *v0,

+                                const SWvertex *v1,

+                                const SWvertex *v2)

 {

- const DMesaContext c = (DMesaContext)ctx->DriverCtx;

- GLuint w = c->Buffer->width, b = c->Buffer->height - 1;

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint _b_ = dmesa->Buffer->height - 1;

+#ifndef MATROX

+ GLuint _w_ = dmesa->Buffer->width;

 

 #define INTERP_Z 1

 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE

 #define INTERP_RGB 1

 

-#define RENDER_SPAN(span)						\

- GLuint i, offset = FLIP2(span.y)*w + span.x;				\

+#define RENDER_SPAN(span) \

+ GLuint i, offset = FLIP2(span.y)*_w_ + span.x;				\

  for (i = 0; i < span.end; i++, offset++) {				\

      const DEPTH_TYPE z = FixedToDepth(span.z);				\

      if (z < zRow[i]) {							\

@@ -549,6 +731,22 @@
  }

 

 #include "swrast/s_tritemp.h"

+#else  /* MATROX */

+ MGAvertex m0, m1, m2;

+ m0.win[0] = v0->win[0];

+ m0.win[1] = FLIP2(v0->win[1]);

+ m0.win[2] = v0->win[2];

+ m1.win[0] = v1->win[0];

+ m1.win[1] = FLIP2(v1->win[1]);

+ m1.win[2] = v1->win[2];

+ m2.win[0] = v2->win[0];

+ m2.win[1] = FLIP2(v2->win[1]);

+ m2.win[2] = v2->win[2];

+ *(unsigned long *)m0.color = *(unsigned long *)v0->color;

+ *(unsigned long *)m1.color = *(unsigned long *)v1->color;

+ *(unsigned long *)m2.color = *(unsigned long *)v2->color;

+ mga_draw_tri_rgb_iter_zless((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);

+#endif /* MATROX */

 }

 

 

@@ -566,7 +764,7 @@
      || (ctx->Polygon.StippleFlag)

      || (ctx->Texture._EnabledUnits)

      || (swrast->_RasterMask & MULTI_DRAW_BIT)

-     || ((ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK))) {

+     || (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)) {

     return (swrast_tri_func)NULL;

  }

 

@@ -574,11 +772,11 @@
      && ctx->Depth.Func==GL_LESS

      && ctx->Depth.Mask==GL_TRUE

      && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {

-    return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_smooth_z : tri_rgb_flat_z;

+    return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter_zless : tri_rgb_flat_zless;

  }

 

  if (swrast->_RasterMask==0) { /* no depth test */

-    return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_smooth : tri_rgb_flat;

+    return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter : tri_rgb_flat;

  }

 

  return (swrast_tri_func)NULL;

@@ -601,25 +799,210 @@
 

 

 /****************************************************************************

+ * Optimized line rendering

+ ***************************************************************************/

+

+#ifdef MATROX

+static __inline void matrox_line_clip_hack (GLcontext *ctx, int _b_, MGAvertex *m0, const SWvertex *vert0, MGAvertex *m1, const SWvertex *vert1)

+{

+ int x0 = vert0->win[0];

+ int y0 = vert0->win[1];

+ int x1 = vert1->win[0];

+ int y1 = vert1->win[1];

+ /* s_linetemp.h { */

+ GLint w = ctx->DrawBuffer->Width;

+ GLint h = ctx->DrawBuffer->Height;

+ if ((x0==w) | (x1==w)) {

+    if ((x0==w) & (x1==w))

+       return;

+    x0 -= x0==w;

+    x1 -= x1==w;

+ }

+ if ((y0==h) | (y1==h)) {

+    if ((y0==h) & (y1==h))

+       return;

+    y0 -= y0==h;

+    y1 -= y1==h;

+ }

+ /* } s_linetemp.h */

+ m0->win[0] = x0;

+ m0->win[1] = FLIP2(y0);

+ m1->win[0] = x1;

+ m1->win[1] = FLIP2(y1);

+}

+#endif

+

+/*

+ * NON-depth-buffered flat line.

+ */

+static void line_rgb_flat (GLcontext *ctx,

+                           const SWvertex *vert0,

+                           const SWvertex *vert1)

+{

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint _b_ = dmesa->Buffer->height - 1;

+#ifndef MATROX

+ GLuint _w_ = dmesa->Buffer->width;

+ GLuint rgb = vl_mixrgb(vert1->color);

+

+#define INTERP_XY 1

+#define CLIP_HACK 1

+#define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb);

+

+#include "swrast/s_linetemp.h"

+#else

+ MGAvertex m0, m1;

+ matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);

+ *(unsigned long *)m1.color = *(unsigned long *)vert1->color;

+ mga_draw_line_rgb_flat(&m0, &m1);

+#endif

+}

+

+

+

+/*

+ * Z-less flat line.

+ */

+static void line_rgb_flat_zless (GLcontext *ctx,

+                                 const SWvertex *vert0,

+                                 const SWvertex *vert1)

+{

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint _b_ = dmesa->Buffer->height - 1;

+#ifndef MATROX

+ GLuint _w_ = dmesa->Buffer->width;

+ GLuint rgb = vl_mixrgb(vert1->color);

+

+#define INTERP_XY 1

+#define INTERP_Z 1

+#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE

+#define CLIP_HACK 1

+#define PLOT(X,Y) \

+ if (Z < *zPtr) {				\

+    *zPtr = Z;					\

+    vl_putpixel(FLIP2(Y) * _w_ + X, rgb);	\

+ }

+

+#include "swrast/s_linetemp.h"

+#else

+ MGAvertex m0, m1;

+ matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);

+ m0.win[2] = vert0->win[2];

+ m1.win[2] = vert1->win[2];

+ *(unsigned long *)m1.color = *(unsigned long *)vert1->color;

+ mga_draw_line_rgb_flat_zless(&m0, &m1);

+#endif

+}

+

+

+

+#ifndef MATROX

+#define line_rgb_iter NULL

+#define line_rgb_iter_zless NULL

+#else  /* MATROX */

+/*

+ * NON-depth-buffered iterated line.

+ */

+static void line_rgb_iter (GLcontext *ctx,

+                           const SWvertex *vert0,

+                           const SWvertex *vert1)

+{

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint _b_ = dmesa->Buffer->height - 1;

+ MGAvertex m0, m1;

+ matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);

+ *(unsigned long *)m0.color = *(unsigned long *)vert0->color;

+ *(unsigned long *)m1.color = *(unsigned long *)vert1->color;

+ mga_draw_line_rgb_iter(&m0, &m1);

+}

+

+

+

+/*

+ * Z-less iterated line.

+ */

+static void line_rgb_iter_zless (GLcontext *ctx,

+                                 const SWvertex *vert0,

+                                 const SWvertex *vert1)

+{

+ const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;

+ GLuint _b_ = dmesa->Buffer->height - 1;

+ MGAvertex m0, m1;

+ matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);

+ m0.win[2] = vert0->win[2];

+ m1.win[2] = vert1->win[2];

+ *(unsigned long *)m0.color = *(unsigned long *)vert0->color;

+ *(unsigned long *)m1.color = *(unsigned long *)vert1->color;

+ mga_draw_line_rgb_iter_zless(&m0, &m1);

+}

+#endif /* MATROX */

+

+

+

+/*

+ * Analyze context state to see if we can provide a fast line function

+ * Otherwise, return NULL.

+ */

+static swrast_line_func dmesa_choose_line_function (GLcontext *ctx)

+{

+ const SWcontext *swrast = SWRAST_CONTEXT(ctx);

+

+ if ((ctx->RenderMode != GL_RENDER)

+     || (ctx->Line.SmoothFlag)

+     || (ctx->Texture._EnabledUnits)

+     || (ctx->Line.StippleFlag)

+     || (swrast->_RasterMask & MULTI_DRAW_BIT)

+     || (ctx->Line.Width!=1.0F)) {

+    return (swrast_line_func)NULL;

+ }

+

+ if (swrast->_RasterMask==DEPTH_BIT

+     && ctx->Depth.Func==GL_LESS

+     && ctx->Depth.Mask==GL_TRUE

+     && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {

+    return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter_zless : line_rgb_flat_zless;

+ }

+

+ if (swrast->_RasterMask==0) { /* no depth test */

+    return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter : line_rgb_flat;

+ }

+

+ return (swrast_line_func)NULL;

+}

+

+

+

+/* Override for the swrast line-selection function.  Try to use one

+ * of our internal line functions, otherwise fall back to the

+ * standard swrast functions.

+ */

+static void dmesa_choose_line (GLcontext *ctx)

+{

+ SWcontext *swrast = SWRAST_CONTEXT(ctx);

+

+ if (!(swrast->Line=dmesa_choose_line_function(ctx)))

+    _swrast_choose_line(ctx);

+}

+

+

+

+/****************************************************************************

  * Miscellaneous device driver funcs

  ***************************************************************************/

 

 static void clear_index (GLcontext *ctx, GLuint index)

 {

- DMesaContext c = (DMesaContext)ctx->DriverCtx;

-

- c->ClearIndex = index;

+ ((DMesaContext)ctx->DriverCtx)->ClearIndex = index;

 }

 

 static void clear_color (GLcontext *ctx, const GLfloat color[4])

 {

  GLubyte col[4];

- DMesaContext c = (DMesaContext)ctx->DriverCtx;

  CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);

  CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);

  CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);

  CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]);

- c->ClearColor = vl_mixrgba(col);

+ ((DMesaContext)ctx->DriverCtx)->ClearColor = vl_mixrgba(col);

 }

 

 

@@ -640,6 +1023,7 @@
 

  /* we can't handle color or index masking */

  if ((*colorMask == 0xffffffff) && (ctx->Color.IndexMask == 0xffffffff)) {

+#ifndef MATROX

     if (mask & DD_BACK_LEFT_BIT) {

        int color = c->visual->rgb_flag ? c->ClearColor : c->ClearIndex;

 

@@ -651,6 +1035,27 @@
 

        mask &= ~DD_BACK_LEFT_BIT;

     }

+#else  /* MATROX */

+    unsigned short z = -1;

+    int color = c->ClearColor;

+    if (mask & DD_DEPTH_BIT) {

+       z = ctx->Depth.Clear * 0xffff;

+    }

+    if (all) {

+       mga_clear(mask & DD_FRONT_LEFT_BIT,

+                 mask & DD_BACK_LEFT_BIT,

+                 mask & DD_DEPTH_BIT,

+                 0, 0, c->Buffer->width, c->Buffer->height,

+                 color, z);

+    } else {

+       mga_clear(mask & DD_FRONT_LEFT_BIT,

+                 mask & DD_BACK_LEFT_BIT,

+                 mask & DD_DEPTH_BIT,

+                 x, y, width, height,

+                 color, z);

+    }

+    mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT);

+#endif /* MATROX */

  }

 

  if (mask) {

@@ -688,7 +1093,14 @@
 {

  switch (name) {

         case GL_RENDERER:

-             return (const GLubyte *)"Mesa DJGPP\0port (c) Borca Daniel dec-2002";

+             return (const GLubyte *)"Mesa DJGPP"

+                                     #ifdef FX

+                                     " (FX)"

+                                     #endif

+                                     #ifdef MATROX

+                                     " (MGA)"

+                                     #endif

+                                     "\0port (c) Borca Daniel feb-2003";

         default:

              return NULL;

  }

@@ -717,6 +1129,13 @@
 /****************************************************************************

  * State

  ***************************************************************************/

+#define DMESA_NEW_LINE   (_NEW_LINE | \

+                          _NEW_TEXTURE | \

+                          _NEW_LIGHT | \

+                          _NEW_DEPTH | \

+                          _NEW_RENDERMODE | \

+                          _SWRAST_NEW_RASTERMASK)

+

 #define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \

                             _NEW_TEXTURE | \

                             _NEW_LIGHT | \

@@ -731,8 +1150,10 @@
 {

  SWcontext *swrast = SWRAST_CONTEXT(ctx);

 

+ swrast->choose_line = dmesa_choose_line;

  swrast->choose_triangle = dmesa_choose_tri;

 

+ swrast->invalidate_line |= DMESA_NEW_LINE;

  swrast->invalidate_triangle |= DMESA_NEW_TRIANGLE;

 }

 

@@ -808,22 +1229,21 @@
  /* Install swsetup for tnl->Driver.Render.*:

   */

  _swsetup_Wakeup(ctx);

-}

 

-

-

-static void dmesa_update_state (GLcontext *ctx, GLuint new_state)

-{

- struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference(ctx);

-

- /* Propogate statechange information to swrast and swrast_setup

-  * modules. The DMesa driver has no internal GL-dependent state.

+ /* The span functions should be in `dmesa_update_state', but I'm

+  * pretty sure they will never change during the life of the Visual

   */

- _swrast_InvalidateState( ctx, new_state );

- _ac_InvalidateState( ctx, new_state );

- _tnl_InvalidateState( ctx, new_state );

- _swsetup_InvalidateState( ctx, new_state );

+#ifdef MATROX

+ if (((DMesaContext)ctx->DriverCtx)->visual->zbuffer == -1) {

+    /* Depth span/pixel functions */

+    dd->WriteDepthSpan = write_depth_span;

+    dd->WriteDepthPixels = write_depth_pixels;

+    dd->ReadDepthSpan = read_depth_span;

+    dd->ReadDepthPixels = read_depth_pixels;

+ }

+#endif

 

+#ifndef MATROX

  /* Index span/pixel functions */

  dd->WriteCI32Span = write_index_span;

  dd->WriteCI8Span = write_index8_span;

@@ -832,6 +1252,7 @@
  dd->WriteMonoCIPixels = write_mono_index_pixels;

  dd->ReadCI32Span = read_index_span;

  dd->ReadCI32Pixels = read_index_pixels;

+#endif

 

  /* RGB(A) span/pixel functions */

  dd->WriteRGBASpan = write_rgba_span;

@@ -842,7 +1263,20 @@
  dd->ReadRGBASpan = read_rgba_span;

  dd->ReadRGBAPixels = read_rgba_pixels;

 }

-#endif

+

+

+

+static void dmesa_update_state (GLcontext *ctx, GLuint new_state)

+{

+ /* Propogate statechange information to swrast and swrast_setup

+  * modules. The DMesa driver has no internal GL-dependent state.

+  */

+ _swrast_InvalidateState( ctx, new_state );

+ _ac_InvalidateState( ctx, new_state );

+ _tnl_InvalidateState( ctx, new_state );

+ _swsetup_InvalidateState( ctx, new_state );

+}

+#endif /* FX */

 

 

 

@@ -868,9 +1302,15 @@
  DMesaVisual v;

  GLint redBits, greenBits, blueBits, alphaBits, indexBits;

 

+#ifndef MATROX

  if (!dbFlag) {

     return NULL;

  }

+#else

+ if (!rgbFlag) {

+    return NULL;

+ }

+#endif

 

  alphaBits = 0;

 

@@ -909,9 +1349,15 @@
     }

  }

 

+#ifndef MATROX

  if ((colDepth=vl_video_init(width, height, colDepth, rgbFlag, refresh)) <= 0) {

     return NULL;

  }

+#else

+ if (mga_open(width, height, colDepth, dbFlag ? 2 : 1, depthSize == 16, refresh) < 0) {

+    return NULL;

+ }

+#endif

 

  if (alphaFlag && (alphaBits==0)) {

     alphaBits = 8;

@@ -938,11 +1384,19 @@
     v->depth = colDepth;

     v->db_flag = dbFlag;

     v->rgb_flag = rgbFlag;

+

+    v->zbuffer = (depthSize > 0) ? 1 : 0;

+#ifdef MATROX

+    mga_get(MGA_GET_HPIXELS, &v->stride_in_pixels);

+    if (depthSize == 16) {

+       v->zbuffer = -1;

+    }

+#endif

  }

 

  return v;

 

-#else

+#else  /* FX */

 

  int i = 0, fx_attrib[32];

 

@@ -958,7 +1412,7 @@
  fx_attrib[i] = FXMESA_NONE;

 

  return (DMesaVisual)fxMesaCreateBestContext(-1, width, height, fx_attrib);

-#endif

+#endif /* FX */

 }

 

 

@@ -969,8 +1423,13 @@
  _mesa_destroy_visual(v->gl_visual);

  free(v);

 

+#ifndef MATROX

  vl_video_exit();

 #else

+ mga_close(1, 1);

+#endif

+

+#else

  fxMesaDestroyContext((fxMesaContext)v);

 #endif

 }

@@ -988,7 +1447,7 @@
 

     _mesa_initialize_framebuffer(&b->gl_buffer,

                                  visual->gl_visual,

-                                 visual->gl_visual->depthBits > 0,

+                                 visual->zbuffer == 1,

                                  visual->gl_visual->stencilBits > 0,

                                  visual->gl_visual->accumRedBits > 0,

                                  visual->gl_visual->alphaBits > 0);

@@ -1009,7 +1468,9 @@
 void DMesaDestroyBuffer (DMesaBuffer b)

 {

 #ifndef FX

+#ifndef MATROX

  free(b->the_window);

+#endif

  _mesa_free_framebuffer_data(&b->gl_buffer);

  free(b);

 #endif

@@ -1050,10 +1511,9 @@
 

  return c;

 

-#else

-

+#else  /* FX */

  return (DMesaContext)visual;

-#endif

+#endif /* FX */

 }

 

 

@@ -1076,7 +1536,7 @@
 

 GLboolean DMesaMoveBuffer (GLint xpos, GLint ypos)

 {

-#ifndef FX

+#if !defined(FX) && !defined(MATROX)

  GET_CURRENT_CONTEXT(ctx);

  DMesaBuffer b = ((DMesaContext)ctx->DriverCtx)->Buffer;

 

@@ -1089,7 +1549,6 @@
  }

 

 #else

-

  return GL_FALSE;

 #endif

 }

@@ -1098,7 +1557,7 @@
 

 GLboolean DMesaResizeBuffer (GLint width, GLint height)

 {

-#ifndef FX

+#if !defined(FX) && !defined(MATROX)

  GET_CURRENT_CONTEXT(ctx);

  DMesaBuffer b = ((DMesaContext)ctx->DriverCtx)->Buffer;

 

@@ -1111,7 +1570,6 @@
  }

 

 #else

-

  return GL_FALSE;

 #endif

 }

@@ -1125,9 +1583,11 @@
 {

 #ifndef FX

  if ((c != NULL) && (b != NULL)) {

+#ifndef MATROX

     if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, b->width, b->height) != 0) {

        return GL_FALSE;

     }

+#endif

 

     c->Buffer = b;

 

@@ -1142,7 +1602,6 @@
  }

 

 #else

-

  fxMesaMakeCurrent((fxMesaContext)c);

 #endif

 

@@ -1157,8 +1616,14 @@
 #ifndef FX

  GET_CURRENT_CONTEXT(ctx);

  _mesa_notifySwapBuffers(ctx);

+#ifndef MATROX

  vl_flip();

 #else

+ if (((DMesaContext)ctx->DriverCtx)->visual->db_flag) {

+    mga_swapbuffers(1);

+ }

+#endif

+#else

  fxMesaSwapBuffers();

 #endif

 }

@@ -1167,14 +1632,26 @@
 

 void DMesaSetCI (int ndx, GLfloat red, GLfloat green, GLfloat blue)

 {

-#ifndef FX

+#if !defined(FX) && !defined(MATROX)

  vl_setCI(ndx, red, green, blue);

 #endif

 }

 

 

 

-void DMesaGetIntegerv (GLenum pname, GLint *params)

+DMesaContext DMesaGetCurrentContext (void)

+{

+#ifndef FX

+ GET_CURRENT_CONTEXT(ctx);

+ return (ctx == NULL) ? NULL : (DMesaContext)ctx->DriverCtx;

+#else

+ return (DMesaContext)fxMesaGetCurrentContext();

+#endif

+}

+

+

+

+int DMesaGetIntegerv (GLenum pname, GLint *params)

 {

 #ifndef FX

  GET_CURRENT_CONTEXT(ctx);

@@ -1184,33 +1661,36 @@
 #endif

 

  if (c == NULL) {

-    return;

+    return -1;

  }

 

  switch (pname) {

-        case DMESA_Y_ORIGIN:

+        case DMESA_GET_SCREEN_SIZE:

              #ifndef FX

-             params[0] = GL_FALSE;

+             #ifndef MATROX

+             vl_get(VL_GET_SCREEN_SIZE, params);

              #else

-             params[0] = GL_TRUE;

+             mga_get(MGA_GET_SCREEN_SIZE, params);

              #endif

-             break;

-        case DMESA_SCREEN_SIZE:

-             #ifndef FX

-             vl_get_screen_size(&params[0], &params[1]);

              #else

              params[0] = c->screen_width;

              params[1] = c->screen_height;

              #endif

              break;

-        case DMESA_ARGB_ORDER:

+        case DMESA_GET_DRIVER_CAPS:

              #ifndef FX

-             params[0] = GL_FALSE;

+             #ifndef MATROX

+             params[0] = DMESA_DRIVER_SWDB_BIT;

              #else

-             params[0] = !c->bgrOrder;

+             params[0] = 0;

+             #endif

+             #else

+             params[0] = DMESA_DRIVER_LLWO_BIT;

              #endif

              break;

         default:

-             break;

+             return -1;

  }

+

+ return 0;

 }

diff --git a/src/mesa/drivers/dos/dpmi.c b/src/mesa/drivers/dos/dpmi.c
index 882cda3..db6a306 100644
--- a/src/mesa/drivers/dos/dpmi.c
+++ b/src/mesa/drivers/dos/dpmi.c
@@ -46,7 +46,7 @@
 /* _create_linear_mapping:

  *  Maps a physical address range into linear memory.

  */

-static int _create_linear_mapping (unsigned long *linear, unsigned long physaddr, int size)

+int _create_linear_mapping (unsigned long *linear, unsigned long physaddr, int size)

 {

  __dpmi_meminfo meminfo;

 

@@ -71,7 +71,7 @@
 /* _remove_linear_mapping:

  *  Frees the DPMI resources being used to map a linear address range.

  */

-static void _remove_linear_mapping (unsigned long *linear)

+void _remove_linear_mapping (unsigned long *linear)

 {

  __dpmi_meminfo meminfo;

 

@@ -127,3 +127,22 @@
     *segment = 0;

  }

 }

+

+

+

+/* Desc: retrieve CPU MMX capability

+ *

+ * In  : -

+ * Out : FALSE if CPU cannot do MMX

+ *

+ * Note: -

+ */

+int _can_mmx (void)

+{

+#ifdef USE_MMX_ASM

+ extern int _mesa_identify_x86_cpu_features (void);

+ return (_mesa_identify_x86_cpu_features() & 0x00800000);

+#else

+ return 0;

+#endif

+}

diff --git a/src/mesa/drivers/dos/internal.h b/src/mesa/drivers/dos/internal.h
index 824d963..304a737 100644
--- a/src/mesa/drivers/dos/internal.h
+++ b/src/mesa/drivers/dos/internal.h
@@ -79,9 +79,9 @@
         void (*blit) (void);

         void (*setCI_f) (int index, float red, float green, float blue);

         void (*setCI_i) (int index, int red, int green, int blue);

-        int (*getCIprec) (void);

+        int (*get) (int pname, int *params);

         void (*restore) (void);

-        void (*finit) (void);

+        void (*fini) (void);

 } vl_driver;

 

 

@@ -89,13 +89,15 @@
 /*

  * memory mapping

  */

+int _create_linear_mapping (unsigned long *linear, unsigned long physaddr, int size);

+void _remove_linear_mapping (unsigned long *linear);

 int _create_selector (int *segment, unsigned long base, int size);

 void _remove_selector (int *segment);

 

 /*

  * system routines

  */

-int vl_can_mmx (void);

+int _can_mmx (void);

 

 /*

  * asm routines to deal with virtual buffering

diff --git a/src/mesa/drivers/dos/mga/m_ttemp.h b/src/mesa/drivers/dos/mga/m_ttemp.h
new file mode 100644
index 0000000..d3de69a
--- /dev/null
+++ b/src/mesa/drivers/dos/mga/m_ttemp.h
@@ -0,0 +1,377 @@
+/*

+ * Mesa 3-D graphics library

+ * Version:  5.0

+ * 

+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.

+ * 

+ * Permission is hereby granted, free of charge, to any person obtaining a

+ * copy of this software and associated documentation files (the "Software"),

+ * to deal in the Software without restriction, including without limitation

+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the

+ * Software is furnished to do so, subject to the following conditions:

+ * 

+ * The above copyright notice and this permission notice shall be included

+ * in all copies or substantial portions of the Software.

+ * 

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL

+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN

+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ */

+

+/*

+ * DOS/DJGPP device driver v1.3 for Mesa 5.0  --  MGA2064W triangle template

+ *

+ *  Copyright (c) 2003 - Borca Daniel

+ *  Email : dborca@yahoo.com

+ *  Web   : http://www.geocities.com/dborca

+ */

+

+

+/*

+ * Triangle Rasterizer Template

+ *

+ * This file is #include'd to generate custom triangle rasterizers.

+ *

+ * The following macros may be defined to indicate what auxillary information

+ * must be interplated across the triangle:

+ *    INTERP_Z        - if defined, interpolate Z values

+ *    INTERP_RGB      - if defined, interpolate RGB values

+ *

+ *    TAG             - function name

+ *    CULL            - enable culling for: 0=no, 1=back, -1=front

+ *

+ *    SETUP_CODE      - to be executed once per triangle (usually HW init)

+ *

+ * For flatshaded primitives, the provoking vertex is the final one.

+ * This code was designed for the origin to be in the upper-left corner.

+ *

+ * Inspired by triangle rasterizer code written by Brian Paul.

+ */

+

+

+

+#define TRI_SWAP(a, b)        \

+do {                          \

+    const MGAvertex *tmp = a; \

+    a = b;                    \

+    b = tmp;                  \

+} while (0)

+

+void TAG (int cull, const MGAvertex *v1, const MGAvertex *v2, const MGAvertex *v3)

+{

+ int area;

+ int x1, y1, x2, y2, x3, y3;

+ int eMaj_dx, eMaj_dy, eBot_dx, eBot_dy, eTop_dx, eTop_dy;

+#ifdef INTERP_RGB

+#define FIFO_CNT_RGB 3

+ int eMaj_dr, eBot_dr, eMaj_dg, eBot_dg, eMaj_db, eBot_db;

+ int drdx, drdy, dgdx, dgdy, dbdx, dbdy;

+#else

+#define FIFO_CNT_RGB 0

+#endif

+#ifdef INTERP_Z

+#define FIFO_CNT_Z 1

+ int dzdx, dzdy;

+ int eMaj_dz, eBot_dz;

+ int z1, z2, z3;

+#else

+#define FIFO_CNT_Z 0

+#endif

+

+#if defined(INTERP_Z) || defined(INTERP_RGB)

+ double one_area;

+#ifndef INTERP_RGB

+ int red = v3->color[0];

+ int green = v3->color[1];

+ int blue = v3->color[2];

+#endif

+#else

+ unsigned long color = mga_mixrgb_full(v3->color);

+#endif

+

+ int sgn = 0;

+

+ /* sort along the vertical axis */

+ if (v2->win[1] < v1->win[1]) {

+    TRI_SWAP(v1, v2);

+#ifdef CULL

+    cull = -cull;

+#endif

+ }

+

+ if (v3->win[1] < v1->win[1]) {

+    TRI_SWAP(v1, v3);

+    TRI_SWAP(v2, v3);

+ } else if (v3->win[1] < v2->win[1]) {

+    TRI_SWAP(v2, v3);

+#ifdef CULL

+    cull = -cull;

+#endif    

+ }

+

+ x1 = v1->win[0];

+ y1 = v1->win[1];

+ x2 = v2->win[0];

+ y2 = v2->win[1];

+ x3 = v3->win[0];

+ y3 = v3->win[1];

+

+ /* compute deltas for each edge */

+ eMaj_dx = x3 - x1;

+ eMaj_dy = y3 - y1;

+ eBot_dx = x2 - x1;

+ eBot_dy = y2 - y1;

+ eTop_dx = x3 - x2;

+ eTop_dy = y3 - y2;

+

+ /* compute area */

+ if ((area = eMaj_dx * eBot_dy - eBot_dx * eMaj_dy) == 0) {

+    return;

+ }

+#ifdef CULL

+ if ((area * cull) > 0) {

+    return;

+ }

+#endif

+

+ mga_select();

+

+ /* set engine state */

+#ifdef SETUP_CODE

+ SETUP_CODE

+#endif

+

+ /* draw lower triangle */

+#if defined(INTERP_Z) || defined(INTERP_RGB)

+ one_area = (double)(1<<15) / (double)area;

+ mga_fifo(1);

+#else

+ mga_fifo(2);

+ mga_outl(M_FCOL, color);

+#endif

+ mga_outl(M_YDST, y1);

+

+#ifdef INTERP_Z

+ z1 = v1->win[2];

+ z2 = v2->win[2];

+ z3 = v3->win[2];

+

+ /* compute d?/dx and d?/dy derivatives */

+ eMaj_dz = z3 - z1;

+ eBot_dz = z2 - z1;

+ dzdx = (eMaj_dz * eBot_dy - eMaj_dy * eBot_dz) * one_area;

+ dzdy = (eMaj_dx * eBot_dz - eMaj_dz * eBot_dx) * one_area;

+

+#ifndef INTERP_RGB

+ mga_fifo(11);

+ mga_outl(M_DR2, dzdx);

+ mga_outl(M_DR3, dzdy);

+ mga_outl(M_DR4, red<<15);

+ mga_outl(M_DR6, 0);

+ mga_outl(M_DR7, 0);

+ mga_outl(M_DR8, green<<15);

+ mga_outl(M_DR10, 0);

+ mga_outl(M_DR11, 0);

+ mga_outl(M_DR12, blue<<15);

+ mga_outl(M_DR14, 0);

+ mga_outl(M_DR15, 0);

+#else

+ mga_fifo(2);

+ mga_outl(M_DR2, dzdx);

+ mga_outl(M_DR3, dzdy);

+#endif

+#endif

+

+#ifdef INTERP_RGB

+ /* compute color deltas */

+ eMaj_dr = v3->color[0] - v1->color[0];

+ eBot_dr = v2->color[0] - v1->color[0];

+ eMaj_dg = v3->color[1] - v1->color[1];

+ eBot_dg = v2->color[1] - v1->color[1];

+ eMaj_db = v3->color[2] - v1->color[2];

+ eBot_db = v2->color[2] - v1->color[2];

+

+ /* compute color increments */

+ drdx = (eMaj_dr * eBot_dy - eMaj_dy * eBot_dr) * one_area;

+ drdy = (eMaj_dx * eBot_dr - eMaj_dr * eBot_dx) * one_area;

+ dgdx = (eMaj_dg * eBot_dy - eMaj_dy * eBot_dg) * one_area;

+ dgdy = (eMaj_dx * eBot_dg - eMaj_dg * eBot_dx) * one_area;

+ dbdx = (eMaj_db * eBot_dy - eMaj_dy * eBot_db) * one_area;

+ dbdy = (eMaj_dx * eBot_db - eMaj_db * eBot_dx) * one_area;

+

+ mga_fifo(6);

+ mga_outl(M_DR6, drdx);

+ mga_outl(M_DR7, drdy);

+ mga_outl(M_DR10, dgdx);

+ mga_outl(M_DR11, dgdy);

+ mga_outl(M_DR14, dbdx);

+ mga_outl(M_DR15, dbdy);

+#endif

+

+ if (area > 0) { /* major edge on the right */

+    if (eBot_dy) { /* have lower triangle */

+       mga_fifo(9 + FIFO_CNT_Z + FIFO_CNT_RGB);

+

+       mga_outl(M_AR0, eBot_dy);

+       if (x2 < x1) {

+          mga_outl(M_AR1, eBot_dx + eBot_dy - 1);

+          mga_outl(M_AR2, eBot_dx);

+          sgn |= M_SDXL;

+       } else {

+          mga_outl(M_AR1, -eBot_dx);

+          mga_outl(M_AR2, -eBot_dx);

+       }

+

+       mga_outl(M_AR6, eMaj_dy);

+       if (x3 < x1) {

+          mga_outl(M_AR4, eMaj_dx + eMaj_dy - 1);

+          mga_outl(M_AR5, eMaj_dx);

+          sgn |= M_SDXR;

+       } else {

+          mga_outl(M_AR4, -eMaj_dx);

+          mga_outl(M_AR5, -eMaj_dx);

+       }

+

+       mga_outl(M_FXBNDRY, (x1<<16) | x1);

+#ifdef INTERP_Z

+       mga_outl(M_DR0, z1<<15);

+#endif

+#ifdef INTERP_RGB

+       mga_outl(M_DR4, v1->color[0]<<15);

+       mga_outl(M_DR8, v1->color[1]<<15);

+       mga_outl(M_DR12, v1->color[2]<<15);

+#endif

+       mga_outl(M_SGN, sgn);

+       mga_outl(M_LEN | M_EXEC, eBot_dy);

+    } else { /* no lower triangle */

+       mga_fifo(4 + FIFO_CNT_Z + FIFO_CNT_RGB);

+

+       mga_outl(M_AR6, eMaj_dy);

+       if (x3 < x1) {

+          mga_outl(M_AR4, eMaj_dx + eMaj_dy - 1);

+          mga_outl(M_AR5, eMaj_dx);

+          sgn |= M_SDXR;

+       } else {

+          mga_outl(M_AR4, -eMaj_dx);

+          mga_outl(M_AR5, -eMaj_dx);

+       }

+

+       mga_outl(M_FXBNDRY, (x1<<16) | x2);

+#ifdef INTERP_Z

+       mga_outl(M_DR0, z2<<15);

+#endif

+#ifdef INTERP_RGB

+       mga_outl(M_DR4, v2->color[0]<<15);

+       mga_outl(M_DR8, v2->color[1]<<15);

+       mga_outl(M_DR12, v2->color[2]<<15);

+#endif

+    }

+

+    /* draw upper triangle */

+    if (eTop_dy) {

+       mga_fifo(5);

+       mga_outl(M_AR0, eTop_dy);

+       if (x3 < x2) {

+          mga_outl(M_AR1, eTop_dx + eTop_dy - 1);

+          mga_outl(M_AR2, eTop_dx);

+          sgn |= M_SDXL;

+       } else {

+          mga_outl(M_AR1, -eTop_dx);

+          mga_outl(M_AR2, -eTop_dx);

+          sgn &= ~M_SDXL;

+       }

+       mga_outl(M_SGN, sgn);

+       mga_outl(M_LEN | M_EXEC, eTop_dy);

+    }

+ } else { /* major edge on the left */

+    if (eBot_dy) { /* have lower triangle */

+       mga_fifo(9 + FIFO_CNT_Z + FIFO_CNT_RGB);

+

+       mga_outl(M_AR0, eMaj_dy);

+       if (x3 < x1) {

+          mga_outl(M_AR1, eMaj_dx + eMaj_dy - 1);

+          mga_outl(M_AR2, eMaj_dx);

+          sgn |= M_SDXL;

+       } else {

+          mga_outl(M_AR1, -eMaj_dx);

+          mga_outl(M_AR2, -eMaj_dx);

+       }

+

+       mga_outl(M_AR6, eBot_dy);

+       if (x2 < x1) {

+          mga_outl(M_AR4, eBot_dx + eBot_dy - 1);

+          mga_outl(M_AR5, eBot_dx);

+          sgn |= M_SDXR;

+       } else {

+          mga_outl(M_AR4, -eBot_dx);

+          mga_outl(M_AR5, -eBot_dx);

+       }

+

+       mga_outl(M_FXBNDRY, (x1<<16) | x1);

+#ifdef INTERP_Z

+       mga_outl(M_DR0, z1<<15);

+#endif

+#ifdef INTERP_RGB

+       mga_outl(M_DR4, v1->color[0]<<15);

+       mga_outl(M_DR8, v1->color[1]<<15);

+       mga_outl(M_DR12, v1->color[2]<<15);

+#endif

+       mga_outl(M_SGN, sgn);

+       mga_outl(M_LEN | M_EXEC, eBot_dy);

+    } else { /* no lower triangle */

+       mga_fifo(4 + FIFO_CNT_Z + FIFO_CNT_RGB);

+

+       mga_outl(M_AR0, eMaj_dy);

+       if (x3 < x1) {

+          mga_outl(M_AR1, eMaj_dx + eMaj_dy - 1);

+          mga_outl(M_AR2, eMaj_dx);

+          sgn |= M_SDXL;

+       } else {

+          mga_outl(M_AR1, -eMaj_dx);

+          mga_outl(M_AR2, -eMaj_dx);

+       }

+

+       mga_outl(M_FXBNDRY, (x2<<16) | x1);

+#ifdef INTERP_Z

+       mga_outl(M_DR0, z1<<15);

+#endif

+#ifdef INTERP_RGB

+       mga_outl(M_DR4, v1->color[0]<<15);

+       mga_outl(M_DR8, v1->color[1]<<15);

+       mga_outl(M_DR12, v1->color[2]<<15);

+#endif

+    }

+

+    /* draw upper triangle */

+    if (eTop_dy) {

+       mga_fifo(5);

+       mga_outl(M_AR6, eTop_dy);

+       if (x3 < x2) {

+          mga_outl(M_AR4, eTop_dx + eTop_dy - 1);

+          mga_outl(M_AR5, eTop_dx);

+          sgn |= M_SDXR;

+       } else {

+          mga_outl(M_AR4, -eTop_dx);

+          mga_outl(M_AR5, -eTop_dx);

+          sgn &= ~M_SDXR;

+       }

+       mga_outl(M_SGN, sgn);

+       mga_outl(M_LEN | M_EXEC, eTop_dy);

+    }

+ }

+}

+

+#undef FIFO_CNT_RGB

+#undef FIFO_CNT_Z

+

+#undef TRI_SWAP

+

+#undef SETUP_CODE

+#undef INTERP_RGB

+#undef INTERP_Z

+#undef CULL

+#undef TAG

diff --git a/src/mesa/drivers/dos/mga/m_ttemp2.h b/src/mesa/drivers/dos/mga/m_ttemp2.h
new file mode 100644
index 0000000..27a1c8b
--- /dev/null
+++ b/src/mesa/drivers/dos/mga/m_ttemp2.h
@@ -0,0 +1,375 @@
+/*

+ * Mesa 3-D graphics library

+ * Version:  5.0

+ * 

+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.

+ * 

+ * Permission is hereby granted, free of charge, to any person obtaining a

+ * copy of this software and associated documentation files (the "Software"),

+ * to deal in the Software without restriction, including without limitation

+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the

+ * Software is furnished to do so, subject to the following conditions:

+ * 

+ * The above copyright notice and this permission notice shall be included

+ * in all copies or substantial portions of the Software.

+ * 

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL

+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN

+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ */

+

+/*

+ * DOS/DJGPP device driver v1.3 for Mesa 5.0  --  MGA2064W triangle template

+ *

+ *  Copyright (c) 2003 - Borca Daniel

+ *  Email : dborca@yahoo.com

+ *  Web   : http://www.geocities.com/dborca

+ */

+

+

+/*

+ * Triangle Rasterizer Template

+ *

+ * This file is #include'd to generate custom triangle rasterizers.

+ *

+ * The following macros may be defined to indicate what auxillary information

+ * must be interplated across the triangle:

+ *    INTERP_Z        - if defined, interpolate Z values

+ *    INTERP_RGB      - if defined, interpolate RGB values

+ *

+ *    TAG             - function name

+ *    CULL            - enable culling for: 0=no, 1=back, -1=front

+ *

+ *    SETUP_CODE      - to be executed once per triangle (usually HW init)

+ *

+ * For flatshaded primitives, the provoking vertex is the final one.

+ * This code was designed for the origin to be in the upper-left corner.

+ *

+ * Inspired by triangle rasterizer code written by Brian Paul.

+ */

+

+

+

+#define TRI_SWAP(a, b)        \

+do {                          \

+    const MGAvertex *tmp = a; \

+    a = b;                    \

+    b = tmp;                  \

+} while (0)

+

+void TAG (int cull, const MGAvertex *v1, const MGAvertex *v2, const MGAvertex *v3)

+{

+ int area;

+ int x1, y1, x2, y2, x3, y3;

+ int eMaj_dx, eMaj_dy, eBot_dx, eBot_dy, eTop_dx, eTop_dy;

+#ifdef INTERP_RGB

+#define FIFO_CNT_RGB 3

+ int eMaj_dr, eBot_dr, eMaj_dg, eBot_dg, eMaj_db, eBot_db;

+ int drdx, drdy, dgdx, dgdy, dbdx, dbdy;

+#else

+#define FIFO_CNT_RGB 0

+#endif

+#ifdef INTERP_Z

+#define FIFO_CNT_Z 1

+ int dzdx, dzdy;

+ int eMaj_dz, eBot_dz;

+ int z1, z2, z3;

+#else

+#define FIFO_CNT_Z 0

+#endif

+

+#if defined(INTERP_Z) || defined(INTERP_RGB)

+#ifndef INTERP_RGB

+ int red = v3->color[0];

+ int green = v3->color[1];

+ int blue = v3->color[2];

+#endif

+#else

+ unsigned long color = mga_mixrgb_full(v3->color);

+#endif

+

+ int sgn = 0;

+

+ /* sort along the vertical axis */

+ if (v2->win[1] < v1->win[1]) {

+    TRI_SWAP(v1, v2);

+#ifdef CULL

+    cull = -cull;

+#endif

+ }

+

+ if (v3->win[1] < v1->win[1]) {

+    TRI_SWAP(v1, v3);

+    TRI_SWAP(v2, v3);

+ } else if (v3->win[1] < v2->win[1]) {

+    TRI_SWAP(v2, v3);

+#ifdef CULL

+    cull = -cull;

+#endif    

+ }

+

+ x1 = v1->win[0];

+ y1 = v1->win[1];

+ x2 = v2->win[0];

+ y2 = v2->win[1];

+ x3 = v3->win[0];

+ y3 = v3->win[1];

+

+ /* compute deltas for each edge */

+ eMaj_dx = x3 - x1;

+ eMaj_dy = y3 - y1;

+ eBot_dx = x2 - x1;

+ eBot_dy = y2 - y1;

+ eTop_dx = x3 - x2;

+ eTop_dy = y3 - y2;

+

+ /* compute area */

+ if ((area = eMaj_dx * eBot_dy - eBot_dx * eMaj_dy) == 0) {

+    return;

+ }

+#ifdef CULL

+ if ((area * cull) > 0) {

+    return;

+ }

+#endif

+

+ mga_select();

+

+ /* set engine state */

+#ifdef SETUP_CODE

+ SETUP_CODE

+#endif

+

+ /* draw lower triangle */

+#if defined(INTERP_Z) || defined(INTERP_RGB)

+ mga_fifo(1);

+#else

+ mga_fifo(2);

+ mga_outl(M_FCOL, color);

+#endif

+ mga_outl(M_YDST, y1);

+

+#ifdef INTERP_Z

+ z1 = v1->win[2];

+ z2 = v2->win[2];

+ z3 = v3->win[2];

+

+ /* compute d?/dx and d?/dy derivatives */

+ eMaj_dz = z3 - z1;

+ eBot_dz = z2 - z1;

+ dzdx = ((long long)(eMaj_dz * eBot_dy - eMaj_dy * eBot_dz)<<15) / area;

+ dzdy = ((long long)(eMaj_dx * eBot_dz - eMaj_dz * eBot_dx)<<15) / area;

+

+#ifndef INTERP_RGB

+ mga_fifo(11);

+ mga_outl(M_DR2, dzdx);

+ mga_outl(M_DR3, dzdy);

+ mga_outl(M_DR4, red<<15);

+ mga_outl(M_DR6, 0);

+ mga_outl(M_DR7, 0);

+ mga_outl(M_DR8, green<<15);

+ mga_outl(M_DR10, 0);

+ mga_outl(M_DR11, 0);

+ mga_outl(M_DR12, blue<<15);

+ mga_outl(M_DR14, 0);

+ mga_outl(M_DR15, 0);

+#else

+ mga_fifo(2);

+ mga_outl(M_DR2, dzdx);

+ mga_outl(M_DR3, dzdy);

+#endif

+#endif

+

+#ifdef INTERP_RGB

+ /* compute color deltas */

+ eMaj_dr = v3->color[0] - v1->color[0];

+ eBot_dr = v2->color[0] - v1->color[0];

+ eMaj_dg = v3->color[1] - v1->color[1];

+ eBot_dg = v2->color[1] - v1->color[1];

+ eMaj_db = v3->color[2] - v1->color[2];

+ eBot_db = v2->color[2] - v1->color[2];

+

+ /* compute color increments */

+ drdx = ((long long)(eMaj_dr * eBot_dy - eMaj_dy * eBot_dr)<<15) / area;

+ drdy = ((long long)(eMaj_dx * eBot_dr - eMaj_dr * eBot_dx)<<15) / area;

+ dgdx = ((long long)(eMaj_dg * eBot_dy - eMaj_dy * eBot_dg)<<15) / area;

+ dgdy = ((long long)(eMaj_dx * eBot_dg - eMaj_dg * eBot_dx)<<15) / area;

+ dbdx = ((long long)(eMaj_db * eBot_dy - eMaj_dy * eBot_db)<<15) / area;

+ dbdy = ((long long)(eMaj_dx * eBot_db - eMaj_db * eBot_dx)<<15) / area;

+

+ mga_fifo(6);

+ mga_outl(M_DR6, drdx);

+ mga_outl(M_DR7, drdy);

+ mga_outl(M_DR10, dgdx);

+ mga_outl(M_DR11, dgdy);

+ mga_outl(M_DR14, dbdx);

+ mga_outl(M_DR15, dbdy);

+#endif

+

+ if (area > 0) { /* major edge on the right */

+    if (eBot_dy) { /* have lower triangle */

+       mga_fifo(9 + FIFO_CNT_Z + FIFO_CNT_RGB);

+

+       mga_outl(M_AR0, eBot_dy);

+       if (x2 < x1) {

+          mga_outl(M_AR1, eBot_dx + eBot_dy - 1);

+          mga_outl(M_AR2, eBot_dx);

+          sgn |= M_SDXL;

+       } else {

+          mga_outl(M_AR1, -eBot_dx);

+          mga_outl(M_AR2, -eBot_dx);

+       }

+

+       mga_outl(M_AR6, eMaj_dy);

+       if (x3 < x1) {

+          mga_outl(M_AR4, eMaj_dx + eMaj_dy - 1);

+          mga_outl(M_AR5, eMaj_dx);

+          sgn |= M_SDXR;

+       } else {

+          mga_outl(M_AR4, -eMaj_dx);

+          mga_outl(M_AR5, -eMaj_dx);

+       }

+

+       mga_outl(M_FXBNDRY, (x1<<16) | x1);

+#ifdef INTERP_Z

+       mga_outl(M_DR0, z1<<15);

+#endif

+#ifdef INTERP_RGB

+       mga_outl(M_DR4, v1->color[0]<<15);

+       mga_outl(M_DR8, v1->color[1]<<15);

+       mga_outl(M_DR12, v1->color[2]<<15);

+#endif

+       mga_outl(M_SGN, sgn);

+       mga_outl(M_LEN | M_EXEC, eBot_dy);

+    } else { /* no lower triangle */

+       mga_fifo(4 + FIFO_CNT_Z + FIFO_CNT_RGB);

+

+       mga_outl(M_AR6, eMaj_dy);

+       if (x3 < x1) {

+          mga_outl(M_AR4, eMaj_dx + eMaj_dy - 1);

+          mga_outl(M_AR5, eMaj_dx);

+          sgn |= M_SDXR;

+       } else {

+          mga_outl(M_AR4, -eMaj_dx);

+          mga_outl(M_AR5, -eMaj_dx);

+       }

+

+       mga_outl(M_FXBNDRY, (x1<<16) | x2);

+#ifdef INTERP_Z

+       mga_outl(M_DR0, z2<<15);

+#endif

+#ifdef INTERP_RGB

+       mga_outl(M_DR4, v2->color[0]<<15);

+       mga_outl(M_DR8, v2->color[1]<<15);

+       mga_outl(M_DR12, v2->color[2]<<15);

+#endif

+    }

+

+    /* draw upper triangle */

+    if (eTop_dy) {

+       mga_fifo(5);

+       mga_outl(M_AR0, eTop_dy);

+       if (x3 < x2) {

+          mga_outl(M_AR1, eTop_dx + eTop_dy - 1);

+          mga_outl(M_AR2, eTop_dx);

+          sgn |= M_SDXL;

+       } else {

+          mga_outl(M_AR1, -eTop_dx);

+          mga_outl(M_AR2, -eTop_dx);

+          sgn &= ~M_SDXL;

+       }

+       mga_outl(M_SGN, sgn);

+       mga_outl(M_LEN | M_EXEC, eTop_dy);

+    }

+ } else { /* major edge on the left */

+    if (eBot_dy) { /* have lower triangle */

+       mga_fifo(9 + FIFO_CNT_Z + FIFO_CNT_RGB);

+

+       mga_outl(M_AR0, eMaj_dy);

+       if (x3 < x1) {

+          mga_outl(M_AR1, eMaj_dx + eMaj_dy - 1);

+          mga_outl(M_AR2, eMaj_dx);

+          sgn |= M_SDXL;

+       } else {

+          mga_outl(M_AR1, -eMaj_dx);

+          mga_outl(M_AR2, -eMaj_dx);

+       }

+

+       mga_outl(M_AR6, eBot_dy);

+       if (x2 < x1) {

+          mga_outl(M_AR4, eBot_dx + eBot_dy - 1);

+          mga_outl(M_AR5, eBot_dx);

+          sgn |= M_SDXR;

+       } else {

+          mga_outl(M_AR4, -eBot_dx);

+          mga_outl(M_AR5, -eBot_dx);

+       }

+

+       mga_outl(M_FXBNDRY, (x1<<16) | x1);

+#ifdef INTERP_Z

+       mga_outl(M_DR0, z1<<15);

+#endif

+#ifdef INTERP_RGB

+       mga_outl(M_DR4, v1->color[0]<<15);

+       mga_outl(M_DR8, v1->color[1]<<15);

+       mga_outl(M_DR12, v1->color[2]<<15);

+#endif

+       mga_outl(M_SGN, sgn);

+       mga_outl(M_LEN | M_EXEC, eBot_dy);

+    } else { /* no lower triangle */

+       mga_fifo(4 + FIFO_CNT_Z + FIFO_CNT_RGB);

+

+       mga_outl(M_AR0, eMaj_dy);

+       if (x3 < x1) {

+          mga_outl(M_AR1, eMaj_dx + eMaj_dy - 1);

+          mga_outl(M_AR2, eMaj_dx);

+          sgn |= M_SDXL;

+       } else {

+          mga_outl(M_AR1, -eMaj_dx);

+          mga_outl(M_AR2, -eMaj_dx);

+       }

+

+       mga_outl(M_FXBNDRY, (x2<<16) | x1);

+#ifdef INTERP_Z

+       mga_outl(M_DR0, z1<<15);

+#endif

+#ifdef INTERP_RGB

+       mga_outl(M_DR4, v1->color[0]<<15);

+       mga_outl(M_DR8, v1->color[1]<<15);

+       mga_outl(M_DR12, v1->color[2]<<15);

+#endif

+    }

+

+    /* draw upper triangle */

+    if (eTop_dy) {

+       mga_fifo(5);

+       mga_outl(M_AR6, eTop_dy);

+       if (x3 < x2) {

+          mga_outl(M_AR4, eTop_dx + eTop_dy - 1);

+          mga_outl(M_AR5, eTop_dx);

+          sgn |= M_SDXR;

+       } else {

+          mga_outl(M_AR4, -eTop_dx);

+          mga_outl(M_AR5, -eTop_dx);

+          sgn &= ~M_SDXR;

+       }

+       mga_outl(M_SGN, sgn);

+       mga_outl(M_LEN | M_EXEC, eTop_dy);

+    }

+ }

+}

+

+#undef FIFO_CNT_RGB

+#undef FIFO_CNT_Z

+

+#undef TRI_SWAP

+

+#undef SETUP_CODE

+#undef INTERP_RGB

+#undef INTERP_Z

+#undef CULL

+#undef TAG

diff --git a/src/mesa/drivers/dos/mga/mga.c b/src/mesa/drivers/dos/mga/mga.c
new file mode 100644
index 0000000..59bb09c
--- /dev/null
+++ b/src/mesa/drivers/dos/mga/mga.c
@@ -0,0 +1,1536 @@
+/*

+ * Mesa 3-D graphics library

+ * Version:  5.0

+ * 

+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.

+ * 

+ * Permission is hereby granted, free of charge, to any person obtaining a

+ * copy of this software and associated documentation files (the "Software"),

+ * to deal in the Software without restriction, including without limitation

+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the

+ * Software is furnished to do so, subject to the following conditions:

+ * 

+ * The above copyright notice and this permission notice shall be included

+ * in all copies or substantial portions of the Software.

+ * 

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL

+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN

+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ */

+

+/*

+ * DOS/DJGPP device driver v1.3 for Mesa 5.0  --  MGA2064W

+ *

+ *  Copyright (c) 2003 - Borca Daniel

+ *  Email : dborca@yahoo.com

+ *  Web   : http://www.geocities.com/dborca

+ *

+ * Thanks to Shawn Hargreaves for FreeBE/AF

+ */

+

+

+#include <dpmi.h>

+#include <stdlib.h>

+#include <string.h>

+

+#include "../internal.h"

+#include "mga_reg.h"

+#include "mga_hw.h"

+#include "mga_mode.h"

+#include "mga.h"

+

+

+

+/* cached drawing engine state */

+#define OP_NONE 0

+

+#define OP_DRAWRECT (\

+           M_DWG_TRAP |           /* opcod */    \

+           M_DWG_BLK |            /* atype */    \

+                                  /* linear */   \

+           M_DWG_NOZCMP |         /* zmode */    \

+           M_DWG_SOLID |          /* solid */    \

+           M_DWG_ARZERO |         /* arzero */   \

+           M_DWG_SGNZERO |        /* sgnzero */  \

+           M_DWG_SHFTZERO |       /* shftzero */ \

+           M_DWG_BOP_SRC          /* bop */      \

+                                  /* trans */    \

+                                  /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_DRAWRECT_TX32BGR (\

+           M_DWG_TEXTURE_TRAP |   /* opcod */    \

+           M_DWG_I |              /* atype */    \

+                                  /* linear */   \

+           M_DWG_NOZCMP |         /* zmode */    \

+                                  /* solid */    \

+           M_DWG_ARZERO |         /* arzero */   \

+           M_DWG_SGNZERO |        /* sgnzero */  \

+           M_DWG_SHFTZERO |       /* shftzero */ \

+           M_DWG_BOP_SRC |        /* bop */      \

+                                  /* trans */    \

+           M_DWG_BU32BGR          /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_DRAWRECT_TX24BGR (\

+           M_DWG_TEXTURE_TRAP |   /* opcod */    \

+           M_DWG_I |              /* atype */    \

+                                  /* linear */   \

+           M_DWG_NOZCMP |         /* zmode */    \

+                                  /* solid */    \

+           M_DWG_ARZERO |         /* arzero */   \

+           M_DWG_SGNZERO |        /* sgnzero */  \

+           M_DWG_SHFTZERO |       /* shftzero */ \

+           M_DWG_BOP_SRC |        /* bop */      \

+                                  /* trans */    \

+           M_DWG_BU24BGR          /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_DRAWLINE (\

+           M_DWG_AUTOLINE_CLOSE | /* opcod */    \

+           M_DWG_RPL |            /* atype */    \

+                                  /* linear */   \

+           M_DWG_NOZCMP |         /* zmode */    \

+           M_DWG_SOLID |          /* solid */    \

+                                  /* arzero */   \

+                                  /* sgnzero */  \

+           M_DWG_SHFTZERO |       /* shftzero */ \

+           M_DWG_BOP_SRC |        /* bop */      \

+                                  /* trans */    \

+           M_DWG_BFCOL            /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_DRAWLINE_I (\

+           M_DWG_AUTOLINE_CLOSE | /* opcod */    \

+           M_DWG_I |              /* atype */    \

+                                  /* linear */   \

+           M_DWG_NOZCMP |         /* zmode */    \

+                                  /* solid */    \

+                                  /* arzero */   \

+                                  /* sgnzero */  \

+                                  /* shftzero */ \

+           M_DWG_BOP_SRC |        /* bop */      \

+                                  /* trans */    \

+           M_DWG_BFCOL            /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_DRAWLINE_ZI (\

+           M_DWG_AUTOLINE_CLOSE | /* opcod */    \

+           M_DWG_ZI |             /* atype */    \

+                                  /* linear */   \

+           M_DWG_ZLT |            /* zmode */    \

+                                  /* solid */    \

+                                  /* arzero */   \

+                                  /* sgnzero */  \

+                                  /* shftzero */ \

+           M_DWG_BOP_SRC |        /* bop */      \

+                                  /* trans */    \

+           M_DWG_BFCOL            /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_DRAWTRAP (\

+           M_DWG_TRAP |           /* opcod */    \

+           M_DWG_BLK |            /* atype */    \

+                                  /* linear */   \

+           M_DWG_NOZCMP |         /* zmode */    \

+           M_DWG_SOLID |          /* solid */    \

+                                  /* arzero */   \

+                                  /* sgnzero */  \

+           M_DWG_SHFTZERO |       /* shftzero */ \

+           M_DWG_BOP_SRC          /* bop */      \

+                                  /* trans */    \

+                                  /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_DRAWTRAP_I (\

+           M_DWG_TRAP |           /* opcod */    \

+           M_DWG_I |              /* atype */    \

+                                  /* linear */   \

+           M_DWG_NOZCMP |         /* zmode */    \

+                                  /* solid */    \

+                                  /* arzero */   \

+                                  /* sgnzero */  \

+           M_DWG_SHFTZERO |       /* shftzero */ \

+           M_DWG_BOP_SRC          /* bop */      \

+                                  /* trans */    \

+                                  /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_DRAWTRAP_ZI (\

+           M_DWG_TRAP |           /* opcod */    \

+           M_DWG_ZI |             /* atype */    \

+                                  /* linear */   \

+           M_DWG_ZLT |            /* zmode */    \

+                                  /* solid */    \

+                                  /* arzero */   \

+                                  /* sgnzero */  \

+           M_DWG_SHFTZERO |       /* shftzero */ \

+           M_DWG_BOP_SRC          /* bop */      \

+                                  /* trans */    \

+                                  /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_ILOAD_32BGR (\

+           M_DWG_ILOAD |          /* opcod */    \

+           M_DWG_RPL |            /* atype */    \

+                                  /* linear */   \

+                                  /* zmode */    \

+                                  /* solid */    \

+                                  /* arzero */   \

+           M_DWG_SGNZERO |        /* sgnzero */  \

+           M_DWG_SHFTZERO |       /* shftzero */ \

+           M_DWG_BOP_SRC |        /* bop */      \

+                                  /* trans */    \

+           M_DWG_BU32BGR          /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+#define OP_ILOAD_24BGR (\

+           M_DWG_ILOAD |          /* opcod */    \

+           M_DWG_RPL |            /* atype */    \

+                                  /* linear */   \

+                                  /* zmode */    \

+                                  /* solid */    \

+                                  /* arzero */   \

+           M_DWG_SGNZERO |        /* sgnzero */  \

+           M_DWG_SHFTZERO |       /* shftzero */ \

+           M_DWG_BOP_SRC |        /* bop */      \

+                                  /* trans */    \

+           M_DWG_BU24BGR          /* bltmod */   \

+                                  /* pattern */  \

+                                  /* transc */   )

+

+

+

+/* internal hardware data structures */

+static int interleave;

+static unsigned long zorg;

+static unsigned long vram;

+static char card_name[80];

+

+

+

+/* some info about current mode */

+static int __bpp, __bypp;

+static int __pixwidth, __bytwidth, __pagewidth, __width, __height, __zheight;

+static int __operation;

+static int __scrollx, __scrolly;

+

+

+

+/* buffers */

+static int mga_readbuffer, mga_writebuffer;

+static long mga_readbuffer_ptr, mga_writebuffer_ptr;

+static long mga_backbuffer_ptr, mga_frontbuffer_ptr;

+

+

+

+/* lookup table for scaling 2 bit colors up to 8 bits */

+static int _rgb_scale_2[4] = {

+       0, 85, 170, 255

+};

+

+/* lookup table for scaling 3 bit colors up to 8 bits */

+static int _rgb_scale_3[8] = {

+       0, 36, 73, 109, 146, 182, 219, 255

+};

+

+/* lookup table for scaling 5 bit colors up to 8 bits */

+static int _rgb_scale_5[32] = {

+   0,   8,   16,  25,  33,  41,  49,  58,

+   66,  74,  82,  90,  99,  107, 115, 123,

+   132, 140, 148, 156, 165, 173, 181, 189,

+   197, 206, 214, 222, 230, 239, 247, 255

+};

+

+/* lookup table for scaling 6 bit colors up to 8 bits */

+static int _rgb_scale_6[64] = {

+   0,   4,   8,   12,  16,  20,  24,  28,

+   32,  36,  40,  45,  49,  53,  57,  61,

+   65,  69,  73,  77,  81,  85,  89,  93,

+   97,  101, 105, 109, 113, 117, 121, 125,

+   130, 134, 138, 142, 146, 150, 154, 158,

+   162, 166, 170, 174, 178, 182, 186, 190,

+   194, 198, 202, 206, 210, 215, 219, 223,

+   227, 231, 235, 239, 243, 247, 251, 255

+};

+

+

+

+/*

+ * pixel/color routines

+ */

+void (*mga_putpixel) (unsigned int offset, int color);

+int (*mga_getpixel) (unsigned int offset);

+void (*mga_getrgba) (unsigned int offset, unsigned char rgba[4]);

+int (*mga_mixrgb) (const unsigned char rgb[]);

+static int (*mga_mixrgb_full) (const unsigned char rgb[]);

+

+

+

+/* mga_fifo:

+ *  Waits until there are at least <n> free slots in the FIFO buffer.

+ */

+#define mga_fifo(n) do { } while (mga_inb(M_FIFOSTATUS) < (n))

+

+

+

+static int _mga_rread (int port, int index)

+{

+ mga_select();

+ mga_outb(port, index);

+ return mga_inb(port+1);

+}

+

+

+

+static void _mga_rwrite (int port, int index, int v)

+{

+ mga_select();

+ mga_outb(port, index);

+ mga_outb(port+1, v);

+}

+

+

+

+static void _mga_ralter (int port, int index, int mask, int v)

+{

+ int temp;

+ temp = _mga_rread(port, index);

+ temp &= (~mask);

+ temp |= (v & mask);

+ _mga_rwrite(port, index, temp);

+}

+

+

+

+/* WaitTillIdle:

+ *  Delay until the hardware controller has finished drawing.

+ */

+void mga_wait_idle (void)

+{

+ int tries = 2;

+

+ /*hwptr_unselect(oldptr);*/

+

+ mga_select();

+

+ while (tries--) {

+       do {

+       } while (!(mga_inl(M_FIFOSTATUS) & 0x200));

+

+       do {

+       } while (mga_inl(M_STATUS) & 0x10000);

+

+       mga_outb(M_CRTC_INDEX, 0);

+ }

+

+ /*hwptr_select(oldptr);*/

+}

+

+

+

+/* Desc: Waits for the next vertical sync period.

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+static void _mga_wait_retrace (void)

+{

+ int t1 = 0;

+ int t2 = 0;

+

+ do {

+     t1 = t2;

+     t2 = mga_inl(M_VCOUNT);

+ } while (t2 >= t1);

+}

+

+

+

+/* Desc: fix scan lines

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+static unsigned long _mga_fix_scans (unsigned long l)

+{

+ unsigned long m = 0;

+

+ switch (__bpp) {

+        case 8:

+             m = interleave?128:64;

+             break;

+        case 15:

+        case 16:

+             m = interleave?64:32;

+             break;

+        case 24:

+             m = interleave?128:64;

+             break;

+        case 32:

+             m = 32;

+             break;

+ }

+

+ m -= 1;

+ return (l + m) & ~m;

+}

+

+

+

+/* Desc: HW scrolling function

+ *

+ * In  :

+ * Out :

+ *

+ * Note: view Z-buffer in 16bit modes: _mga_display_start(0, 0, __height, 1)

+ */

+void mga_display_start (long boffset, long x, long y, long waitVRT)

+{

+ long addr;

+

+ mga_select();

+

+ if (waitVRT >= 0) {

+

+    addr = __bytwidth * y + (boffset + x) * __bypp;

+

+    if (interleave) {

+       addr /= 8;

+    } else {

+       addr /= 4;

+    }

+

+    _mga_rwrite(M_CRTC_INDEX, 0x0D, (addr)&0xFF);

+    _mga_rwrite(M_CRTC_INDEX, 0x0C, (addr>>8)&0xFF);

+    _mga_ralter(M_CRTC_EXT_INDEX, 0, 0x0F, (addr>>16)&0x0F);

+

+    while (waitVRT--) {

+          _mga_wait_retrace();

+    }

+ }

+

+ __scrollx = x;

+ __scrolly = y;

+}

+

+

+

+/* Desc: set READ buffer

+ *

+ * In  : either FRONT or BACK buffer

+ * Out :

+ *

+ * Note:

+ */

+void mga_set_readbuffer (int buffer)

+{

+ mga_readbuffer = buffer;

+

+ mga_readbuffer_ptr = (mga_readbuffer == MGA_FRONTBUFFER) ? mga_frontbuffer_ptr : mga_backbuffer_ptr;

+}

+

+

+

+/* Desc: set WRITE buffer

+ *

+ * In  : either FRONT or BACK buffer

+ * Out :

+ *

+ * Note:

+ */

+void mga_set_writebuffer (int buffer)

+{

+ mga_writebuffer = buffer;

+

+ mga_writebuffer_ptr = (mga_writebuffer == MGA_FRONTBUFFER) ? mga_frontbuffer_ptr : mga_backbuffer_ptr;

+

+ mga_select();

+ mga_fifo(1);

+ mga_outl(M_YDSTORG, mga_writebuffer_ptr);

+

+ __operation = OP_NONE;

+}

+

+

+

+/* Desc: swap buffers

+ *

+ * In  : number of vertical retraces to wait

+ * Out :

+ *

+ * Note:

+ */

+void mga_swapbuffers (int swapinterval)

+{

+ /* flip the buffers */

+ mga_backbuffer_ptr ^= __pagewidth;

+ mga_frontbuffer_ptr ^= __pagewidth;

+

+ /* update READ/WRITE pointers */

+ mga_set_readbuffer(mga_readbuffer);

+ mga_set_writebuffer(mga_writebuffer);

+

+ /* make sure we always see the FRONT buffer */

+ mga_display_start(mga_frontbuffer_ptr, __scrollx, __scrolly, swapinterval);

+}

+

+

+

+/* Desc: color composition (w/o ALPHA)

+ *

+ * In  : array of integers (R, G, B)

+ * Out : color

+ *

+ * Note: -

+ */

+static __inline int _mga_mixrgb8 (const unsigned char rgb[])

+{

+ return (rgb[0]&0xe0)|((rgb[1]>>5)<<2)|(rgb[2]>>6);

+}

+static __inline int _mga_mixrgb15 (const unsigned char rgb[])

+{

+ return ((rgb[0]>>3)<<10)|((rgb[1]>>3)<<5)|(rgb[2]>>3);

+}

+static __inline int _mga_mixrgb16 (const unsigned char rgb[])

+{

+ return ((rgb[0]>>3)<<11)|((rgb[1]>>2)<<5)|(rgb[2]>>3);

+}

+static __inline int _mga_mixrgb32 (const unsigned char rgb[])

+{

+ return (rgb[0]<<16)|(rgb[1]<<8)|(rgb[2]);

+}

+

+

+

+/* Desc: color composition (w/o ALPHA) + replication

+ *

+ * In  : array of integers (R, G, B)

+ * Out : color

+ *

+ * Note: -

+ */

+static int _mga_mixrgb8_full (const unsigned char rgb[])

+{

+ int color = _mga_mixrgb8(rgb);

+ color |= color<<8;

+ return (color<<16) | color;

+}

+static int _mga_mixrgb15_full (const unsigned char rgb[])

+{

+ int color = _mga_mixrgb15(rgb);

+ return (color<<16) | color;

+}

+static int _mga_mixrgb16_full (const unsigned char rgb[])

+{

+ int color = _mga_mixrgb16(rgb);

+ return (color<<16) | color;

+}

+#define _mga_mixrgb32_full _mga_mixrgb32

+

+

+

+/* Desc: putpixel

+ *

+ * In  : pixel offset, pixel value

+ * Out : -

+ *

+ * Note: uses current write buffer

+ */

+static void _mga_putpixel8 (unsigned int offset, int color)

+{

+ hwptr_pokeb(mgaptr.linear_map, mga_writebuffer_ptr + offset, color);

+}

+#define _mga_putpixel15 _mga_putpixel16

+static void _mga_putpixel16 (unsigned int offset, int color)

+{

+ hwptr_pokew(mgaptr.linear_map, (mga_writebuffer_ptr + offset) * 2, color);

+}

+static void _mga_putpixel32 (unsigned int offset, int color)

+{

+ hwptr_pokel(mgaptr.linear_map, (mga_writebuffer_ptr + offset) * 4, color);

+}

+

+

+

+/* Desc: pixel retrieval

+ *

+ * In  : pixel offset

+ * Out : pixel value

+ *

+ * Note: uses current read buffer

+ */

+static __inline int _mga_getpixel8 (unsigned int offset)

+{

+ return hwptr_peekb(mgaptr.linear_map, mga_readbuffer_ptr + offset);

+}

+#define _mga_getpixel15 _mga_getpixel16

+static __inline int _mga_getpixel16 (unsigned int offset)

+{

+ return hwptr_peekw(mgaptr.linear_map, (mga_readbuffer_ptr + offset) * 2);

+}

+static __inline int _mga_getpixel32 (unsigned int offset)

+{

+ return hwptr_peekl(mgaptr.linear_map, (mga_readbuffer_ptr + offset) * 4);

+}

+

+

+

+/* Desc: color decomposition

+ *

+ * In  : pixel offset, array of integers to hold color components (R, G, B, A)

+ * Out : -

+ *

+ * Note: uses current read buffer

+ */

+static void _mga_getrgba8 (unsigned int offset, unsigned char rgba[4])

+{

+ int c = _mga_getpixel8(offset);

+ rgba[0] = _rgb_scale_3[(c >> 5) & 0x7];

+ rgba[1] = _rgb_scale_3[(c >> 2) & 0x7];

+ rgba[2] = _rgb_scale_2[c & 0x3];

+ rgba[3] = 255;

+}

+static void _mga_getrgba15 (unsigned int offset, unsigned char rgba[4])

+{

+ int c = _mga_getpixel15(offset);

+ rgba[0] = _rgb_scale_5[(c >> 10) & 0x1F];

+ rgba[1] = _rgb_scale_5[(c >> 5) & 0x1F];

+ rgba[2] = _rgb_scale_5[c & 0x1F];

+ rgba[3] = 255;

+}

+static void _mga_getrgba16 (unsigned int offset, unsigned char rgba[4])

+{

+ int c = _mga_getpixel16(offset);

+ rgba[0] = _rgb_scale_5[(c >> 11) & 0x1F];

+ rgba[1] = _rgb_scale_6[(c >> 5) & 0x3F];

+ rgba[2] = _rgb_scale_5[c & 0x1F];

+ rgba[3] = 255;

+}

+static void _mga_getrgba32 (unsigned int offset, unsigned char rgba[4])

+{

+ int c = _mga_getpixel32(offset);

+ rgba[0] = c >> 16;

+ rgba[1] = c >> 8;

+ rgba[2] = c; 

+ rgba[3] = c >> 24;

+}

+

+

+

+/* Desc: RGB flat line

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+void mga_draw_line_rgb_flat (const MGAvertex *v1, const MGAvertex *v2)

+{

+ unsigned long color;

+ int x1 = v1->win[0];

+ int y1 = v1->win[1];

+ int x2 = v2->win[0];

+ int y2 = v2->win[1];

+

+ if ((x1 == x2) && (y1 == y2)) {

+    return;

+ }

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_DRAWLINE) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_DRAWLINE);

+    __operation = OP_DRAWLINE;

+ }

+

+ color = mga_mixrgb_full(v2->color);

+

+ /* draw the line */

+ mga_fifo(3);

+ mga_outl(M_FCOL, color);

+ mga_outl(M_XYSTRT, (y1<<16) | x1);

+ mga_outl(M_XYEND | M_EXEC, (y2<<16) | x2);

+}

+

+

+

+/* Desc: RGB flat Z-less line

+ *

+ * In  :

+ * Out :

+ *

+ * Note: I never figured out "diagonal increments"

+ */

+void mga_draw_line_rgb_flat_zless (const MGAvertex *v1, const MGAvertex *v2)

+{

+ int z1, dz;

+ int x1 = v1->win[0];

+ int y1 = v1->win[1];

+ int x2 = v2->win[0];

+ int y2 = v2->win[1];

+ int dx = abs(x2 - x1);

+ int dy = abs(y2 - y1);

+

+ if ((dx == 0) && (dy == 0)) {

+    return;

+ }

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_DRAWLINE_ZI) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_DRAWLINE_ZI);

+    __operation = OP_DRAWLINE_ZI;

+ }

+

+ if (dx < dy) {

+    dx = dy;

+ }

+

+ z1 = v1->win[2] << 15;

+ dz = ((v2->win[2] << 15) - z1) / dx;

+

+ /* draw the line */

+ mga_fifo(14);

+ mga_outl(M_DR0, z1);

+ mga_outl(M_DR2, dz);

+ mga_outl(M_DR3, dz);

+ mga_outl(M_DR4, v2->color[0] << 15);

+ mga_outl(M_DR6, 0);

+ mga_outl(M_DR7, 0);

+ mga_outl(M_DR8, v2->color[1] << 15);

+ mga_outl(M_DR10, 0);

+ mga_outl(M_DR11, 0);

+ mga_outl(M_DR12, v2->color[2] << 15);

+ mga_outl(M_DR14, 0);

+ mga_outl(M_DR15, 0);

+ mga_outl(M_XYSTRT, (y1<<16) | x1);

+ mga_outl(M_XYEND | M_EXEC, (y2<<16) | x2);

+}

+

+

+

+/* Desc: RGB iterated line

+ *

+ * In  :

+ * Out :

+ *

+ * Note: I never figured out "diagonal increments"

+ */

+void mga_draw_line_rgb_iter (const MGAvertex *v1, const MGAvertex *v2)

+{

+ int r1, g1, b1;

+ int dr, dg, db;

+ int x1 = v1->win[0];

+ int y1 = v1->win[1];

+ int x2 = v2->win[0];

+ int y2 = v2->win[1];

+ int dx = abs(x2 - x1);

+ int dy = abs(y2 - y1);

+

+ if ((dx == 0) && (dy == 0)) {

+    return;

+ }

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_DRAWLINE_I) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_DRAWLINE_I);

+    __operation = OP_DRAWLINE_I;

+ }

+

+ if (dx < dy) {

+    dx = dy;

+ }

+

+ r1 = v1->color[0] << 15;

+ g1 = v1->color[1] << 15;

+ b1 = v1->color[2] << 15;

+ dr = ((v2->color[0] << 15) - r1) / dx;

+ dg = ((v2->color[1] << 15) - g1) / dx;

+ db = ((v2->color[2] << 15) - b1) / dx;

+

+ /* draw the line */

+ mga_fifo(11);

+ mga_outl(M_DR4, r1);

+ mga_outl(M_DR6, dr);

+ mga_outl(M_DR7, dr);

+ mga_outl(M_DR8, g1);

+ mga_outl(M_DR10, dg);

+ mga_outl(M_DR11, dg);

+ mga_outl(M_DR12, b1);

+ mga_outl(M_DR14, db);

+ mga_outl(M_DR15, db);

+ mga_outl(M_XYSTRT, (y1<<16) | x1);

+ mga_outl(M_XYEND | M_EXEC, (y2<<16) | x2);

+}

+

+

+

+/* Desc: RGB iterated Z-less line

+ *

+ * In  :

+ * Out :

+ *

+ * Note: I never figured out "diagonal increments"

+ */

+void mga_draw_line_rgb_iter_zless (const MGAvertex *v1, const MGAvertex *v2)

+{

+ int z1, dz;

+ int r1, g1, b1;

+ int dr, dg, db;

+ int x1 = v1->win[0];

+ int y1 = v1->win[1];

+ int x2 = v2->win[0];

+ int y2 = v2->win[1];

+ int dx = abs(x2 - x1);

+ int dy = abs(y2 - y1);

+

+ if ((dx == 0) && (dy == 0)) {

+    return;

+ }

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_DRAWLINE_ZI) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_DRAWLINE_ZI);

+    __operation = OP_DRAWLINE_ZI;

+ }

+

+ if (dx < dy) {

+    dx = dy;

+ }

+

+ z1 = v1->win[2] << 15;

+ dz = ((v2->win[2] << 15) - z1) / dx;

+

+ r1 = v1->color[0] << 15;

+ g1 = v1->color[1] << 15;

+ b1 = v1->color[2] << 15;

+ dr = ((v2->color[0] << 15) - r1) / dx;

+ dg = ((v2->color[1] << 15) - g1) / dx;

+ db = ((v2->color[2] << 15) - b1) / dx;

+

+ /* draw the line */

+ mga_fifo(14);

+ mga_outl(M_DR0, z1);

+ mga_outl(M_DR2, dz);

+ mga_outl(M_DR3, dz);

+ mga_outl(M_DR4, r1);

+ mga_outl(M_DR6, dr);

+ mga_outl(M_DR7, dr);

+ mga_outl(M_DR8, g1);

+ mga_outl(M_DR10, dg);

+ mga_outl(M_DR11, dg);

+ mga_outl(M_DR12, b1);

+ mga_outl(M_DR14, db);

+ mga_outl(M_DR15, db);

+ mga_outl(M_XYSTRT, (y1<<16) | x1);

+ mga_outl(M_XYEND | M_EXEC, (y2<<16) | x2);

+}

+

+

+

+/* Desc: RGB flat triangle

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+#define TAG mga_draw_tri_rgb_flat

+#define CULL

+#define SETUP_CODE                   \

+ if (__operation != OP_DRAWTRAP) {   \

+    mga_fifo(1);                     \

+    mga_outl(M_DWGCTL, OP_DRAWTRAP); \

+    __operation = OP_DRAWTRAP;       \

+ }

+#include "m_ttemp.h"

+

+

+

+/* Desc: RGB flat Z-less triangle

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+#define TAG mga_draw_tri_rgb_flat_zless

+#define CULL

+#define INTERP_Z

+#define SETUP_CODE                      \

+ if (__operation != OP_DRAWTRAP_ZI) {   \

+    mga_fifo(1);                        \

+    mga_outl(M_DWGCTL, OP_DRAWTRAP_ZI); \

+    __operation = OP_DRAWTRAP_ZI;       \

+ }

+#include "m_ttemp.h"

+

+

+

+/* Desc: RGB iterated triangle

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+#define TAG mga_draw_tri_rgb_iter

+#define CULL

+#define INTERP_RGB

+#define SETUP_CODE                     \

+ if (__operation != OP_DRAWTRAP_I) {   \

+    mga_fifo(1);                       \

+    mga_outl(M_DWGCTL, OP_DRAWTRAP_I); \

+    __operation = OP_DRAWTRAP_I;       \

+ }

+#include "m_ttemp.h"

+

+

+

+/* Desc: RGB iterated Z-less triangle

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+#define TAG mga_draw_tri_rgb_iter_zless

+#define CULL

+#define INTERP_Z

+#define INTERP_RGB

+#define SETUP_CODE                      \

+ if (__operation != OP_DRAWTRAP_ZI) {   \

+    mga_fifo(1);                        \

+    mga_outl(M_DWGCTL, OP_DRAWTRAP_ZI); \

+    __operation = OP_DRAWTRAP_ZI;       \

+ }

+#include "m_ttemp.h"

+

+

+

+/* Desc: RGB flat rectangle

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+void mga_draw_rect_rgb_flat (int left, int top, int width, int height, int color)

+{

+ if (__bpp == 8) {

+    color |= color << 8;

+ }

+ if (__bpp <= 16) {

+    color |= color << 16;

+ }

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_DRAWRECT) {

+

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_DRAWRECT);

+    __operation = OP_DRAWRECT;

+ }

+

+ /* draw the rectangle */

+ mga_fifo(3);

+ mga_outl(M_FCOL, color);

+ mga_outl(M_FXBNDRY, ((left+width)<<16) | left);

+ mga_outl(M_YDSTLEN | M_EXEC, (top<<16) | height);

+}

+

+

+

+/* Desc: 32RGB textured span

+ *

+ * In  :

+ * Out :

+ *

+ * Note: 0 <= width <= 7*1024

+ */

+void mga_draw_span_rgb_tx32 (int left, int top, int width, const unsigned long *bitmap)

+{

+ int i;

+

+ if (!width) {

+    return;

+ }

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_DRAWRECT_TX32BGR) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_DRAWRECT_TX32BGR);

+    __operation = OP_DRAWRECT_TX32BGR;

+ }

+

+ /* draw the rectangle */

+ mga_fifo(2);

+ mga_outl(M_FXBNDRY, ((left+width)<<16) | left);

+ mga_outl(M_YDSTLEN | M_EXEC, (top<<16) | 1);

+

+ /* copy data to the pseudo-dma window */

+ i = 0;

+ do {

+     mga_outl(i, *bitmap);

+     bitmap++;

+     i += 4;

+ } while (--width);

+}

+

+

+

+/* Desc: 24RGB textured span

+ *

+ * In  :

+ * Out :

+ *

+ * Note: 0 <= width <= 7*1024

+ */

+void mga_draw_span_rgb_tx24 (int left, int top, int width, const unsigned long *bitmap)

+{

+ int i;

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_DRAWRECT_TX24BGR) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_DRAWRECT_TX24BGR);

+    __operation = OP_DRAWRECT_TX24BGR;

+ }

+

+ /* draw the rectangle */

+ mga_fifo(2);

+ mga_outl(M_FXBNDRY, ((left+width)<<16) | left);

+ mga_outl(M_YDSTLEN | M_EXEC, (top<<16) | 1);

+

+ /* copy data to the pseudo-dma window */

+ i = 0;

+ width = (width * 3 + 3) / 4;

+ while (width) {

+       mga_outl(i & (7 * 1024 - 1), *bitmap);

+       bitmap++;

+       i += 4;

+       width--;

+ }

+}

+

+

+

+/* Desc: 32RGB textured rectangle

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+void mga_draw_rect_rgb_tx32 (int left, int top, int width, int height, const unsigned long *bitmap)

+{

+ int i;

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_DRAWRECT_TX32BGR) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_DRAWRECT_TX32BGR);

+    __operation = OP_DRAWRECT_TX32BGR;

+ }

+

+ /* draw the rectangle */

+ mga_fifo(2);

+ mga_outl(M_FXBNDRY, ((left+width)<<16) | left);

+ mga_outl(M_YDSTLEN | M_EXEC, (top<<16) | height);

+

+ /* copy data to the pseudo-dma window */

+ i = 0;

+ width *= height;

+ while (width) {

+       mga_outl(i & (7 * 1024 - 1), *bitmap);

+       bitmap++;

+       i += 4;

+       width--;

+ }

+}

+

+

+

+/* Desc: 24RGB textured rectangle

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+void mga_draw_rect_rgb_tx24 (int left, int top, int width, int height, const unsigned long *bitmap)

+{

+ int i;

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_DRAWRECT_TX24BGR) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_DRAWRECT_TX24BGR);

+    __operation = OP_DRAWRECT_TX24BGR;

+ }

+

+ /* draw the rectangle */

+ mga_fifo(2);

+ mga_outl(M_FXBNDRY, ((left+width)<<16) | left);

+ mga_outl(M_YDSTLEN | M_EXEC, (top<<16) | height);

+

+ /* copy data to the pseudo-dma window */

+ i = 0;

+ width = (width * height * 3 + 3) / 4;

+ while (width) {

+       mga_outl(i & (7 * 1024 - 1), *bitmap);

+       bitmap++;

+       i += 4;

+       width--;

+ }

+}

+

+

+

+/* Desc: copy 32RGB image to screen

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+void mga_iload_32RGB (int left, int top, int width, int height, const unsigned long *bitmap)

+{

+ int i;

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_ILOAD_32BGR) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_ILOAD_32BGR);

+    __operation = OP_ILOAD_32BGR;

+ }

+

+ /* draw the bitmap */

+ mga_fifo(5);

+ mga_outl(M_AR0, width-1);

+ mga_outl(M_AR3, 0);

+ mga_outl(M_AR5, 0);

+ mga_outl(M_FXBNDRY, ((left+width-1)<<16) | left);

+ mga_outl(M_YDSTLEN | M_EXEC, (top<<16) | height);

+

+ /* copy data to the pseudo-dma window */

+ i = 0;

+ width *= height;

+ while (width) {

+       mga_outl(i & (7 * 1024 - 1), *bitmap);

+       bitmap++;

+       i += 4;

+       width--;

+ }

+}

+

+

+

+/* Desc: copy 24RGB image to screen

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+void mga_iload_24RGB (int left, int top, int width, int height, const unsigned long *bitmap)

+{

+ int i;

+

+ mga_select();

+

+ /* set engine state */

+ if (__operation != OP_ILOAD_24BGR) {

+    mga_fifo(1);

+    mga_outl(M_DWGCTL, OP_ILOAD_24BGR);

+    __operation = OP_ILOAD_24BGR;

+ }

+

+ /* draw the bitmap */

+ mga_fifo(5);

+ mga_outl(M_AR0, width-1);

+ mga_outl(M_AR3, 0);

+ mga_outl(M_AR5, 0);

+ mga_outl(M_FXBNDRY, ((left+width-1)<<16) | left);

+ mga_outl(M_YDSTLEN | M_EXEC, (top<<16) | height);

+

+ /* copy data to the pseudo-dma window */

+ i = 0;

+ width = (width * height * 3 + 3) / 4;

+ while (width) {

+       mga_outl(i & (7 * 1024 - 1), *bitmap);

+       bitmap++;

+       i += 4;

+       width--;

+ }

+}

+

+

+

+/* Desc: get Z-buffer value

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+unsigned short mga_getz (int offset)

+{

+ return hwptr_peekw(mgaptr.linear_map, zorg + (mga_readbuffer_ptr + offset) * 2);

+}

+

+

+

+/* Desc: put Z-buffer value

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+void mga_setz (int offset, unsigned short z)

+{

+ hwptr_pokew(mgaptr.linear_map, zorg + (mga_writebuffer_ptr + offset) * 2, z);

+}

+

+

+

+/* Desc: clear Z-buffer

+ *

+ * In  :

+ * Out :

+ *

+ * Note: uses current write buffer

+ */

+static void _mga_clear_zed (int left, int top, int width, int height, unsigned short z)

+{

+ if (__bpp == 16) {

+    /* GPU store (high bandwidth)

+     * Hack alert:

+     * can cause problems with concurrent FB accesses

+     */

+    mga_select();

+    mga_fifo(1);

+    mga_outl(M_YDSTORG, mga_writebuffer_ptr + zorg/2);

+    mga_draw_rect_rgb_flat(left, top, width, height, z);

+    mga_fifo(1);

+    mga_outl(M_YDSTORG, mga_writebuffer_ptr);

+ } else {

+    /* CPU store */

+    unsigned long i, zz = (z<<16) | z;

+    unsigned long ofs = zorg + (top * __pixwidth + left + mga_writebuffer_ptr) * 2;

+    hwptr_select(mgaptr.linear_map);

+    while (height--) {

+          i = width/2;

+          while (i--) {

+                hwptr_nspokel(mgaptr.linear_map, ofs, zz);

+                ofs += 4;

+          }

+          if (width & 1) {

+             hwptr_nspokew(mgaptr.linear_map, ofs, z);

+             ofs += 2;

+          }

+          ofs += (__pixwidth - width) * 2;

+    }

+ }

+}

+

+

+

+/* Desc: clear color- and Z-buffer

+ *

+ * In  : front  = clear front buffer

+ *       back   = clear back buffer

+ *       zed    = clear depth buffer

+ *       left   = leftmost pixel to be cleared

+ *       top    = starting line

+ *       width  = number of pixels

+ *       height = number of lines

+ *       color  = color to clear to

+ *       z      = z value (ignored if zed==0)

+ * Out :

+ *

+ * Note:

+ */

+void mga_clear (int front, int back, int zed, int left, int top, int width, int height, int color, unsigned short z)

+{

+ if (front) {

+    if (mga_writebuffer == MGA_FRONTBUFFER) {

+       mga_draw_rect_rgb_flat(left, top, width, height, color);

+       if (zed) {

+          _mga_clear_zed(left, top, width, height, z);

+       }

+       front = 0;

+    }

+ }

+ if (back) {

+    if (mga_writebuffer == MGA_BACKBUFFER) {

+       mga_draw_rect_rgb_flat(left, top, width, height, color);

+       if (zed) {

+          _mga_clear_zed(left, top, width, height, z);

+       }

+       back = 0;

+    }

+ }

+ if (front) {

+    int old = mga_writebuffer;

+    mga_set_writebuffer(MGA_FRONTBUFFER);

+    mga_draw_rect_rgb_flat(left, top, width, height, color);

+    if (zed) {

+       _mga_clear_zed(left, top, width, height, z);

+    }

+    mga_set_writebuffer(old);

+    front = 0;

+ }

+ if (back) {

+    int old = mga_writebuffer;

+    mga_set_writebuffer(MGA_BACKBUFFER);

+    mga_draw_rect_rgb_flat(left, top, width, height, color);

+    if (zed) {

+       _mga_clear_zed(left, top, width, height, z);

+    }

+    mga_set_writebuffer(old);

+    back = 0;

+ }

+}

+

+

+

+/* Desc: Attempts to enter specified video mode.

+ *

+ * In  : ptr to mode structure, number of pages, Z-buffer request, refresh rate

+ * Out : 0 if success

+ *

+ * Note: also set up the accelerator engine

+ */

+int mga_open (int width, int height, int bpp, int buffers, int zbuffer, int refresh)

+{

+ static int mill_strides[] = { 640, 768, 800, 960, 1024, 1152, 1280, 1600, 1920, 2048, 0 };

+ unsigned int i, used;

+ MGA_MODE *p;

+

+ if (mga_hw_init(&vram, &interleave, card_name) == 0) {

+    return -1;

+ }

+

+ if ((p = mga_mode_find(width, height, bpp)) == NULL) {

+    return -1;

+ }

+

+ __bpp = p->bpp;

+ __width = __pagewidth = p->xres;

+ __height = p->yres;

+

+ if (buffers > 1) {

+    __pagewidth = _mga_fix_scans(__pagewidth);

+    __pixwidth = __pagewidth * buffers;

+ } else {

+    __pixwidth = __pagewidth;

+    __pixwidth = _mga_fix_scans(__pixwidth);

+ }

+

+ for (i=0; mill_strides[i]; i++) {

+     if (__pixwidth <= mill_strides[i]) {

+        __pixwidth = mill_strides[i];

+        break;

+     }

+ }

+

+ __bypp = (__bpp+7)/8;

+ __bytwidth = __pixwidth * __bypp;

+

+ /* compute used memory: framebuffer + zbuffer */

+ used = __bytwidth * __height;

+ if (zbuffer) {

+    zorg = (used + 511) & ~511;

+    /* Hack alert:

+     * a 16-bit Z-buffer size is (stride_in_pixels * number_of_lines * 2)

+     * We cannot mess with the Z-buffer width, but we might decrease the

+     * number of lines, if the user requests less than (screen_height). For

+     * example with a 2MB card, one can have 640x480x16 display with 2 color

+     * buffers and Z-buffer if the maximum requested height is 339:

+     *    Total = (640*480 * 2 + 640*339 * 2) * 2

+     * However, this means the user must not write beyond the window's height

+     * and if we'll ever implement moveable windows, we'll have to reconsider

+     * this hack.

+     */

+#if 1

+    __zheight = height;  /* smaller */

+    used = zorg + __pixwidth * 2 * __zheight;

+#else

+    __zheight = __height;

+    used = zorg + __pixwidth * 2 * __zheight;

+#endif

+ }

+

+ if (mill_strides[i] && (vram>=used)) {

+    /* enter mode */

+    mga_mode_switch(p, refresh);

+    /* change the scan line length */

+    _mga_ralter(M_CRTC_INDEX, 0x14, 0x40, 0);           /* disable DWORD */

+    _mga_ralter(M_CRTC_INDEX, 0x17, 0x40, 0x40);        /* wbmode = BYTE */

+    if (interleave) {

+       _mga_rwrite(M_CRTC_INDEX, 0x13, __bytwidth/16);

+       _mga_ralter(M_CRTC_EXT_INDEX, 0, 0x30, ((__bytwidth/16)>>4)&0x30);

+    } else {

+       _mga_rwrite(M_CRTC_INDEX, 0x13, __bytwidth/8);

+       _mga_ralter(M_CRTC_EXT_INDEX, 0, 0x30, ((__bytwidth/8)>>4)&0x30);

+    }

+ } else {

+    return -1;

+ }

+

+ /* setup buffers */

+ mga_frontbuffer_ptr = 0;

+ if (buffers > 1) {

+    mga_backbuffer_ptr = __pagewidth;

+    mga_set_readbuffer(MGA_BACKBUFFER);

+    mga_set_writebuffer(MGA_BACKBUFFER);

+ } else {

+    mga_backbuffer_ptr = 0;

+    mga_set_readbuffer(MGA_FRONTBUFFER);

+    mga_set_writebuffer(MGA_FRONTBUFFER);

+ }

+ mga_display_start(mga_frontbuffer_ptr, __scrollx = 0, __scrolly = 0, 1);

+

+ /* set up the accelerator engine */

+ mga_select();

+

+ mga_fifo(8);

+ mga_outl(M_PITCH, __pixwidth);

+ mga_outl(M_PLNWT, 0xFFFFFFFF);

+ mga_outl(M_OPMODE, M_DMA_BLIT);

+ mga_outl(M_CXBNDRY, 0xFFFF0000);

+ mga_outl(M_YTOP, 0x00000000);

+ mga_outl(M_YBOT, 0x007FFFFF);

+ mga_outl(M_ZORG, zorg);

+

+#define INITPTR(bpp) \

+        mga_putpixel = _mga_putpixel##bpp; \

+        mga_getrgba = _mga_getrgba##bpp;   \

+        mga_getpixel = _mga_getpixel##bpp; \

+        mga_mixrgb = _mga_mixrgb##bpp;     \

+        mga_mixrgb_full = _mga_mixrgb##bpp##_full

+

+ switch (__bpp) {

+	case 8:

+	     mga_outl(M_MACCESS, 0);

+             INITPTR(8);

+	     break;

+	case 15:

+	     mga_outl(M_MACCESS, 0x80000001);

+             INITPTR(15);

+	     break;

+	case 16:

+	     mga_outl(M_MACCESS, 1);

+             INITPTR(16);

+	     break;

+	case 32:

+	     mga_outl(M_MACCESS, 2);

+             INITPTR(32);

+	     break;

+ }

+

+#undef INITPTR

+

+ /* disable VGA aperture */

+ i = mga_inb(M_MISC_R);

+ mga_outb(M_MISC_W, i & ~2);

+

+ /* clear Z-buffer (if any) */

+ if (zbuffer) {

+    unsigned long ofs = zorg;

+    unsigned long len = zorg + __pixwidth * 2 * __zheight;

+

+    hwptr_select(mgaptr.linear_map);

+    for (; ofs<len; ofs+=4) {

+        hwptr_nspokel(mgaptr.linear_map, ofs, -1);

+    }

+ }

+

+ return 0;

+}

+

+

+

+/* Desc:

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+void mga_close (int restore, int unmap)

+{

+ if (restore) {

+    mga_mode_restore();

+ }

+ if (unmap) {

+    mga_hw_fini();

+ }

+}

+

+

+

+/* Desc: state retrieval

+ *

+ * In  : parameter name, ptr to storage

+ * Out : 0 if request successfully processed

+ *

+ * Note: -

+ */

+int mga_get (int pname, int *params)

+{

+ switch (pname) {

+        case MGA_GET_CARD_NAME:

+             strcat(strcpy((char *)params, "Matrox "), card_name);

+             break;

+        case MGA_GET_VRAM:

+             params[0] = vram;

+             break;

+        case MGA_GET_CI_PREC:

+             params[0] = 0;

+             break;

+        case MGA_GET_HPIXELS:

+             params[0] = __pixwidth;

+             break;

+        case MGA_GET_SCREEN_SIZE:

+             params[0] = __width;

+             params[1] = __height;

+             break;

+        default:

+             return -1;

+ }

+ return 0;

+}

diff --git a/src/mesa/drivers/dos/mga/mga.h b/src/mesa/drivers/dos/mga/mga.h
new file mode 100644
index 0000000..fc5722b
--- /dev/null
+++ b/src/mesa/drivers/dos/mga/mga.h
@@ -0,0 +1,91 @@
+/*

+ * Mesa 3-D graphics library

+ * Version:  5.0

+ * 

+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.

+ * 

+ * Permission is hereby granted, free of charge, to any person obtaining a

+ * copy of this software and associated documentation files (the "Software"),

+ * to deal in the Software without restriction, including without limitation

+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the

+ * Software is furnished to do so, subject to the following conditions:

+ * 

+ * The above copyright notice and this permission notice shall be included

+ * in all copies or substantial portions of the Software.

+ * 

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL

+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN

+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ */

+

+/*

+ * DOS/DJGPP device driver v1.3 for Mesa 5.0  --  MGA2064W

+ *

+ *  Copyright (c) 2003 - Borca Daniel

+ *  Email : dborca@yahoo.com

+ *  Web   : http://www.geocities.com/dborca

+ */

+

+

+#ifndef MGA_H_included

+#define MGA_H_included

+

+#define MGA_GET_CARD_NAME   0x0100

+#define MGA_GET_VRAM        0x0101

+#define MGA_GET_CI_PREC     0x0200

+#define MGA_GET_HPIXELS     0x0201

+#define MGA_GET_SCREEN_SIZE 0x0202

+

+int mga_open (int width, int height, int bpp, int buffers, int zbuffer, int refresh);

+void mga_clear (int front, int back, int zed, int left, int top, int width, int height, int color, unsigned short z);

+int mga_get (int pname, int *params);

+void mga_close (int restore, int unmap);

+

+extern void (*mga_putpixel) (unsigned int offset, int color);

+extern int (*mga_getpixel) (unsigned int offset);

+extern void (*mga_getrgba) (unsigned int offset, unsigned char rgba[4]);

+extern int (*mga_mixrgb) (const unsigned char rgb[]);

+

+#define MGA_BACKBUFFER !0

+#define MGA_FRONTBUFFER 0

+void mga_set_readbuffer (int buffer);

+void mga_set_writebuffer (int buffer);

+void mga_swapbuffers (int swapinterval);

+

+unsigned short mga_getz (int offset);

+void mga_setz (int offset, unsigned short z);

+

+void mga_wait_idle (void);

+

+/*

+ * vertex structure, used for primitive rendering

+ */

+typedef struct {

+        int win[4];             /* X, Y, Z, ? */

+        unsigned char color[4]; /* R, G, B, A */

+} MGAvertex;

+

+void mga_draw_line_rgb_flat (const MGAvertex *v1, const MGAvertex *v2);

+void mga_draw_line_rgb_flat_zless (const MGAvertex *v1, const MGAvertex *v2);

+void mga_draw_line_rgb_iter (const MGAvertex *v1, const MGAvertex *v2);

+void mga_draw_line_rgb_iter_zless (const MGAvertex *v1, const MGAvertex *v2);

+

+void mga_draw_tri_rgb_flat (int cull, const MGAvertex *v1, const MGAvertex *v2, const MGAvertex *v3);

+void mga_draw_tri_rgb_flat_zless (int cull, const MGAvertex *v1, const MGAvertex *v2, const MGAvertex *v3);

+void mga_draw_tri_rgb_iter (int cull, const MGAvertex *v1, const MGAvertex *v2, const MGAvertex *v3);

+void mga_draw_tri_rgb_iter_zless (int cull, const MGAvertex *v1, const MGAvertex *v2, const MGAvertex *v3);

+

+void mga_draw_rect_rgb_flat (int left, int top, int width, int height, int color);

+void mga_draw_rect_rgb_tx32 (int left, int top, int width, int height, const unsigned long *bitmap);

+void mga_draw_rect_rgb_tx24 (int left, int top, int width, int height, const unsigned long *bitmap);

+void mga_draw_span_rgb_tx32 (int left, int top, int width, const unsigned long *bitmap);

+void mga_draw_span_rgb_tx24 (int left, int top, int width, const unsigned long *bitmap);

+

+void mga_iload_32RGB (int left, int top, int width, int height, const unsigned long *bitmap);

+void mga_iload_24RGB (int left, int top, int width, int height, const unsigned long *bitmap);

+

+#endif

diff --git a/src/mesa/drivers/dos/mga/mga_hw.c b/src/mesa/drivers/dos/mga/mga_hw.c
new file mode 100644
index 0000000..4354ce8
--- /dev/null
+++ b/src/mesa/drivers/dos/mga/mga_hw.c
@@ -0,0 +1,416 @@
+/*

+ * Mesa 3-D graphics library

+ * Version:  5.0

+ * 

+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.

+ * 

+ * Permission is hereby granted, free of charge, to any person obtaining a

+ * copy of this software and associated documentation files (the "Software"),

+ * to deal in the Software without restriction, including without limitation

+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the

+ * Software is furnished to do so, subject to the following conditions:

+ * 

+ * The above copyright notice and this permission notice shall be included

+ * in all copies or substantial portions of the Software.

+ * 

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL

+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN

+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ */

+

+/*

+ * DOS/DJGPP device driver v1.3 for Mesa 5.0  --  MGA2064W HW mapping

+ *

+ *  Copyright (c) 2003 - Borca Daniel

+ *  Email : dborca@yahoo.com

+ *  Web   : http://www.geocities.com/dborca

+ */

+

+

+#include <crt0.h>

+#include <dpmi.h>

+#include <pc.h>

+#include <string.h>

+#include <sys/nearptr.h>

+#include <sys/segments.h>

+

+#include "../internal.h"

+#include "mga_reg.h"

+#include "mga_hw.h"

+

+

+

+/* Hack alert:

+ * these should really be externs

+ */

+/* PCI access routines */

+static int pci_find_device (int deviceID, int vendorID, int deviceIndex, int *handle);

+static unsigned long pci_read_long (int handle, int index);

+static void pci_write_long (int handle, int index, unsigned long value);

+

+

+

+/* PCI device identifiers */

+#define MATROX_VENDOR_ID 0x102B

+

+typedef enum {

+        MATROX_MILL_ID = 0x0519

+} MATROX_ID;

+

+static MATROX_ID matrox_id_list[] = {

+       MATROX_MILL_ID,

+       0

+};

+

+

+

+/* internal hardware data structures */

+#if !MGA_FARPTR

+static int dirty;

+#endif

+static int bus_id;

+static unsigned long reg40;

+static unsigned long io_mem_base[4], linear_base;

+static unsigned long io_mem_size[4], linear_size;

+static MATROX_ID matrox_id;

+

+

+

+/* interface structures containing hardware pointer data */

+MGA_HWPTR mgaptr;

+

+

+

+/* Desc: create MMAP

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+static int _create_mmap (__dpmi_paddr *m, unsigned long base, unsigned long size)

+{

+#if MGA_FARPTR

+ int sel;

+ if (_create_selector(&sel, base, size)) {

+    return -1;

+ }

+ m->selector = sel;

+ m->offset32 = 0;

+#else

+ m->selector = _my_ds();

+ if (_create_linear_mapping(&m->offset32, base, size)) {

+    return -1;

+ }

+ m->offset32 -= __djgpp_base_address;

+#endif

+ return 0;

+}

+

+

+

+/* Desc: destroy MMAP

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+static void _destroy_mmap (__dpmi_paddr *m)

+{

+#if MGA_FARPTR

+ int sel = m->selector;

+ _remove_selector(&sel);

+#else

+ m->offset32 += __djgpp_base_address;

+ _remove_linear_mapping(&m->offset32);

+#endif

+ m->selector = 0;

+ m->offset32 = 0;

+}

+

+

+

+/* Desc: Counts amount of installed RAM

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+static int _mga_get_vram (MATROX_ID chip, unsigned long base)

+{

+ int ProbeSize = 8;

+ int SizeFound = 2;

+ unsigned char tmp;

+ int i;

+ __dpmi_paddr fb;

+

+ switch (chip) {

+	case MATROX_MILL_ID:

+	     ProbeSize = 8;

+	     break;

+ }

+

+ if (_create_mmap(&fb, base, ProbeSize*1024*1024)) {

+    return 0;

+ }

+

+ /* turn MGA mode on - enable linear frame buffer (CRTCEXT3) */

+ mga_select();

+ mga_outb(M_CRTC_EXT_INDEX, 3);

+ tmp = mga_inb(M_CRTC_EXT_DATA);

+ mga_outb(M_CRTC_EXT_DATA, tmp | M_MGAMODE);

+

+ /* write, read and compare method */

+ for (i=ProbeSize; i>2; i-= 2) {

+     hwptr_pokeb(fb, i*1024*1024 - 1, 0xAA);

+     mga_select();

+     mga_outb(M_CRTC_INDEX, 0); /* flush the cache */

+     mga_inl(M_STATUS); /* delay */

+     mga_inl(M_STATUS); /* delay */

+     mga_inl(M_STATUS); /* delay */

+     if (hwptr_peekb(fb, i*1024*1024 - 1) == 0xAA) {

+	SizeFound = i;

+	break;

+     }

+ }

+

+ /* restore CRTCEXT3 state */

+ mga_select();

+ mga_outb(M_CRTC_EXT_INDEX, 3);

+ mga_outb(M_CRTC_EXT_DATA, tmp);

+

+ _destroy_mmap(&fb);

+

+ return SizeFound*1024*1024;

+}

+

+

+

+/* Desc: Frees all resources allocated by MGA init code.

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+void mga_hw_fini (void)

+{

+ int i;

+

+ pci_write_long(bus_id, 0x40, reg40);

+

+ for (i=0; i<4; i++) {

+     _destroy_mmap(&mgaptr.io_mem_map[i]);

+ }

+

+ _destroy_mmap(&mgaptr.linear_map);

+

+#if !MGA_FARPTR

+ if (dirty) {

+    __djgpp_nearptr_disable();

+    dirty = FALSE;

+ }

+#endif

+

+ matrox_id = 0;

+}

+

+

+

+/* Desc: Attempts to detect MGA.

+ *

+ * In  :

+ * Out :

+ *

+ * Note: The first thing ever to be called. This is in charge of filling in

+ *       the driver header with all the required information and function

+ *       pointers. We do not yet have access to the video memory, so we can't

+ *       talk directly to the card.

+ */

+int mga_hw_init (unsigned long *vram, int *interleave, char *name)

+{

+ int i;

+ unsigned long pci_base[2];

+

+ if (matrox_id) {

+    return matrox_id;

+ }

+

+#if !MGA_FARPTR

+ /* enable nearptr access */

+ if (_crt0_startup_flags & _CRT0_FLAG_NEARPTR) {

+    dirty = FALSE;

+ } else {

+    if (__djgpp_nearptr_enable() == 0)

+       return NULL;

+

+    dirty = TRUE;

+ }

+#endif

+

+ /* find PCI device */

+ matrox_id = 0;

+

+ for (bus_id=0, i=0; matrox_id_list[i]; i++) {

+     if (pci_find_device(matrox_id_list[i], MATROX_VENDOR_ID, 0, &bus_id)) {

+	matrox_id = matrox_id_list[i];

+	break;

+     }

+ }

+

+ /* set up the card name */

+ switch (matrox_id) {

+	case MATROX_MILL_ID:

+	     if (name) strcpy(name, "Millennium");

+	     break;

+        default:

+             matrox_id = 0;

+             return -1;

+ }

+

+ reg40 = pci_read_long(bus_id, 0x40);

+#if 0 /* overclock a little :) */

+ {

+  int rfhcnt = (reg40 >> 16) & 0xF;

+  if ((reg40 & 0x200000) && (rfhcnt < 0xC)) {

+     pci_write_long(bus_id, 0x40, (reg40 & 0xFFF0FFFF) | 0x000C0000);

+  }

+ }

+#endif

+

+ /* read hardware configuration data */

+ for (i=0; i<2; i++)

+     pci_base[i] = pci_read_long(bus_id, 16+i*4);

+

+ /* work out the linear framebuffer and MMIO addresses */

+ if (matrox_id == MATROX_MILL_ID) {

+    if (pci_base[0])

+       io_mem_base[0] = pci_base[0] & 0xFFFFC000;

+

+    if (pci_base[1])

+       linear_base = pci_base[1] & 0xFF800000;

+ }

+

+ if (!linear_base || !io_mem_base[0])

+    return NULL;

+

+ /* deal with the memory mapping crap */

+ io_mem_size[0] = 0x4000;

+

+ for (i=0; i<4; i++) {

+     if (io_mem_base[i]) {

+        if (_create_mmap(&mgaptr.io_mem_map[i], io_mem_base[i], io_mem_size[i])) {

+	   mga_hw_fini();

+	   return NULL;

+	}

+     }

+ }

+

+ *vram = linear_size = _mga_get_vram(matrox_id, linear_base);

+

+ if (_create_mmap(&mgaptr.linear_map, linear_base, linear_size)) {

+    mga_hw_fini();

+    return NULL;

+ }

+

+ /* fill in user data */

+ *interleave = linear_size > 2*1024*1024;

+

+ return matrox_id;

+}

+

+

+

+/* PCI routines added by SET */

+#define PCIAddr   0xCF8

+#define PCIData   0xCFC

+#define PCIEnable 0x80000000

+

+

+

+/* FindPCIDevice:

+ *  Replacement for the INT 1A - PCI BIOS v2.0c+ - FIND PCI DEVICE, AX = B102h

+ *

+ *  Note: deviceIndex is because a card can hold more than one PCI chip.

+ * 

+ *  Searches the board of the vendor supplied in vendorID with 

+ *  identification number deviceID and index deviceIndex (normally 0). 

+ *  The value returned in handle can be used to access the PCI registers 

+ *  of this board.

+ *

+ *  Return: 1 if found 0 if not found.

+ */

+static int pci_find_device (int deviceID, int vendorID, int deviceIndex, int *handle)

+{

+ int model, vendor, card, device;

+ unsigned value, full_id, bus, busMax;

+

+ deviceIndex <<= 8;

+

+ /* for each PCI bus */

+ for (bus=0, busMax=0x10000; bus<busMax; bus+=0x10000) {

+

+     /* for each hardware device */

+     for (device=0, card=0; card<32; card++, device+=0x800) {

+	 value = PCIEnable | bus | deviceIndex | device;

+	 outportl(PCIAddr, value);

+	 full_id = inportl(PCIData);

+

+	 /* get the vendor and model ID */

+	 vendor = full_id & 0xFFFF;

+	 model = full_id >> 16;

+

+	 if (vendor != 0xFFFF) {

+	    /* is this the one we want? */

+	    if ((deviceID == model) && (vendorID == vendor)) {

+	       *handle = value;

+	       return 1;

+	    }

+

+	    /* is it a bridge to a secondary bus? */

+	    outportl(PCIAddr, value | 8);

+

+	    if (((inportl(PCIData) >> 16) == 0x0600) || (full_id==0x00011011))

+	       busMax += 0x10000;

+         }

+     }

+ }

+

+ return 0;

+}

+

+

+

+/* Desc:

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+static unsigned long pci_read_long (int handle, int index)

+{

+ outportl(PCIAddr, PCIEnable | handle | index);

+ return inportl(PCIData);

+}

+

+

+

+/* Desc:

+ *

+ * In  :

+ * Out :

+ *

+ * Note:

+ */

+static void pci_write_long (int handle, int index, unsigned long value)

+{

+ outportl(PCIAddr, PCIEnable | handle | index);

+ outportl(PCIData, value);

+}

diff --git a/src/mesa/drivers/dos/mga/mga_hw.h b/src/mesa/drivers/dos/mga/mga_hw.h
new file mode 100644
index 0000000..246ed9c
--- /dev/null
+++ b/src/mesa/drivers/dos/mga/mga_hw.h
@@ -0,0 +1,113 @@
+/*

+ * Mesa 3-D graphics library

+ * Version:  5.0

+ * 

+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.

+ * 

+ * Permission is hereby granted, free of charge, to any person obtaining a

+ * copy of this software and associated documentation files (the "Software"),

+ * to deal in the Software without restriction, including without limitation

+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the

+ * Software is furnished to do so, subject to the following conditions:

+ * 

+ * The above copyright notice and this permission notice shall be included

+ * in all copies or substantial portions of the Software.

+ * 

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL

+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN

+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ */

+

+/*

+ * DOS/DJGPP device driver v1.3 for Mesa 5.0  --  MGA2064W HW mapping

+ *

+ *  Copyright (c) 2003 - Borca Daniel

+ *  Email : dborca@yahoo.com

+ *  Web   : http://www.geocities.com/dborca

+ */

+

+

+#ifndef MGA_HW_included

+#define MGA_HW_included

+

+

+

+/* set this to zero to use near pointers */

+#define MGA_FARPTR 1

+

+

+

+/* access macros */

+#if MGA_FARPTR

+

+#include <sys/farptr.h>

+

+#define hwptr_pokeb(ptr, off, val)     _farpokeb((ptr).selector, (ptr).offset32+(off), (val))

+#define hwptr_pokew(ptr, off, val)     _farpokew((ptr).selector, (ptr).offset32+(off), (val))

+#define hwptr_pokel(ptr, off, val)     _farpokel((ptr).selector, (ptr).offset32+(off), (val))

+

+#define hwptr_peekb(ptr, off)          _farpeekb((ptr).selector, (ptr).offset32+(off))

+#define hwptr_peekw(ptr, off)          _farpeekw((ptr).selector, (ptr).offset32+(off))

+#define hwptr_peekl(ptr, off)          _farpeekl((ptr).selector, (ptr).offset32+(off))

+

+#define hwptr_select(ptr)              _farsetsel((ptr).selector)

+#define hwptr_unselect(ptr)            (ptr).selector = _fargetsel()

+

+#define hwptr_nspokeb(ptr, off, val)   _farnspokeb((ptr).offset32+(off), (val))

+#define hwptr_nspokew(ptr, off, val)   _farnspokew((ptr).offset32+(off), (val))

+#define hwptr_nspokel(ptr, off, val)   _farnspokel((ptr).offset32+(off), (val))

+

+#define hwptr_nspeekb(ptr, off)        _farnspeekb((ptr).offset32+(off))

+#define hwptr_nspeekw(ptr, off)        _farnspeekw((ptr).offset32+(off))

+#define hwptr_nspeekl(ptr, off)        _farnspeekl((ptr).offset32+(off))

+

+#else

+

+#define hwptr_pokeb(ptr, off, val)     *((volatile unsigned char *)((ptr).offset32+(off))) = (val)

+#define hwptr_pokew(ptr, off, val)     *((volatile unsigned short *)((ptr).offset32+(off))) = (val)

+#define hwptr_pokel(ptr, off, val)     *((volatile unsigned long *)((ptr).offset32+(off))) = (val)

+

+#define hwptr_peekb(ptr, off)          (*((volatile unsigned char *)((ptr).offset32+(off))))

+#define hwptr_peekw(ptr, off)          (*((volatile unsigned short *)((ptr).offset32+(off))))

+#define hwptr_peekl(ptr, off)          (*((volatile unsigned long *)((ptr).offset32+(off))))

+

+#define hwptr_select(ptr)

+#define hwptr_unselect(ptr)

+

+#define hwptr_nspokeb(ptr, off, val)   *((volatile unsigned char *)((ptr).offset32+(off))) = (val)

+#define hwptr_nspokew(ptr, off, val)   *((volatile unsigned short *)((ptr).offset32+(off))) = (val)

+#define hwptr_nspokel(ptr, off, val)   *((volatile unsigned long *)((ptr).offset32+(off))) = (val)

+

+#define hwptr_nspeekb(ptr, off)        (*((volatile unsigned char *)((ptr).offset32+(off))))

+#define hwptr_nspeekw(ptr, off)        (*((volatile unsigned short *)((ptr).offset32+(off))))

+#define hwptr_nspeekl(ptr, off)        (*((volatile unsigned long *)((ptr).offset32+(off))))

+

+#endif

+

+

+

+/* helpers for accessing the Matrox registers */

+#define mga_select()          hwptr_select(mgaptr.io_mem_map[0])

+#define mga_inb(addr)         hwptr_nspeekb(mgaptr.io_mem_map[0], addr)

+#define mga_inw(addr)         hwptr_nspeekw(mgaptr.io_mem_map[0], addr)

+#define mga_inl(addr)         hwptr_nspeekl(mgaptr.io_mem_map[0], addr)

+#define mga_outb(addr, val)   hwptr_nspokeb(mgaptr.io_mem_map[0], addr, val)

+#define mga_outw(addr, val)   hwptr_nspokew(mgaptr.io_mem_map[0], addr, val)

+#define mga_outl(addr, val)   hwptr_nspokel(mgaptr.io_mem_map[0], addr, val)

+

+

+

+typedef struct MGA_HWPTR {

+        __dpmi_paddr io_mem_map[4], linear_map;

+} MGA_HWPTR;

+

+extern MGA_HWPTR mgaptr;

+

+void mga_hw_fini (void);

+int mga_hw_init (unsigned long *vram, int *interleave, char *name);

+

+#endif

diff --git a/src/mesa/drivers/dos/mga/mga_mode.c b/src/mesa/drivers/dos/mga/mga_mode.c
new file mode 100644
index 0000000..33f47a6
--- /dev/null
+++ b/src/mesa/drivers/dos/mga/mga_mode.c
@@ -0,0 +1,231 @@
+/*

+ * Mesa 3-D graphics library

+ * Version:  5.0

+ * 

+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.

+ * 

+ * Permission is hereby granted, free of charge, to any person obtaining a

+ * copy of this software and associated documentation files (the "Software"),

+ * to deal in the Software without restriction, including without limitation

+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the

+ * Software is furnished to do so, subject to the following conditions:

+ * 

+ * The above copyright notice and this permission notice shall be included

+ * in all copies or substantial portions of the Software.

+ * 

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL

+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN

+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ */

+

+/*

+ * DOS/DJGPP device driver v1.3 for Mesa 5.0  --  MGA2064W mode switching

+ *

+ *  Copyright (c) 2003 - Borca Daniel

+ *  Email : dborca@yahoo.com

+ *  Web   : http://www.geocities.com/dborca

+ */

+

+

+#include <dpmi.h>

+#include <string.h>

+#include <stubinfo.h>

+#include <sys/exceptn.h>

+#include <sys/farptr.h>

+#include <sys/movedata.h>

+#include <sys/segments.h>

+

+#include "../internal.h"

+#include "mga_mode.h"

+

+

+

+static MGA_MODE oldmode;

+static MGA_MODE modes[64];

+

+

+

+/*

+ * VESA info

+ */

+#define V_SIGN     0

+#define V_MINOR    4

+#define V_MAJOR    5

+#define V_OEM_OFS  6

+#define V_OEM_SEG  8

+#define V_MODE_OFS 14

+#define V_MODE_SEG 16

+#define V_MEMORY   18

+

+/*

+ * mode info

+ */

+#define M_ATTR     0

+#define M_GRAN     4

+#define M_SCANLEN  16

+#define M_XRES     18

+#define M_YRES     20

+#define M_BPP      25

+#define M_RED      31

+#define M_GREEN    33

+#define M_BLUE     35

+#define M_PHYS_PTR 40

+

+

+

+/* Desc: get available modes

+ *

+ * In  : -

+ * Out : linear modes list ptr

+ *

+ * Note: shouldn't use VESA...

+ */

+static MGA_MODE *_mga_mode_check (void)

+{

+ __dpmi_regs r;

+ word16 *p;

+ MGA_MODE *q;

+ char vesa_info[512], tmp[512];

+

+ _farpokel(_stubinfo->ds_selector, 0, 0x32454256);

+ r.x.ax = 0x4f00;

+ r.x.di = 0;

+ r.x.es = _stubinfo->ds_segment;

+ __dpmi_int(0x10, &r);

+ movedata(_stubinfo->ds_selector, 0, _my_ds(), (unsigned)vesa_info, 512);

+ if ((r.x.ax!=0x004f) || ((_32_ vesa_info[V_SIGN])!=0x41534556)) {

+    return NULL;

+ }

+

+ p = (word16 *)(((_16_ vesa_info[V_MODE_SEG])<<4) + (_16_ vesa_info[V_MODE_OFS]));

+ q = modes;

+ do {

+     if ((q->mode=_farpeekw(__djgpp_dos_sel, (unsigned long)(p++)))==0xffff) {

+        break;

+     }

+

+     r.x.ax = 0x4f01;

+     r.x.cx = q->mode;

+     r.x.di = 512;

+     r.x.es = _stubinfo->ds_segment;

+     __dpmi_int(0x10, &r);

+     movedata(_stubinfo->ds_selector, 512, _my_ds(), (unsigned)tmp, 256);

+     switch (tmp[M_BPP]) {

+            case 16:

+                 q->bpp = tmp[M_RED] + tmp[M_GREEN] + tmp[M_BLUE];

+                 break;

+            case 8:

+            case 15:

+            case 24:

+            case 32:

+                 q->bpp = tmp[M_BPP];

+                 break;

+            default:

+                 q->bpp = 0;

+     }

+     if ((r.x.ax==0x004f) && ((tmp[M_ATTR]&0x11)==0x11) && q->bpp && (tmp[M_ATTR]&0x80)) {

+        q->xres = _16_ tmp[M_XRES];

+        q->yres = _16_ tmp[M_YRES];

+        q->mode |= 0x4000;

+        q++;

+     }

+ } while (TRUE);

+

+ return modes;

+}

+

+

+

+/* Desc: save current mode

+ *

+ * In  : ptr to mode structure

+ * Out : 0 if success

+ *

+ * Note: shouldn't use VESA...

+ */

+static int _mga_mode_save (MGA_MODE *p)

+{

+ __asm("\n\

+		movw	$0x4f03, %%ax	\n\

+		int	$0x10		\n\

+		movl	%%ebx, %0	\n\

+ ":"=g"(p->mode)::"%eax", "%ebx");

+ return 0;

+}

+

+

+

+/* Desc: switch to specified mode

+ *

+ * In  : ptr to mode structure, refresh rate

+ * Out : 0 if success

+ *

+ * Note: shouldn't use VESA...

+ */

+int mga_mode_switch (MGA_MODE *p, int refresh)

+{

+ if (oldmode.mode == 0) {

+    _mga_mode_save(&oldmode);

+ }

+ __asm("movw $0x4f02, %%ax; int  $0x10"::"b"(p->mode):"%eax");

+ return 0;

+

+ (void)refresh; /* silence compiler warning */

+}

+

+

+

+/* Desc: restore to the mode prior to first call to `mga_switch'

+ *

+ * In  : -

+ * Out : 0 if success

+ *

+ * Note: shouldn't use VESA...

+ */

+int mga_mode_restore (void)

+{

+ if (oldmode.mode != 0) {

+    __asm("movw $0x4f02, %%ax; int  $0x10"::"b"(oldmode.mode):"%eax");

+    oldmode.mode = 0;

+ }

+ return 0;

+}

+

+

+

+/* Desc: return suitable mode

+ *

+ * In  : width, height, bpp

+ * Out : ptr to mode structure

+ *

+ * Note: -

+ */

+MGA_MODE *mga_mode_find (int width, int height, int bpp)

+{

+ static MGA_MODE *q = NULL;

+

+ MGA_MODE *p;

+ unsigned int min;

+

+ if (q == NULL) {

+    if ((q = _mga_mode_check()) == NULL) {

+       return NULL;

+    }

+ }

+

+ /* search for a mode that fits our request */

+ for (min=-1, p=NULL; q->mode!=0xffff; q++) {

+     if ((q->xres>=width) && (q->yres>=height) && (q->bpp==bpp)) {

+        if (min>=(unsigned)(q->xres*q->yres)) {

+           min = q->xres*q->yres;

+           p = q;

+        }

+     }

+ }

+

+ return p;

+}

diff --git a/src/mesa/drivers/dos/vesa/vesa.h b/src/mesa/drivers/dos/mga/mga_mode.h
similarity index 71%
copy from src/mesa/drivers/dos/vesa/vesa.h
copy to src/mesa/drivers/dos/mga/mga_mode.h
index eb914e1..4049bd8 100644
--- a/src/mesa/drivers/dos/vesa/vesa.h
+++ b/src/mesa/drivers/dos/mga/mga_mode.h
@@ -1,8 +1,8 @@
 /*

  * Mesa 3-D graphics library

- * Version:  4.0

+ * Version:  5.0

  * 

- * Copyright (C) 1999  Brian Paul   All Rights Reserved.

+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.

  * 

  * Permission is hereby granted, free of charge, to any person obtaining a

  * copy of this software and associated documentation files (the "Software"),

@@ -23,25 +23,25 @@
  */

 

 /*

- * DOS/DJGPP device driver v1.3 for Mesa 5.0

+ * DOS/DJGPP device driver v1.3 for Mesa 5.0  --  MGA2064W mode switching

  *

- *  Copyright (C) 2002 - Borca Daniel

+ *  Copyright (c) 2003 - Borca Daniel

  *  Email : dborca@yahoo.com

  *  Web   : http://www.geocities.com/dborca

  */

 

 

-#ifndef VESA_H_included

-#define VESA_H_included

+#ifndef MGA_MODE_included

+#define MGA_MODE_included

 

-#include "../internal.h"

+typedef struct MGA_MODE {

+        int mode;

+        int xres, yres;

+        int bpp;

+} MGA_MODE;

 

-extern void *vesa_swbank;

-

-extern void vesa_b_dump_virtual (void);

-extern void vesa_l_dump_virtual (void);

-extern void vesa_l_dump_virtual_mmx (void);

-

-extern vl_driver VESA;

+int mga_mode_switch (MGA_MODE *p, int refresh);

+int mga_mode_restore (void);

+MGA_MODE *mga_mode_find (int width, int height, int bpp);

 

 #endif

diff --git a/src/mesa/drivers/dos/mga/mga_reg.h b/src/mesa/drivers/dos/mga/mga_reg.h
new file mode 100644
index 0000000..73d22de
--- /dev/null
+++ b/src/mesa/drivers/dos/mga/mga_reg.h
@@ -0,0 +1,207 @@
+/*

+ * Mesa 3-D graphics library

+ * Version:  5.0

+ * 

+ * Copyright (C) 1999-2002  Brian Paul   All Rights Reserved.

+ * 

+ * Permission is hereby granted, free of charge, to any person obtaining a

+ * copy of this software and associated documentation files (the "Software"),

+ * to deal in the Software without restriction, including without limitation

+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,

+ * and/or sell copies of the Software, and to permit persons to whom the

+ * Software is furnished to do so, subject to the following conditions:

+ * 

+ * The above copyright notice and this permission notice shall be included

+ * in all copies or substantial portions of the Software.

+ * 

+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS

+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL

+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN

+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN

+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+ */

+

+/*

+ * DOS/DJGPP device driver v1.3 for Mesa 5.0  --  MGA2064W register mnemonics

+ *

+ *  Copyright (c) 2003 - Borca Daniel

+ *  Email : dborca@yahoo.com

+ *  Web   : http://www.geocities.com/dborca

+ */

+

+

+#ifndef MGA_REG_H_included

+#define MGA_REG_H_included

+

+/* Matrox hardware registers: */

+#define M_AR0                 0x1C60

+#define M_AR1                 0x1C64

+#define M_AR2                 0x1C68

+#define M_AR3                 0x1C6C

+#define M_AR4                 0x1C70

+#define M_AR5                 0x1C74

+#define M_AR6                 0x1C78

+#define M_BCOL                0x1C20

+#define M_CXBNDRY             0x1C80

+#define M_CXLEFT              0x1CA0

+#define M_CXRIGHT             0x1CA4

+#define M_DR0                 0x1CC0

+#define M_DR2                 0x1CC8

+#define M_DR3                 0x1CCC

+#define M_DR4                 0x1CD0

+#define M_DR6                 0x1CD8

+#define M_DR7                 0x1CDC

+#define M_DR8                 0x1CE0

+#define M_DR10                0x1CE8

+#define M_DR11                0x1CEC

+#define M_DR12                0x1CF0

+#define M_DR14                0x1CF8

+#define M_DR15                0x1CFC

+#define M_DWGCTL              0x1C00

+#define M_FCOL                0x1C24

+#define M_FIFOSTATUS          0x1E10

+#define M_FXBNDRY             0x1C84

+#define M_FXLEFT              0x1CA8

+#define M_FXRIGHT             0x1CAC

+#define M_ICLEAR              0x1E18

+#define M_IEN                 0x1E1C

+#define M_LEN                 0x1C5C

+#define M_MACCESS             0x1C04

+#define M_OPMODE              0x1E54

+#define M_PAT0                0x1C10

+#define M_PAT1                0x1C14

+#define M_PITCH               0x1C8C

+#define M_PLNWT               0x1C1C

+#define M_RESET               0x1E40

+#define M_SGN                 0x1C58

+#define M_SHIFT               0x1C50

+#define M_SRC0                0x1C30

+#define M_SRC1                0x1C34

+#define M_SRC2                0x1C38

+#define M_SRC3                0x1C3C

+#define M_STATUS              0x1E14

+#define M_VCOUNT              0x1E20

+#define M_XDST                0x1CB0

+#define M_XYEND               0x1C44

+#define M_XYSTRT              0x1C40

+#define M_YBOT                0x1C9C

+#define M_YDST                0x1C90

+#define M_YDSTLEN             0x1C88

+#define M_YDSTORG             0x1C94

+#define M_YTOP                0x1C98

+#define M_ZORG                0x1C0C

+

+#define M_EXEC                0x0100

+

+/* DWGCTL: opcod */

+#define M_DWG_LINE_OPEN       0x0

+#define M_DWG_AUTOLINE_OPEN   0x1

+#define M_DWG_LINE_CLOSE      0x2

+#define M_DWG_AUTOLINE_CLOSE  0x3

+#define M_DWG_TRAP            0x4

+#define M_DWG_TEXTURE_TRAP    0x5

+#define M_DWG_BITBLT          0x8

+#define M_DWG_FBITBLT         0xC

+#define M_DWG_ILOAD           0x9

+#define M_DWG_ILOAD_SCALE     0xD

+#define M_DWG_ILOAD_FILTER    0xF

+#define M_DWG_IDUMP           0xA

+

+/* DWGCTL: atype */

+#define M_DWG_RPL             (0x0 << 4)

+#define M_DWG_RSTR            (0x1 << 4)

+#define M_DWG_ZI              (0x3 << 4)

+#define M_DWG_BLK             (0x4 << 4)

+#define M_DWG_I               (0x7 << 4)

+

+/* DWGCTL: linear */

+#define M_DWG_LINEAR          (0x1 << 7)

+

+/* DWGCTL: zmode */

+#define M_DWG_NOZCMP          (0x0 << 8)

+#define M_DWG_ZE              (0x2 << 8)

+#define M_DWG_ZNE             (0x3 << 8)

+#define M_DWG_ZLT             (0x4 << 8)

+#define M_DWG_ZLTE            (0x5 << 8)

+#define M_DWG_ZGT             (0x6 << 8)

+#define M_DWG_ZGTE            (0x7 << 8)

+

+/* DWGCTL: solid */

+#define M_DWG_SOLID           (0x1 << 11)

+

+/* DWGCTL: arzero */

+#define M_DWG_ARZERO          (0x1 << 12)

+

+/* DWGCTL: sgnzero */

+#define M_DWG_SGNZERO         (0x1 << 13)

+

+/* DWGCTL: shiftzero */

+#define M_DWG_SHFTZERO        (0x1 << 14)

+

+/* DWGCTL: bop */

+#define M_DWG_BOP_XOR         (0x6 << 16)

+#define M_DWG_BOP_AND         (0x8 << 16)

+#define M_DWG_BOP_SRC         (0xC << 16)

+#define M_DWG_BOP_OR          (0xE << 16)

+

+/* DWGCTL: trans */

+#define M_DWG_TRANS_0         (0x0 << 20)

+#define M_DWG_TRANS_1         (0x1 << 20)

+#define M_DWG_TRANS_2         (0x2 << 20)

+#define M_DWG_TRANS_3         (0x3 << 20)

+#define M_DWG_TRANS_4         (0x4 << 20)

+#define M_DWG_TRANS_5         (0x5 << 20)

+#define M_DWG_TRANS_6         (0x6 << 20)

+#define M_DWG_TRANS_7         (0x7 << 20)

+#define M_DWG_TRANS_8         (0x8 << 20)

+#define M_DWG_TRANS_9         (0x9 << 20)

+#define M_DWG_TRANS_A         (0xA << 20)

+#define M_DWG_TRANS_B         (0xB << 20)

+#define M_DWG_TRANS_C         (0xC << 20)

+#define M_DWG_TRANS_D         (0xD << 20)

+#define M_DWG_TRANS_E         (0xE << 20)

+#define M_DWG_TRANS_F         (0xF << 20)

+

+/* DWGCTL: bltmod */

+#define M_DWG_BMONOLEF        (0x0 << 25)

+#define M_DWG_BMONOWF         (0x4 << 25)

+#define M_DWG_BPLAN           (0x1 << 25)

+#define M_DWG_BFCOL           (0x2 << 25)

+#define M_DWG_BUYUV           (0xE << 25)

+#define M_DWG_BU32BGR         (0x3 << 25)

+#define M_DWG_BU32RGB         (0x7 << 25)

+#define M_DWG_BU24BGR         (0xB << 25)

+#define M_DWG_BU24RGB         (0xF << 25)

+

+/* DWGCTL: pattern */

+#define M_DWG_PATTERN         (0x1 << 29)

+

+/* DWGCTL: transc */

+#define M_DWG_TRANSC          (0x1 << 30)

+

+/* OPMODE: */

+#define M_DMA_GENERAL         (0x0 << 2)

+#define M_DMA_BLIT            (0x1 << 2)

+#define M_DMA_VECTOR          (0x2 << 2)

+

+/* SGN: */

+#define M_SDXL                (0x1 << 1)

+#define M_SDXR                (0x1 << 5)

+

+

+

+/* VGAREG */

+#define M_CRTC_INDEX          0x1FD4

+#define M_CRTC_DATA           0x1FD5

+

+#define M_CRTC_EXT_INDEX      0x1FDE

+#define M_CRTC_EXT_DATA       0x1FDF

+

+#define M_MISC_R              0x1FCC

+#define M_MISC_W              0x1FC2

+

+/* CRTCEXT3: */

+#define M_MGAMODE             (0x1 << 7)

+

+#endif

diff --git a/src/mesa/drivers/dos/vesa/vesa.c b/src/mesa/drivers/dos/vesa.c
similarity index 92%
rename from src/mesa/drivers/dos/vesa/vesa.c
rename to src/mesa/drivers/dos/vesa.c
index 1f3de84..eebaa50 100644
--- a/src/mesa/drivers/dos/vesa/vesa.c
+++ b/src/mesa/drivers/dos/vesa.c
@@ -40,11 +40,12 @@
 #include <sys/farptr.h>

 #include <sys/movedata.h>

 

+#include "video.h"

 #include "vesa.h"

 

 

 

-static vl_mode modes[64];

+static vl_mode modes[128];

 

 static word16 vesa_ver;

 static int banked_selector, linear_selector;

@@ -52,7 +53,7 @@
 

 static int vesa_color_precision = 6;

 

-static void *vesa_pmcode;

+static word16 *vesa_pmcode;

 unsigned int vesa_gran_mask, vesa_gran_shift;

 

 

@@ -203,18 +204,22 @@
 

  if (vesa_info[V_MAJOR] >= 2) {

     r.x.ax = 0x4f0a;

-    r.h.bl = 0;

+    r.x.bx = 0;

     __dpmi_int(0x10, &r);

     if (r.x.ax == 0x004f) {

-       vesa_pmcode = malloc(r.x.cx);

+       vesa_pmcode = (word16 *)malloc(r.x.cx);

        movedata(__djgpp_dos_sel, (r.x.es << 4) + r.x.di, _my_ds(), (unsigned)vesa_pmcode, r.x.cx);

-       p = (word16 *)((long)vesa_pmcode + ((word16 *)vesa_pmcode)[3]);

-       while (*p++ != 0xffff) ;

-       if (*p != 0xffff) {

+       if (vesa_pmcode[3]) {

+          p = (word16 *)((long)vesa_pmcode + vesa_pmcode[3]);

+          while (*p++ != 0xffff) ;

+       } else {

+          p = NULL;

+       }

+       if (p && (*p != 0xffff)) {

           free(vesa_pmcode);

           vesa_pmcode = NULL;

        } else {

-          vesa_swbank = (char *)vesa_pmcode + ((word16 *)vesa_pmcode)[0];

+          vesa_swbank = (void *)((long)vesa_pmcode + vesa_pmcode[0]);

        }

     }

  }

@@ -232,7 +237,7 @@
  *

  * Note: -

  */

-static void vesa_finit (void)

+static void vesa_fini (void)

 {

  if (vesa_ver) {

     _remove_selector(&linear_selector);

@@ -363,7 +368,7 @@
  __dpmi_regs r;

 

  if (p->mode & 0x4000) {

-    VESA.blit = vl_can_mmx() ? vesa_l_dump_virtual_mmx : vesa_l_dump_virtual;

+    VESA.blit = _can_mmx() ? vesa_l_dump_virtual_mmx : vesa_l_dump_virtual;

  } else {

     VESA.blit = vesa_b_dump_virtual;

     { int n; for (vesa_gran_shift=0, n=p->gran; n; vesa_gran_shift++, n>>=1) ; }

@@ -492,16 +497,23 @@
 

 

 

-/* Desc: retrieve CI precision

+/* Desc: state retrieval

  *

- * In  : -

- * Out : precision in bits

+ * In  : parameter name, ptr to storage

+ * Out : 0 if request successfully processed

  *

  * Note: -

  */

-static int vesa_getCIprec (void)

+static int vesa_get (int pname, int *params)

 {

- return vesa_color_precision;

+ switch (pname) {

+        case VL_GET_CI_PREC:

+             params[0] = vesa_color_precision;

+             break;

+        default:

+             return -1;

+ }

+ return 0;

 }

 

 

@@ -515,7 +527,7 @@
           NULL,

           vesa_setCI_f,

           vesa_setCI_i,

-          vesa_getCIprec,

+          vesa_get,

           vesa_restore,

-          vesa_finit

+          vesa_fini

 };

diff --git a/src/mesa/drivers/dos/vesa/vesa.h b/src/mesa/drivers/dos/vesa.h
similarity index 98%
rename from src/mesa/drivers/dos/vesa/vesa.h
rename to src/mesa/drivers/dos/vesa.h
index eb914e1..369196f 100644
--- a/src/mesa/drivers/dos/vesa/vesa.h
+++ b/src/mesa/drivers/dos/vesa.h
@@ -34,7 +34,7 @@
 #ifndef VESA_H_included

 #define VESA_H_included

 

-#include "../internal.h"

+#include "internal.h"

 

 extern void *vesa_swbank;

 

diff --git a/src/mesa/drivers/dos/vga/vga.c b/src/mesa/drivers/dos/vga.c
similarity index 87%
rename from src/mesa/drivers/dos/vga/vga.c
rename to src/mesa/drivers/dos/vga.c
index d1d2db5..ed89962 100644
--- a/src/mesa/drivers/dos/vga/vga.c
+++ b/src/mesa/drivers/dos/vga.c
@@ -34,11 +34,12 @@
 #include <pc.h>

 #include <stdlib.h>

 

+#include "video.h"

 #include "vga.h"

 

 

 

-static vl_mode modes[4] = {

+static vl_mode modes[] = {

        {0x13 | 0x4000, 320, 200, 320, 8, -1, 320*200},

        {0xffff, -1, -1, -1, -1, -1, -1}

 };

@@ -99,7 +100,7 @@
  *

  * Note: -

  */

-static void vga_finit (void)

+static void vga_fini (void)

 {

  if (vga_ver) {

     _remove_selector(&linear_selector);

@@ -120,7 +121,7 @@
  if (!(p->mode & 0x4000)) {

     return -1;

  }

- VGA.blit = vl_can_mmx() ? vesa_l_dump_virtual_mmx : vesa_l_dump_virtual;

+ VGA.blit = _can_mmx() ? vesa_l_dump_virtual_mmx : vesa_l_dump_virtual;

 

  if (oldmode == -1) {

     __asm("\n\

@@ -134,6 +135,8 @@
  __asm("int $0x10"::"a"(p->mode&0xff));

 

  return 0;

+

+ (void)refresh; /* silence compiler warning */

 }

 

 

@@ -196,16 +199,23 @@
 

 

 

-/* Desc: retrieve CI precision

+/* Desc: state retrieval

  *

- * In  : -

- * Out : precision in bits

+ * In  : parameter name, ptr to storage

+ * Out : 0 if request successfully processed

  *

  * Note: -

  */

-static int vga_getCIprec (void)

+static int vga_get (int pname, int *params)

 {

- return vga_color_precision;

+ switch (pname) {

+        case VL_GET_CI_PREC:

+             params[0] = vga_color_precision;

+             break;

+        default:

+             return -1;

+ }

+ return 0;

 }

 

 

@@ -219,7 +229,7 @@
           NULL,

           vga_setCI_f,

           vga_setCI_i,

-          vga_getCIprec,

+          vga_get,

           vga_restore,

-          vga_finit

+          vga_fini

 };

diff --git a/src/mesa/drivers/dos/vga/vga.h b/src/mesa/drivers/dos/vga.h
similarity index 96%
rename from src/mesa/drivers/dos/vga/vga.h
rename to src/mesa/drivers/dos/vga.h
index b7ae84c..d104794 100644
--- a/src/mesa/drivers/dos/vga/vga.h
+++ b/src/mesa/drivers/dos/vga.h
@@ -34,8 +34,8 @@
 #ifndef VGA_H_included

 #define VGA_H_included

 

-#include "../internal.h"

-#include "../vesa/vesa.h"

+#include "internal.h"

+#include "vesa.h"

 

 extern vl_driver VGA;

 

diff --git a/src/mesa/drivers/dos/video.c b/src/mesa/drivers/dos/video.c
index aba99ac..3e93e60 100644
--- a/src/mesa/drivers/dos/video.c
+++ b/src/mesa/drivers/dos/video.c
@@ -35,10 +35,10 @@
 

 #include <stdlib.h>

 

-#include "video.h"

 #include "internal.h"

-#include "vesa/vesa.h"

-#include "vga/vga.h"

+#include "vesa.h"

+#include "vga.h"

+#include "video.h"

 

 

 

@@ -56,22 +56,22 @@
 

 /* lookup table for scaling 5 bit colors up to 8 bits */

 static int _rgb_scale_5[32] = {

-   0,   8,   16,  24,  32,  41,  49,  57,

-   65,  74,  82,  90,  98,  106, 115, 123,

-   131, 139, 148, 156, 164, 172, 180, 189,

-   197, 205, 213, 222, 230, 238, 246, 255

+   0,   8,   16,  25,  33,  41,  49,  58,

+   66,  74,  82,  90,  99,  107, 115, 123,

+   132, 140, 148, 156, 165, 173, 181, 189,

+   197, 206, 214, 222, 230, 239, 247, 255

 };

 

 /* lookup table for scaling 6 bit colors up to 8 bits */

 static int _rgb_scale_6[64] = {

    0,   4,   8,   12,  16,  20,  24,  28,

-   32,  36,  40,  44,  48,  52,  56,  60,

-   64,  68,  72,  76,  80,  85,  89,  93,

+   32,  36,  40,  45,  49,  53,  57,  61,

+   65,  69,  73,  77,  81,  85,  89,  93,

    97,  101, 105, 109, 113, 117, 121, 125,

-   129, 133, 137, 141, 145, 149, 153, 157,

-   161, 165, 170, 174, 178, 182, 186, 190,

-   194, 198, 202, 206, 210, 214, 218, 222,

-   226, 230, 234, 238, 242, 246, 250, 255

+   130, 134, 138, 142, 146, 150, 154, 158,

+   162, 166, 170, 174, 178, 182, 186, 190,

+   194, 198, 202, 206, 210, 215, 219, 223,

+   227, 231, 235, 239, 243, 247, 251, 255

 };

 

 /* FakeColor data */

@@ -376,36 +376,24 @@
 

 

 

-/* Desc: get screen geometry

+/* Desc: state retrieval

  *

- * In  : ptr to WIDTH, ptr to HEIGHT

+ * In  : name, storage

  * Out : -

  *

  * Note: -

  */

-void vl_get_screen_size (int *width, int *height)

+int vl_get (int pname, int *params)

 {

- *width = video_mode->xres;

- *height = video_mode->yres;

-}

-

-

-

-/* Desc: retrieve CPU MMX capability

- *

- * In  : -

- * Out : FALSE if CPU cannot do MMX

- *

- * Note: -

- */

-int vl_can_mmx (void)

-{

-#ifdef USE_MMX_ASM

- extern int _mesa_identify_x86_cpu_features (void);

- return (_mesa_identify_x86_cpu_features() & 0x00800000);

-#else

+ switch (pname) {

+        case VL_GET_SCREEN_SIZE:

+             params[0] = video_mode->xres;

+             params[1] = video_mode->yres;

+             break;

+        default:

+             return drv->get(pname, params);

+ }

  return 0;

-#endif

 }

 

 

@@ -431,7 +419,7 @@
         vl_mixfix = vl_mixfix##bpp;    \

         vl_mixrgb = vl_mixrgb##bpp;    \

         vl_mixrgba = vl_mixrgba##bpp;  \

-        vl_clear = vl_can_mmx() ? v_clear##bpp##_mmx : v_clear##bpp

+        vl_clear = _can_mmx() ? v_clear##bpp##_mmx : v_clear##bpp

         

  switch (p->bpp) {

         case 8:

@@ -475,7 +463,7 @@
 void vl_video_exit (void)

 {

  drv->restore();

- drv->finit();

+ drv->fini();

 }

 

 

@@ -523,7 +511,7 @@
  if ((vl_setup_mode(p) == 0) && (drv->entermode(p, refresh) == 0)) {

     vl_flip = drv->blit;

     if (fake) {

-       min = drv->getCIprec();

+       drv->get(VL_GET_CI_PREC, (int *)(&min));

        fake_buildpalette(min);

        if (min == 8) {

           vl_getrgba = v_getrgba8fake8;

diff --git a/src/mesa/drivers/dos/video.h b/src/mesa/drivers/dos/video.h
index 8dfb9a9..e908178 100644
--- a/src/mesa/drivers/dos/video.h
+++ b/src/mesa/drivers/dos/video.h
@@ -36,6 +36,12 @@
 

 typedef int fixed;

 

+#define VL_GET_CARD_NAME   0x0100

+#define VL_GET_VRAM        0x0101

+#define VL_GET_CI_PREC     0x0200

+#define VL_GET_HPIXELS     0x0201

+#define VL_GET_SCREEN_SIZE 0x0202

+

 extern int (*vl_mixfix) (fixed r, fixed g, fixed b);

 extern int (*vl_mixrgb) (const unsigned char rgb[]);

 extern int (*vl_mixrgba) (const unsigned char rgba[]);

@@ -50,7 +56,7 @@
 void vl_setCI (int index, float red, float green, float blue);

 

 int vl_sync_buffer (void **buffer, int x, int y, int width, int height);

-void vl_get_screen_size (int *width, int *height);

+int vl_get (int pname, int *params);

 

 void vl_video_exit (void);

 int vl_video_init (int width, int height, int bpp, int rgb, int refresh);

diff --git a/src/mesa/drivers/dos/virtual.S b/src/mesa/drivers/dos/virtual.S
index c5a7297..0605514 100644
--- a/src/mesa/drivers/dos/virtual.S
+++ b/src/mesa/drivers/dos/virtual.S
@@ -108,7 +108,7 @@
 		.global	_v_clear8_mmx

 _v_clear8_mmx:

 #ifdef USE_MMX_ASM

-		movq	4(%esp), %mm0

+		movd	4(%esp), %mm0

 		punpcklbw %mm0, %mm0

 		punpcklwd %mm0, %mm0

 		jmp	_v_clear_common_mmx

@@ -125,7 +125,7 @@
 		.global	_v_clear16_mmx

 _v_clear16_mmx:

 #ifdef USE_MMX_ASM

-		movq	4(%esp), %mm0

+		movd	4(%esp), %mm0

 		punpcklwd %mm0, %mm0

 		jmp	_v_clear_common_mmx

 #endif

@@ -141,7 +141,7 @@
 		.global	_v_clear32_mmx

 _v_clear32_mmx:

 #ifdef USE_MMX_ASM

-		movq	4(%esp), %mm0

+		movd	4(%esp), %mm0

 		.balign	4

 _v_clear_common_mmx:

 		punpckldq %mm0, %mm0

diff --git a/src/mesa/main/Makefile.DJ b/src/mesa/main/Makefile.DJ
index cabeff1..e2714f9 100644
--- a/src/mesa/main/Makefile.DJ
+++ b/src/mesa/main/Makefile.DJ
@@ -40,6 +40,9 @@
 #			As a consequence, you'll need the DJGPP Glide3

 #			library to build any application.

 #			default = no

+#	MATROX=1	build for Matrox Millennium I (MGA2064W) cards.

+#			This is experimental and not intensively tested.

+#			default = no

 #	HAVE_X86=1	optimize for i386.

 #			default = no

 #	HAVE_MMX=1	allow MMX specializations, provided your assembler

@@ -70,8 +73,17 @@
 

 CC = gcc

 CFLAGS += -I$(TOP)/include -I.

-ifdef FX

-CFLAGS += -D__DOS__ -I$(GLIDE) -DFX -DFX_GLIDE3 -DFXMESA_USE_ARGB

+ifeq ($(FX),1)

+CFLAGS += -D__DOS__ -DH3

+CFLAGS += -I$(GLIDE) -DFX -DFX_GLIDE3 -DFXMESA_USE_ARGB

+LIBNAME = "MesaGL/FX DJGPP"

+else

+ifeq ($(MATROX),1)

+CFLAGS += -DMATROX

+LIBNAME = "MesaGL/MGA DJGPP"

+else

+LIBNAME = "MesaGL DJGPP"

+endif

 endif

 

 AR = ar

@@ -228,22 +240,22 @@
 	X86/3dnow_xform4.S \

 	X86/3dnow_normal.S

 

-ifdef HAVE_MMX

+ifeq ($(HAVE_MMX),1)

 X86_SOURCES += $(MMX_SOURCES)

 CFLAGS += -DUSE_MMX_ASM

 HAVE_X86 = 1

 endif

-ifdef HAVE_SSE

+ifeq ($(HAVE_SSE),1)

 X86_SOURCES += $(SSE_SOURCES)

 CFLAGS += -DUSE_SSE_ASM

 HAVE_X86 = 1

 endif

-ifdef HAVE_3DNOW

+ifeq ($(HAVE_3DNOW),1)

 X86_SOURCES += $(K3D_SOURCES)

 CFLAGS += -DUSE_3DNOW_ASM

 HAVE_X86 = 1

 endif

-ifdef HAVE_X86

+ifeq ($(HAVE_X86),1)

 CFLAGS += -DUSE_X86_ASM

 else

 X86_SOURCES =

@@ -251,15 +263,7 @@
 

 DRIVER_SOURCES = \

 	DOS/dmesa.c

-ifndef FX

-DRIVER_SOURCES += \

-	DOS/video.c \

-	DOS/virtual.S \

-	DOS/vesa/vesa.c \

-	DOS/vesa/blit.S \

-	DOS/vga/vga.c \

-	DOS/dpmi.c

-else

+ifeq ($(FX),1)

 DRIVER_SOURCES += \

 	FX/fxapi.c \

 	FX/fxdd.c \

@@ -270,6 +274,22 @@
 	FX/fxtris.c \

 	FX/fxvb.c \

 	FX/fxglidew.c

+else

+ifeq ($(MATROX),1)

+DRIVER_SOURCES += \

+	DOS/mga/mga.c \

+	DOS/mga/mga_hw.c \

+	DOS/mga/mga_mode.c \

+	DOS/dpmi.c

+else

+DRIVER_SOURCES += \

+	DOS/video.c \

+	DOS/virtual.S \

+	DOS/vesa.c \

+	DOS/blit.S \

+	DOS/vga.c \

+	DOS/dpmi.c

+endif

 endif

 

 SOURCES = $(CORE_SOURCES) $(X86_SOURCES) $(DRIVER_SOURCES)

@@ -295,10 +315,10 @@
 	$(warning Missing DXE3GEN and/or DXE3.LD! You must have DXE3GEN)

 	$(warning somewhere in PATH, and DXE3.LD in DJGPP/LIB directory.)

 else

-ifdef FX

-	-dxe3gen -o $(LIBDIR)/$(GL_DXE) -I $(LIBDIR)/$(GL_IMP) -D "MesaGL/FX DJGPP" -E _gl -E _DMesa -P glid3.dxe -U $(OBJECTS)

+ifeq ($(FX),1)

+	-dxe3gen -o $(LIBDIR)/$(GL_DXE) -I $(LIBDIR)/$(GL_IMP) -D $(LIBNAME) -E _gl -E _DMesa -P glid3.dxe -U $(OBJECTS)

 else

-	-dxe3gen -o $(LIBDIR)/$(GL_DXE) -I $(LIBDIR)/$(GL_IMP) -D "MesaGL DJGPP" -E _gl -E _DMesa -U $(OBJECTS)

+	-dxe3gen -o $(LIBDIR)/$(GL_DXE) -I $(LIBDIR)/$(GL_IMP) -D $(LIBNAME) -E _gl -E _DMesa -U $(OBJECTS)

 endif

 endif

 

@@ -319,8 +339,7 @@
 	-$(RM) $(subst /,\,tnl/*.o)

 	-$(RM) $(subst /,\,X86/*.o)

 	-$(RM) $(subst /,\,DOS/*.o)

-	-$(RM) $(subst /,\,DOS/vesa/*.o)

-	-$(RM) $(subst /,\,DOS/vga/*.o)

+	-$(RM) $(subst /,\,DOS/mga/*.o)

 	-$(RM) $(subst /,\,FX/*.o)

 

 -include depend