summaryrefslogtreecommitdiffstats
path: root/src/mesa/drivers/dos
diff options
context:
space:
mode:
authorBrian Paul <[email protected]>2002-02-12 03:24:56 +0000
committerBrian Paul <[email protected]>2002-02-12 03:24:56 +0000
commitdb41d2ea8c8b6ceddf54f87268085a83d8f342ba (patch)
tree5fb285d9f22e09a2c6fd1cd09b3a13d2329d5553 /src/mesa/drivers/dos
parentcc27365d775632647a1d07d78203421d27e8cd1c (diff)
Daniel Borca's new DOS/DJGPP driver.
Diffstat (limited to 'src/mesa/drivers/dos')
-rw-r--r--src/mesa/drivers/dos/dmesa.c592
-rw-r--r--src/mesa/drivers/dos/dmesaint.h231
-rw-r--r--src/mesa/drivers/dos/dvesa.c549
-rw-r--r--src/mesa/drivers/dos/dvesa.h127
4 files changed, 1499 insertions, 0 deletions
diff --git a/src/mesa/drivers/dos/dmesa.c b/src/mesa/drivers/dos/dmesa.c
new file mode 100644
index 00000000000..01be3012242
--- /dev/null
+++ b/src/mesa/drivers/dos/dmesa.c
@@ -0,0 +1,592 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.0
+ *
+ * Copyright (C) 1999 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 v0.1 for Mesa 4.0
+ *
+ * Copyright (C) 2002 - Borca Daniel
+ * Email : [email protected]
+ * Web : http://www.geocities.com/dborca
+ */
+
+
+#ifdef PC_HEADER
+#include "all.h"
+#else
+#include "glheader.h"
+#include "context.h"
+#include "GL/dmesa.h"
+#include "matrix.h"
+#include "texformat.h"
+#include "texstore.h"
+#include "array_cache/acache.h"
+#include "swrast/swrast.h"
+#include "swrast_setup/swrast_setup.h"
+#include "tnl/tnl.h"
+#include "tnl/t_context.h"
+#include "tnl/t_pipeline.h"
+#endif
+
+#include "dvesa.h"
+#include "dmesaint.h"
+
+
+
+/*
+ * In C++ terms, this class derives from the GLvisual class.
+ * Add system-specific fields to it.
+ */
+struct dmesa_visual {
+ GLvisual *gl_visual;
+ GLboolean db_flag; /* double buffered? */
+ GLboolean rgb_flag; /* RGB mode? */
+ GLuint depth; /* bits per pixel (1, 8, 24, etc) */
+};
+
+/*
+ * In C++ terms, this class derives from the GLframebuffer class.
+ * Add system-specific fields to it.
+ */
+struct dmesa_buffer {
+ GLframebuffer *gl_buffer; /* The depth, stencil, accum, etc buffers */
+ void *the_window; /* your window handle, etc */
+
+ int width, height; /* size in pixels */
+ int xpos, ypos; /* buffer position */
+ int xsize, len; /* number of bytes in a line, then total */
+ int delta; /* used to wrap around */
+ int offset; /* offset in video */
+ struct dvmode *video;
+};
+
+/*
+ * In C++ terms, this class derives from the GLcontext class.
+ * Add system-specific fields to it.
+ */
+struct dmesa_context {
+ GLcontext *gl_ctx; /* the core library context */
+ DMesaVisual visual;
+ DMesaBuffer Buffer;
+ GLuint ClearColor;
+ /* etc... */
+};
+
+
+
+static void dmesa_update_state (GLcontext *ctx, GLuint new_state);
+
+
+
+/**********************************************************************/
+/***** Read/Write pixels *****/
+/**********************************************************************/
+
+
+
+WRITE_RGBA_SPAN(15)
+WRITE_RGBA_SPAN(16)
+WRITE_RGBA_SPAN(24)
+WRITE_RGBA_SPAN(32)
+
+WRITE_RGB_SPAN(15)
+WRITE_RGB_SPAN(16)
+WRITE_RGB_SPAN(24)
+WRITE_RGB_SPAN(32)
+
+WRITE_MONO_RGBA_SPAN(15)
+WRITE_MONO_RGBA_SPAN(16)
+WRITE_MONO_RGBA_SPAN(24)
+WRITE_MONO_RGBA_SPAN(32)
+
+READ_RGBA_SPAN(15)
+READ_RGBA_SPAN(16)
+READ_RGBA_SPAN(24)
+READ_RGBA_SPAN(32)
+
+WRITE_RGBA_PIXELS(15)
+WRITE_RGBA_PIXELS(16)
+WRITE_RGBA_PIXELS(24)
+WRITE_RGBA_PIXELS(32)
+
+WRITE_MONO_RGBA_PIXELS(15)
+WRITE_MONO_RGBA_PIXELS(16)
+WRITE_MONO_RGBA_PIXELS(24)
+WRITE_MONO_RGBA_PIXELS(32)
+
+READ_RGBA_PIXELS(15)
+READ_RGBA_PIXELS(16)
+READ_RGBA_PIXELS(24)
+READ_RGBA_PIXELS(32)
+
+
+
+/**********************************************************************/
+/***** Miscellaneous device driver funcs *****/
+/**********************************************************************/
+
+
+
+static void clear_color (GLcontext *ctx, const GLchan color[4])
+{
+ DMesaContext c = (DMesaContext)ctx->DriverCtx;
+ c->ClearColor = dv_color(color);
+}
+
+
+
+static void clear (GLcontext *ctx, GLbitfield mask, GLboolean all,
+ GLint x, GLint y, GLint width, GLint height)
+{
+ DMesaContext c = (DMesaContext)ctx->DriverCtx;
+ const GLuint *colorMask = (GLuint *)&ctx->Color.ColorMask;
+ DMesaBuffer b = c->Buffer;
+
+/*
+ * Clear the specified region of the buffers indicated by 'mask'
+ * using the clear color or index as specified by one of the two
+ * functions above.
+ * If all==GL_TRUE, clear whole buffer, else just clear region defined
+ * by x,y,width,height
+ */
+
+ /* we can't handle color or index masking */
+ if (*colorMask==0xffffffff && ctx->Color.IndexMask==0xffffffff) {
+ if (mask&DD_BACK_LEFT_BIT) {
+ if (all) {
+ dv_clear_virtual(b->the_window, b->len, c->ClearColor);
+ } else {
+ dv_fillrect(b->the_window, b->width, x, y, width, height, c->ClearColor);
+ }
+ mask &= ~DD_BACK_LEFT_BIT;
+ }
+ }
+
+ if (mask) {
+ _swrast_Clear(ctx, mask, all, x, y, width, height);
+ }
+}
+
+
+
+/*
+ * Set the current reading buffer.
+ */
+static void set_read_buffer (GLcontext *ctx, GLframebuffer *buffer,
+ GLenum mode)
+{
+/*
+ DMesaContext c = (DMesaContext)ctx->DriverCtx;
+ dmesa_update_state(ctx);
+*/
+}
+
+
+
+/*
+ * Set the destination/draw buffer.
+ */
+static GLboolean set_draw_buffer (GLcontext *ctx, GLenum mode)
+{
+ if (mode==GL_BACK_LEFT) {
+ return GL_TRUE;
+ } else {
+ return GL_FALSE;
+ }
+}
+
+
+
+/*
+ * Return the width and height of the current buffer.
+ * If anything special has to been done when the buffer/window is
+ * resized, do it now.
+ */
+static void get_buffer_size (GLcontext *ctx, GLuint *width, GLuint *height)
+{
+ DMesaContext c = (DMesaContext)ctx->DriverCtx;
+
+ *width = c->Buffer->width;
+ *height = c->Buffer->height;
+}
+
+
+
+static const GLubyte* get_string (GLcontext *ctx, GLenum name)
+{
+ switch (name) {
+ case GL_RENDERER:
+ return (const GLubyte *)"DOS Mesa";
+ default:
+ return NULL;
+ }
+}
+
+
+
+/**********************************************************************/
+/***** Miscellaneous device driver funcs *****/
+/***** Note that these functions are mandatory *****/
+/**********************************************************************/
+
+
+
+/* OPTIONAL FUNCTION: implements glFinish if possible */
+static void finish (GLcontext *ctx)
+{
+/*
+ DMesaContext c = (DMesaContext)ctx->DriverCtx;
+*/
+}
+
+
+
+/* OPTIONAL FUNCTION: implements glFlush if possible */
+static void flush (GLcontext *ctx)
+{
+/*
+ DMesaContext c = (DMesaContext)ctx->DriverCtx;
+*/
+}
+
+
+
+/**********************************************************************/
+/**********************************************************************/
+
+
+
+/* Setup pointers and other driver state that is constant for the life
+ * of a context.
+ */
+void dmesa_init_pointers (GLcontext *ctx)
+{
+ TNLcontext *tnl;
+
+ ctx->Driver.UpdateState = dmesa_update_state;
+
+ ctx->Driver.GetString = get_string;
+ ctx->Driver.GetBufferSize = get_buffer_size;
+ ctx->Driver.Flush = flush;
+ ctx->Driver.Finish = finish;
+
+ /* Software rasterizer pixel paths:
+ */
+ ctx->Driver.Accum = _swrast_Accum;
+ ctx->Driver.Bitmap = _swrast_Bitmap;
+ ctx->Driver.Clear = clear;
+ ctx->Driver.ResizeBuffersMESA = _swrast_alloc_buffers;
+ ctx->Driver.CopyPixels = _swrast_CopyPixels;
+ ctx->Driver.DrawPixels = _swrast_DrawPixels;
+ ctx->Driver.ReadPixels = _swrast_ReadPixels;
+
+ /* Software texture functions:
+ */
+ ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
+ ctx->Driver.TexImage1D = _mesa_store_teximage1d;
+ ctx->Driver.TexImage2D = _mesa_store_teximage2d;
+ ctx->Driver.TexImage3D = _mesa_store_teximage3d;
+ ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
+ ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
+ ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
+ ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
+
+ ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
+ ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
+ ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
+ ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
+ ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
+
+ ctx->Driver.BaseCompressedTexFormat = _mesa_base_compressed_texformat;
+ ctx->Driver.CompressedTextureSize = _mesa_compressed_texture_size;
+ ctx->Driver.GetCompressedTexImage = _mesa_get_compressed_teximage;
+
+ /* Swrast hooks for imaging extensions:
+ */
+ ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
+ ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
+ ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
+ ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
+
+ /* Statechange callbacks:
+ */
+ ctx->Driver.SetDrawBuffer = set_draw_buffer;
+ ctx->Driver.ClearColor = clear_color;
+
+ /* Initialize the TNL driver interface:
+ */
+ tnl = TNL_CONTEXT(ctx);
+ tnl->Driver.RunPipeline = _tnl_run_pipeline;
+
+ /* Install swsetup for tnl->Driver.Render.*:
+ */
+ _swsetup_Wakeup(ctx);
+}
+
+
+
+static void dmesa_update_state (GLcontext *ctx, GLuint new_state)
+{
+ DMesaContext c = (DMesaContext)ctx->DriverCtx;
+ struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
+
+ /* Initialize all the pointers in the DD struct. Do this whenever */
+ /* a new context is made current or we change buffers via set_buffer! */
+
+ _swrast_InvalidateState(ctx, new_state);
+ _swsetup_InvalidateState(ctx, new_state);
+ _ac_InvalidateState(ctx, new_state);
+ _tnl_InvalidateState(ctx, new_state);
+
+ swdd->SetReadBuffer = set_read_buffer;
+
+ /* RGB(A) span/pixel functions */
+ switch (c->visual->depth) {
+ case 15:
+ swdd->WriteRGBASpan = write_rgba_span_15;
+ swdd->WriteRGBSpan = write_rgb_span_15;
+ swdd->WriteMonoRGBASpan = write_mono_rgba_span_15;
+ swdd->WriteRGBAPixels = write_rgba_pixels_15;
+ swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels_15;
+ swdd->ReadRGBASpan = read_rgba_span_15;
+ swdd->ReadRGBAPixels = read_rgba_pixels_15;
+ break;
+ case 16:
+ swdd->WriteRGBASpan = write_rgba_span_16;
+ swdd->WriteRGBSpan = write_rgb_span_16;
+ swdd->WriteMonoRGBASpan = write_mono_rgba_span_16;
+ swdd->WriteRGBAPixels = write_rgba_pixels_16;
+ swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels_16;
+ swdd->ReadRGBASpan = read_rgba_span_16;
+ swdd->ReadRGBAPixels = read_rgba_pixels_16;
+ break;
+ case 24:
+ swdd->WriteRGBASpan = write_rgba_span_24;
+ swdd->WriteRGBSpan = write_rgb_span_24;
+ swdd->WriteMonoRGBASpan = write_mono_rgba_span_24;
+ swdd->WriteRGBAPixels = write_rgba_pixels_24;
+ swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels_24;
+ swdd->ReadRGBASpan = read_rgba_span_24;
+ swdd->ReadRGBAPixels = read_rgba_pixels_24;
+ break;
+ case 32:
+ swdd->WriteRGBASpan = write_rgba_span_32;
+ swdd->WriteRGBSpan = write_rgb_span_32;
+ swdd->WriteMonoRGBASpan = write_mono_rgba_span_32;
+ swdd->WriteRGBAPixels = write_rgba_pixels_32;
+ swdd->WriteMonoRGBAPixels = write_mono_rgba_pixels_32;
+ swdd->ReadRGBASpan = read_rgba_span_32;
+ swdd->ReadRGBAPixels = read_rgba_pixels_32;
+ break;
+ }
+}
+
+
+
+/**********************************************************************/
+/***** DMesa Public API Functions *****/
+/**********************************************************************/
+
+
+
+/*
+ * The exact arguments to this function will depend on your window system
+ */
+DMesaVisual DMesaCreateVisual (GLint colDepth, GLboolean dbFlag,
+ GLint depthSize, GLint stencilSize,
+ GLint accumSize)
+{
+ DMesaVisual v;
+ GLint redBits, greenBits, blueBits, alphaBits;
+
+ if (!dbFlag) {
+ return NULL;
+ }
+ switch (colDepth) {
+ case 15:
+ redBits = 5;
+ greenBits = 5;
+ blueBits = 5;
+ break;
+ case 16:
+ redBits = 5;
+ greenBits = 6;
+ blueBits = 5;
+ break;
+ case 24:
+ case 32:
+ redBits = 8;
+ greenBits = 8;
+ blueBits = 8;
+ break;
+ default:
+ return NULL;
+ }
+ alphaBits = 8;
+
+ if ((v=(DMesaVisual)calloc(1, sizeof(struct dmesa_visual)))!=NULL) {
+ /* Create core visual */
+ v->gl_visual = _mesa_create_visual(colDepth>8, /* rgb */
+ dbFlag,
+ GL_FALSE, /* stereo */
+ redBits,
+ greenBits,
+ blueBits,
+ alphaBits,
+ 0, /* indexBits */
+ depthSize,
+ stencilSize,
+ accumSize, /* accumRed */
+ accumSize, /* accumGreen */
+ accumSize, /* accumBlue */
+ alphaBits?accumSize:0, /* accumAlpha */
+ 1); /* numSamples */
+
+ v->depth = colDepth;
+ v->db_flag = dbFlag;
+ }
+
+ return v;
+}
+
+
+
+void DMesaDestroyVisual (DMesaVisual v)
+{
+ _mesa_destroy_visual(v->gl_visual);
+ free(v);
+}
+
+
+
+DMesaBuffer DMesaCreateBuffer (DMesaVisual visual,
+ GLint width, GLint height,
+ GLint xpos, GLint ypos)
+{
+ DMesaBuffer b;
+
+ if ((b=(DMesaBuffer)calloc(1, sizeof(struct dmesa_buffer)))!=NULL) {
+ if (visual->db_flag) {
+ if ((b->the_window=calloc(1, width*height*((visual->depth+7)/8)))==NULL) {
+ return NULL;
+ }
+ }
+
+ b->gl_buffer = _mesa_create_framebuffer(visual->gl_visual,
+ visual->gl_visual->depthBits > 0,
+ visual->gl_visual->stencilBits > 0,
+ visual->gl_visual->accumRedBits > 0,
+ visual->gl_visual->alphaBits > 0);
+ b->width = width;
+ b->height = height;
+ b->xpos = xpos;
+ b->ypos = ypos;
+ }
+
+ return b;
+}
+
+
+
+void DMesaDestroyBuffer (DMesaBuffer b)
+{
+ free(b->the_window);
+ _mesa_destroy_framebuffer(b->gl_buffer);
+ free(b);
+}
+
+
+
+DMesaContext DMesaCreateContext (DMesaVisual visual,
+ DMesaContext share)
+{
+ DMesaContext c;
+ GLboolean direct = GL_FALSE;
+
+ if ((c=(DMesaContext)calloc(1, sizeof(struct dmesa_context)))!=NULL) {
+ c->gl_ctx = _mesa_create_context(visual->gl_visual,
+ share ? share->gl_ctx : NULL,
+ (void *)c, direct);
+
+ /* you probably have to do a bunch of other initializations here. */
+ c->visual = visual;
+
+ /* Initialize the software rasterizer and helper modules.
+ */
+ _swrast_CreateContext(c->gl_ctx);
+ _ac_CreateContext(c->gl_ctx);
+ _tnl_CreateContext(c->gl_ctx);
+ _swsetup_CreateContext(c->gl_ctx);
+ dmesa_init_pointers(c->gl_ctx);
+ }
+
+ return c;
+}
+
+
+
+void DMesaDestroyContext (DMesaContext c)
+{
+ _mesa_destroy_context(c->gl_ctx);
+ free(c);
+}
+
+
+
+/*
+ * Make the specified context and buffer the current one.
+ */
+GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b)
+{
+ if (c&&b) {
+ c->Buffer = b;
+ if ((b->video=dv_select_mode(b->xpos, b->ypos, b->width, b->height, c->visual->depth, &b->delta, &b->offset))==NULL) {
+ return GL_FALSE;
+ }
+
+ b->xsize = b->width*((c->visual->depth+7)/8);
+ b->len = b->xsize*b->height;
+
+ dmesa_update_state(c->gl_ctx, 0);
+ _mesa_make_current(c->gl_ctx, b->gl_buffer);
+ if (c->gl_ctx->Viewport.Width==0) {
+ /* initialize viewport to window size */
+ _mesa_Viewport(0, 0, c->Buffer->width, c->Buffer->height);
+ }
+ } else {
+ /* Detach */
+ _mesa_make_current(NULL, NULL);
+ }
+
+ return GL_TRUE;
+}
+
+
+
+void DMesaSwapBuffers (DMesaBuffer b)
+{
+ /* copy/swap back buffer to front if applicable */
+ if (b->the_window) {
+ dv_dump_virtual(b->the_window, b->xsize, b->height, b->offset, b->delta);
+ }
+}
diff --git a/src/mesa/drivers/dos/dmesaint.h b/src/mesa/drivers/dos/dmesaint.h
new file mode 100644
index 00000000000..b8aa7064d57
--- /dev/null
+++ b/src/mesa/drivers/dos/dmesaint.h
@@ -0,0 +1,231 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.0
+ *
+ * Copyright (C) 1999 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 v0.1 for Mesa 4.0
+ *
+ * Copyright (C) 2002 - Borca Daniel
+ * Email : [email protected]
+ * Web : http://www.geocities.com/dborca
+ */
+
+
+#ifndef DMESAINT_H_included
+#define DMESAINT_H_included
+
+
+
+#define FLIP(y) (c->Buffer->height - (y) - 1)
+#define FLIP2(y) (h - (y) - 1)
+
+
+
+/**********************************************************************/
+/***** Write spans of pixels *****/
+/**********************************************************************/
+#define WRITE_RGBA_SPAN(bpp) \
+static void write_rgba_span_##bpp (const GLcontext *ctx, GLuint n, GLint x, GLint y, \
+ const GLubyte rgba[][4], const GLubyte mask[]) \
+{ \
+ DMesaContext c = (DMesaContext)ctx->DriverCtx; \
+ void *b = c->Buffer->the_window; \
+ GLuint i, offset; \
+ \
+ offset = c->Buffer->width * FLIP(y) + x; \
+ if (mask) { \
+ /* draw some pixels */ \
+ for (i=0; i<n; i++, offset++) { \
+ if (mask[i]) { \
+ dv_putpixel##bpp(b, offset, dv_color##bpp(rgba[i])); \
+ } \
+ } \
+ } else { \
+ /* draw all pixels */ \
+ for (i=0; i<n; i++, offset++) { \
+ dv_putpixel##bpp(b, offset, dv_color##bpp(rgba[i])); \
+ } \
+ } \
+}
+
+
+
+#define WRITE_RGB_SPAN(bpp) \
+static void write_rgb_span_##bpp (const GLcontext *ctx, GLuint n, GLint x, GLint y, \
+ const GLubyte rgb[][3], const GLubyte mask[]) \
+{ \
+ DMesaContext c = (DMesaContext)ctx->DriverCtx; \
+ void *b = c->Buffer->the_window; \
+ GLuint i, offset; \
+ \
+ offset = c->Buffer->width * FLIP(y) + x; \
+ if (mask) { \
+ /* draw some pixels */ \
+ for (i=0; i<n; i++, offset++) { \
+ if (mask[i]) { \
+ dv_putpixel##bpp(b, offset, dv_color##bpp(rgb[i])); \
+ } \
+ } \
+ } else { \
+ /* draw all pixels */ \
+ for (i=0; i<n; i++, offset++) { \
+ dv_putpixel##bpp(b, offset, dv_color##bpp(rgb[i])); \
+ } \
+ } \
+}
+
+
+
+#define WRITE_MONO_RGBA_SPAN(bpp) \
+static void write_mono_rgba_span_##bpp (const GLcontext *ctx, \
+ GLuint n, GLint x, GLint y, \
+ const GLchan color[4], const GLubyte mask[]) \
+{ \
+ DMesaContext c = (DMesaContext)ctx->DriverCtx; \
+ void *b = c->Buffer->the_window; \
+ GLuint i, offset, rgba = dv_color##bpp(color); \
+ \
+ offset = c->Buffer->width * FLIP(y) + x; \
+ if (mask) { \
+ /* draw some pixels */ \
+ for (i=0; i<n; i++, offset++) { \
+ if (mask[i]) { \
+ dv_putpixel##bpp(b, offset, rgba); \
+ } \
+ } \
+ } else { \
+ /* draw all pixels */ \
+ for (i=0; i<n; i++, offset++) { \
+ dv_putpixel##bpp(b, offset, rgba); \
+ } \
+ } \
+}
+
+
+
+/**********************************************************************/
+/***** Read spans of pixels *****/
+/**********************************************************************/
+#define READ_RGBA_SPAN(bpp) \
+static void read_rgba_span_##bpp (const GLcontext *ctx, GLuint n, GLint x, GLint y, \
+ GLubyte rgba[][4]) \
+{ \
+ DMesaContext c = (DMesaContext)ctx->DriverCtx; \
+ void *b = c->Buffer->the_window; \
+ GLuint i, offset; \
+ \
+ offset = c->Buffer->width * FLIP(y) + x; \
+ /* read all pixels */ \
+ for (i=0; i<n; i++, offset++) { \
+ dv_getrgba##bpp(b, offset, rgba[i]); \
+ } \
+}
+
+
+
+/**********************************************************************/
+/***** Write arrays of pixels *****/
+/**********************************************************************/
+#define WRITE_RGBA_PIXELS(bpp) \
+static void write_rgba_pixels_##bpp (const GLcontext *ctx, \
+ GLuint n, const GLint x[], const GLint y[], \
+ const GLubyte rgba[][4], const GLubyte mask[]) \
+{ \
+ DMesaContext c = (DMesaContext)ctx->DriverCtx; \
+ void *b = c->Buffer->the_window; \
+ GLuint i, w = c->Buffer->width, h = c->Buffer->height; \
+ \
+ if (mask) { \
+ /* draw some pixels */ \
+ for (i=0; i<n; i++) { \
+ if (mask[i]) { \
+ dv_putpixel##bpp(b, FLIP2(y[i])*w + x[i], dv_color##bpp(rgba[i])); \
+ } \
+ } \
+ } else { \
+ /* draw all pixels */ \
+ for (i=0; i<n; i++) { \
+ dv_putpixel##bpp(b, FLIP2(y[i])*w + x[i], dv_color##bpp(rgba[i])); \
+ } \
+ } \
+}
+
+
+
+#define WRITE_MONO_RGBA_PIXELS(bpp) \
+static void write_mono_rgba_pixels_##bpp (const GLcontext *ctx, \
+ GLuint n, const GLint x[], const GLint y[], \
+ const GLchan color[4], const GLubyte mask[]) \
+{ \
+ DMesaContext c = (DMesaContext)ctx->DriverCtx; \
+ void *b = c->Buffer->the_window; \
+ GLuint i, w = c->Buffer->width, h = c->Buffer->height, rgba = dv_color##bpp(color); \
+ \
+ if (mask) { \
+ /* draw some pixels */ \
+ for (i=0; i<n; i++) { \
+ if (mask[i]) { \
+ dv_putpixel##bpp(b, FLIP2(y[i])*w + x[i], rgba); \
+ } \
+ } \
+ } else { \
+ /* draw all pixels */ \
+ for (i=0; i<n; i++) { \
+ dv_putpixel##bpp(b, FLIP2(y[i])*w + x[i], rgba); \
+ } \
+ } \
+}
+
+
+
+
+/**********************************************************************/
+/***** Read arrays of pixels *****/
+/**********************************************************************/
+#define READ_RGBA_PIXELS(bpp) \
+static void read_rgba_pixels_##bpp (const GLcontext *ctx, \
+ GLuint n, const GLint x[], const GLint y[], \
+ GLubyte rgba[][4], const GLubyte mask[]) \
+{ \
+ DMesaContext c = (DMesaContext)ctx->DriverCtx; \
+ void *b = c->Buffer->the_window; \
+ GLuint i, w = c->Buffer->width, h = c->Buffer->height; \
+ \
+ if (mask) { \
+ /* read some pixels */ \
+ for (i=0; i<n; i++) { \
+ if (mask[i]) { \
+ dv_getrgba##bpp(b, FLIP2(y[i])*w + x[i], rgba[i]); \
+ } \
+ } \
+ } else { \
+ /* read all pixels */ \
+ for (i=0; i<n; i++) { \
+ dv_getrgba##bpp(b, FLIP2(y[i])*w + x[i], rgba[i]); \
+ } \
+ } \
+}
+
+
+
+#endif
diff --git a/src/mesa/drivers/dos/dvesa.c b/src/mesa/drivers/dos/dvesa.c
new file mode 100644
index 00000000000..27464e530d7
--- /dev/null
+++ b/src/mesa/drivers/dos/dvesa.c
@@ -0,0 +1,549 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.0
+ *
+ * Copyright (C) 1999 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 v0.1 for Mesa 4.0
+ *
+ * Copyright (C) 2002 - Borca Daniel
+ * Email : [email protected]
+ * 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/segments.h>
+
+#include "dvesa.h"
+
+
+
+typedef struct dvmode {
+ int mode;
+ int xres, yres;
+ int scanlen;
+ int bpp;
+ word32 opaque;
+} dvmode;
+
+#define _16_ *(word16 *)&
+#define _32_ *(word32 *)&
+
+static int init;
+static int selector = -1;
+static int granularity;
+static dvmode modes[128];
+static void (*dv_putpixel) (void *buffer, int offset, int color);
+int (*dv_color) (const unsigned char rgba[]);
+void (*dv_dump_virtual) (void *buffer, int width, int height, int offset, int delta);
+void (*dv_clear_virtual) (void *buffer, int len, int color);
+
+extern void dv_dump_virtual_linear (void *buffer, int width, int height, int offset, int delta);
+extern void dv_dump_virtual_banked (void *buffer, int width, int height, int offset, int delta);
+
+extern void dv_clear_virtual16 (void *buffer, int len, int color);
+extern void dv_clear_virtual24 (void *buffer, int len, int color);
+extern void dv_clear_virtual32 (void *buffer, int len, int color);
+
+/* lookup table for scaling 5 bit colors up to 8 bits */
+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
+};
+
+/* lookup table for scaling 6 bit colors up to 8 bits */
+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,
+ 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
+};
+
+
+
+/*
+ * colors
+ */
+int dv_color15 (const unsigned char rgba[])
+{
+ return ((rgba[0]>>3)<<10)|((rgba[1]>>3)<<5)|(rgba[2]>>3);
+}
+int dv_color16 (const unsigned char rgba[])
+{
+ return ((rgba[0]>>3)<<11)|((rgba[1]>>2)<<5)|(rgba[2]>>3);
+}
+int dv_color32 (const unsigned char rgba[])
+{
+ return (rgba[0]<<16)|(rgba[1]<<8)|(rgba[2]);
+}
+
+
+
+/*
+ * getpixel + decompose
+ */
+void dv_getrgba15 (void *buffer, int offset, unsigned char rgba[4])
+{
+ int c = ((word16 *)buffer)[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;
+}
+void dv_getrgba16 (void *buffer, int offset, unsigned char rgba[4])
+{
+ int c = ((word16 *)buffer)[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;
+}
+void dv_getrgba24 (void *buffer, int offset, unsigned char rgba[4])
+{
+ int c = *(word32 *)(buffer+offset*3);
+ rgba[0] = c >> 16;
+ rgba[1] = c >> 8;
+ rgba[2] = c;
+ rgba[3] = 255;
+}
+void dv_getrgba32 (void *buffer, int offset, unsigned char rgba[4])
+{
+ int c = ((word32 *)buffer)[offset];
+ rgba[0] = c >> 16;
+ rgba[1] = c >> 8;
+ rgba[2] = c;
+ rgba[3] = 255;
+}
+
+
+
+/*
+ * request mapping from DPMI
+ */
+static word32 _map_linear (word32 phys, word32 len)
+{
+ __dpmi_meminfo meminfo;
+
+ if (phys >= 0x100000) {
+ /* map into linear memory */
+ meminfo.address = (long)phys;
+ meminfo.size = len;
+ if (__dpmi_physical_address_mapping(&meminfo)) {
+ return 0;
+ }
+ return meminfo.address;
+ } else {
+ /* exploit 1 -> 1 physical to linear mapping in low megabyte */
+ return phys;
+ }
+}
+
+
+
+/*
+ * attempts to detect VESA and video modes
+ */
+static word16 dv_get_vesa (void)
+{
+ __dpmi_regs r;
+ unsigned short *p;
+ dvmode *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);
+ if (r.x.ax==0x004f) {
+ movedata(_stubinfo->ds_selector, 0, _my_ds(), (unsigned)vesa_info, 512);
+ if ((_32_ vesa_info[0])==0x41534556) {
+ p = (unsigned short *)(((_16_ vesa_info[0x10])<<4) + (_16_ vesa_info[0x0e]));
+ 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[0x19]) {
+ case 16:
+ q->bpp = tmp[0x1f] + tmp[0x21] + tmp[0x23];
+ break;
+ case 15:
+ case 24:
+ case 32:
+ q->bpp = tmp[0x19];
+ break;
+ default:
+ q->bpp = 0;
+ }
+ if ((r.x.ax==0x004f)&&((tmp[0]&0x11)==0x11)&&q->bpp) {
+ q->xres = _16_ tmp[0x12];
+ q->yres = _16_ tmp[0x14];
+ q->scanlen = _16_ tmp[0x10];
+ q->opaque = (_16_ tmp[4])<<10;
+ if (tmp[0]&0x80) {
+ *(q+1) = *q++;
+ q->opaque = _32_ tmp[0x28];
+ q->mode |= 0x4000;
+ }
+ q++;
+ }
+ } while (!0);
+
+ return _16_ vesa_info[4];
+ }
+ }
+
+ return 0;
+}
+
+
+
+/*
+ * select a mode
+ */
+dvmode *dv_select_mode (int x, int y, int width, int height, int depth, int *delta, int *offset)
+{
+ dvmode *p, *q;
+ unsigned int min;
+
+ if ((width&3)||(height&3)||(depth<=8)) {
+ return NULL;
+ }
+
+ if (!init) {
+ init = !init;
+ if (!dv_get_vesa()) {
+ return NULL;
+ }
+ }
+
+ for (min=-1, p=NULL, q=modes; q->mode!=0xffff; q++) {
+ if ((q->xres>=(x+width))&&(q->yres>=(y+height))&&(q->bpp==depth)) {
+ if (min>(unsigned)(q->xres*q->yres)) {
+ min = q->xres*q->yres;
+ p = q;
+ }
+ }
+ }
+
+ if (p) {
+ int sel = -1;
+ unsigned base, limit;
+
+ if ((p->mode|0x4000)==(p+1)->mode) {
+ p++;
+ }
+
+ if (selector==-1) {
+ if ((selector=sel=__dpmi_allocate_ldt_descriptors(1))==-1) {
+ return NULL;
+ }
+ }
+ if (p->mode&0x4000) {
+ limit = ((p->scanlen*p->yres+0xfffUL)&~0xfffUL) - 1;
+ if ((base=_map_linear(p->opaque, limit))==NULL) {
+ if (sel!=-1) {
+ selector = -1;
+ __dpmi_free_ldt_descriptor(sel);
+ }
+ return NULL;
+ }
+ dv_dump_virtual = dv_dump_virtual_linear;
+ } else {
+ limit = granularity = p->opaque;
+ base = 0xa0000;
+ dv_dump_virtual = dv_dump_virtual_banked;
+ }
+ __dpmi_set_segment_base_address(selector, base);
+ __dpmi_set_descriptor_access_rights(selector, ((_my_ds()&3)<<5)|0x4092);
+ __dpmi_set_segment_limit(selector, limit);
+
+ switch (p->bpp) {
+ case 15:
+ dv_clear_virtual = dv_clear_virtual16;
+ dv_putpixel = dv_putpixel16;
+ dv_color = dv_color15;
+ break;
+ case 16:
+ dv_clear_virtual = dv_clear_virtual16;
+ dv_putpixel = dv_putpixel16;
+ dv_color = dv_color16;
+ break;
+ case 24:
+ dv_clear_virtual = dv_clear_virtual24;
+ dv_putpixel = dv_putpixel24;
+ dv_color = dv_color32;
+ break;
+ case 32:
+ dv_clear_virtual = dv_clear_virtual32;
+ dv_putpixel = dv_putpixel32;
+ dv_color = dv_color32;
+ break;
+ default:
+ dv_clear_virtual = NULL;
+ dv_putpixel = NULL;
+ }
+
+ *delta = p->scanlen - ((depth+7)/8) * width;
+ *offset = p->scanlen*y + ((depth+7)/8) * x;
+
+ __asm__("movw $0x4f02, %%ax; int $0x10"::"b"(p->mode):"%eax");
+ }
+
+ return p;
+}
+
+
+
+/*
+ * fill rectangle
+ */
+void dv_fillrect (void *buffer, int bwidth, int x, int y, int width, int height, int color)
+{
+ int i, offset;
+
+ offset = y*bwidth + x;
+ bwidth -= width;
+ for (height+=y; y<height; y++) {
+ for (i=0; i<width; i++, offset++) {
+ dv_putpixel(buffer, offset, color);
+ }
+ offset += bwidth;
+ }
+}
+
+
+
+/*
+ * dv_dump_virtual_linear
+ */
+__asm__("\n\
+ .balign 4 \n\
+ .global _dv_dump_virtual_linear \n\
+_dv_dump_virtual_linear: \n\
+ pushl %fs \n\
+ pushl %ebx \n\
+ pushl %esi \n\
+ pushl %edi \n\
+ movl _selector, %fs \n\
+ movl 4*4+4+0(%esp), %esi \n\
+ movl 4*4+4+12(%esp), %edi \n\
+ movl 4*4+4+4(%esp), %ecx \n\
+ movl 4*4+4+8(%esp), %edx \n\
+ movl 4*4+4+16(%esp), %ebx \n\
+ shrl $2, %ecx \n\
+ .balign 4 \n\
+ 0: \n\
+ pushl %ecx \n\
+ .balign 4 \n\
+ 1: \n\
+ movl (%esi), %eax \n\
+ addl $4, %esi \n\
+ movl %eax, %fs:(%edi) \n\
+ addl $4, %edi \n\
+ decl %ecx \n\
+ jnz 1b \n\
+ popl %ecx \n\
+ addl %ebx, %edi \n\
+ decl %edx \n\
+ jnz 0b \n\
+ popl %edi \n\
+ popl %esi \n\
+ popl %ebx \n\
+ popl %fs \n\
+ ret");
+/*
+ * dv_dump_virtual_banked
+ */
+__asm__("\n\
+ .balign 4 \n\
+ .global _dv_dump_virtual_banked \n\
+_dv_dump_virtual_banked: \n\
+ pushl %fs \n\
+ pushl %ebx \n\
+ pushl %esi \n\
+ pushl %edi \n\
+ pushl %ebp \n\
+ movl _selector, %fs \n\
+ movl 4*5+4+0(%esp), %esi \n\
+ movl _granularity, %ebp \n\
+ xorl %edx, %edx \n\
+ movl 4*5+4+12(%esp), %eax \n\
+ divl %ebp \n\
+ movl %edx, %edi \n\
+ pushl %eax \n\
+ movl %eax, %edx \n\
+ xorl %ebx, %ebx \n\
+ movw $0x4f05, %ax \n\
+ int $0x10 \n\
+ movl 4*6+4+16(%esp), %ebx \n\
+ movl 4*6+4+4(%esp), %ecx \n\
+ movl 4*6+4+8(%esp), %edx \n\
+ shrl $2, %ecx \n\
+ .balign 4 \n\
+ 0: \n\
+ pushl %ecx \n\
+ .balign 4 \n\
+ 1: \n\
+ cmpl %ebp, %edi \n\
+ jb 2f \n\
+ pushl %ebx \n\
+ pushl %edx \n\
+ incl 12(%esp) \n\
+ movw $0x4f05, %ax \n\
+ movl 12(%esp), %edx \n\
+ xorl %ebx, %ebx \n\
+ int $0x10 \n\
+ popl %edx \n\
+ popl %ebx \n\
+ subl %ebp, %edi \n\
+ 2: \n\
+ movl (%esi), %eax \n\
+ addl $4, %esi \n\
+ movl %eax, %fs:(%edi) \n\
+ addl $4, %edi \n\
+ decl %ecx \n\
+ jnz 1b \n\
+ popl %ecx \n\
+ addl %ebx, %edi \n\
+ decl %edx \n\
+ jnz 0b \n\
+ popl %eax \n\
+ popl %ebp \n\
+ popl %edi \n\
+ popl %esi \n\
+ popl %ebx \n\
+ popl %fs \n\
+ ret");
+
+
+
+/*
+ * dv_clear_virtual??
+ */
+__asm__("\n\
+ .balign 4 \n\
+ .global _dv_clear_virtual16 \n\
+_dv_clear_virtual16: \n\
+ movl 12(%esp), %eax \n\
+ pushw %ax \n\
+ pushw %ax \n\
+ popl %eax \n\
+ jmp _dv_clear_virtual_common\n\
+ .balign 4 \n\
+ .global _dv_clear_virtual32 \n\
+_dv_clear_virtual32: \n\
+ movl 12(%esp), %eax \n\
+ \n\
+ .balign 4 \n\
+ .global _dv_clear_virtual_common\n\
+_dv_clear_virtual_common: \n\
+ movl 8(%esp), %ecx \n\
+ movl 4(%esp), %edx \n\
+ shrl $2, %ecx \n\
+ .balign 4 \n\
+ 0: \n\
+ movl %eax, (%edx) \n\
+ addl $4, %edx \n\
+ decl %ecx \n\
+ jnz 0b \n\
+ ret");
+__asm__("\n\
+ .balign 4 \n\
+ .global _dv_clear_virtual24 \n\
+_dv_clear_virtual24: \n\
+ movl 8(%esp), %edx \n\
+ movl $0xaaaaaaab, %eax \n\
+ mull %edx \n\
+ movl 12(%esp), %eax \n\
+ movl %edx, %ecx \n\
+ movl 4(%esp), %edx \n\
+ pushl %ebx \n\
+ shrl %ecx \n\
+ movb 18(%esp), %bl \n\
+ .balign 4 \n\
+ 0: \n\
+ movw %ax, (%edx) \n\
+ movb %bl, 2(%edx) \n\
+ addl $3, %edx \n\
+ decl %ecx \n\
+ jnz 0b \n\
+ popl %ebx \n\
+ ret");
+
+
+
+/*
+ * dv_putpixel??
+ */
+__asm__("\n\
+ .balign 4 \n\
+ .global _dv_putpixel16 \n\
+_dv_putpixel16: \n\
+ movl 8(%esp), %edx \n\
+ shll %edx \n\
+ movl 12(%esp), %eax \n\
+ addl 4(%esp), %edx \n\
+ movw %ax, (%edx) \n\
+ ret");
+__asm__("\n\
+ .balign 4 \n\
+ .global _dv_putpixel32 \n\
+_dv_putpixel32: \n\
+ movl 8(%esp), %edx \n\
+ shll $2, %edx \n\
+ movl 12(%esp), %eax \n\
+ addl 4(%esp), %edx \n\
+ movl %eax, (%edx) \n\
+ ret");
+__asm__("\n\
+ .global _dv_putpixel24 \n\
+_dv_putpixel24: \n\
+ movl 8(%esp), %edx \n\
+ leal (%edx, %edx, 2), %edx \n\
+ movl 12(%esp), %eax \n\
+ addl 4(%esp), %edx \n\
+ movw %ax, (%edx) \n\
+ shrl $16, %eax \n\
+ movb %al, 2(%edx) \n\
+ ret");
diff --git a/src/mesa/drivers/dos/dvesa.h b/src/mesa/drivers/dos/dvesa.h
new file mode 100644
index 00000000000..aaa4be7950f
--- /dev/null
+++ b/src/mesa/drivers/dos/dvesa.h
@@ -0,0 +1,127 @@
+/*
+ * Mesa 3-D graphics library
+ * Version: 4.0
+ *
+ * Copyright (C) 1999 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 v0.1 for Mesa 4.0
+ *
+ * Copyright (C) 2002 - Borca Daniel
+ * Email : [email protected]
+ * Web : http://www.geocities.com/dborca
+ */
+
+
+#ifndef DVESA_H_included
+#define DVESA_H_included
+
+typedef unsigned char word8;
+typedef unsigned short word16;
+typedef unsigned long word32;
+
+struct dvmode;
+
+extern int (*dv_color) (const unsigned char rgba[]);
+extern void (*dv_dump_virtual) (void *buffer, int width, int height, int offset, int delta);
+extern void (*dv_clear_virtual) (void *buffer, int len, int color);
+
+struct dvmode *dv_select_mode (int x, int y, int width, int height, int depth, int *delta, int *offset);
+void dv_fillrect (void *buffer, int bwidth, int x, int y, int width, int height, int color);
+
+/*
+ * not so public...
+ */
+extern int _rgb_scale_5[32];
+extern int _rgb_scale_6[64];
+
+/*
+ * dv_putpixel inlines
+ */
+#define dv_putpixel15 dv_putpixel16
+extern __inline__ void dv_putpixel16 (void *buffer, int offset, int color)
+{
+ ((word16 *)buffer)[offset] = (word16)color;
+}
+extern __inline__ void dv_putpixel24 (void *buffer, int offset, int color)
+{
+ *(word16 *)(buffer+offset*3) = (word16)color;
+ *(word8 *)(buffer+offset*3+2) = (word8)(color>>16);
+}
+extern __inline__ void dv_putpixel32 (void *buffer, int offset, int color)
+{
+ ((word32 *)buffer)[offset] = color;
+}
+
+/*
+ * dv_color inlines
+ */
+extern __inline__ int dv_color15 (const unsigned char rgba[])
+{
+ return ((rgba[0]>>3)<<10)|((rgba[1]>>3)<<5)|(rgba[2]>>3);
+}
+extern __inline__ int dv_color16 (const unsigned char rgba[])
+{
+ return ((rgba[0]>>3)<<11)|((rgba[1]>>2)<<5)|(rgba[2]>>3);
+}
+#define dv_color24 dv_color32
+extern __inline__ int dv_color32 (const unsigned char rgba[])
+{
+ return (rgba[0]<<16)|(rgba[1]<<8)|(rgba[2]);
+}
+
+/*
+ * dv_getrgba inlines
+ */
+extern __inline__ void dv_getrgba15 (void *buffer, int offset, unsigned char rgba[4])
+{
+ int c = ((word16 *)buffer)[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;
+}
+extern __inline__ void dv_getrgba16 (void *buffer, int offset, unsigned char rgba[4])
+{
+ int c = ((word16 *)buffer)[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;
+}
+extern __inline__ void dv_getrgba24 (void *buffer, int offset, unsigned char rgba[4])
+{
+ int c = *(word32 *)(buffer+offset*3);
+ rgba[0] = c >> 16;
+ rgba[1] = c >> 8;
+ rgba[2] = c;
+ rgba[3] = 255;
+}
+extern __inline__ void dv_getrgba32 (void *buffer, int offset, unsigned char rgba[4])
+{
+ int c = ((word32 *)buffer)[offset];
+ rgba[0] = c >> 16;
+ rgba[1] = c >> 8;
+ rgba[2] = c;
+ rgba[3] = 255;
+}
+
+#endif