Forced subs support for mencoder
[mplayer/glamo.git] / osdep / vbelib.c
blob356a0e3ac3644d361d7a068dbaa4ae4a70be3227
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
7 of GNU General Public licence v2.
8 Written by Nick Kurshev <nickols_k@mail.ru>
9 */
11 #include <../config.h>
12 #ifdef HAVE_VESA
14 #include "vbelib.h"
15 #include "lrmi.h"
16 #include <stdlib.h>
17 #include <string.h>
18 #include <stdio.h>
19 #include <sys/io.h>
20 #include <sys/mman.h>
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <ctype.h>
24 #include <unistd.h>
25 #include <fcntl.h>
27 static struct VesaProtModeInterface vbe_pm_info;
28 static struct VesaModeInfoBlock curr_mode_info;
30 static inline int VERR(const void *p)
32 register int retval;
33 __asm __volatile(
34 "xorl %0, %0\n\t"
35 "verr %1\n\t"
36 "setnz %b0"
37 :"=q"(retval)
38 :"m"(*(unsigned char *)p)
39 :"memory","cc");
40 return retval;
43 #if 0
44 static inline int VERW(const void *p)
46 register int retval;
47 __asm __volatile(
48 "xorl %0, %0\n\t"
49 "verw %1\n\t"
50 "setnz %b0"
51 :"=q"(retval)
52 :"m"(*(unsigned char *)p)
53 :"memory","cc");
54 return retval;
56 #endif
58 #define HAVE_VERBOSE_VAR 1
60 #ifdef HAVE_VERBOSE_VAR
61 extern int verbose;
63 static void __dump_regs(struct LRMI_regs *r)
65 printf("vbelib: eax=%08lXh ebx=%08lXh ecx=%08lXh edx=%08lXh\n"
66 "vbelib: edi=%08lXh esi=%08lXh ebp=%08lXh esp=%08lXh\n"
67 "vbelib: ds=%04Xh es=%04Xh ss=%04Xh cs:ip=%04X:%04X\n"
68 "vbelib: fs=%04Xh gs=%04Xh ss:sp=%04X:%04X flags=%04X\n"
69 ,(unsigned long)r->eax,(unsigned long)r->ebx,(unsigned long)r->ecx,(unsigned long)r->edx
70 ,(unsigned long)r->edi,(unsigned long)r->esi,(unsigned long)r->ebp,(unsigned long)r->reserved
71 ,r->ds,r->es,r->ss,r->cs,r->ip
72 ,r->fs,r->gs,r->ss,r->sp,r->flags);
75 static inline int VBE_LRMI_int(int int_no, struct LRMI_regs *r)
77 int retval;
78 if(verbose > 1)
80 printf("vbelib: registers before int %02X\n",int_no);
81 __dump_regs(r);
83 retval = LRMI_int(int_no,r);
84 if(verbose > 1)
86 printf("vbelib: Interrupt handler returns: %X\n",retval);
87 printf("vbelib: registers after int %02X\n",int_no);
88 __dump_regs(r);
90 return retval;
92 #else
93 #define VBE_LRMI_int(int_no,regs) (VBE_LRMI_int(int_no,regs))
94 #endif
96 static FILE *my_stdin;
97 static FILE *my_stdout;
98 static FILE *my_stderr;
100 static void __set_cursor_type(FILE *stdout_fd,int cursor_on)
102 fprintf(stdout_fd,"\033[?25%c",cursor_on?'h':'l');
105 /* TODO: do it only on LCD or DFP. We should extract such info from DDC */
106 static void hide_terminal_output( void )
108 my_stdin = fopen(ttyname(fileno(stdin )),"r");
109 my_stdout = fopen(ttyname(fileno(stdout)),"w");
110 my_stderr = fopen(ttyname(fileno(stderr)),"w");
111 __set_cursor_type(stdout,0);
112 /*if(isatty(fileno(stdin ))) stdin =freopen("/dev/null","r",stdin );*/
113 if(isatty(fileno(stdout))) stdout=freopen("/dev/null","w",stdout);
114 if(isatty(fileno(stderr))) stderr=freopen("/dev/null","w",stderr);
117 static unsigned hh_int_10_seg;
118 static int fd_mem;
120 the list of supported video modes is stored in the reserved portion of
121 the SuperVGA information record by some implementations, and it may
122 thus be necessary to either copy the mode list or use a different
123 buffer for all subsequent VESA calls
125 static void *controller_info;
126 int vbeInit( void )
128 unsigned short iopl_port;
129 size_t i;
130 int retval;
131 if(!LRMI_init()) return VBE_VM86_FAIL;
132 if(!(controller_info = LRMI_alloc_real(sizeof(struct VbeInfoBlock)))) return VBE_OUT_OF_DOS_MEM;
134 Allow read/write to ALL io ports
136 hh_int_10_seg = *(unsigned short *)PhysToVirtSO(0x0000,0x0042);
137 /* Video BIOS should be at C000:0000 and above */
138 hh_int_10_seg >>= 12;
139 if(hh_int_10_seg < 0xC) return VBE_BROKEN_BIOS;
140 ioperm(0, 1024, 1);
141 iopl(3);
142 memset(&vbe_pm_info,0,sizeof(struct VesaProtModeInterface));
143 retval = vbeGetProtModeInfo(&vbe_pm_info);
144 if(retval != VBE_OK) return retval;
145 i = 0;
146 if(vbe_pm_info.iopl_ports) /* Can be NULL !!!*/
147 while((iopl_port=vbe_pm_info.iopl_ports[i]) != 0xFFFF
148 && vbe_pm_info.iopl_ports[i++] > 1023) ioperm(iopl_port,1,1);
149 iopl(3);
150 fd_mem = open("/dev/mem",O_RDWR);
151 hide_terminal_output();
152 return VBE_OK;
155 int vbeDestroy( void )
157 if (my_stdout) __set_cursor_type(my_stdout,1);
158 close(fd_mem);
159 LRMI_free_real(controller_info);
160 return VBE_OK;
163 /* Fixme!!! This code is compatible only with mplayer's version of lrmi*/
164 static inline int is_addr_valid(const void *p)
166 return (p < (const void *)0x502) ||
167 (p >= (const void *)0x10000 && p < (const void *)0x20000) ||
168 (p >= (const void *)0xa0000 && p < (const void *)0x100000);
171 static int check_str(const unsigned char *str)
173 size_t i;
174 int null_found = 0;
175 for(i = 0;i < 256;i++)
177 if(is_addr_valid(&str[i]))
179 if(VERR(&str[i]))
181 if(!str[i]) { null_found = 1; break; }
183 else break;
185 else break;
187 return null_found;
190 static int check_wrd(const unsigned short *str)
192 size_t i;
193 int ffff_found = 0;
194 for(i = 0;i < 1024;i++)
196 if(is_addr_valid(&str[i]))
198 if(VERR(&str[i]))
200 if(str[i] == 0xffff) { ffff_found = 1; break; }
202 else break;
204 else break;
206 return ffff_found;
209 static void print_str(unsigned char *str)
211 size_t i;
212 fflush(stdout);
213 printf("vbelib: ");
214 for(i = 0;i < 256;i++) { printf("%02X(%c) ",str[i],isprint(str[i])?str[i]:'.'); if(!str[i]) break; }
215 printf("\n");
216 fflush(stdout);
219 static void print_wrd(unsigned short *str)
221 size_t i;
222 fflush(stdout);
223 printf("vbelib: ");
224 for(i = 0;i < 256;i++) { printf("%04X ",str[i]); if(str[i] == 0xffff) break; }
225 printf("\n");
226 fflush(stdout);
229 int vbeGetControllerInfo(struct VbeInfoBlock *data)
231 struct LRMI_regs r;
232 int retval;
233 memcpy(controller_info,data,sizeof(struct VbeInfoBlock));
234 memset(&r,0,sizeof(struct LRMI_regs));
235 r.eax = 0x4f00;
236 r.es = VirtToPhysSeg(controller_info);
237 r.edi = VirtToPhysOff(controller_info);
238 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
239 retval = r.eax & 0xffff;
240 if(retval == 0x4f)
242 FarPtr fpdata;
243 retval = VBE_OK;
244 memcpy(data,controller_info,sizeof(struct VbeInfoBlock));
245 fpdata.seg = (unsigned long)(data->OemStringPtr) >> 16;
246 fpdata.off = (unsigned long)(data->OemStringPtr) & 0xffff;
247 data->OemStringPtr = PhysToVirt(fpdata);
248 if(!check_str(data->OemStringPtr)) data->OemStringPtr = NULL;
249 #ifdef HAVE_VERBOSE_VAR
250 if(verbose > 1)
252 printf("vbelib: OemStringPtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemStringPtr);
253 if(data->OemStringPtr) print_str(data->OemStringPtr);
254 fflush(stdout);
256 #endif
257 fpdata.seg = (unsigned long)(data->VideoModePtr) >> 16;
258 fpdata.off = (unsigned long)(data->VideoModePtr) & 0xffff;
259 data->VideoModePtr = PhysToVirt(fpdata);
260 if(!check_wrd(data->VideoModePtr))
262 data->VideoModePtr = NULL;
263 retval = VBE_BROKEN_BIOS;
265 #ifdef HAVE_VERBOSE_VAR
266 if(verbose > 1)
268 printf("vbelib: VideoModePtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->VideoModePtr);
269 if(data->VideoModePtr) print_wrd(data->VideoModePtr);
270 fflush(stdout);
272 #endif
273 fpdata.seg = (unsigned long)(data->OemVendorNamePtr) >> 16;
274 fpdata.off = (unsigned long)(data->OemVendorNamePtr) & 0xffff;
275 data->OemVendorNamePtr = PhysToVirt(fpdata);
276 if(!check_str(data->OemVendorNamePtr)) data->OemVendorNamePtr = NULL;
277 #ifdef HAVE_VERBOSE_VAR
278 if(verbose > 1)
280 printf("vbelib: OemVendorNamePtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemVendorNamePtr);
281 if(data->OemVendorNamePtr) print_str(data->OemVendorNamePtr);
282 fflush(stdout);
284 #endif
285 fpdata.seg = (unsigned long)(data->OemProductNamePtr) >> 16;
286 fpdata.off = (unsigned long)(data->OemProductNamePtr) & 0xffff;
287 data->OemProductNamePtr = PhysToVirt(fpdata);
288 if(!check_str(data->OemProductNamePtr)) data->OemProductNamePtr = NULL;
289 #ifdef HAVE_VERBOSE_VAR
290 if(verbose > 1)
292 printf("vbelib: OemProductNamePtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemProductNamePtr);
293 if(data->OemVendorNamePtr) print_str(data->OemProductNamePtr);
294 fflush(stdout);
296 #endif
297 fpdata.seg = (unsigned long)(data->OemProductRevPtr) >> 16;
298 fpdata.off = (unsigned long)(data->OemProductRevPtr) & 0xffff;
299 data->OemProductRevPtr = PhysToVirt(fpdata);
300 if(!check_str(data->OemProductRevPtr)) data->OemProductRevPtr = NULL;
301 #ifdef HAVE_VERBOSE_VAR
302 if(verbose > 1)
304 printf("vbelib: OemProductRevPtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemProductRevPtr);
305 if(data->OemProductRevPtr) print_str(data->OemProductRevPtr);
306 fflush(stdout);
308 #endif
310 return retval;
313 int vbeGetModeInfo(unsigned mode,struct VesaModeInfoBlock *data)
315 struct LRMI_regs r;
316 void *rm_space;
317 int retval;
318 if(!(rm_space = LRMI_alloc_real(sizeof(struct VesaModeInfoBlock)))) return VBE_OUT_OF_DOS_MEM;
319 memset(&r,0,sizeof(struct LRMI_regs));
320 r.eax = 0x4f01;
321 r.ecx = mode;
322 r.es = VirtToPhysSeg(rm_space);
323 r.edi = VirtToPhysOff(rm_space);
324 if(!VBE_LRMI_int(0x10,&r))
326 LRMI_free_real(rm_space);
327 return VBE_VM86_FAIL;
329 retval = r.eax & 0xffff;
330 if(retval == 0x4f)
332 retval = VBE_OK;
333 memcpy(data,rm_space,sizeof(struct VesaModeInfoBlock));
335 LRMI_free_real(rm_space);
336 return retval;
339 int vbeSetMode(unsigned mode,struct VesaCRTCInfoBlock *data)
341 struct LRMI_regs r;
342 void *rm_space = NULL;
343 int retval;
344 memset(&r,0,sizeof(struct LRMI_regs));
345 if(data)
347 if(!(rm_space = LRMI_alloc_real(sizeof(struct VesaCRTCInfoBlock)))) return VBE_OUT_OF_DOS_MEM;
348 r.es = VirtToPhysSeg(rm_space);
349 r.edi = VirtToPhysOff(rm_space);
350 memcpy(rm_space,data,sizeof(struct VesaCRTCInfoBlock));
352 r.eax = 0x4f02;
353 r.ebx = mode;
354 retval = VBE_LRMI_int(0x10,&r);
355 LRMI_free_real(rm_space);
356 if(!retval) return VBE_VM86_FAIL;
357 retval = r.eax & 0xffff;
358 if(retval == 0x4f)
360 /* Just info for internal use (currently in SetDiplayStart func). */
361 vbeGetModeInfo(mode&0x1f,&curr_mode_info);
362 retval = VBE_OK;
364 return retval;
367 int vbeGetMode(unsigned *mode)
369 struct LRMI_regs r;
370 int retval;
371 memset(&r,0,sizeof(struct LRMI_regs));
372 r.eax = 0x4f03;
373 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
374 retval = r.eax & 0xffff;
375 if(retval == 0x4f)
377 *mode = r.ebx;
378 retval = VBE_OK;
380 return retval;
383 int vbeGetPixelClock(unsigned *mode,unsigned *pixel_clock) // in Hz
385 struct LRMI_regs r;
386 int retval;
387 memset(&r,0,sizeof(struct LRMI_regs));
388 r.eax = 0x4f0b;
389 r.ebx = 0;
390 r.edx = *mode;
391 r.ecx = *pixel_clock;
392 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
393 retval = r.eax & 0xffff;
394 if(retval == 0x4f)
396 *pixel_clock = r.ecx;
397 retval = VBE_OK;
399 return retval;
403 int vbeSaveState(void **data)
405 struct LRMI_regs r;
406 int retval;
407 void *rm_space;
408 memset(&r,0,sizeof(struct LRMI_regs));
409 r.eax = 0x4f04;
410 r.edx = 0x00;
411 r.ecx = 0x0f;
412 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
413 retval = r.eax & 0xffff;
414 if(retval != 0x4f) return retval;
415 if(!(rm_space = LRMI_alloc_real((r.ebx & 0xffff)*64))) return VBE_OUT_OF_DOS_MEM;
416 r.eax = 0x4f04;
417 r.edx = 0x01;
418 r.ecx = 0x0f;
419 r.es = VirtToPhysSeg(rm_space);
420 r.ebx = VirtToPhysOff(rm_space);
421 if(!VBE_LRMI_int(0x10,&r))
423 LRMI_free_real(rm_space);
424 return VBE_VM86_FAIL;
426 retval = r.eax & 0xffff;
427 if(retval != 0x4f)
429 LRMI_free_real(rm_space);
430 return retval;
432 *data = rm_space;
433 return VBE_OK;
436 int vbeRestoreState(void *data)
438 struct LRMI_regs r;
439 int retval;
440 memset(&r,0,sizeof(struct LRMI_regs));
441 r.eax = 0x4f04;
442 r.edx = 0x02;
443 r.ecx = 0x0f;
444 r.es = VirtToPhysSeg(data);
445 r.ebx = VirtToPhysOff(data);
446 retval = VBE_LRMI_int(0x10,&r);
447 LRMI_free_real(data);
448 if(!retval) return VBE_VM86_FAIL;
449 retval = r.eax & 0xffff;
450 if(retval == 0x4f) retval = VBE_OK;
451 return retval;
454 int vbeGetWindow(unsigned *win_num)
456 struct LRMI_regs r;
457 int retval;
458 memset(&r,0,sizeof(struct LRMI_regs));
459 r.eax = 0x4f05;
460 r.ebx = (*win_num & 0x0f) | 0x0100;
461 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
462 retval = r.eax & 0xffff;
463 if(retval == 0x4f)
465 *win_num = r.edx & 0xffff;
466 retval = VBE_OK;
468 return retval;
471 int vbeSetWindow(unsigned win_num,unsigned win_gran)
473 int retval;
474 if(vbe_pm_info.SetWindowCall)
476 /* Don't verbose this stuff from performance reasons */
477 /* 32-bit function call is much better of int 10h */
478 __asm __volatile(
479 "pushl %%ebx\n"
480 "movl %1, %%ebx\n"
481 ::"a"(0x4f05),"S"(win_num & 0x0f),"d"(win_gran):"memory");
482 (*vbe_pm_info.SetWindowCall)();
483 __asm __volatile("popl %%ebx":::"memory");
484 retval = VBE_OK;
486 else
488 struct LRMI_regs r;
489 memset(&r,0,sizeof(struct LRMI_regs));
490 r.eax = 0x4f05;
491 r.ebx = win_num & 0x0f;
492 r.edx = win_gran;
493 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
494 retval = r.eax & 0xffff;
495 if(retval == 0x4f) retval = VBE_OK;
497 return retval;
500 int vbeGetScanLineLength(unsigned *num_pixels,unsigned *num_bytes)
502 struct LRMI_regs r;
503 int retval;
504 memset(&r,0,sizeof(struct LRMI_regs));
505 r.eax = 0x4f06;
506 r.ebx = 1;
507 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
508 retval = r.eax & 0xffff;
509 if(retval == 0x4f)
511 if(num_bytes) *num_bytes = r.ebx & 0xffff;
512 if(num_pixels) *num_pixels= r.ecx & 0xffff;
513 retval = VBE_OK;
515 return retval;
518 int vbeGetMaxScanLines(unsigned *num_pixels,unsigned *num_bytes, unsigned *num_lines)
520 struct LRMI_regs r;
521 int retval;
522 memset(&r,0,sizeof(struct LRMI_regs));
523 r.eax = 0x4f06;
524 r.ebx = 3;
525 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
526 retval = r.eax & 0xffff;
527 if(retval == 0x4f)
529 if(num_bytes) *num_bytes = r.ebx & 0xffff;
530 if(num_pixels) *num_pixels= r.ecx & 0xffff;
531 if(num_lines) *num_lines = r.edx & 0xffff;
532 retval = VBE_OK;
534 return retval;
537 int vbeSetScanLineLength(unsigned num_pixels)
539 int retval;
540 struct LRMI_regs r;
541 memset(&r,0,sizeof(struct LRMI_regs));
542 r.eax = 0x4f06;
543 r.ebx = 0;
544 r.ecx = num_pixels;
545 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
546 retval = r.eax & 0xffff;
547 if(retval == 0x4f) retval = VBE_OK;
548 return retval;
551 int vbeSetScanLineLengthB(unsigned num_bytes)
553 int retval;
554 struct LRMI_regs r;
555 memset(&r,0,sizeof(struct LRMI_regs));
556 r.eax = 0x4f06;
557 r.ebx = 2;
558 r.ecx = num_bytes;
559 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
560 retval = r.eax & 0xffff;
561 if(retval == 0x4f) retval = VBE_OK;
562 return retval;
565 int vbeGetDisplayStart(unsigned *pixel_num,unsigned *scan_line)
567 struct LRMI_regs r;
568 int retval;
569 memset(&r,0,sizeof(struct LRMI_regs));
570 r.eax = 0x4f07;
571 r.ebx = 1;
572 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
573 retval = r.eax & 0xffff;
574 if(retval == 0x4f)
576 if(pixel_num) *pixel_num = r.ecx & 0xffff;
577 if(scan_line) *scan_line = r.edx & 0xffff;
578 retval = VBE_OK;
580 return retval;
583 int vbeSetDisplayStart(unsigned long offset, int vsync)
585 int retval;
586 if(vbe_pm_info.SetDisplayStart)
588 /* Don't verbose this stuff from performance reasons */
589 /* 32-bit function call is much better of int 10h */
590 __asm __volatile(
591 "pushl %%ebx\n"
592 "movl %1, %%ebx\n"
593 ::"a"(0x4f07),"S"(vsync ? 0x80 : 0),
594 "c"((offset>>2) & 0xffff),"d"((offset>>18)&0xffff):"memory");
595 (*vbe_pm_info.SetDisplayStart)();
596 __asm __volatile("popl %%ebx":::"memory");
597 retval = VBE_OK;
599 else
601 #if 0
602 /* Something wrong here */
603 struct LRMI_regs r;
604 unsigned long pixel_num;
605 memset(&r,0,sizeof(struct LRMI_regs));
606 pixel_num = offset%(unsigned long)curr_mode_info.BytesPerScanLine;
607 if(pixel_num*(unsigned long)curr_mode_info.BytesPerScanLine!=offset) pixel_num++;
608 r.eax = 0x4f07;
609 r.ebx = vsync ? 0x82 : 2;
610 r.ecx = pixel_num;
611 r.edx = offset/(unsigned long)curr_mode_info.BytesPerScanLine;
612 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
613 retval = r.eax & 0xffff;
614 if(retval == 0x4f) retval = VBE_OK;
615 #endif
616 retval = VBE_BROKEN_BIOS;
618 return retval;
621 int vbeSetScheduledDisplayStart(unsigned long offset, int vsync)
623 int retval;
624 struct LRMI_regs r;
625 unsigned long pixel_num;
626 memset(&r,0,sizeof(struct LRMI_regs));
627 pixel_num = offset%(unsigned long)curr_mode_info.BytesPerScanLine;
628 if(pixel_num*(unsigned long)curr_mode_info.BytesPerScanLine!=offset) pixel_num++;
629 r.eax = 0x4f07;
630 r.ebx = vsync ? 0x82 : 2;
631 r.ecx = offset;
632 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
633 retval = r.eax & 0xffff;
634 if(retval == 0x4f) retval = VBE_OK;
635 return retval;
638 struct realVesaProtModeInterface
640 unsigned short SetWindowCall;
641 unsigned short SetDisplayStart;
642 unsigned short SetPaletteData;
643 unsigned short iopl_ports;
644 }__attribute__((packed));
646 int vbeGetProtModeInfo(struct VesaProtModeInterface *pm_info)
648 struct LRMI_regs r;
649 int retval;
650 unsigned info_offset;
651 struct realVesaProtModeInterface *rm_info;
652 memset(&r,0,sizeof(struct LRMI_regs));
653 r.eax = 0x4f0a;
654 r.ebx = 0;
655 if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL;
656 retval = r.eax & 0xffff;
657 if(retval == 0x4f)
659 retval = VBE_OK;
660 info_offset = r.edi&0xffff;
661 if((r.es >> 12) != hh_int_10_seg) retval = VBE_BROKEN_BIOS;
662 rm_info = PhysToVirtSO(r.es,info_offset);
663 pm_info->SetWindowCall = PhysToVirtSO(r.es,info_offset+rm_info->SetWindowCall);
664 if(!is_addr_valid(pm_info->SetWindowCall)) retval = VBE_BROKEN_BIOS;
665 #ifdef HAVE_VERBOSE_VAR
666 if(verbose > 1) printf("vbelib: SetWindowCall=%04X:%04X => %p\n",r.es,info_offset+rm_info->SetWindowCall,pm_info->SetWindowCall);
667 #endif
668 pm_info->SetDisplayStart = PhysToVirtSO(r.es,info_offset+rm_info->SetDisplayStart);
669 if(!is_addr_valid(pm_info->SetDisplayStart)) retval = VBE_BROKEN_BIOS;
670 #ifdef HAVE_VERBOSE_VAR
671 if(verbose > 1) printf("vbelib: SetDisplayStart=%04X:%04X => %p\n",r.es,info_offset+rm_info->SetDisplayStart,pm_info->SetDisplayStart);
672 #endif
673 pm_info->SetPaletteData = PhysToVirtSO(r.es,info_offset+rm_info->SetPaletteData);
674 if(!is_addr_valid(pm_info->SetPaletteData)) retval = VBE_BROKEN_BIOS;
675 #ifdef HAVE_VERBOSE_VAR
676 if(verbose > 1) printf("vbelib: SetPaletteData=%04X:%04X => %p\n",r.es,info_offset+rm_info->SetPaletteData,pm_info->SetPaletteData);
677 #endif
678 pm_info->iopl_ports = PhysToVirtSO(r.es,info_offset+rm_info->iopl_ports);
679 if(!rm_info->iopl_ports) pm_info->iopl_ports = NULL;
680 else
681 if(!check_wrd(pm_info->iopl_ports))
683 pm_info->iopl_ports = NULL;
684 /* retval = VBE_BROKEN_BIOS; <- It's for broken BIOSes only */
686 #ifdef HAVE_VERBOSE_VAR
687 if(verbose > 1)
689 printf("vbelib: iopl_ports=%04X:%04X => %p\n",r.es,info_offset+rm_info->iopl_ports,pm_info->iopl_ports);
690 if(pm_info->iopl_ports) print_wrd(pm_info->iopl_ports);
691 fflush(stdout);
693 #endif
695 return retval;
697 /* --------- Standard VGA stuff -------------- */
698 int vbeWriteString(int x, int y, int attr, char *str)
700 struct LRMI_regs r;
701 void *rm_space = NULL;
702 int retval;
703 memset(&r,0,sizeof(struct LRMI_regs));
704 r.ecx = strlen(str);
705 r.edx = ((y<<8)&0xff00)|(x&0xff);
706 r.ebx = attr;
707 if(!(rm_space = LRMI_alloc_real(r.ecx))) return VBE_OUT_OF_DOS_MEM;
708 r.es = VirtToPhysSeg(rm_space);
709 r.ebp = VirtToPhysOff(rm_space);
710 memcpy(rm_space,str,r.ecx);
711 r.eax = 0x1300;
712 retval = VBE_LRMI_int(0x10,&r);
713 LRMI_free_real(rm_space);
714 if(!retval) return VBE_VM86_FAIL;
715 retval = r.eax & 0xffff;
716 if(retval == 0x4f) retval = VBE_OK;
717 return retval;
720 void * vbeMapVideoBuffer(unsigned long phys_addr,unsigned long size)
722 void *lfb;
723 if(fd_mem == -1) return NULL;
724 if(verbose > 1) printf("vbelib: vbeMapVideoBuffer(%08lX,%08lX)\n",phys_addr,size);
725 /* Here we don't need with MAP_FIXED and prefered address (first argument) */
726 lfb = mmap((void *)0,size,PROT_READ | PROT_WRITE,MAP_SHARED,fd_mem,phys_addr);
727 return lfb == (void *)-1 ? 0 : lfb;
730 void vbeUnmapVideoBuffer(unsigned long linear_addr,unsigned long size)
732 if(verbose > 1) printf("vbelib: vbeUnmapVideoBuffer(%08lX,%08lX)\n",linear_addr,size);
733 munmap((void *)linear_addr,size);
736 #endif