From 60f84fcc91c5fb86843c528416399303da113a2f Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Thu, 20 Feb 2003 15:43:52 +0000 Subject: latest DOS updates (Daniel Borca) --- docs/README.DJ | 37 +- include/GL/dmesa.h | 29 +- progs/samples/Makefile.DJ | 10 +- src/glut/dos/glutint.h | 5 +- src/glut/dos/init.c | 13 +- src/glut/dos/mouse.c | 14 +- src/glut/dos/window.c | 18 +- src/mesa/drivers/dos/blit.S | 199 +++++ src/mesa/drivers/dos/dmesa.c | 746 ++++++++++++++--- src/mesa/drivers/dos/dpmi.c | 23 +- src/mesa/drivers/dos/internal.h | 8 +- src/mesa/drivers/dos/mga/m_ttemp.h | 377 +++++++++ src/mesa/drivers/dos/mga/m_ttemp2.h | 375 +++++++++ src/mesa/drivers/dos/mga/mga.c | 1536 +++++++++++++++++++++++++++++++++++ src/mesa/drivers/dos/mga/mga.h | 91 +++ src/mesa/drivers/dos/mga/mga_hw.c | 416 ++++++++++ src/mesa/drivers/dos/mga/mga_hw.h | 113 +++ src/mesa/drivers/dos/mga/mga_mode.c | 231 ++++++ src/mesa/drivers/dos/mga/mga_mode.h | 47 ++ src/mesa/drivers/dos/mga/mga_reg.h | 207 +++++ src/mesa/drivers/dos/vesa.c | 533 ++++++++++++ src/mesa/drivers/dos/vesa.h | 47 ++ src/mesa/drivers/dos/vesa/blit.S | 199 ----- src/mesa/drivers/dos/vesa/vesa.c | 521 ------------ src/mesa/drivers/dos/vesa/vesa.h | 47 -- src/mesa/drivers/dos/vga.c | 235 ++++++ src/mesa/drivers/dos/vga.h | 42 + src/mesa/drivers/dos/vga/vga.c | 225 ----- src/mesa/drivers/dos/vga/vga.h | 42 - src/mesa/drivers/dos/video.c | 66 +- src/mesa/drivers/dos/video.h | 8 +- src/mesa/drivers/dos/virtual.S | 6 +- src/mesa/main/Makefile.DJ | 59 +- 33 files changed, 5242 insertions(+), 1283 deletions(-) create mode 100644 src/mesa/drivers/dos/blit.S create mode 100644 src/mesa/drivers/dos/mga/m_ttemp.h create mode 100644 src/mesa/drivers/dos/mga/m_ttemp2.h create mode 100644 src/mesa/drivers/dos/mga/mga.c create mode 100644 src/mesa/drivers/dos/mga/mga.h create mode 100644 src/mesa/drivers/dos/mga/mga_hw.c create mode 100644 src/mesa/drivers/dos/mga/mga_hw.h create mode 100644 src/mesa/drivers/dos/mga/mga_mode.c create mode 100644 src/mesa/drivers/dos/mga/mga_mode.h create mode 100644 src/mesa/drivers/dos/mga/mga_reg.h create mode 100644 src/mesa/drivers/dos/vesa.c create mode 100644 src/mesa/drivers/dos/vesa.h delete mode 100644 src/mesa/drivers/dos/vesa/blit.S delete mode 100644 src/mesa/drivers/dos/vesa/vesa.c delete mode 100644 src/mesa/drivers/dos/vesa/vesa.h create mode 100644 src/mesa/drivers/dos/vga.c create mode 100644 src/mesa/drivers/dos/vga.h delete mode 100644 src/mesa/drivers/dos/vga/vga.c delete mode 100644 src/mesa/drivers/dos/vga/vga.h diff --git a/docs/README.DJ b/docs/README.DJ index 6589f52a2e..13167611ba 100644 --- a/docs/README.DJ +++ b/docs/README.DJ @@ -32,8 +32,9 @@ Available options: 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 @@ Available options: 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 @@ FAQ: 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 @@ FAQ: 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 @@ FAQ: 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 @@ v1.2 (nov-2002) * 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 16f6bff88c..2c0ef81abe 100644 --- a/include/GL/dmesa.h +++ b/include/GL/dmesa.h @@ -87,6 +87,11 @@ DMesaContext DMesaCreateContext (DMesaVisual visual, DMesaContext share); */ void DMesaDestroyContext (DMesaContext c); +/* + * Return a handle to the current context. + */ +DMesaContext DMesaGetCurrentContext (void); + /* @@ -101,21 +106,17 @@ DMesaBuffer DMesaCreateBuffer (DMesaVisual visual, */ 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 @@ void DMesaSetCI (int ndx, GLfloat red, GLfloat green, GLfloat blue); /* * 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 b5724f432a..3d679ebe7c 100644 --- a/progs/samples/Makefile.DJ +++ b/progs/samples/Makefile.DJ @@ -65,16 +65,12 @@ CFLAGS += -I$(TOP)/include 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 77a8322c44..bbabf0fdb2 100644 --- a/src/glut/dos/glutint.h +++ b/src/glut/dos/glutint.h @@ -105,6 +105,9 @@ extern GLboolean g_redisplay; 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 @@ extern void __glutFatalUsage(char *format,...); -#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 0f848f6f36..6c034ff5e2 100644 --- a/src/glut/dos/init.c +++ b/src/glut/dos/init.c @@ -38,6 +38,9 @@ GLboolean g_redisplay = GL_FALSE; 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 @@ void APIENTRY glutInit (int *argc, char **argv) } __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 @@ void APIENTRY glutMainLoop (void) { 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 c67f8093b1..d82f5e8a8c 100644 --- a/src/glut/dos/mouse.c +++ b/src/glut/dos/mouse.c @@ -39,19 +39,7 @@ int g_mouse_x = 0, g_mouse_y = 0; 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 a7a7d9ca59..cad4726936 100644 --- a/src/glut/dos/window.c +++ b/src/glut/dos/window.c @@ -27,12 +27,15 @@ */ +#include + #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 @@ static void clean (void) 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 @@ void APIENTRY glutSwapBuffers (void) } 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/blit.S b/src/mesa/drivers/dos/blit.S new file mode 100644 index 0000000000..3598614c9f --- /dev/null +++ b/src/mesa/drivers/dos/blit.S @@ -0,0 +1,199 @@ +/* + * 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 v1.3 for Mesa 5.0 + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + + .file "blit.S" + +/* + * extern unsigned int vesa_gran_mask, vesa_gran_shift; + * extern int vl_video_selector; + + * extern void *vl_current_draw_buffer; + * extern int vl_current_stride, vl_current_height; + * extern int vl_current_offset, vl_current_delta; + */ + + .text + +/* Desc: VESA bank switching routine (BIOS) + * + * In : EBX=0, EDX = bank number + * Out : - + * + * Note: thrashes EAX + */ + .p2align 5,,31 +_vesa_swbankBIOS: + movw $0x4f05, %ax + int $0x10 + ret + + .p2align 2,,3 + .global _vesa_swbank +_vesa_swbank: .long _vesa_swbankBIOS + +/* Desc: void vesa_b_dump_virtual (void); + * + * In : - + * Out : - + * + * Note: uses current draw buffer + */ + .p2align 5,,31 + .global _vesa_b_dump_virtual +_vesa_b_dump_virtual: + cld + pushl %es + pushl %ebx + pushl %esi + pushl %edi + pushl %ebp + movl _vl_video_selector, %es + movl _vl_current_draw_buffer, %esi + movl _vl_current_offset, %edi + movl _vesa_gran_shift, %ecx + movl _vesa_gran_mask, %ebp + movl %edi, %edx + xorl %ebx, %ebx + andl %ebp, %edi + shrl %cl, %edx + incl %ebp + call *_vesa_swbank + movl _vl_current_stride, %ecx + movl _vl_current_height, %eax + movl _vl_current_delta, %ebx + shrl $2, %ecx + .balign 4 + 0: + pushl %ecx + .balign 4 + 1: + cmpl %ebp, %edi + jb 2f + pushl %eax + pushl %ebx + incl %edx + xorl %ebx, %ebx + call *_vesa_swbank + popl %ebx + popl %eax + subl %ebp, %edi + .balign 4 + 2: + movsl + decl %ecx + jnz 1b + popl %ecx + addl %ebx, %edi + decl %eax + jnz 0b + popl %ebp + popl %edi + popl %esi + popl %ebx + popl %es + ret + +/* Desc: void vesa_l_dump_virtual (void); + * + * In : - + * Out : - + * + * Note: uses current draw buffer + */ + .p2align 5,,31 + .global _vesa_l_dump_virtual +_vesa_l_dump_virtual: + cld + pushl %es + pushl %esi + pushl %edi + movl _vl_video_selector, %es + movl _vl_current_draw_buffer, %esi + movl _vl_current_offset, %edi + movl _vl_current_stride, %ecx + movl _vl_current_height, %edx + movl _vl_current_delta, %eax + shrl $2, %ecx + .balign 4 + 0: + pushl %ecx + rep; movsl + popl %ecx + addl %eax, %edi + decl %edx + jnz 0b + popl %edi + popl %esi + popl %es + ret + +/* Desc: void vesa_l_dump_virtual_mmx (void); + * + * In : - + * Out : - + * + * Note: uses current draw buffer + */ + .p2align 5,,31 + .global _vesa_l_dump_virtual_mmx +_vesa_l_dump_virtual_mmx: +#ifdef USE_MMX_ASM + pushl %esi + pushl %edi + movl _vl_video_selector, %fs + movl _vl_current_draw_buffer, %esi + movl _vl_current_offset, %edi + movl _vl_current_stride, %ecx + movl _vl_current_height, %edx + movl _vl_current_delta, %eax + shrl $3, %ecx + .balign 4 + 0: + pushl %ecx + .balign 4 + 1: + movq (%esi), %mm0 + addl $8, %esi + movq %mm0, %fs:(%edi) + addl $8, %edi + decl %ecx + jnz 1b + popl %ecx + addl %eax, %edi + decl %edx + jnz 0b + popl %edi + popl %esi + emms +#endif + ret diff --git a/src/mesa/drivers/dos/dmesa.c b/src/mesa/drivers/dos/dmesa.c index ec9f3b2224..a72973832a 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 @@ struct dmesa_visual { 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 @@ struct dmesa_context { /**************************************************************************** * 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 @@ struct dmesa_context { 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; iDriverCtx; + 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; iDriverCtx; + 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; iDriverCtx; + 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; iDriverCtx; - 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; iDriverCtx; - 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; iDriverCtx; - 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; iDriverCtx; + 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; iDriverCtx; + 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; iDriverCtx; + 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; iDriverCtx; + 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; iDriverCtx; - 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; iDriverCtx; - 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; iDriverCtx; - 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; iDriverCtx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + if (mask) { + /* draw some values */ + for (i=0; iDriverCtx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + /* read all values */ + for (i=0; iDriverCtx; + GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1; + + if (mask) { + /* draw some values */ + for (i=0; iDriverCtx; + GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1; + + /* read all values */ + for (i=0; iDriverCtx; - 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 @@ static void tri_rgb_smooth (GLcontext *ctx, } #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 @@ static void tri_rgb_smooth_z (GLcontext *ctx, } #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 @@ static swrast_tri_func dmesa_choose_tri_function (GLcontext *ctx) || (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 @@ static swrast_tri_func dmesa_choose_tri_function (GLcontext *ctx) && 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; @@ -600,26 +798,211 @@ static void dmesa_choose_tri (GLcontext *ctx) +/**************************************************************************** + * 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 @@ static void clear (GLcontext *ctx, GLbitfield mask, GLboolean all, /* 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 @@ static void clear (GLcontext *ctx, GLbitfield mask, GLboolean all, 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 @@ static const GLubyte* get_string (GLcontext *ctx, GLenum name) { 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 @@ static void flush (GLcontext *ctx) /**************************************************************************** * 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 @@ static void dmesa_register_swrast_functions (GLcontext *ctx) { 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 @@ static void dmesa_init_pointers (GLcontext *ctx) /* 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 @@ static void dmesa_update_state (GLcontext *ctx, GLuint new_state) 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 @@ static void dmesa_update_state (GLcontext *ctx, GLuint new_state) 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 DMesaCreateVisual (GLint width, 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 @@ DMesaVisual DMesaCreateVisual (GLint width, } } +#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 @@ DMesaVisual DMesaCreateVisual (GLint width, 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 @@ DMesaVisual DMesaCreateVisual (GLint width, fx_attrib[i] = FXMESA_NONE; return (DMesaVisual)fxMesaCreateBestContext(-1, width, height, fx_attrib); -#endif +#endif /* FX */ } @@ -969,7 +1423,12 @@ void DMesaDestroyVisual (DMesaVisual v) _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 @@ DMesaBuffer DMesaCreateBuffer (DMesaVisual visual, _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 @@ DMesaBuffer DMesaCreateBuffer (DMesaVisual visual, 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 @@ DMesaContext DMesaCreateContext (DMesaVisual visual, return c; -#else - +#else /* FX */ return (DMesaContext)visual; -#endif +#endif /* FX */ } @@ -1076,7 +1536,7 @@ void DMesaDestroyContext (DMesaContext c) 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 @@ GLboolean DMesaMoveBuffer (GLint xpos, GLint ypos) } #else - return GL_FALSE; #endif } @@ -1098,7 +1557,7 @@ GLboolean DMesaMoveBuffer (GLint xpos, GLint ypos) 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 @@ GLboolean DMesaResizeBuffer (GLint width, GLint height) } #else - return GL_FALSE; #endif } @@ -1125,9 +1583,11 @@ GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b) { #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 @@ GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b) } #else - fxMesaMakeCurrent((fxMesaContext)c); #endif @@ -1157,7 +1616,13 @@ void DMesaSwapBuffers (DMesaBuffer b) #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 DMesaSwapBuffers (DMesaBuffer b) 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 @@ void DMesaGetIntegerv (GLenum pname, GLint *params) #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(¶ms[0], ¶ms[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 882cda390a..db6a306339 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 @@ static int _create_linear_mapping (unsigned long *linear, unsigned long physaddr /* _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 @@ void _remove_selector (int *segment) *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 824d963d36..304a7377ba 100644 --- a/src/mesa/drivers/dos/internal.h +++ b/src/mesa/drivers/dos/internal.h @@ -79,9 +79,9 @@ typedef struct { 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 @@ typedef struct { /* * 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 0000000000..d3de69a825 --- /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 0000000000..27a1c8ba03 --- /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 0000000000..59bb09c9d3 --- /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 +#include +#include + +#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 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 +#include +#include +#include +#include +#include + +#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> 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 0000000000..246ed9c6ad --- /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 + +#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 0000000000..33f47a6486 --- /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 +#include +#include +#include +#include +#include +#include + +#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/mga/mga_mode.h b/src/mesa/drivers/dos/mga/mga_mode.h new file mode 100644 index 0000000000..4049bd8fd2 --- /dev/null +++ b/src/mesa/drivers/dos/mga/mga_mode.h @@ -0,0 +1,47 @@ +/* + * 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 + */ + + +#ifndef MGA_MODE_included +#define MGA_MODE_included + +typedef struct MGA_MODE { + int mode; + int xres, yres; + int bpp; +} MGA_MODE; + +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 0000000000..73d22de2b8 --- /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.c b/src/mesa/drivers/dos/vesa.c new file mode 100644 index 0000000000..eebaa5006b --- /dev/null +++ b/src/mesa/drivers/dos/vesa.c @@ -0,0 +1,533 @@ +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * 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 v1.3 for Mesa 5.0 + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "video.h" +#include "vesa.h" + + + +static vl_mode modes[128]; + +static word16 vesa_ver; +static int banked_selector, linear_selector; +static int oldmode = -1; + +static int vesa_color_precision = 6; + +static word16 *vesa_pmcode; +unsigned int vesa_gran_mask, vesa_gran_shift; + + + +/* + * 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 + +/* + * VESA 3.0 CRTC timings structure + */ +typedef struct CRTCInfoBlock { + unsigned short HorizontalTotal; + unsigned short HorizontalSyncStart; + unsigned short HorizontalSyncEnd; + unsigned short VerticalTotal; + unsigned short VerticalSyncStart; + unsigned short VerticalSyncEnd; + unsigned char Flags; + unsigned long PixelClock; /* units of Hz */ + unsigned short RefreshRate; /* units of 0.01 Hz */ + unsigned char reserved[40]; +} __PACKED__ CRTCInfoBlock; + +#define HNEG (1 << 2) +#define VNEG (1 << 3) +#define DOUBLESCAN (1 << 0) + + + +/* Desc: Attempts to detect VESA, check video modes and create selectors. + * + * In : - + * Out : mode array + * + * Note: - + */ +static vl_mode *vesa_init (void) +{ + __dpmi_regs r; + word16 *p; + vl_mode *q; + char vesa_info[512], tmp[512]; + int maxsize = 0; + word32 linearfb = 0; + + if (vesa_ver) { + return modes; + } + + _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) { + q->xres = _16_ tmp[M_XRES]; + q->yres = _16_ tmp[M_YRES]; + q->scanlen = _16_ tmp[M_SCANLEN]; + q->gran = (_16_ tmp[M_GRAN])<<10; + if (tmp[M_ATTR]&0x80) { +#if 0 + *(q+1) = *q++; +#else + vl_mode *q1 = q + 1; + *q1 = *q++; +#endif + linearfb = _32_ tmp[M_PHYS_PTR]; + q->mode |= 0x4000; + } + if (maxsize<(q->scanlen*q->yres)) { + maxsize = q->scanlen*q->yres; + } + q++; + } + } while (TRUE); + + if (q==modes) { + return NULL; + } + if (linearfb) { + maxsize = ((maxsize+0xfffUL)&~0xfffUL); + if (_create_selector(&linear_selector, linearfb, maxsize)) { + return NULL; + } + } + if (_create_selector(&banked_selector, 0xa0000, modes[0].gran)) { + _remove_selector(&linear_selector); + return NULL; + } + + for (q=modes; q->mode!=0xffff; q++) { + q->sel = (q->mode&0x4000) ? linear_selector : banked_selector; + } + + if (vesa_info[V_MAJOR] >= 2) { + r.x.ax = 0x4f0a; + r.x.bx = 0; + __dpmi_int(0x10, &r); + if (r.x.ax == 0x004f) { + 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); + 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 = (void *)((long)vesa_pmcode + vesa_pmcode[0]); + } + } + } + + vesa_ver = _16_ vesa_info[V_MINOR]; + return modes; +} + + + +/* Desc: Frees all resources allocated by VESA init code. + * + * In : - + * Out : - + * + * Note: - + */ +static void vesa_fini (void) +{ + if (vesa_ver) { + _remove_selector(&linear_selector); + _remove_selector(&banked_selector); + if (vesa_pmcode != NULL) { + free(vesa_pmcode); + vesa_pmcode = NULL; + } + } +} + + + +/* Desc: Uses VESA 3.0 function 0x4F0B to find the closest pixel clock to the requested value. + * + * In : mode, clock + * Out : desired clock + * + * Note: - + */ +static unsigned long _closest_pixclk (int mode_no, unsigned long vclk) +{ + __dpmi_regs r; + + r.x.ax = 0x4F0B; + r.h.bl = 0; + r.d.ecx = vclk; + r.x.dx = mode_no; + __dpmi_int(0x10, &r); + + return (r.x.ax==0x004f) ? r.d.ecx : 0; +} + + + +/* Desc: Calculates CRTC mode timings. + * + * In : crtc block, geometry, adjust + * Out : + * + * Note: + */ +static void _crtc_timing (CRTCInfoBlock *crtc, int xres, int yres, int xadjust, int yadjust) +{ + int HTotal, VTotal; + int HDisp, VDisp; + int HSS, VSS; + int HSE, VSE; + int HSWidth, VSWidth; + int SS, SE; + int doublescan = FALSE; + + if (yres < 400) { + doublescan = TRUE; + yres *= 2; + } + + HDisp = xres; + HTotal = (int)(HDisp * 1.27) & ~0x7; + HSWidth = (int)((HTotal - HDisp) / 5) & ~0x7; + HSS = HDisp + 16; + HSE = HSS + HSWidth; + VDisp = yres; + VTotal = VDisp * 1.07; + VSWidth = (VTotal / 100) + 1; + VSS = VDisp + ((int)(VTotal - VDisp) / 5) + 1; + VSE = VSS + VSWidth; + + SS = HSS + xadjust; + SE = HSE + xadjust; + + if (xadjust < 0) { + if (SS < (HDisp + 8)) { + SS = HDisp + 8; + SE = SS + HSWidth; + } + } else { + if ((HTotal - 24) < SE) { + SE = HTotal - 24; + SS = SE - HSWidth; + } + } + + HSS = SS; + HSE = SE; + + SS = VSS + yadjust; + SE = VSE + yadjust; + + if (yadjust < 0) { + if (SS < (VDisp + 3)) { + SS = VDisp + 3; + SE = SS + VSWidth; + } + } else { + if ((VTotal - 4) < SE) { + SE = VTotal - 4; + SS = SE - VSWidth; + } + } + + VSS = SS; + VSE = SE; + + crtc->HorizontalTotal = HTotal; + crtc->HorizontalSyncStart = HSS; + crtc->HorizontalSyncEnd = HSE; + crtc->VerticalTotal = VTotal; + crtc->VerticalSyncStart = VSS; + crtc->VerticalSyncEnd = VSE; + crtc->Flags = HNEG | VNEG; + + if (doublescan) + crtc->Flags |= DOUBLESCAN; +} + + + +/* Desc: Attempts to enter specified video mode. + * + * In : ptr to mode structure, refresh rate + * Out : 0 if success + * + * Note: - + */ +static int vesa_entermode (vl_mode *p, int refresh) +{ + __dpmi_regs r; + + if (p->mode & 0x4000) { + 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) ; } + vesa_gran_mask = (1<<(--vesa_gran_shift)) - 1; + if ((unsigned)p->gran != (vesa_gran_mask+1)) { + return !0; + } + } + + if (oldmode == -1) { + r.x.ax = 0x4f03; + __dpmi_int(0x10, &r); + oldmode = r.x.bx; + } + + r.x.ax = 0x4f02; + r.x.bx = p->mode; + + if (refresh && ((vesa_ver>>8) >= 3)) { + /* VESA 3.0 stuff for controlling the refresh rate */ + CRTCInfoBlock crtc; + unsigned long vclk; + double f0; + + _crtc_timing(&crtc, p->xres, p->yres, 0, 0); + + vclk = (double)crtc.HorizontalTotal * crtc.VerticalTotal * refresh; + vclk = _closest_pixclk(p->mode, vclk); + + if (vclk != 0) { + f0 = (double)vclk / (crtc.HorizontalTotal * crtc.VerticalTotal); + /*_current_refresh_rate = (int)(f0 + 0.5);*/ + + crtc.PixelClock = vclk; + crtc.RefreshRate = refresh * 100; + + movedata(_my_ds(), (unsigned)&crtc, _stubinfo->ds_selector, 0, sizeof(crtc)); + + r.x.di = 0; + r.x.es = _stubinfo->ds_segment; + r.x.bx |= 0x0800; + } + } + + __dpmi_int(0x10, &r); + if (r.x.ax != 0x004f) { + return !0; + } + + if (p->bpp == 8) { + r.x.ax = 0x4f08; + r.x.bx = 0x0800; + __dpmi_int(0x10, &r); + if (r.x.ax == 0x004f) { + r.x.ax = 0x4f08; + r.h.bl = 0x01; + __dpmi_int(0x10, &r); + vesa_color_precision = r.h.bh; + } + } + + return 0; +} + + + +/* Desc: Restores to the mode prior to first call to vesa_entermode. + * + * In : - + * Out : - + * + * Note: - + */ +static void vesa_restore (void) +{ + __dpmi_regs r; + + if (oldmode != -1) { + r.x.ax = 0x4f02; + r.x.bx = oldmode; + __dpmi_int(0x10, &r); + } +} + + + +/* Desc: set one palette entry + * + * In : color index, R, G, B + * Out : - + * + * Note: uses integer values + */ +static void vesa_setCI_i (int index, int red, int green, int blue) +{ +#if 0 + __asm("\n\ + movw $0x1010, %%ax \n\ + movb %1, %%dh \n\ + movb %2, %%ch \n\ + int $0x10 \n\ + "::"b"(index), "m"(red), "m"(green), "c"(blue):"%eax", "%edx"); +#else + outportb(0x03C8, index); + outportb(0x03C9, red); + outportb(0x03C9, green); + outportb(0x03C9, blue); +#endif +} + + + +/* Desc: set one palette entry + * + * In : color index, R, G, B + * Out : - + * + * Note: uses normalized values + */ +static void vesa_setCI_f (int index, float red, float green, float blue) +{ + float max = (1 << vesa_color_precision) - 1; + + vesa_setCI_i(index, (int)(red * max), (int)(green * max), (int)(blue * max)); +} + + + +/* Desc: state retrieval + * + * In : parameter name, ptr to storage + * Out : 0 if request successfully processed + * + * Note: - + */ +static int vesa_get (int pname, int *params) +{ + switch (pname) { + case VL_GET_CI_PREC: + params[0] = vesa_color_precision; + break; + default: + return -1; + } + return 0; +} + + + +/* + * the driver + */ +vl_driver VESA = { + vesa_init, + vesa_entermode, + NULL, + vesa_setCI_f, + vesa_setCI_i, + vesa_get, + vesa_restore, + vesa_fini +}; diff --git a/src/mesa/drivers/dos/vesa.h b/src/mesa/drivers/dos/vesa.h new file mode 100644 index 0000000000..369196f144 --- /dev/null +++ b/src/mesa/drivers/dos/vesa.h @@ -0,0 +1,47 @@ +/* + * 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 v1.3 for Mesa 5.0 + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#ifndef VESA_H_included +#define VESA_H_included + +#include "internal.h" + +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; + +#endif diff --git a/src/mesa/drivers/dos/vesa/blit.S b/src/mesa/drivers/dos/vesa/blit.S deleted file mode 100644 index 3598614c9f..0000000000 --- a/src/mesa/drivers/dos/vesa/blit.S +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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 v1.3 for Mesa 5.0 - * - * Copyright (C) 2002 - Borca Daniel - * Email : dborca@yahoo.com - * Web : http://www.geocities.com/dborca - */ - - - .file "blit.S" - -/* - * extern unsigned int vesa_gran_mask, vesa_gran_shift; - * extern int vl_video_selector; - - * extern void *vl_current_draw_buffer; - * extern int vl_current_stride, vl_current_height; - * extern int vl_current_offset, vl_current_delta; - */ - - .text - -/* Desc: VESA bank switching routine (BIOS) - * - * In : EBX=0, EDX = bank number - * Out : - - * - * Note: thrashes EAX - */ - .p2align 5,,31 -_vesa_swbankBIOS: - movw $0x4f05, %ax - int $0x10 - ret - - .p2align 2,,3 - .global _vesa_swbank -_vesa_swbank: .long _vesa_swbankBIOS - -/* Desc: void vesa_b_dump_virtual (void); - * - * In : - - * Out : - - * - * Note: uses current draw buffer - */ - .p2align 5,,31 - .global _vesa_b_dump_virtual -_vesa_b_dump_virtual: - cld - pushl %es - pushl %ebx - pushl %esi - pushl %edi - pushl %ebp - movl _vl_video_selector, %es - movl _vl_current_draw_buffer, %esi - movl _vl_current_offset, %edi - movl _vesa_gran_shift, %ecx - movl _vesa_gran_mask, %ebp - movl %edi, %edx - xorl %ebx, %ebx - andl %ebp, %edi - shrl %cl, %edx - incl %ebp - call *_vesa_swbank - movl _vl_current_stride, %ecx - movl _vl_current_height, %eax - movl _vl_current_delta, %ebx - shrl $2, %ecx - .balign 4 - 0: - pushl %ecx - .balign 4 - 1: - cmpl %ebp, %edi - jb 2f - pushl %eax - pushl %ebx - incl %edx - xorl %ebx, %ebx - call *_vesa_swbank - popl %ebx - popl %eax - subl %ebp, %edi - .balign 4 - 2: - movsl - decl %ecx - jnz 1b - popl %ecx - addl %ebx, %edi - decl %eax - jnz 0b - popl %ebp - popl %edi - popl %esi - popl %ebx - popl %es - ret - -/* Desc: void vesa_l_dump_virtual (void); - * - * In : - - * Out : - - * - * Note: uses current draw buffer - */ - .p2align 5,,31 - .global _vesa_l_dump_virtual -_vesa_l_dump_virtual: - cld - pushl %es - pushl %esi - pushl %edi - movl _vl_video_selector, %es - movl _vl_current_draw_buffer, %esi - movl _vl_current_offset, %edi - movl _vl_current_stride, %ecx - movl _vl_current_height, %edx - movl _vl_current_delta, %eax - shrl $2, %ecx - .balign 4 - 0: - pushl %ecx - rep; movsl - popl %ecx - addl %eax, %edi - decl %edx - jnz 0b - popl %edi - popl %esi - popl %es - ret - -/* Desc: void vesa_l_dump_virtual_mmx (void); - * - * In : - - * Out : - - * - * Note: uses current draw buffer - */ - .p2align 5,,31 - .global _vesa_l_dump_virtual_mmx -_vesa_l_dump_virtual_mmx: -#ifdef USE_MMX_ASM - pushl %esi - pushl %edi - movl _vl_video_selector, %fs - movl _vl_current_draw_buffer, %esi - movl _vl_current_offset, %edi - movl _vl_current_stride, %ecx - movl _vl_current_height, %edx - movl _vl_current_delta, %eax - shrl $3, %ecx - .balign 4 - 0: - pushl %ecx - .balign 4 - 1: - movq (%esi), %mm0 - addl $8, %esi - movq %mm0, %fs:(%edi) - addl $8, %edi - decl %ecx - jnz 1b - popl %ecx - addl %eax, %edi - decl %edx - jnz 0b - popl %edi - popl %esi - emms -#endif - ret diff --git a/src/mesa/drivers/dos/vesa/vesa.c b/src/mesa/drivers/dos/vesa/vesa.c deleted file mode 100644 index 1f3de844d7..0000000000 --- a/src/mesa/drivers/dos/vesa/vesa.c +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 4.1 - * - * 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 v1.3 for Mesa 5.0 - * - * Copyright (C) 2002 - Borca Daniel - * Email : dborca@yahoo.com - * Web : http://www.geocities.com/dborca - */ - - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "vesa.h" - - - -static vl_mode modes[64]; - -static word16 vesa_ver; -static int banked_selector, linear_selector; -static int oldmode = -1; - -static int vesa_color_precision = 6; - -static void *vesa_pmcode; -unsigned int vesa_gran_mask, vesa_gran_shift; - - - -/* - * 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 - -/* - * VESA 3.0 CRTC timings structure - */ -typedef struct CRTCInfoBlock { - unsigned short HorizontalTotal; - unsigned short HorizontalSyncStart; - unsigned short HorizontalSyncEnd; - unsigned short VerticalTotal; - unsigned short VerticalSyncStart; - unsigned short VerticalSyncEnd; - unsigned char Flags; - unsigned long PixelClock; /* units of Hz */ - unsigned short RefreshRate; /* units of 0.01 Hz */ - unsigned char reserved[40]; -} __PACKED__ CRTCInfoBlock; - -#define HNEG (1 << 2) -#define VNEG (1 << 3) -#define DOUBLESCAN (1 << 0) - - - -/* Desc: Attempts to detect VESA, check video modes and create selectors. - * - * In : - - * Out : mode array - * - * Note: - - */ -static vl_mode *vesa_init (void) -{ - __dpmi_regs r; - word16 *p; - vl_mode *q; - char vesa_info[512], tmp[512]; - int maxsize = 0; - word32 linearfb = 0; - - if (vesa_ver) { - return modes; - } - - _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) { - q->xres = _16_ tmp[M_XRES]; - q->yres = _16_ tmp[M_YRES]; - q->scanlen = _16_ tmp[M_SCANLEN]; - q->gran = (_16_ tmp[M_GRAN])<<10; - if (tmp[M_ATTR]&0x80) { -#if 0 - *(q+1) = *q++; -#else - vl_mode *q1 = q + 1; - *q1 = *q++; -#endif - linearfb = _32_ tmp[M_PHYS_PTR]; - q->mode |= 0x4000; - } - if (maxsize<(q->scanlen*q->yres)) { - maxsize = q->scanlen*q->yres; - } - q++; - } - } while (TRUE); - - if (q==modes) { - return NULL; - } - if (linearfb) { - maxsize = ((maxsize+0xfffUL)&~0xfffUL); - if (_create_selector(&linear_selector, linearfb, maxsize)) { - return NULL; - } - } - if (_create_selector(&banked_selector, 0xa0000, modes[0].gran)) { - _remove_selector(&linear_selector); - return NULL; - } - - for (q=modes; q->mode!=0xffff; q++) { - q->sel = (q->mode&0x4000) ? linear_selector : banked_selector; - } - - if (vesa_info[V_MAJOR] >= 2) { - r.x.ax = 0x4f0a; - r.h.bl = 0; - __dpmi_int(0x10, &r); - if (r.x.ax == 0x004f) { - vesa_pmcode = 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) { - free(vesa_pmcode); - vesa_pmcode = NULL; - } else { - vesa_swbank = (char *)vesa_pmcode + ((word16 *)vesa_pmcode)[0]; - } - } - } - - vesa_ver = _16_ vesa_info[V_MINOR]; - return modes; -} - - - -/* Desc: Frees all resources allocated by VESA init code. - * - * In : - - * Out : - - * - * Note: - - */ -static void vesa_finit (void) -{ - if (vesa_ver) { - _remove_selector(&linear_selector); - _remove_selector(&banked_selector); - if (vesa_pmcode != NULL) { - free(vesa_pmcode); - vesa_pmcode = NULL; - } - } -} - - - -/* Desc: Uses VESA 3.0 function 0x4F0B to find the closest pixel clock to the requested value. - * - * In : mode, clock - * Out : desired clock - * - * Note: - - */ -static unsigned long _closest_pixclk (int mode_no, unsigned long vclk) -{ - __dpmi_regs r; - - r.x.ax = 0x4F0B; - r.h.bl = 0; - r.d.ecx = vclk; - r.x.dx = mode_no; - __dpmi_int(0x10, &r); - - return (r.x.ax==0x004f) ? r.d.ecx : 0; -} - - - -/* Desc: Calculates CRTC mode timings. - * - * In : crtc block, geometry, adjust - * Out : - * - * Note: - */ -static void _crtc_timing (CRTCInfoBlock *crtc, int xres, int yres, int xadjust, int yadjust) -{ - int HTotal, VTotal; - int HDisp, VDisp; - int HSS, VSS; - int HSE, VSE; - int HSWidth, VSWidth; - int SS, SE; - int doublescan = FALSE; - - if (yres < 400) { - doublescan = TRUE; - yres *= 2; - } - - HDisp = xres; - HTotal = (int)(HDisp * 1.27) & ~0x7; - HSWidth = (int)((HTotal - HDisp) / 5) & ~0x7; - HSS = HDisp + 16; - HSE = HSS + HSWidth; - VDisp = yres; - VTotal = VDisp * 1.07; - VSWidth = (VTotal / 100) + 1; - VSS = VDisp + ((int)(VTotal - VDisp) / 5) + 1; - VSE = VSS + VSWidth; - - SS = HSS + xadjust; - SE = HSE + xadjust; - - if (xadjust < 0) { - if (SS < (HDisp + 8)) { - SS = HDisp + 8; - SE = SS + HSWidth; - } - } else { - if ((HTotal - 24) < SE) { - SE = HTotal - 24; - SS = SE - HSWidth; - } - } - - HSS = SS; - HSE = SE; - - SS = VSS + yadjust; - SE = VSE + yadjust; - - if (yadjust < 0) { - if (SS < (VDisp + 3)) { - SS = VDisp + 3; - SE = SS + VSWidth; - } - } else { - if ((VTotal - 4) < SE) { - SE = VTotal - 4; - SS = SE - VSWidth; - } - } - - VSS = SS; - VSE = SE; - - crtc->HorizontalTotal = HTotal; - crtc->HorizontalSyncStart = HSS; - crtc->HorizontalSyncEnd = HSE; - crtc->VerticalTotal = VTotal; - crtc->VerticalSyncStart = VSS; - crtc->VerticalSyncEnd = VSE; - crtc->Flags = HNEG | VNEG; - - if (doublescan) - crtc->Flags |= DOUBLESCAN; -} - - - -/* Desc: Attempts to enter specified video mode. - * - * In : ptr to mode structure, refresh rate - * Out : 0 if success - * - * Note: - - */ -static int vesa_entermode (vl_mode *p, int refresh) -{ - __dpmi_regs r; - - if (p->mode & 0x4000) { - VESA.blit = vl_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) ; } - vesa_gran_mask = (1<<(--vesa_gran_shift)) - 1; - if ((unsigned)p->gran != (vesa_gran_mask+1)) { - return !0; - } - } - - if (oldmode == -1) { - r.x.ax = 0x4f03; - __dpmi_int(0x10, &r); - oldmode = r.x.bx; - } - - r.x.ax = 0x4f02; - r.x.bx = p->mode; - - if (refresh && ((vesa_ver>>8) >= 3)) { - /* VESA 3.0 stuff for controlling the refresh rate */ - CRTCInfoBlock crtc; - unsigned long vclk; - double f0; - - _crtc_timing(&crtc, p->xres, p->yres, 0, 0); - - vclk = (double)crtc.HorizontalTotal * crtc.VerticalTotal * refresh; - vclk = _closest_pixclk(p->mode, vclk); - - if (vclk != 0) { - f0 = (double)vclk / (crtc.HorizontalTotal * crtc.VerticalTotal); - /*_current_refresh_rate = (int)(f0 + 0.5);*/ - - crtc.PixelClock = vclk; - crtc.RefreshRate = refresh * 100; - - movedata(_my_ds(), (unsigned)&crtc, _stubinfo->ds_selector, 0, sizeof(crtc)); - - r.x.di = 0; - r.x.es = _stubinfo->ds_segment; - r.x.bx |= 0x0800; - } - } - - __dpmi_int(0x10, &r); - if (r.x.ax != 0x004f) { - return !0; - } - - if (p->bpp == 8) { - r.x.ax = 0x4f08; - r.x.bx = 0x0800; - __dpmi_int(0x10, &r); - if (r.x.ax == 0x004f) { - r.x.ax = 0x4f08; - r.h.bl = 0x01; - __dpmi_int(0x10, &r); - vesa_color_precision = r.h.bh; - } - } - - return 0; -} - - - -/* Desc: Restores to the mode prior to first call to vesa_entermode. - * - * In : - - * Out : - - * - * Note: - - */ -static void vesa_restore (void) -{ - __dpmi_regs r; - - if (oldmode != -1) { - r.x.ax = 0x4f02; - r.x.bx = oldmode; - __dpmi_int(0x10, &r); - } -} - - - -/* Desc: set one palette entry - * - * In : color index, R, G, B - * Out : - - * - * Note: uses integer values - */ -static void vesa_setCI_i (int index, int red, int green, int blue) -{ -#if 0 - __asm("\n\ - movw $0x1010, %%ax \n\ - movb %1, %%dh \n\ - movb %2, %%ch \n\ - int $0x10 \n\ - "::"b"(index), "m"(red), "m"(green), "c"(blue):"%eax", "%edx"); -#else - outportb(0x03C8, index); - outportb(0x03C9, red); - outportb(0x03C9, green); - outportb(0x03C9, blue); -#endif -} - - - -/* Desc: set one palette entry - * - * In : color index, R, G, B - * Out : - - * - * Note: uses normalized values - */ -static void vesa_setCI_f (int index, float red, float green, float blue) -{ - float max = (1 << vesa_color_precision) - 1; - - vesa_setCI_i(index, (int)(red * max), (int)(green * max), (int)(blue * max)); -} - - - -/* Desc: retrieve CI precision - * - * In : - - * Out : precision in bits - * - * Note: - - */ -static int vesa_getCIprec (void) -{ - return vesa_color_precision; -} - - - -/* - * the driver - */ -vl_driver VESA = { - vesa_init, - vesa_entermode, - NULL, - vesa_setCI_f, - vesa_setCI_i, - vesa_getCIprec, - vesa_restore, - vesa_finit -}; diff --git a/src/mesa/drivers/dos/vesa/vesa.h b/src/mesa/drivers/dos/vesa/vesa.h deleted file mode 100644 index eb914e16c1..0000000000 --- a/src/mesa/drivers/dos/vesa/vesa.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * 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 v1.3 for Mesa 5.0 - * - * Copyright (C) 2002 - Borca Daniel - * Email : dborca@yahoo.com - * Web : http://www.geocities.com/dborca - */ - - -#ifndef VESA_H_included -#define VESA_H_included - -#include "../internal.h" - -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; - -#endif diff --git a/src/mesa/drivers/dos/vga.c b/src/mesa/drivers/dos/vga.c new file mode 100644 index 0000000000..ed89962840 --- /dev/null +++ b/src/mesa/drivers/dos/vga.c @@ -0,0 +1,235 @@ +/* + * Mesa 3-D graphics library + * Version: 4.1 + * + * 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 v1.3 for Mesa 5.0 + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#include +#include + +#include "video.h" +#include "vga.h" + + + +static vl_mode modes[] = { + {0x13 | 0x4000, 320, 200, 320, 8, -1, 320*200}, + {0xffff, -1, -1, -1, -1, -1, -1} +}; + +static word16 vga_ver; +static int linear_selector; +static int oldmode = -1; + +#define vga_color_precision 6 + + + +/* Desc: Attempts to detect VGA, check video modes and create selectors. + * + * In : - + * Out : mode array + * + * Note: - + */ +static vl_mode *vga_init (void) +{ + int rv = 0; + + if (vga_ver) { + return modes; + } + + __asm("\n\ + movw $0x1a00, %%ax \n\ + int $0x10 \n\ + cmpb $0x1a, %%al \n\ + jne 0f \n\ + cmpb $0x07, %%bl \n\ + jb 0f \n\ + andl $0xff, %%ebx \n\ + movl %%ebx, %0 \n\ + 0:":"=g"(rv)::"%eax", "%ebx"); + if (rv == 0) { + return NULL; + } + + if (_create_selector(&linear_selector, 0xa0000, 0x10000)) { + return NULL; + } + + modes[0].sel = linear_selector; + + vga_ver = rv; + return modes; +} + + + +/* Desc: Frees all resources allocated by VGA init code. + * + * In : - + * Out : - + * + * Note: - + */ +static void vga_fini (void) +{ + if (vga_ver) { + _remove_selector(&linear_selector); + } +} + + + +/* Desc: Attempts to enter specified video mode. + * + * In : ptr to mode structure, refresh rate + * Out : 0 if success + * + * Note: - + */ +static int vga_entermode (vl_mode *p, int refresh) +{ + if (!(p->mode & 0x4000)) { + return -1; + } + VGA.blit = _can_mmx() ? vesa_l_dump_virtual_mmx : vesa_l_dump_virtual; + + if (oldmode == -1) { + __asm("\n\ + movb $0x0f, %%ah \n\ + int $0x10 \n\ + andl $0xff, %%eax \n\ + movl %%eax, %0 \n\ + ":"=g"(oldmode)::"%eax", "%ebx"); + } + + __asm("int $0x10"::"a"(p->mode&0xff)); + + return 0; + + (void)refresh; /* silence compiler warning */ +} + + + +/* Desc: Restores to the mode prior to first call to vga_entermode. + * + * In : - + * Out : - + * + * Note: - + */ +static void vga_restore (void) +{ + if (oldmode != -1) { + __asm("int $0x10"::"a"(oldmode)); + } +} + + + +/* Desc: set one palette entry + * + * In : color index, R, G, B + * Out : - + * + * Note: uses integer values + */ +static void vga_setCI_i (int index, int red, int green, int blue) +{ +#if 0 + __asm("\n\ + movw $0x1010, %%ax \n\ + movb %1, %%dh \n\ + movb %2, %%ch \n\ + int $0x10 \n\ + "::"b"(index), "m"(red), "m"(green), "c"(blue):"%eax", "%edx"); +#else + outportb(0x03C8, index); + outportb(0x03C9, red); + outportb(0x03C9, green); + outportb(0x03C9, blue); +#endif +} + + + +/* Desc: set one palette entry + * + * In : color index, R, G, B + * Out : - + * + * Note: uses normalized values + */ +static void vga_setCI_f (int index, float red, float green, float blue) +{ + float max = (1 << vga_color_precision) - 1; + + vga_setCI_i(index, (int)(red * max), (int)(green * max), (int)(blue * max)); +} + + + +/* Desc: state retrieval + * + * In : parameter name, ptr to storage + * Out : 0 if request successfully processed + * + * Note: - + */ +static int vga_get (int pname, int *params) +{ + switch (pname) { + case VL_GET_CI_PREC: + params[0] = vga_color_precision; + break; + default: + return -1; + } + return 0; +} + + + +/* + * the driver + */ +vl_driver VGA = { + vga_init, + vga_entermode, + NULL, + vga_setCI_f, + vga_setCI_i, + vga_get, + vga_restore, + vga_fini +}; diff --git a/src/mesa/drivers/dos/vga.h b/src/mesa/drivers/dos/vga.h new file mode 100644 index 0000000000..d104794041 --- /dev/null +++ b/src/mesa/drivers/dos/vga.h @@ -0,0 +1,42 @@ +/* + * 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 v1.3 for Mesa 5.0 + * + * Copyright (C) 2002 - Borca Daniel + * Email : dborca@yahoo.com + * Web : http://www.geocities.com/dborca + */ + + +#ifndef VGA_H_included +#define VGA_H_included + +#include "internal.h" +#include "vesa.h" + +extern vl_driver VGA; + +#endif diff --git a/src/mesa/drivers/dos/vga/vga.c b/src/mesa/drivers/dos/vga/vga.c deleted file mode 100644 index d1d2db51b5..0000000000 --- a/src/mesa/drivers/dos/vga/vga.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * Mesa 3-D graphics library - * Version: 4.1 - * - * 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 v1.3 for Mesa 5.0 - * - * Copyright (C) 2002 - Borca Daniel - * Email : dborca@yahoo.com - * Web : http://www.geocities.com/dborca - */ - - -#include -#include - -#include "vga.h" - - - -static vl_mode modes[4] = { - {0x13 | 0x4000, 320, 200, 320, 8, -1, 320*200}, - {0xffff, -1, -1, -1, -1, -1, -1} -}; - -static word16 vga_ver; -static int linear_selector; -static int oldmode = -1; - -#define vga_color_precision 6 - - - -/* Desc: Attempts to detect VGA, check video modes and create selectors. - * - * In : - - * Out : mode array - * - * Note: - - */ -static vl_mode *vga_init (void) -{ - int rv = 0; - - if (vga_ver) { - return modes; - } - - __asm("\n\ - movw $0x1a00, %%ax \n\ - int $0x10 \n\ - cmpb $0x1a, %%al \n\ - jne 0f \n\ - cmpb $0x07, %%bl \n\ - jb 0f \n\ - andl $0xff, %%ebx \n\ - movl %%ebx, %0 \n\ - 0:":"=g"(rv)::"%eax", "%ebx"); - if (rv == 0) { - return NULL; - } - - if (_create_selector(&linear_selector, 0xa0000, 0x10000)) { - return NULL; - } - - modes[0].sel = linear_selector; - - vga_ver = rv; - return modes; -} - - - -/* Desc: Frees all resources allocated by VGA init code. - * - * In : - - * Out : - - * - * Note: - - */ -static void vga_finit (void) -{ - if (vga_ver) { - _remove_selector(&linear_selector); - } -} - - - -/* Desc: Attempts to enter specified video mode. - * - * In : ptr to mode structure, refresh rate - * Out : 0 if success - * - * Note: - - */ -static int vga_entermode (vl_mode *p, int refresh) -{ - if (!(p->mode & 0x4000)) { - return -1; - } - VGA.blit = vl_can_mmx() ? vesa_l_dump_virtual_mmx : vesa_l_dump_virtual; - - if (oldmode == -1) { - __asm("\n\ - movb $0x0f, %%ah \n\ - int $0x10 \n\ - andl $0xff, %%eax \n\ - movl %%eax, %0 \n\ - ":"=g"(oldmode)::"%eax", "%ebx"); - } - - __asm("int $0x10"::"a"(p->mode&0xff)); - - return 0; -} - - - -/* Desc: Restores to the mode prior to first call to vga_entermode. - * - * In : - - * Out : - - * - * Note: - - */ -static void vga_restore (void) -{ - if (oldmode != -1) { - __asm("int $0x10"::"a"(oldmode)); - } -} - - - -/* Desc: set one palette entry - * - * In : color index, R, G, B - * Out : - - * - * Note: uses integer values - */ -static void vga_setCI_i (int index, int red, int green, int blue) -{ -#if 0 - __asm("\n\ - movw $0x1010, %%ax \n\ - movb %1, %%dh \n\ - movb %2, %%ch \n\ - int $0x10 \n\ - "::"b"(index), "m"(red), "m"(green), "c"(blue):"%eax", "%edx"); -#else - outportb(0x03C8, index); - outportb(0x03C9, red); - outportb(0x03C9, green); - outportb(0x03C9, blue); -#endif -} - - - -/* Desc: set one palette entry - * - * In : color index, R, G, B - * Out : - - * - * Note: uses normalized values - */ -static void vga_setCI_f (int index, float red, float green, float blue) -{ - float max = (1 << vga_color_precision) - 1; - - vga_setCI_i(index, (int)(red * max), (int)(green * max), (int)(blue * max)); -} - - - -/* Desc: retrieve CI precision - * - * In : - - * Out : precision in bits - * - * Note: - - */ -static int vga_getCIprec (void) -{ - return vga_color_precision; -} - - - -/* - * the driver - */ -vl_driver VGA = { - vga_init, - vga_entermode, - NULL, - vga_setCI_f, - vga_setCI_i, - vga_getCIprec, - vga_restore, - vga_finit -}; diff --git a/src/mesa/drivers/dos/vga/vga.h b/src/mesa/drivers/dos/vga/vga.h deleted file mode 100644 index b7ae84c961..0000000000 --- a/src/mesa/drivers/dos/vga/vga.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 v1.3 for Mesa 5.0 - * - * Copyright (C) 2002 - Borca Daniel - * Email : dborca@yahoo.com - * Web : http://www.geocities.com/dborca - */ - - -#ifndef VGA_H_included -#define VGA_H_included - -#include "../internal.h" -#include "../vesa/vesa.h" - -extern vl_driver VGA; - -#endif diff --git a/src/mesa/drivers/dos/video.c b/src/mesa/drivers/dos/video.c index aba99ac542..3e93e6095a 100644 --- a/src/mesa/drivers/dos/video.c +++ b/src/mesa/drivers/dos/video.c @@ -35,10 +35,10 @@ #include -#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 @@ int vl_current_offset, vl_current_delta; /* 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 @@ int vl_sync_buffer (void **buffer, int x, int y, int width, int height) -/* 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 @@ static int vl_setup_mode (vl_mode *p) 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 @@ static int vl_setup_mode (vl_mode *p) void vl_video_exit (void) { drv->restore(); - drv->finit(); + drv->fini(); } @@ -523,7 +511,7 @@ int vl_video_init (int width, int height, int bpp, int rgb, int refresh) 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 8dfb9a9176..e908178ad4 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 @@ extern int (*vl_getpixel) (unsigned int offset); 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 c5a72975fe..0605514b14 100644 --- a/src/mesa/drivers/dos/virtual.S +++ b/src/mesa/drivers/dos/virtual.S @@ -108,7 +108,7 @@ _v_clear_common: .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 @@ _v_clear8_mmx: .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 @@ _v_clear16_mmx: .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 cabeff1036..e2714f9088 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 @@ GL_IMP = libigl.a 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 @@ K3D_SOURCES = \ 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 @@ endif 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 @@ DRIVER_SOURCES += \ 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 @@ ifeq ($(DXE3GEN),) $(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 @@ clean: -$(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 -- cgit v1.2.3