9d50952c52730c82976a70ccbea594e22f226a75
2 * Mesa 3-D graphics library
5 * Copyright (C) 1999 Brian Paul All Rights Reserved.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 * DOS/DJGPP device driver v0.4 for Mesa 4.0
28 * Copyright (C) 2002 - Borca Daniel
29 * Email : dborca@yahoo.com
30 * Web : http://www.geocities.com/dborca
38 #include <sys/exceptn.h>
39 #include <sys/segments.h>
40 #include <sys/farptr.h>
47 typedef unsigned char word8
;
48 typedef unsigned short word16
;
49 typedef unsigned long word32
;
51 typedef struct vl_mode
{
58 #define _16_ *(word16 *)&
59 #define _32_ *(word32 *)&
63 static vl_mode modes
[64];
65 /* card specific: valid forever */
66 static word16 vesa_ver
;
67 static word32 hw_granularity
, hw_linearfb
;
68 static unsigned int gran_shift
, gran_mask
;
69 /* based upon mode specific data: valid entire session */
70 static int video_selector
, banked_selector
, linear_selector
;
71 static int video_scanlen
, video_bypp
;
72 /* valid until next buffer */
73 static int current_offset
, current_delta
, current_width
;
77 /* lookup table for scaling 5 bit colors up to 8 bits */
78 static int _rgb_scale_5
[32] =
80 0, 8, 16, 24, 32, 41, 49, 57,
81 65, 74, 82, 90, 98, 106, 115, 123,
82 131, 139, 148, 156, 164, 172, 180, 189,
83 197, 205, 213, 222, 230, 238, 246, 255
86 /* lookup table for scaling 6 bit colors up to 8 bits */
87 static int _rgb_scale_6
[64] =
89 0, 4, 8, 12, 16, 20, 24, 28,
90 32, 36, 40, 44, 48, 52, 56, 60,
91 64, 68, 72, 76, 80, 85, 89, 93,
92 97, 101, 105, 109, 113, 117, 121, 125,
93 129, 133, 137, 141, 145, 149, 153, 157,
94 161, 165, 170, 174, 178, 182, 186, 190,
95 194, 198, 202, 206, 210, 214, 218, 222,
96 226, 230, 234, 238, 242, 246, 250, 255
104 void (*vl_clear
) (void *buffer
, int len
, int color
);
106 #define v_clear15 v_clear16
107 extern void v_clear16 (void *buffer
, int len
, int color
);
108 extern void v_clear32 (void *buffer
, int len
, int color
);
112 .global _v_clear16 \n\
114 movl 12(%esp), %eax \n\
118 jmp _v_clear_common \n\
120 .global _v_clear32 \n\
122 movl 12(%esp), %eax \n\
125 movl 8(%esp), %ecx \n\
126 movl 4(%esp), %edx \n\
130 movl %eax, (%edx) \n\
135 extern void v_clear24 (void *buffer
, int len
, int color
);
139 .global _v_clear24 \n\
141 movl 8(%esp), %edx \n\
142 movl $0xaaaaaaab, %eax \n\
144 movl 12(%esp), %eax \n\
146 movl 4(%esp), %edx \n\
149 movb 18(%esp), %bl \n\
153 movb %bl, 2(%edx) \n\
163 * virtual rectangle clearing
165 void vl_rect (void *buffer
, int x
, int y
, int width
, int height
, int color
)
167 int offset
= y
*current_width
+ x
;
168 int delta
= current_width
- width
;
170 for (y
=0; y
<height
; y
++) {
171 for (x
=0; x
<width
; x
++, offset
++) {
172 vl_putpixel(buffer
, offset
, color
);
183 void (*vl_flip
) (void *buffer
, int width
, int height
);
185 extern void b_dump_virtual (void *buffer
, int width
, int height
);
189 .global _b_dump_virtual \n\
195 movl _video_selector, %fs \n\
196 movl 4*4+4+0(%esp), %esi \n\
197 movl _hw_granularity, %ebp \n\
199 movl _current_offset, %eax \n\
205 movw $0x4f05, %ax \n\
207 movl _current_delta, %ebx \n\
208 movl 5*4+4+4(%esp), %ecx \n\
209 movl 5*4+4+8(%esp), %edx \n\
221 movw $0x4f05, %ax \n\
222 movl 12(%esp), %edx \n\
229 movl (%esi), %eax \n\
231 movl %eax, %fs:(%edi) \n\
245 extern void l_dump_virtual (void *buffer
, int width
, int height
);
249 .global _l_dump_virtual \n\
254 movl _video_selector, %fs \n\
255 movl 3*4+4+0(%esp), %esi \n\
256 movl _current_offset, %edi \n\
257 movl 3*4+4+4(%esp), %ecx \n\
258 movl 3*4+4+8(%esp), %edx \n\
259 movl _current_delta, %ebx \n\
266 movl (%esi), %eax \n\
268 movl %eax, %fs:(%edi) \n\
284 * mix RGBA components
286 int (*vl_mixrgba
) (const unsigned char rgba
[]);
288 #define vl_mixrgba15 vl_mixrgb15
289 #define vl_mixrgba16 vl_mixrgb16
290 #define vl_mixrgba24 vl_mixrgb24
291 static int vl_mixrgba32 (const unsigned char rgba
[])
293 return (rgba
[3]<<24)|(rgba
[0]<<16)|(rgba
[1]<<8)|(rgba
[2]);
301 int (*vl_mixrgb
) (const unsigned char rgb
[]);
303 static int vl_mixrgb15 (const unsigned char rgb
[])
305 return ((rgb
[0]>>3)<<10)|((rgb
[1]>>3)<<5)|(rgb
[2]>>3);
307 static int vl_mixrgb16 (const unsigned char rgb
[])
309 return ((rgb
[0]>>3)<<11)|((rgb
[1]>>2)<<5)|(rgb
[2]>>3);
311 #define vl_mixrgb24 vl_mixrgb32
312 static int vl_mixrgb32 (const unsigned char rgb
[])
314 return (rgb
[0]<<16)|(rgb
[1]<<8)|(rgb
[2]);
322 void (*vl_putpixel
) (void *buffer
, int offset
, int color
);
324 #define v_putpixel15 v_putpixel16
325 extern void v_putpixel16 (void *buffer
, int offset
, int color
);
329 .global _v_putpixel16 \n\
331 movl 8(%esp), %edx \n\
333 movl 12(%esp), %eax \n\
334 addl 4(%esp), %edx \n\
337 extern void v_putpixel24 (void *buffer
, int offset
, int color
);
341 .global _v_putpixel24 \n\
343 movl 8(%esp), %edx \n\
344 leal (%edx, %edx, 2), %edx \n\
345 movl 12(%esp), %eax \n\
346 addl 4(%esp), %edx \n\
349 movb %al, 2(%edx) \n\
351 extern void v_putpixel32 (void *buffer
, int offset
, int color
);
355 .global _v_putpixel32 \n\
357 movl 8(%esp), %edx \n\
359 movl 12(%esp), %eax \n\
360 addl 4(%esp), %edx \n\
361 movl %eax, (%edx) \n\
367 * get pixel and decompose R, G, B, A
369 void (*vl_getrgba
) (void *buffer
, int offset
, unsigned char rgba
[4]);
374 static void v_getrgba15 (void *buffer
, int offset
, unsigned char rgba
[4])
376 int c
= ((word16
*)buffer
)[offset
];
377 rgba
[0] = _rgb_scale_5
[(c
>> 10) & 0x1F];
378 rgba
[1] = _rgb_scale_5
[(c
>> 5) & 0x1F];
379 rgba
[2] = _rgb_scale_5
[c
& 0x1F];
382 static void v_getrgba16 (void *buffer
, int offset
, unsigned char rgba
[4])
384 int c
= ((word16
*)buffer
)[offset
];
385 rgba
[0] = _rgb_scale_5
[(c
>> 11) & 0x1F];
386 rgba
[1] = _rgb_scale_6
[(c
>> 5) & 0x3F];
387 rgba
[2] = _rgb_scale_5
[c
& 0x1F];
390 static void v_getrgba24 (void *buffer
, int offset
, unsigned char rgba
[4])
392 int c
= *(word32
*)((long)buffer
+offset
*3);
398 static void v_getrgba32 (void *buffer
, int offset
, unsigned char rgba
[4])
400 int c
= ((word32
*)buffer
)[offset
];
410 * sync buffer with video hardware
412 void *vl_sync_buffer (void *buffer
, int x
, int y
, int width
, int height
)
419 current_offset
= video_scanlen
* y
+ video_bypp
* x
;
420 if ((newbuf
=realloc(buffer
, width
*height
*video_bypp
))!=NULL
) {
421 current_width
= width
;
422 current_delta
= video_scanlen
- video_bypp
* width
;
433 * attempts to detect VESA and video modes
435 static word16
vl_vesa_init (void)
440 char vesa_info
[512], tmp
[512];
443 _farpokel(_stubinfo
->ds_selector
, 0, 0x32454256);
446 r
.x
.es
= _stubinfo
->ds_segment
;
447 __dpmi_int(0x10, &r
);
448 if (r
.x
.ax
==0x004f) {
449 movedata(_stubinfo
->ds_selector
, 0, _my_ds(), (unsigned)vesa_info
, 512);
450 if ((_32_ vesa_info
[0])==0x41534556) {
451 p
= (unsigned short *)(((_16_ vesa_info
[0x10])<<4) + (_16_ vesa_info
[0x0e]));
454 if ((q
->mode
=_farpeekw(__djgpp_dos_sel
, (unsigned long)(p
++)))==0xffff) {
461 r
.x
.es
= _stubinfo
->ds_segment
;
462 __dpmi_int(0x10, &r
);
463 movedata(_stubinfo
->ds_selector
, 512, _my_ds(), (unsigned)tmp
, 256);
466 q
->bpp
= tmp
[0x1f] + tmp
[0x21] + tmp
[0x23];
476 if ((r
.x
.ax
==0x004f)&&((tmp
[0]&0x11)==0x11)&&q
->bpp
) {
477 q
->xres
= _16_ tmp
[0x12];
478 q
->yres
= _16_ tmp
[0x14];
479 q
->scanlen
= _16_ tmp
[0x10];
480 hw_granularity
= (_16_ tmp
[4])<<10;
483 hw_linearfb
= _32_ tmp
[0x28];
486 if (maxsize
<(q
->scanlen
*q
->yres
)) {
487 maxsize
= q
->scanlen
*q
->yres
;
494 maxsize
= ((maxsize
+0xfffUL
)&~0xfffUL
);
495 if (_create_selector(&linear_selector
, hw_linearfb
, maxsize
)) {
499 if (_create_selector(&banked_selector
, 0xa0000, hw_granularity
)) {
500 _remove_selector(&linear_selector
);
504 return _16_ vesa_info
[4];
516 static int vl_setup_mode (vl_mode
*p
)
518 if (p
->mode
&0x4000) {
519 video_selector
= linear_selector
;
520 vl_flip
= l_dump_virtual
;
522 { int n
; for (gran_shift
=0, n
=hw_granularity
; n
; gran_shift
++, n
>>=1) ; }
523 gran_mask
= (1<<(--gran_shift
)) - 1;
524 if (hw_granularity
!=(gran_mask
+1)) {
527 video_selector
= banked_selector
;
528 vl_flip
= b_dump_virtual
;
531 #define INITPTR(bpp) \
532 vl_putpixel = v_putpixel##bpp; \
533 vl_getrgba = v_getrgba##bpp; \
534 vl_clear = v_clear##bpp; \
535 vl_mixrgb = vl_mixrgb##bpp; \
536 vl_mixrgba = vl_mixrgba##bpp;
557 video_bypp
= (p
->bpp
+7)/8;
558 video_scanlen
= p
->scanlen
;
566 * shutdown the video engine
568 void vl_video_exit (int textmode
)
572 __asm__("movw $0x3, %%ax; int $0x10":::"%eax");
575 _remove_selector(&linear_selector
);
576 _remove_selector(&banked_selector
);
585 * initialize video engine
590 int vl_video_init (int width
, int height
, int bpp
)
595 /* check for prior initialization */
600 /* initialize hardware */
601 if (!(vesa_ver
=vl_vesa_init())) {
606 /* search for a mode that fits our request */
607 for (min
=-1, p
=NULL
, q
=modes
; q
->mode
!=0xffff; q
++) {
608 if ((q
->xres
>=width
)&&(q
->yres
>=height
)&&(q
->bpp
==bpp
)) {
609 if (min
>=(unsigned)(q
->xres
*q
->yres
)) {
610 min
= q
->xres
*q
->yres
;
618 __asm__("movw $0x4f02, %%ax; int $0x10"::"b"(p
->mode
):"%eax");
621 /* no suitable mode found, abort */