Mercurial > mplayer.hg
annotate linux/vbelib.c @ 9278:caea8ed36b48
The reason why mplayer crashes (in some cases) when using x11
output and -wid (>0) parameter is this:
Mplayer by default creates a colormap using DirectColor visual. If the
window given to mplayer uses TrueColor visual there will be an error
when mplayer sets the colormap for the window. This patch
modifies mplayer to use TrueColor visual if the window given to mplayer
uses TrueColor. Another solution is to make sure that the window given to
mplayer is created using DirectColor visual if it is supported by the
display.
Jouni Tulkki <jitulkki@cc.hut.fi>
author | arpi |
---|---|
date | Tue, 04 Feb 2003 18:31:44 +0000 |
parents | 21e1ab99cb21 |
children |
rev | line source |
---|---|
2243 | 1 /* |
2 This file contains implementation of VESA library which is based on | |
3 LRMI (Linux real-mode interface). | |
4 So it's not an emulator - it calls real int 10h handler under Linux. | |
5 Note: VESA is available only on x86 systems. | |
6 You can redistribute this file under terms and conditions | |
2632 | 7 of GNU General Public licence v2. |
2243 | 8 Written by Nick Kurshev <nickols_k@mail.ru> |
9 */ | |
10 #include "vbelib.h" | |
11 #include "lrmi.h" | |
12 #include <stdlib.h> | |
13 #include <string.h> | |
14 #include <stdio.h> | |
15 #include <sys/io.h> | |
2610 | 16 #include <sys/mman.h> |
17 #include <sys/types.h> | |
18 #include <sys/stat.h> | |
2407 | 19 #include <ctype.h> |
2610 | 20 #include <unistd.h> |
21 #include <fcntl.h> | |
2243 | 22 |
23 static struct VesaProtModeInterface vbe_pm_info; | |
2632 | 24 static struct VesaModeInfoBlock curr_mode_info; |
2243 | 25 |
2536 | 26 static inline int VERR(const void *p) |
2515 | 27 { |
28 register int retval; | |
29 __asm __volatile( | |
30 "xorl %0, %0\n\t" | |
31 "verr %1\n\t" | |
32 "setnz %b0" | |
4405
7eda15bbb3f9
fixing assembly bug. By Thierry Vignaud <tvignaud@mandrakesoft.com>
nick
parents:
3016
diff
changeset
|
33 :"=q"(retval) |
2515 | 34 :"m"(*(unsigned char *)p) |
4405
7eda15bbb3f9
fixing assembly bug. By Thierry Vignaud <tvignaud@mandrakesoft.com>
nick
parents:
3016
diff
changeset
|
35 :"memory","cc"); |
2515 | 36 return retval; |
37 } | |
38 | |
39 #if 0 | |
2536 | 40 static inline int VERW(const void *p) |
2515 | 41 { |
42 register int retval; | |
43 __asm __volatile( | |
44 "xorl %0, %0\n\t" | |
45 "verw %1\n\t" | |
46 "setnz %b0" | |
4405
7eda15bbb3f9
fixing assembly bug. By Thierry Vignaud <tvignaud@mandrakesoft.com>
nick
parents:
3016
diff
changeset
|
47 :"=q"(retval) |
2515 | 48 :"m"(*(unsigned char *)p) |
4405
7eda15bbb3f9
fixing assembly bug. By Thierry Vignaud <tvignaud@mandrakesoft.com>
nick
parents:
3016
diff
changeset
|
49 :"memory","cc"); |
2515 | 50 return retval; |
51 } | |
52 #endif | |
53 | |
2294 | 54 #define HAVE_VERBOSE_VAR 1 |
55 | |
56 #ifdef HAVE_VERBOSE_VAR | |
57 extern int verbose; | |
58 | |
59 static void __dump_regs(struct LRMI_regs *r) | |
60 { | |
61 printf("vbelib: eax=%08lXh ebx=%08lXh ecx=%08lXh edx=%08lXh\n" | |
62 "vbelib: edi=%08lXh esi=%08lXh ebp=%08lXh esp=%08lXh\n" | |
2445 | 63 "vbelib: ds=%04Xh es=%04Xh ss=%04Xh cs:ip=%04X:%04X\n" |
64 "vbelib: fs=%04Xh gs=%04Xh ss:sp=%04X:%04X flags=%04X\n" | |
65 ,(unsigned long)r->eax,(unsigned long)r->ebx,(unsigned long)r->ecx,(unsigned long)r->edx | |
66 ,(unsigned long)r->edi,(unsigned long)r->esi,(unsigned long)r->ebp,(unsigned long)r->reserved | |
2294 | 67 ,r->ds,r->es,r->ss,r->cs,r->ip |
68 ,r->fs,r->gs,r->ss,r->sp,r->flags); | |
69 } | |
70 | |
71 static inline int VBE_LRMI_int(int int_no, struct LRMI_regs *r) | |
72 { | |
73 int retval; | |
74 if(verbose > 1) | |
75 { | |
76 printf("vbelib: registers before int %02X\n",int_no); | |
77 __dump_regs(r); | |
78 } | |
79 retval = LRMI_int(int_no,r); | |
80 if(verbose > 1) | |
81 { | |
2445 | 82 printf("vbelib: Interrupt handler returns: %X\n",retval); |
2294 | 83 printf("vbelib: registers after int %02X\n",int_no); |
84 __dump_regs(r); | |
85 } | |
86 return retval; | |
87 } | |
88 #else | |
89 #define VBE_LRMI_int(int_no,regs) (VBE_LRMI_int(int_no,regs)) | |
90 #endif | |
91 | |
3016
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
92 static FILE *my_stdin; |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
93 static FILE *my_stdout; |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
94 static FILE *my_stderr; |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
95 |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
96 static void __set_cursor_type(FILE *stdout_fd,int cursor_on) |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
97 { |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
98 fprintf(stdout_fd,"\033[?25%c",cursor_on?'h':'l'); |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
99 } |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
100 |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
101 /* TODO: do it only on LCD or DFP. We should extract such info from DDC */ |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
102 static void hide_terminal_output( void ) |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
103 { |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
104 my_stdin = fopen(ttyname(fileno(stdin )),"r"); |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
105 my_stdout = fopen(ttyname(fileno(stdout)),"w"); |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
106 my_stderr = fopen(ttyname(fileno(stderr)),"w"); |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
107 __set_cursor_type(stdout,0); |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
108 /*if(isatty(fileno(stdin ))) stdin =freopen("/dev/null","r",stdin );*/ |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
109 if(isatty(fileno(stdout))) stdout=freopen("/dev/null","w",stdout); |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
110 if(isatty(fileno(stderr))) stderr=freopen("/dev/null","w",stderr); |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
111 } |
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
112 |
2407 | 113 static unsigned hh_int_10_seg; |
2610 | 114 static int fd_mem; |
6473
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
115 /* |
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
116 the list of supported video modes is stored in the reserved portion of |
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
117 the SuperVGA information record by some implementations, and it may |
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
118 thus be necessary to either copy the mode list or use a different |
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
119 buffer for all subsequent VESA calls |
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
120 */ |
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
121 static void *controller_info; |
2243 | 122 int vbeInit( void ) |
123 { | |
2407 | 124 unsigned short iopl_port; |
2359 | 125 size_t i; |
2552 | 126 int retval; |
2243 | 127 if(!LRMI_init()) return VBE_VM86_FAIL; |
6473
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
128 if(!(controller_info = LRMI_alloc_real(sizeof(struct VbeInfoBlock)))) return VBE_OUT_OF_DOS_MEM; |
2243 | 129 /* |
130 Allow read/write to ALL io ports | |
131 */ | |
2407 | 132 hh_int_10_seg = *(unsigned short *)PhysToVirtSO(0x0000,0x0042); |
2359 | 133 /* Video BIOS should be at C000:0000 and above */ |
2407 | 134 hh_int_10_seg >>= 12; |
135 if(hh_int_10_seg < 0xC) return VBE_BROKEN_BIOS; | |
2243 | 136 ioperm(0, 1024, 1); |
137 iopl(3); | |
138 memset(&vbe_pm_info,0,sizeof(struct VesaProtModeInterface)); | |
2552 | 139 retval = vbeGetProtModeInfo(&vbe_pm_info); |
140 if(retval != VBE_OK) return retval; | |
2359 | 141 i = 0; |
2913 | 142 if(vbe_pm_info.iopl_ports) /* Can be NULL !!!*/ |
2552 | 143 while((iopl_port=vbe_pm_info.iopl_ports[i]) != 0xFFFF |
144 && vbe_pm_info.iopl_ports[i++] > 1023) ioperm(iopl_port,1,1); | |
2359 | 145 iopl(3); |
2610 | 146 fd_mem = open("/dev/mem",O_RDWR); |
3016
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
147 hide_terminal_output(); |
2243 | 148 return VBE_OK; |
149 } | |
150 | |
2610 | 151 int vbeDestroy( void ) |
152 { | |
3016
ea414257856f
Hide terminal's output and text-mode cursor for LCD and DFP
nick
parents:
2913
diff
changeset
|
153 __set_cursor_type(my_stdout,1); |
2610 | 154 close(fd_mem); |
6473
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
155 LRMI_free_real(controller_info); |
2610 | 156 return VBE_OK; |
157 } | |
2243 | 158 |
2536 | 159 /* Fixme!!! This code is compatible only with mplayer's version of lrmi*/ |
160 static inline int is_addr_valid(const void *p) | |
161 { | |
162 return (p < (const void *)0x502) || | |
163 (p >= (const void *)0x10000 && p < (const void *)0x20000) || | |
164 (p >= (const void *)0xa0000 && p < (const void *)0x100000); | |
165 } | |
166 | |
167 static int check_str(const unsigned char *str) | |
2515 | 168 { |
169 size_t i; | |
170 int null_found = 0; | |
171 for(i = 0;i < 256;i++) | |
172 { | |
2536 | 173 if(is_addr_valid(&str[i])) |
2515 | 174 { |
2536 | 175 if(VERR(&str[i])) |
176 { | |
177 if(!str[i]) { null_found = 1; break; } | |
178 } | |
179 else break; | |
2515 | 180 } |
181 else break; | |
182 } | |
183 return null_found; | |
184 } | |
185 | |
2536 | 186 static int check_wrd(const unsigned short *str) |
2515 | 187 { |
188 size_t i; | |
189 int ffff_found = 0; | |
190 for(i = 0;i < 1024;i++) | |
191 { | |
2536 | 192 if(is_addr_valid(&str[i])) |
2515 | 193 { |
2536 | 194 if(VERR(&str[i])) |
195 { | |
196 if(str[i] == 0xffff) { ffff_found = 1; break; } | |
197 } | |
198 else break; | |
2515 | 199 } |
200 else break; | |
201 } | |
202 return ffff_found; | |
203 } | |
204 | |
2407 | 205 static void print_str(unsigned char *str) |
206 { | |
207 size_t i; | |
208 fflush(stdout); | |
209 printf("vbelib: "); | |
210 for(i = 0;i < 256;i++) { printf("%02X(%c) ",str[i],isprint(str[i])?str[i]:'.'); if(!str[i]) break; } | |
211 printf("\n"); | |
212 fflush(stdout); | |
213 } | |
214 | |
215 static void print_wrd(unsigned short *str) | |
216 { | |
217 size_t i; | |
218 fflush(stdout); | |
219 printf("vbelib: "); | |
220 for(i = 0;i < 256;i++) { printf("%04X ",str[i]); if(str[i] == 0xffff) break; } | |
221 printf("\n"); | |
222 fflush(stdout); | |
223 } | |
224 | |
2243 | 225 int vbeGetControllerInfo(struct VbeInfoBlock *data) |
226 { | |
227 struct LRMI_regs r; | |
228 int retval; | |
6473
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
229 memcpy(controller_info,data,sizeof(struct VbeInfoBlock)); |
2243 | 230 memset(&r,0,sizeof(struct LRMI_regs)); |
231 r.eax = 0x4f00; | |
6473
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
232 r.es = VirtToPhysSeg(controller_info); |
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
233 r.edi = VirtToPhysOff(controller_info); |
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
234 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; |
2243 | 235 retval = r.eax & 0xffff; |
236 if(retval == 0x4f) | |
237 { | |
238 FarPtr fpdata; | |
239 retval = VBE_OK; | |
6473
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
240 memcpy(data,controller_info,sizeof(struct VbeInfoBlock)); |
2243 | 241 fpdata.seg = (unsigned long)(data->OemStringPtr) >> 16; |
242 fpdata.off = (unsigned long)(data->OemStringPtr) & 0xffff; | |
243 data->OemStringPtr = PhysToVirt(fpdata); | |
2515 | 244 if(!check_str(data->OemStringPtr)) data->OemStringPtr = NULL; |
2294 | 245 #ifdef HAVE_VERBOSE_VAR |
2407 | 246 if(verbose > 1) |
247 { | |
248 printf("vbelib: OemStringPtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemStringPtr); | |
2515 | 249 if(data->OemStringPtr) print_str(data->OemStringPtr); |
2518 | 250 fflush(stdout); |
2407 | 251 } |
2294 | 252 #endif |
2243 | 253 fpdata.seg = (unsigned long)(data->VideoModePtr) >> 16; |
254 fpdata.off = (unsigned long)(data->VideoModePtr) & 0xffff; | |
255 data->VideoModePtr = PhysToVirt(fpdata); | |
2515 | 256 if(!check_wrd(data->VideoModePtr)) |
257 { | |
258 data->VideoModePtr = NULL; | |
259 retval = VBE_BROKEN_BIOS; | |
260 } | |
2294 | 261 #ifdef HAVE_VERBOSE_VAR |
2407 | 262 if(verbose > 1) |
263 { | |
264 printf("vbelib: VideoModePtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->VideoModePtr); | |
2515 | 265 if(data->VideoModePtr) print_wrd(data->VideoModePtr); |
2518 | 266 fflush(stdout); |
2407 | 267 } |
2294 | 268 #endif |
2243 | 269 fpdata.seg = (unsigned long)(data->OemVendorNamePtr) >> 16; |
270 fpdata.off = (unsigned long)(data->OemVendorNamePtr) & 0xffff; | |
271 data->OemVendorNamePtr = PhysToVirt(fpdata); | |
2515 | 272 if(!check_str(data->OemVendorNamePtr)) data->OemVendorNamePtr = NULL; |
2294 | 273 #ifdef HAVE_VERBOSE_VAR |
2407 | 274 if(verbose > 1) |
275 { | |
276 printf("vbelib: OemVendorNamePtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemVendorNamePtr); | |
2515 | 277 if(data->OemVendorNamePtr) print_str(data->OemVendorNamePtr); |
2518 | 278 fflush(stdout); |
2407 | 279 } |
2294 | 280 #endif |
2243 | 281 fpdata.seg = (unsigned long)(data->OemProductNamePtr) >> 16; |
282 fpdata.off = (unsigned long)(data->OemProductNamePtr) & 0xffff; | |
283 data->OemProductNamePtr = PhysToVirt(fpdata); | |
2515 | 284 if(!check_str(data->OemProductNamePtr)) data->OemProductNamePtr = NULL; |
2294 | 285 #ifdef HAVE_VERBOSE_VAR |
2407 | 286 if(verbose > 1) |
287 { | |
288 printf("vbelib: OemProductNamePtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemProductNamePtr); | |
2515 | 289 if(data->OemVendorNamePtr) print_str(data->OemProductNamePtr); |
2518 | 290 fflush(stdout); |
2407 | 291 } |
2294 | 292 #endif |
2243 | 293 fpdata.seg = (unsigned long)(data->OemProductRevPtr) >> 16; |
294 fpdata.off = (unsigned long)(data->OemProductRevPtr) & 0xffff; | |
295 data->OemProductRevPtr = PhysToVirt(fpdata); | |
2515 | 296 if(!check_str(data->OemProductRevPtr)) data->OemProductRevPtr = NULL; |
2294 | 297 #ifdef HAVE_VERBOSE_VAR |
2407 | 298 if(verbose > 1) |
299 { | |
300 printf("vbelib: OemProductRevPtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemProductRevPtr); | |
2515 | 301 if(data->OemProductRevPtr) print_str(data->OemProductRevPtr); |
2518 | 302 fflush(stdout); |
2407 | 303 } |
2294 | 304 #endif |
2243 | 305 } |
306 return retval; | |
307 } | |
308 | |
309 int vbeGetModeInfo(unsigned mode,struct VesaModeInfoBlock *data) | |
310 { | |
311 struct LRMI_regs r; | |
312 void *rm_space; | |
313 int retval; | |
314 if(!(rm_space = LRMI_alloc_real(sizeof(struct VesaModeInfoBlock)))) return VBE_OUT_OF_DOS_MEM; | |
315 memset(&r,0,sizeof(struct LRMI_regs)); | |
316 r.eax = 0x4f01; | |
317 r.ecx = mode; | |
318 r.es = VirtToPhysSeg(rm_space); | |
319 r.edi = VirtToPhysOff(rm_space); | |
2294 | 320 if(!VBE_LRMI_int(0x10,&r)) |
2243 | 321 { |
322 LRMI_free_real(rm_space); | |
323 return VBE_VM86_FAIL; | |
324 } | |
325 retval = r.eax & 0xffff; | |
326 if(retval == 0x4f) | |
327 { | |
328 retval = VBE_OK; | |
329 memcpy(data,rm_space,sizeof(struct VesaModeInfoBlock)); | |
330 } | |
6473
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
331 LRMI_free_real(rm_space); |
2243 | 332 return retval; |
333 } | |
334 | |
335 int vbeSetMode(unsigned mode,struct VesaCRTCInfoBlock *data) | |
336 { | |
337 struct LRMI_regs r; | |
338 void *rm_space = NULL; | |
339 int retval; | |
340 memset(&r,0,sizeof(struct LRMI_regs)); | |
341 if(data) | |
342 { | |
343 if(!(rm_space = LRMI_alloc_real(sizeof(struct VesaCRTCInfoBlock)))) return VBE_OUT_OF_DOS_MEM; | |
344 r.es = VirtToPhysSeg(rm_space); | |
345 r.edi = VirtToPhysOff(rm_space); | |
346 memcpy(rm_space,data,sizeof(struct VesaCRTCInfoBlock)); | |
347 } | |
348 r.eax = 0x4f02; | |
349 r.ebx = mode; | |
2294 | 350 retval = VBE_LRMI_int(0x10,&r); |
6473
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
351 LRMI_free_real(rm_space); |
2243 | 352 if(!retval) return VBE_VM86_FAIL; |
353 retval = r.eax & 0xffff; | |
2632 | 354 if(retval == 0x4f) |
355 { | |
356 /* Just info for internal use (currently in SetDiplayStart func). */ | |
357 vbeGetModeInfo(mode&0x1f,&curr_mode_info); | |
358 retval = VBE_OK; | |
359 } | |
2243 | 360 return retval; |
361 } | |
362 | |
363 int vbeGetMode(unsigned *mode) | |
364 { | |
365 struct LRMI_regs r; | |
366 int retval; | |
367 memset(&r,0,sizeof(struct LRMI_regs)); | |
368 r.eax = 0x4f03; | |
2294 | 369 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; |
2243 | 370 retval = r.eax & 0xffff; |
371 if(retval == 0x4f) | |
372 { | |
373 *mode = r.ebx; | |
374 retval = VBE_OK; | |
375 } | |
376 return retval; | |
377 } | |
378 | |
7069 | 379 int vbeGetPixelClock(unsigned *mode,unsigned *pixel_clock) // in Hz |
380 { | |
381 struct LRMI_regs r; | |
382 int retval; | |
383 memset(&r,0,sizeof(struct LRMI_regs)); | |
384 r.eax = 0x4f0b; | |
385 r.ebx = 0; | |
386 r.edx = *mode; | |
387 r.ecx = *pixel_clock; | |
388 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; | |
389 retval = r.eax & 0xffff; | |
390 if(retval == 0x4f) | |
391 { | |
392 *pixel_clock = r.ecx; | |
393 retval = VBE_OK; | |
394 } | |
395 return retval; | |
396 } | |
397 | |
398 | |
2243 | 399 int vbeSaveState(void **data) |
400 { | |
401 struct LRMI_regs r; | |
402 int retval; | |
403 void *rm_space; | |
404 memset(&r,0,sizeof(struct LRMI_regs)); | |
405 r.eax = 0x4f04; | |
406 r.edx = 0x00; | |
407 r.ecx = 0x0f; | |
2294 | 408 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; |
2243 | 409 retval = r.eax & 0xffff; |
410 if(retval != 0x4f) return retval; | |
411 if(!(rm_space = LRMI_alloc_real((r.ebx & 0xffff)*64))) return VBE_OUT_OF_DOS_MEM; | |
412 r.eax = 0x4f04; | |
413 r.edx = 0x01; | |
414 r.ecx = 0x0f; | |
415 r.es = VirtToPhysSeg(rm_space); | |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
416 r.ebx = VirtToPhysOff(rm_space); |
2294 | 417 if(!VBE_LRMI_int(0x10,&r)) |
2243 | 418 { |
419 LRMI_free_real(rm_space); | |
420 return VBE_VM86_FAIL; | |
421 } | |
422 retval = r.eax & 0xffff; | |
423 if(retval != 0x4f) | |
424 { | |
425 LRMI_free_real(rm_space); | |
426 return retval; | |
427 } | |
428 *data = rm_space; | |
429 return VBE_OK; | |
430 } | |
431 | |
432 int vbeRestoreState(void *data) | |
433 { | |
434 struct LRMI_regs r; | |
435 int retval; | |
436 memset(&r,0,sizeof(struct LRMI_regs)); | |
437 r.eax = 0x4f04; | |
438 r.edx = 0x02; | |
439 r.ecx = 0x0f; | |
440 r.es = VirtToPhysSeg(data); | |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
441 r.ebx = VirtToPhysOff(data); |
2294 | 442 retval = VBE_LRMI_int(0x10,&r); |
2243 | 443 LRMI_free_real(data); |
444 if(!retval) return VBE_VM86_FAIL; | |
445 retval = r.eax & 0xffff; | |
446 if(retval == 0x4f) retval = VBE_OK; | |
447 return retval; | |
448 } | |
449 | |
450 int vbeGetWindow(unsigned *win_num) | |
451 { | |
452 struct LRMI_regs r; | |
453 int retval; | |
454 memset(&r,0,sizeof(struct LRMI_regs)); | |
455 r.eax = 0x4f05; | |
456 r.ebx = (*win_num & 0x0f) | 0x0100; | |
2294 | 457 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; |
2243 | 458 retval = r.eax & 0xffff; |
459 if(retval == 0x4f) | |
460 { | |
461 *win_num = r.edx & 0xffff; | |
462 retval = VBE_OK; | |
463 } | |
464 return retval; | |
465 } | |
466 | |
467 int vbeSetWindow(unsigned win_num,unsigned win_gran) | |
468 { | |
469 int retval; | |
470 if(vbe_pm_info.SetWindowCall) | |
471 { | |
2294 | 472 /* Don't verbose this stuff from performance reasons */ |
2243 | 473 /* 32-bit function call is much better of int 10h */ |
474 __asm __volatile( | |
475 "pushl %%ebx\n" | |
476 "movl %1, %%ebx\n" | |
477 ::"a"(0x4f05),"S"(win_num & 0x0f),"d"(win_gran):"memory"); | |
478 (*vbe_pm_info.SetWindowCall)(); | |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
479 __asm __volatile("popl %%ebx":::"memory"); |
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
480 retval = VBE_OK; |
2243 | 481 } |
482 else | |
483 { | |
484 struct LRMI_regs r; | |
485 memset(&r,0,sizeof(struct LRMI_regs)); | |
486 r.eax = 0x4f05; | |
487 r.ebx = win_num & 0x0f; | |
488 r.edx = win_gran; | |
2294 | 489 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; |
2243 | 490 retval = r.eax & 0xffff; |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
491 if(retval == 0x4f) retval = VBE_OK; |
2243 | 492 } |
493 return retval; | |
494 } | |
495 | |
2632 | 496 int vbeGetScanLineLength(unsigned *num_pixels,unsigned *num_bytes) |
497 { | |
498 struct LRMI_regs r; | |
499 int retval; | |
500 memset(&r,0,sizeof(struct LRMI_regs)); | |
501 r.eax = 0x4f06; | |
502 r.ebx = 1; | |
503 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; | |
504 retval = r.eax & 0xffff; | |
505 if(retval == 0x4f) | |
506 { | |
507 if(num_bytes) *num_bytes = r.ebx & 0xffff; | |
508 if(num_pixels) *num_pixels= r.ecx & 0xffff; | |
509 retval = VBE_OK; | |
510 } | |
511 return retval; | |
512 } | |
513 | |
514 int vbeGetMaxScanLines(unsigned *num_pixels,unsigned *num_bytes, unsigned *num_lines) | |
515 { | |
516 struct LRMI_regs r; | |
517 int retval; | |
518 memset(&r,0,sizeof(struct LRMI_regs)); | |
519 r.eax = 0x4f06; | |
520 r.ebx = 3; | |
521 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; | |
522 retval = r.eax & 0xffff; | |
523 if(retval == 0x4f) | |
524 { | |
525 if(num_bytes) *num_bytes = r.ebx & 0xffff; | |
526 if(num_pixels) *num_pixels= r.ecx & 0xffff; | |
527 if(num_lines) *num_lines = r.edx & 0xffff; | |
528 retval = VBE_OK; | |
529 } | |
530 return retval; | |
531 } | |
532 | |
533 int vbeSetScanLineLength(unsigned num_pixels) | |
534 { | |
535 int retval; | |
536 struct LRMI_regs r; | |
537 memset(&r,0,sizeof(struct LRMI_regs)); | |
538 r.eax = 0x4f06; | |
539 r.ebx = 0; | |
540 r.ecx = num_pixels; | |
541 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; | |
542 retval = r.eax & 0xffff; | |
543 if(retval == 0x4f) retval = VBE_OK; | |
544 return retval; | |
545 } | |
546 | |
547 int vbeSetScanLineLengthB(unsigned num_bytes) | |
548 { | |
549 int retval; | |
550 struct LRMI_regs r; | |
551 memset(&r,0,sizeof(struct LRMI_regs)); | |
552 r.eax = 0x4f06; | |
553 r.ebx = 2; | |
554 r.ecx = num_bytes; | |
555 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; | |
556 retval = r.eax & 0xffff; | |
557 if(retval == 0x4f) retval = VBE_OK; | |
558 return retval; | |
559 } | |
560 | |
561 int vbeGetDisplayStart(unsigned *pixel_num,unsigned *scan_line) | |
562 { | |
563 struct LRMI_regs r; | |
564 int retval; | |
565 memset(&r,0,sizeof(struct LRMI_regs)); | |
566 r.eax = 0x4f07; | |
567 r.ebx = 1; | |
568 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; | |
569 retval = r.eax & 0xffff; | |
570 if(retval == 0x4f) | |
571 { | |
572 if(pixel_num) *pixel_num = r.ecx & 0xffff; | |
573 if(scan_line) *scan_line = r.edx & 0xffff; | |
574 retval = VBE_OK; | |
575 } | |
576 return retval; | |
577 } | |
578 | |
579 int vbeSetDisplayStart(unsigned long offset, int vsync) | |
580 { | |
581 int retval; | |
582 if(vbe_pm_info.SetDisplayStart) | |
583 { | |
584 /* Don't verbose this stuff from performance reasons */ | |
585 /* 32-bit function call is much better of int 10h */ | |
586 __asm __volatile( | |
587 "pushl %%ebx\n" | |
588 "movl %1, %%ebx\n" | |
589 ::"a"(0x4f07),"S"(vsync ? 0x80 : 0), | |
2686 | 590 "c"((offset>>2) & 0xffff),"d"((offset>>18)&0xffff):"memory"); |
2632 | 591 (*vbe_pm_info.SetDisplayStart)(); |
592 __asm __volatile("popl %%ebx":::"memory"); | |
593 retval = VBE_OK; | |
594 } | |
595 else | |
596 { | |
2686 | 597 #if 0 |
598 /* Something wrong here */ | |
2632 | 599 struct LRMI_regs r; |
600 unsigned long pixel_num; | |
601 memset(&r,0,sizeof(struct LRMI_regs)); | |
2686 | 602 pixel_num = offset%(unsigned long)curr_mode_info.BytesPerScanLine; |
603 if(pixel_num*(unsigned long)curr_mode_info.BytesPerScanLine!=offset) pixel_num++; | |
2632 | 604 r.eax = 0x4f07; |
2693 | 605 r.ebx = vsync ? 0x82 : 2; |
2632 | 606 r.ecx = pixel_num; |
607 r.edx = offset/(unsigned long)curr_mode_info.BytesPerScanLine; | |
608 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; | |
609 retval = r.eax & 0xffff; | |
610 if(retval == 0x4f) retval = VBE_OK; | |
2686 | 611 #endif |
612 retval = VBE_BROKEN_BIOS; | |
2632 | 613 } |
614 return retval; | |
615 } | |
616 | |
2693 | 617 int vbeSetScheduledDisplayStart(unsigned long offset, int vsync) |
618 { | |
619 int retval; | |
620 struct LRMI_regs r; | |
621 unsigned long pixel_num; | |
622 memset(&r,0,sizeof(struct LRMI_regs)); | |
623 pixel_num = offset%(unsigned long)curr_mode_info.BytesPerScanLine; | |
624 if(pixel_num*(unsigned long)curr_mode_info.BytesPerScanLine!=offset) pixel_num++; | |
625 r.eax = 0x4f07; | |
626 r.ebx = vsync ? 0x82 : 2; | |
627 r.ecx = offset; | |
628 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; | |
629 retval = r.eax & 0xffff; | |
630 if(retval == 0x4f) retval = VBE_OK; | |
631 return retval; | |
632 } | |
633 | |
2243 | 634 struct realVesaProtModeInterface |
635 { | |
636 unsigned short SetWindowCall; | |
637 unsigned short SetDisplayStart; | |
638 unsigned short SetPaletteData; | |
639 unsigned short iopl_ports; | |
640 }__attribute__((packed)); | |
641 | |
642 int vbeGetProtModeInfo(struct VesaProtModeInterface *pm_info) | |
643 { | |
644 struct LRMI_regs r; | |
645 int retval; | |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
646 unsigned info_offset; |
2243 | 647 struct realVesaProtModeInterface *rm_info; |
648 memset(&r,0,sizeof(struct LRMI_regs)); | |
649 r.eax = 0x4f0a; | |
650 r.ebx = 0; | |
2294 | 651 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; |
2243 | 652 retval = r.eax & 0xffff; |
653 if(retval == 0x4f) | |
654 { | |
2407 | 655 retval = VBE_OK; |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
656 info_offset = r.edi&0xffff; |
2407 | 657 if((r.es >> 12) != hh_int_10_seg) retval = VBE_BROKEN_BIOS; |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
658 rm_info = PhysToVirtSO(r.es,info_offset); |
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
659 pm_info->SetWindowCall = PhysToVirtSO(r.es,info_offset+rm_info->SetWindowCall); |
2552 | 660 if(!is_addr_valid(pm_info->SetWindowCall)) retval = VBE_BROKEN_BIOS; |
2294 | 661 #ifdef HAVE_VERBOSE_VAR |
662 if(verbose > 1) printf("vbelib: SetWindowCall=%04X:%04X => %p\n",r.es,info_offset+rm_info->SetWindowCall,pm_info->SetWindowCall); | |
663 #endif | |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
664 pm_info->SetDisplayStart = PhysToVirtSO(r.es,info_offset+rm_info->SetDisplayStart); |
2552 | 665 if(!is_addr_valid(pm_info->SetDisplayStart)) retval = VBE_BROKEN_BIOS; |
2294 | 666 #ifdef HAVE_VERBOSE_VAR |
667 if(verbose > 1) printf("vbelib: SetDisplayStart=%04X:%04X => %p\n",r.es,info_offset+rm_info->SetDisplayStart,pm_info->SetDisplayStart); | |
668 #endif | |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
669 pm_info->SetPaletteData = PhysToVirtSO(r.es,info_offset+rm_info->SetPaletteData); |
2552 | 670 if(!is_addr_valid(pm_info->SetPaletteData)) retval = VBE_BROKEN_BIOS; |
2294 | 671 #ifdef HAVE_VERBOSE_VAR |
672 if(verbose > 1) printf("vbelib: SetPaletteData=%04X:%04X => %p\n",r.es,info_offset+rm_info->SetPaletteData,pm_info->SetPaletteData); | |
673 #endif | |
2254
6e5b548790c9
Fixed bug of 32-bit mode interface detection and save-restore mechanism
nick
parents:
2243
diff
changeset
|
674 pm_info->iopl_ports = PhysToVirtSO(r.es,info_offset+rm_info->iopl_ports); |
2913 | 675 if(!rm_info->iopl_ports) pm_info->iopl_ports = NULL; |
676 else | |
2515 | 677 if(!check_wrd(pm_info->iopl_ports)) |
678 { | |
679 pm_info->iopl_ports = NULL; | |
2913 | 680 /* retval = VBE_BROKEN_BIOS; <- It's for broken BIOSes only */ |
2515 | 681 } |
2294 | 682 #ifdef HAVE_VERBOSE_VAR |
2407 | 683 if(verbose > 1) |
684 { | |
685 printf("vbelib: iopl_ports=%04X:%04X => %p\n",r.es,info_offset+rm_info->iopl_ports,pm_info->iopl_ports); | |
2515 | 686 if(pm_info->iopl_ports) print_wrd(pm_info->iopl_ports); |
2518 | 687 fflush(stdout); |
2407 | 688 } |
2294 | 689 #endif |
2243 | 690 } |
691 return retval; | |
692 } | |
2410 | 693 /* --------- Standard VGA stuff -------------- */ |
694 int vbeWriteString(int x, int y, int attr, char *str) | |
695 { | |
696 struct LRMI_regs r; | |
697 void *rm_space = NULL; | |
698 int retval; | |
699 memset(&r,0,sizeof(struct LRMI_regs)); | |
700 r.ecx = strlen(str); | |
701 r.edx = ((y<<8)&0xff00)|(x&0xff); | |
702 r.ebx = attr; | |
703 if(!(rm_space = LRMI_alloc_real(r.ecx))) return VBE_OUT_OF_DOS_MEM; | |
704 r.es = VirtToPhysSeg(rm_space); | |
705 r.ebp = VirtToPhysOff(rm_space); | |
706 memcpy(rm_space,str,r.ecx); | |
707 r.eax = 0x1300; | |
708 retval = VBE_LRMI_int(0x10,&r); | |
6473
6c45b8bf9a3e
date: 2002/06/16 09:10:00; author: nickols_k; state: Exp; lines: +17 -13
atmos4
parents:
4405
diff
changeset
|
709 LRMI_free_real(rm_space); |
2410 | 710 if(!retval) return VBE_VM86_FAIL; |
711 retval = r.eax & 0xffff; | |
712 if(retval == 0x4f) retval = VBE_OK; | |
713 return retval; | |
2460 | 714 } |
2610 | 715 |
716 void * vbeMapVideoBuffer(unsigned long phys_addr,unsigned long size) | |
717 { | |
718 void *lfb; | |
719 if(fd_mem == -1) return NULL; | |
720 if(verbose > 1) printf("vbelib: vbeMapVideoBuffer(%08lX,%08lX)\n",phys_addr,size); | |
721 /* Here we don't need with MAP_FIXED and prefered address (first argument) */ | |
722 lfb = mmap((void *)0,size,PROT_READ | PROT_WRITE,MAP_SHARED,fd_mem,phys_addr); | |
723 return lfb == (void *)-1 ? 0 : lfb; | |
724 } | |
725 | |
726 void vbeUnmapVideoBuffer(unsigned long linear_addr,unsigned long size) | |
727 { | |
728 if(verbose > 1) printf("vbelib: vbeUnmapVideoBuffer(%08lX,%08lX)\n",linear_addr,size); | |
729 munmap((void *)linear_addr,size); | |
730 } |