r300: do front/back color selection in HW for software TCL path
[mesa.git] / src / mesa / drivers / dos / dpmi.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 4.0
4 *
5 * Copyright (C) 1999 Brian Paul All Rights Reserved.
6 *
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:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
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.
23 */
24
25 /*
26 * DOS/DJGPP device driver for Mesa
27 *
28 * Author: Daniel Borca
29 * Email : dborca@yahoo.com
30 * Web : http://www.geocities.com/dborca
31 */
32
33
34 #include <dpmi.h>
35
36 #include "internal.h"
37
38
39 #ifndef MAX
40 #define MAX(x, y) (((x) < (y)) ? (y) : (x))
41 #endif
42
43
44 /* _create_linear_mapping:
45 * Maps a physical address range into linear memory.
46 */
47 int
48 _create_linear_mapping (unsigned long *linear, unsigned long physaddr, int size)
49 {
50 __dpmi_meminfo meminfo;
51
52 if (physaddr >= 0x100000) {
53 /* map into linear memory */
54 meminfo.address = physaddr;
55 meminfo.size = size;
56 if (__dpmi_physical_address_mapping(&meminfo) != 0) {
57 return -1;
58 }
59
60 *linear = meminfo.address;
61 } else {
62 /* exploit 1 -> 1 physical to linear mapping in low megabyte */
63 *linear = physaddr;
64 }
65
66 return 0;
67 }
68
69
70 /* _remove_linear_mapping:
71 * Frees the DPMI resources being used to map a linear address range.
72 */
73 void
74 _remove_linear_mapping (unsigned long *linear)
75 {
76 __dpmi_meminfo meminfo;
77
78 if (*linear) {
79 if (*linear >= 0x100000) {
80 meminfo.address = *linear;
81 __dpmi_free_physical_address_mapping(&meminfo);
82 }
83
84 *linear = 0;
85 }
86 }
87
88
89 /* _create_selector:
90 * Allocates a selector to access a region of linear memory.
91 */
92 int
93 _create_selector (int *segment, unsigned long base, int size)
94 {
95 /* allocate an ldt descriptor */
96 if ((*segment=__dpmi_allocate_ldt_descriptors(1)) < 0) {
97 *segment = 0;
98 return -1;
99 }
100
101 /* create the linear mapping */
102 if (_create_linear_mapping(&base, base, size)) {
103 __dpmi_free_ldt_descriptor(*segment);
104 *segment = 0;
105 return -1;
106 }
107
108 /* set the descriptor base and limit */
109 __dpmi_set_segment_base_address(*segment, base);
110 __dpmi_set_segment_limit(*segment, MAX(size-1, 0xFFFF));
111
112 return 0;
113 }
114
115
116 /* _remove_selector:
117 * Frees a DPMI segment selector.
118 */
119 void
120 _remove_selector (int *segment)
121 {
122 if (*segment) {
123 unsigned long base;
124 __dpmi_get_segment_base_address(*segment, &base);
125 _remove_linear_mapping(&base);
126 __dpmi_free_ldt_descriptor(*segment);
127 *segment = 0;
128 }
129 }
130
131
132 /* Desc: retrieve CPU MMX capability
133 *
134 * In : -
135 * Out : FALSE if CPU cannot do MMX
136 *
137 * Note: -
138 */
139 int
140 _can_mmx (void)
141 {
142 #ifdef USE_MMX_ASM
143 int x86_cpu_features = 0;
144 __asm("\n\
145 pushfl \n\
146 popl %%eax \n\
147 movl %%eax, %%ecx \n\
148 xorl $0x200000, %%eax\n\
149 pushl %%eax \n\
150 popfl \n\
151 pushfl \n\
152 popl %%eax \n\
153 pushl %%ecx \n\
154 popfl \n\
155 xorl %%ecx, %%eax \n\
156 jz 0f \n\
157 movl $1, %%eax \n\
158 cpuid \n\
159 movl %%edx, %0 \n\
160 0: \n\
161 ":"=g"(x86_cpu_features)::"%eax", "%ebx", "%ecx", "%edx");
162 return (x86_cpu_features & 0x00800000);
163 #else
164 return 0;
165 #endif
166 }