Mercurial > mplayer.hg
changeset 16256:578e8b4c3e7f
use libvbe from vesautils
author | alex |
---|---|
date | Thu, 18 Aug 2005 11:26:04 +0000 |
parents | 2b75978da320 |
children | 73b892059101 |
files | Makefile configure libvo/vo_vesa.c osdep/Makefile osdep/lrmi.c osdep/lrmi.h osdep/vbelib.c osdep/vbelib.h |
diffstat | 8 files changed, 10 insertions(+), 2036 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Thu Aug 18 11:18:44 2005 +0000 +++ b/Makefile Thu Aug 18 11:26:04 2005 +0000 @@ -78,6 +78,7 @@ $(SVGA_LIB) \ $(DIRECTFB_LIB) \ $(CACA_LIB) \ + $(VESA_LIB) \ AO_LIBS = $(ARTS_LIB) \ $(ESD_LIB) \
--- a/configure Thu Aug 18 11:18:44 2005 +0000 +++ b/configure Thu Aug 18 11:26:04 2005 +0000 @@ -4290,23 +4290,22 @@ echocheck "VESA support" if test "$_vesa" = auto ; then -if x86 && linux ; then + cat > $TMPC << EOF +#include <vbe.h> +int main(void) { vbeVersion(); return 0; } +EOF _vesa=no - cat > $TMPC << EOF -#include <sys/io.h> -int main(void) { return 0; } -EOF - cc_check && _vesa=yes -fi + cc_check -lvbe -llrmi && _vesa=yes fi if test "$_vesa" = yes ; then _def_vesa='#define HAVE_VESA 1' + _ld_vesa="-lvbe -llrmi" _vosrc="$_vosrc vo_vesa.c vesa_lvo.c" _vomodules="vesa $_vomodules" echores "yes" else _def_vesa='#undef HAVE_VESA' - echores "no (not supported on this OS/architecture)" + echores "no" _novomodules="vesa $_novomodules" fi @@ -7025,6 +7024,7 @@ GIF_LIB = $_ld_gif SDL_LIB = $_ld_sdl SVGA_LIB = $_ld_svga +VESA_LIB = $_ld_vesa AA_LIB = $_ld_aa CACA_INC = $_inc_caca CACA_LIB = $_ld_caca
--- a/libvo/vo_vesa.c Thu Aug 18 11:18:44 2005 +0000 +++ b/libvo/vo_vesa.c Thu Aug 18 11:26:04 2005 +0000 @@ -30,13 +30,13 @@ #include <sys/stat.h> #include <fcntl.h> +#include <vbe.h> #include "video_out.h" #include "video_out_internal.h" #include "fastmemcpy.h" #include "sub.h" -#include "osdep/vbelib.h" #include "bswap.h" #include "aspect.h" #include "vesa_lvo.h"
--- a/osdep/Makefile Thu Aug 18 11:18:44 2005 +0000 +++ b/osdep/Makefile Thu Aug 18 11:26:04 2005 +0000 @@ -7,12 +7,6 @@ swab.c # timer.c -ifeq ($(TARGET_ARCH_X86),yes) -ifeq ($(TARGET_OS),Linux) -SRCS += lrmi.c vbelib.c -endif -endif - getch = getch2.c timer = timer-lx.c ifeq ($(MACOSX_FINDER_SUPPORT),yes)
--- a/osdep/lrmi.c Thu Aug 18 11:18:44 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,928 +0,0 @@ -/* -Linux Real Mode Interface - A library of DPMI-like functions for Linux. - -Copyright (C) 1998 by Josh Vanderhoof - -You are free to distribute and modify this file, as long as you -do not remove this copyright notice and clearly label modified -versions as being modified. - -This software has NO WARRANTY. Use it at your own risk. -Original location: http://cvs.debian.org/lrmi/ - -Modified for use with MPlayer, see the CVS log for details. -*/ - -#include "../config.h" -#ifdef HAVE_VESA - -#include <signal.h> -#include <stdio.h> -#include <string.h> -#include <sys/io.h> -#include <asm/vm86.h> - -#ifdef USE_LIBC_VM86 -#include <sys/vm86.h> -#endif - -#include <sys/types.h> -#include <sys/stat.h> -#include <sys/mman.h> -#include <unistd.h> -#include <fcntl.h> - -#include "lrmi.h" - -#define REAL_MEM_BASE ((void *)0x10000) -#define REAL_MEM_SIZE 0x10000 -#define REAL_MEM_BLOCKS 0x100 - -struct mem_block - { - unsigned int size : 20; - unsigned int free : 1; - }; - -static struct - { - int ready; - int count; - struct mem_block blocks[REAL_MEM_BLOCKS]; - } mem_info = { .ready = 0, }; - -static int -real_mem_init(void) - { - void *m; - int fd_zero; - - if (mem_info.ready) - return 1; - - fd_zero = open("/dev/zero", O_RDONLY); - if (fd_zero == -1) - { - perror("open /dev/zero"); - return 0; - } - - m = mmap((void *)REAL_MEM_BASE, REAL_MEM_SIZE, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE, fd_zero, 0); - - if (m == (void *)-1) - { - perror("mmap /dev/zero"); - close(fd_zero); - return 0; - } - - mem_info.ready = 1; - mem_info.count = 1; - mem_info.blocks[0].size = REAL_MEM_SIZE; - mem_info.blocks[0].free = 1; - - return 1; - } - - -static void -insert_block(int i) - { - memmove( - mem_info.blocks + i + 1, - mem_info.blocks + i, - (mem_info.count - i) * sizeof(struct mem_block)); - - mem_info.count++; - } - -static void -delete_block(int i) - { - mem_info.count--; - - memmove( - mem_info.blocks + i, - mem_info.blocks + i + 1, - (mem_info.count - i) * sizeof(struct mem_block)); - } - -void * -LRMI_alloc_real(int size) - { - int i; - char *r = (char *)REAL_MEM_BASE; - - if (!mem_info.ready) - return NULL; - - if (mem_info.count == REAL_MEM_BLOCKS) - return NULL; - - size = (size + 15) & ~15; - - for (i = 0; i < mem_info.count; i++) - { - if (mem_info.blocks[i].free && size < mem_info.blocks[i].size) - { - insert_block(i); - - mem_info.blocks[i].size = size; - mem_info.blocks[i].free = 0; - mem_info.blocks[i + 1].size -= size; - - return (void *)r; - } - - r += mem_info.blocks[i].size; - } - - return NULL; - } - - -void -LRMI_free_real(void *m) - { - int i; - char *r = (char *)REAL_MEM_BASE; - - if (!mem_info.ready) - return; - - i = 0; - while (m != (void *)r) - { - r += mem_info.blocks[i].size; - i++; - if (i == mem_info.count) - return; - } - - mem_info.blocks[i].free = 1; - - if (i + 1 < mem_info.count && mem_info.blocks[i + 1].free) - { - mem_info.blocks[i].size += mem_info.blocks[i + 1].size; - delete_block(i + 1); - } - - if (i - 1 >= 0 && mem_info.blocks[i - 1].free) - { - mem_info.blocks[i - 1].size += mem_info.blocks[i].size; - delete_block(i); - } - } - - -#define DEFAULT_VM86_FLAGS (IF_MASK | IOPL_MASK) -#define DEFAULT_STACK_SIZE 0x1000 -#define RETURN_TO_32_INT 255 - -static struct - { - int ready; - unsigned short ret_seg, ret_off; - unsigned short stack_seg, stack_off; - struct vm86_struct vm; - } context = { .ready = 0, }; - - -static inline void -set_bit(unsigned int bit, void *array) - { - unsigned char *a = array; - - a[bit / 8] |= (1 << (bit % 8)); - } - - -static inline unsigned int -get_int_seg(int i) - { - return *(unsigned short *)(i * 4 + 2); - } - - -static inline unsigned int -get_int_off(int i) - { - return *(unsigned short *)(i * 4); - } - - -static inline void -pushw(unsigned short i) - { - struct vm86_regs *r = &context.vm.regs; - r->esp -= 2; - *(unsigned short *)(((unsigned int)r->ss << 4) + r->esp) = i; - } - - -int -LRMI_init(void) - { - void *m; - int fd_mem; - - if (context.ready) - return 1; - - if (!real_mem_init()) - return 0; - - /* - Map the Interrupt Vectors (0x0 - 0x400) + BIOS data (0x400 - 0x502) - and the ROM (0xa0000 - 0x100000) - */ - fd_mem = open("/dev/mem", O_RDWR); - - if (fd_mem == -1) - { - perror("open /dev/mem"); - return 0; - } - - m = mmap((void *)0, 0x502, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE, fd_mem, 0); - - if (m == (void *)-1) - { - perror("mmap /dev/mem"); - return 0; - } - - m = mmap((void *)0xa0000, 0x100000 - 0xa0000, - PROT_READ | PROT_WRITE, - MAP_FIXED | MAP_SHARED, fd_mem, 0xa0000); - - if (m == (void *)-1) - { - perror("mmap /dev/mem"); - return 0; - } - - - /* - Allocate a stack - */ - m = LRMI_alloc_real(DEFAULT_STACK_SIZE); - - context.stack_seg = (unsigned int)m >> 4; - context.stack_off = DEFAULT_STACK_SIZE; - - /* - Allocate the return to 32 bit routine - */ - m = LRMI_alloc_real(2); - - context.ret_seg = (unsigned int)m >> 4; - context.ret_off = (unsigned int)m & 0xf; - - ((unsigned char *)m)[0] = 0xcd; /* int opcode */ - ((unsigned char *)m)[1] = RETURN_TO_32_INT; - - memset(&context.vm, 0, sizeof(context.vm)); - - /* - Enable kernel emulation of all ints except RETURN_TO_32_INT - */ - memset(&context.vm.int_revectored, 0, sizeof(context.vm.int_revectored)); - set_bit(RETURN_TO_32_INT, &context.vm.int_revectored); - - context.ready = 1; - - return 1; - } - - -static void -set_regs(struct LRMI_regs *r) - { - context.vm.regs.edi = r->edi; - context.vm.regs.esi = r->esi; - context.vm.regs.ebp = r->ebp; - context.vm.regs.ebx = r->ebx; - context.vm.regs.edx = r->edx; - context.vm.regs.ecx = r->ecx; - context.vm.regs.eax = r->eax; - context.vm.regs.eflags = DEFAULT_VM86_FLAGS; - context.vm.regs.es = r->es; - context.vm.regs.ds = r->ds; - context.vm.regs.fs = r->fs; - context.vm.regs.gs = r->gs; - } - - -static void -get_regs(struct LRMI_regs *r) - { - r->edi = context.vm.regs.edi; - r->esi = context.vm.regs.esi; - r->ebp = context.vm.regs.ebp; - r->ebx = context.vm.regs.ebx; - r->edx = context.vm.regs.edx; - r->ecx = context.vm.regs.ecx; - r->eax = context.vm.regs.eax; - r->flags = context.vm.regs.eflags; - r->es = context.vm.regs.es; - r->ds = context.vm.regs.ds; - r->fs = context.vm.regs.fs; - r->gs = context.vm.regs.gs; - } - -#define DIRECTION_FLAG (1 << 10) - -static void -em_ins(int size) - { - unsigned int edx, edi; - - edx = context.vm.regs.edx & 0xffff; - edi = context.vm.regs.edi & 0xffff; - edi += (unsigned int)context.vm.regs.ds << 4; - - if (context.vm.regs.eflags & DIRECTION_FLAG) - { - if (size == 4) - asm volatile ("std; insl; cld" - : "=D" (edi) : "d" (edx), "0" (edi)); - else if (size == 2) - asm volatile ("std; insw; cld" - : "=D" (edi) : "d" (edx), "0" (edi)); - else - asm volatile ("std; insb; cld" - : "=D" (edi) : "d" (edx), "0" (edi)); - } - else - { - if (size == 4) - asm volatile ("cld; insl" - : "=D" (edi) : "d" (edx), "0" (edi)); - else if (size == 2) - asm volatile ("cld; insw" - : "=D" (edi) : "d" (edx), "0" (edi)); - else - asm volatile ("cld; insb" - : "=D" (edi) : "d" (edx), "0" (edi)); - } - - edi -= (unsigned int)context.vm.regs.ds << 4; - - context.vm.regs.edi &= 0xffff0000; - context.vm.regs.edi |= edi & 0xffff; - } - -static void -em_rep_ins(int size) - { - unsigned int ecx, edx, edi; - - ecx = context.vm.regs.ecx & 0xffff; - edx = context.vm.regs.edx & 0xffff; - edi = context.vm.regs.edi & 0xffff; - edi += (unsigned int)context.vm.regs.ds << 4; - - if (context.vm.regs.eflags & DIRECTION_FLAG) - { - if (size == 4) - asm volatile ("std; rep; insl; cld" - : "=D" (edi), "=c" (ecx) - : "d" (edx), "0" (edi), "1" (ecx)); - else if (size == 2) - asm volatile ("std; rep; insw; cld" - : "=D" (edi), "=c" (ecx) - : "d" (edx), "0" (edi), "1" (ecx)); - else - asm volatile ("std; rep; insb; cld" - : "=D" (edi), "=c" (ecx) - : "d" (edx), "0" (edi), "1" (ecx)); - } - else - { - if (size == 4) - asm volatile ("cld; rep; insl" - : "=D" (edi), "=c" (ecx) - : "d" (edx), "0" (edi), "1" (ecx)); - else if (size == 2) - asm volatile ("cld; rep; insw" - : "=D" (edi), "=c" (ecx) - : "d" (edx), "0" (edi), "1" (ecx)); - else - asm volatile ("cld; rep; insb" - : "=D" (edi), "=c" (ecx) - : "d" (edx), "0" (edi), "1" (ecx)); - } - - edi -= (unsigned int)context.vm.regs.ds << 4; - - context.vm.regs.edi &= 0xffff0000; - context.vm.regs.edi |= edi & 0xffff; - - context.vm.regs.ecx &= 0xffff0000; - context.vm.regs.ecx |= ecx & 0xffff; - } - -static void -em_outs(int size) - { - unsigned int edx, esi; - - edx = context.vm.regs.edx & 0xffff; - esi = context.vm.regs.esi & 0xffff; - esi += (unsigned int)context.vm.regs.ds << 4; - - if (context.vm.regs.eflags & DIRECTION_FLAG) - { - if (size == 4) - asm volatile ("std; outsl; cld" - : "=S" (esi) : "d" (edx), "0" (esi)); - else if (size == 2) - asm volatile ("std; outsw; cld" - : "=S" (esi) : "d" (edx), "0" (esi)); - else - asm volatile ("std; outsb; cld" - : "=S" (esi) : "d" (edx), "0" (esi)); - } - else - { - if (size == 4) - asm volatile ("cld; outsl" - : "=S" (esi) : "d" (edx), "0" (esi)); - else if (size == 2) - asm volatile ("cld; outsw" - : "=S" (esi) : "d" (edx), "0" (esi)); - else - asm volatile ("cld; outsb" - : "=S" (esi) : "d" (edx), "0" (esi)); - } - - esi -= (unsigned int)context.vm.regs.ds << 4; - - context.vm.regs.esi &= 0xffff0000; - context.vm.regs.esi |= esi & 0xffff; - } - -static void -em_rep_outs(int size) - { - unsigned int ecx, edx, esi; - - ecx = context.vm.regs.ecx & 0xffff; - edx = context.vm.regs.edx & 0xffff; - esi = context.vm.regs.esi & 0xffff; - esi += (unsigned int)context.vm.regs.ds << 4; - - if (context.vm.regs.eflags & DIRECTION_FLAG) - { - if (size == 4) - asm volatile ("std; rep; outsl; cld" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - else if (size == 2) - asm volatile ("std; rep; outsw; cld" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - else - asm volatile ("std; rep; outsb; cld" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - } - else - { - if (size == 4) - asm volatile ("cld; rep; outsl" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - else if (size == 2) - asm volatile ("cld; rep; outsw" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - else - asm volatile ("cld; rep; outsb" - : "=S" (esi), "=c" (ecx) - : "d" (edx), "0" (esi), "1" (ecx)); - } - - esi -= (unsigned int)context.vm.regs.ds << 4; - - context.vm.regs.esi &= 0xffff0000; - context.vm.regs.esi |= esi & 0xffff; - - context.vm.regs.ecx &= 0xffff0000; - context.vm.regs.ecx |= ecx & 0xffff; - } - -static void -em_inbl(unsigned char literal) - { - context.vm.regs.eax = inb(literal) & 0xff; - } - -static void -em_inb(void) - { - asm volatile ("inb (%w1), %b0" - : "=a" (context.vm.regs.eax) - : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax)); - } - -static void -em_inw(void) - { - asm volatile ("inw (%w1), %w0" - : "=a" (context.vm.regs.eax) - : "d" (context.vm.regs.edx), "0" (context.vm.regs.eax)); - } - -static void -em_inl(void) - { - asm volatile ("inl (%w1), %0" - : "=a" (context.vm.regs.eax) - : "d" (context.vm.regs.edx)); - } - -static void -em_outbl(unsigned char literal) - { - outb(context.vm.regs.eax & 0xff, literal); - } - -static void -em_outb(void) - { - asm volatile ("outb %b0, (%w1)" - : : "a" (context.vm.regs.eax), - "d" (context.vm.regs.edx)); - } - -static void -em_outw(void) - { - asm volatile ("outw %w0, (%w1)" - : : "a" (context.vm.regs.eax), - "d" (context.vm.regs.edx)); - } - -static void -em_outl(void) - { - asm volatile ("outl %0, (%w1)" - : : "a" (context.vm.regs.eax), - "d" (context.vm.regs.edx)); - } - -static int -emulate(void) - { - unsigned char *insn; - struct - { - unsigned int size : 1; - unsigned int rep : 1; - } prefix = { 0, 0 }; - int i = 0; - - insn = (unsigned char *)((unsigned int)context.vm.regs.cs << 4); - insn += context.vm.regs.eip; - - while (1) - { - if (insn[i] == 0x66) - { - prefix.size = 1 - prefix.size; - i++; - } - else if (insn[i] == 0xf3) - { - prefix.rep = 1; - i++; - } - else if (insn[i] == 0xf0 || insn[i] == 0xf2 - || insn[i] == 0x26 || insn[i] == 0x2e - || insn[i] == 0x36 || insn[i] == 0x3e - || insn[i] == 0x64 || insn[i] == 0x65 - || insn[i] == 0x67) - { - /* these prefixes are just ignored */ - i++; - } - else if (insn[i] == 0x6c) - { - if (prefix.rep) - em_rep_ins(1); - else - em_ins(1); - i++; - break; - } - else if (insn[i] == 0x6d) - { - if (prefix.rep) - { - if (prefix.size) - em_rep_ins(4); - else - em_rep_ins(2); - } - else - { - if (prefix.size) - em_ins(4); - else - em_ins(2); - } - i++; - break; - } - else if (insn[i] == 0x6e) - { - if (prefix.rep) - em_rep_outs(1); - else - em_outs(1); - i++; - break; - } - else if (insn[i] == 0x6f) - { - if (prefix.rep) - { - if (prefix.size) - em_rep_outs(4); - else - em_rep_outs(2); - } - else - { - if (prefix.size) - em_outs(4); - else - em_outs(2); - } - i++; - break; - } - else if (insn[i] == 0xe4) - { - em_inbl(insn[i + 1]); - i += 2; - break; - } - else if (insn[i] == 0xe6) - { - em_outbl(insn[i + 1]); - i += 2; - break; - } - else if (insn[i] == 0xec) - { - em_inb(); - i++; - break; - } - else if (insn[i] == 0xed) - { - if (prefix.size) - em_inl(); - else - em_inw(); - i++; - break; - } - else if (insn[i] == 0xee) - { - em_outb(); - i++; - break; - } - else if (insn[i] == 0xef) - { - if (prefix.size) - em_outl(); - else - em_outw(); - - i++; - break; - } - else - return 0; - } - - context.vm.regs.eip += i; - return 1; - } - - -/* - I don't know how to make sure I get the right vm86() from libc. - The one I want is syscall # 113 (vm86old() in libc 5, vm86() in glibc) - which should be declared as "int vm86(struct vm86_struct *);" in - <sys/vm86.h>. - - This just does syscall 113 with inline asm, which should work - for both libc's (I hope). -*/ -#if !defined(USE_LIBC_VM86) -static int -lrmi_vm86(struct vm86_struct *vm) - { - int r; -#ifdef __PIC__ - asm volatile ( - "pushl %%ebx\n\t" - "movl %2, %%ebx\n\t" - "int $0x80\n\t" - "popl %%ebx" - : "=a" (r) - : "0" (113), "r" (vm)); -#else - asm volatile ( - "int $0x80" - : "=a" (r) - : "0" (113), "b" (vm)); -#endif - return r; - } -#else -#define lrmi_vm86 vm86 -#endif - - -static void -debug_info(int vret) - { - int i; - unsigned char *p; - - fputs("vm86() failed\n", stderr); - fprintf(stderr, "return = 0x%x\n", vret); - fprintf(stderr, "eax = 0x%08lx\n", context.vm.regs.eax); - fprintf(stderr, "ebx = 0x%08lx\n", context.vm.regs.ebx); - fprintf(stderr, "ecx = 0x%08lx\n", context.vm.regs.ecx); - fprintf(stderr, "edx = 0x%08lx\n", context.vm.regs.edx); - fprintf(stderr, "esi = 0x%08lx\n", context.vm.regs.esi); - fprintf(stderr, "edi = 0x%08lx\n", context.vm.regs.edi); - fprintf(stderr, "ebp = 0x%08lx\n", context.vm.regs.ebp); - fprintf(stderr, "eip = 0x%08lx\n", context.vm.regs.eip); - fprintf(stderr, "cs = 0x%04x\n", context.vm.regs.cs); - fprintf(stderr, "esp = 0x%08lx\n", context.vm.regs.esp); - fprintf(stderr, "ss = 0x%04x\n", context.vm.regs.ss); - fprintf(stderr, "ds = 0x%04x\n", context.vm.regs.ds); - fprintf(stderr, "es = 0x%04x\n", context.vm.regs.es); - fprintf(stderr, "fs = 0x%04x\n", context.vm.regs.fs); - fprintf(stderr, "gs = 0x%04x\n", context.vm.regs.gs); - fprintf(stderr, "eflags = 0x%08lx\n", context.vm.regs.eflags); - - fputs("cs:ip = [ ", stderr); - - p = (unsigned char *)((context.vm.regs.cs << 4) + (context.vm.regs.eip & 0xffff)); - - for (i = 0; i < 16; ++i) - fprintf(stderr, "%02x ", (unsigned int)p[i]); - - fputs("]\n", stderr); - } - - -static int -run_vm86(void) - { - unsigned int vret; - sigset_t allsigs, cursigs; - unsigned long oldgs, oldfs; - - while (1) - { - sigfillset(&allsigs); - sigprocmask(SIG_SETMASK, &allsigs, &cursigs); - asm volatile ("movl %%gs, %0" : "=g" (oldgs)); - asm volatile ("movl %%fs, %0" : "=g" (oldfs)); - vret = lrmi_vm86(&context.vm); - asm volatile ("movl %0, %%fs" :: "g" (oldfs)); - asm volatile ("movl %0, %%gs" :: "g" (oldgs)); - sigprocmask(SIG_SETMASK, &cursigs, NULL); - - if (VM86_TYPE(vret) == VM86_INTx) - { - unsigned int v = VM86_ARG(vret); - - if (v == RETURN_TO_32_INT) - return 1; - - pushw(context.vm.regs.eflags); - pushw(context.vm.regs.cs); - pushw(context.vm.regs.eip); - - context.vm.regs.cs = get_int_seg(v); - context.vm.regs.eip = get_int_off(v); - context.vm.regs.eflags &= ~(VIF_MASK | TF_MASK); - - continue; - } - - if (VM86_TYPE(vret) != VM86_UNKNOWN) - break; - - if (!emulate()) - break; - } - -#ifdef ORIGINAL_LRMI_CODE_THAT_GOT_IFDEFED_OUT - debug_info(vret); -#endif - return 0; - } - - -int -LRMI_call(struct LRMI_regs *r) - { - unsigned int vret; - - memset(&context.vm.regs, 0, sizeof(context.vm.regs)); - - set_regs(r); - - context.vm.regs.cs = r->cs; - context.vm.regs.eip = r->ip; - - if (r->ss == 0 && r->sp == 0) - { - context.vm.regs.ss = context.stack_seg; - context.vm.regs.esp = context.stack_off; - } - else - { - context.vm.regs.ss = r->ss; - context.vm.regs.esp = r->sp; - } - - pushw(context.ret_seg); - pushw(context.ret_off); - - vret = run_vm86(); - - get_regs(r); - - return vret; - } - - -int -LRMI_int(int i, struct LRMI_regs *r) - { - unsigned int vret; - unsigned int seg, off; - - seg = get_int_seg(i); - off = get_int_off(i); - - /* - If the interrupt is in regular memory, it's probably - still pointing at a dos TSR (which is now gone). - */ - if (seg < 0xa000 || (seg << 4) + off >= 0x100000) - { -#ifdef ORIGINAL_LRMI_CODE_THAT_GOT_IFDEFED_OUT - fprintf(stderr, "Int 0x%x is not in rom (%04x:%04x)\n", i, seg, off); -#endif - return 0; - } - - memset(&context.vm.regs, 0, sizeof(context.vm.regs)); - - set_regs(r); - - context.vm.regs.cs = seg; - context.vm.regs.eip = off; - - if (r->ss == 0 && r->sp == 0) - { - context.vm.regs.ss = context.stack_seg; - context.vm.regs.esp = context.stack_off; - } - else - { - context.vm.regs.ss = r->ss; - context.vm.regs.esp = r->sp; - } - - pushw(DEFAULT_VM86_FLAGS); - pushw(context.ret_seg); - pushw(context.ret_off); - - vret = run_vm86(); - - get_regs(r); - - return vret; - } - -#endif
--- a/osdep/lrmi.h Thu Aug 18 11:18:44 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* -Linux Real Mode Interface - A library of DPMI-like functions for Linux. - -Copyright (C) 1998 by Josh Vanderhoof - -You are free to distribute and modify this file, as long as you -do not remove this copyright notice and clearly label modified -versions as being modified. - -This software has NO WARRANTY. Use it at your own risk. -Original location: http://cvs.debian.org/lrmi/ -*/ - -#ifndef LRMI_H -#define LRMI_H - -struct LRMI_regs - { - unsigned int edi; - unsigned int esi; - unsigned int ebp; - unsigned int reserved; - unsigned int ebx; - unsigned int edx; - unsigned int ecx; - unsigned int eax; - unsigned short int flags; - unsigned short int es; - unsigned short int ds; - unsigned short int fs; - unsigned short int gs; - unsigned short int ip; - unsigned short int cs; - unsigned short int sp; - unsigned short int ss; - }; - - -#ifndef LRMI_PREFIX -#define LRMI_PREFIX LRMI_ -#endif - -#define LRMI_CONCAT2(a, b) a ## b -#define LRMI_CONCAT(a, b) LRMI_CONCAT2(a, b) -#define LRMI_MAKENAME(a) LRMI_CONCAT(LRMI_PREFIX, a) - -/* - Initialize - returns 1 if sucessful, 0 for failure -*/ -#define LRMI_init LRMI_MAKENAME(init) -int -LRMI_init(void); - -/* - Simulate a 16 bit far call - returns 1 if sucessful, 0 for failure -*/ -#define LRMI_call LRMI_MAKENAME(call) -int -LRMI_call(struct LRMI_regs *r); - -/* - Simulate a 16 bit interrupt - returns 1 if sucessful, 0 for failure -*/ -#define LRMI_int LRMI_MAKENAME(int) -int -LRMI_int(int interrupt, struct LRMI_regs *r); - -/* - Allocate real mode memory - The returned block is paragraph (16 byte) aligned -*/ -#define LRMI_alloc_real LRMI_MAKENAME(alloc_real) -void * -LRMI_alloc_real(int size); - -/* - Free real mode memory -*/ -#define LRMI_free_real LRMI_MAKENAME(free_real) -void -LRMI_free_real(void *m); - -#endif
--- a/osdep/vbelib.c Thu Aug 18 11:18:44 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,777 +0,0 @@ -/* - This file contains implementation of VESA library which is based on - LRMI (Linux real-mode interface). - So it's not an emulator - it calls real int 10h handler under Linux. - Note: VESA is available only on x86 systems. - You can redistribute this file under terms and conditions - of GNU General Public licence v2. - Written by Nick Kurshev <nickols_k@mail.ru> - Neomagic TV out support by Rudolf Marek <r.marek et sh.cvut.cz> -*/ - -#include <../config.h> -#ifdef HAVE_VESA - -#include "vbelib.h" -#include "lrmi.h" -#include <stdlib.h> -#include <string.h> -#include <stdio.h> -#include <sys/io.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <ctype.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <linux/kd.h> - -static struct VesaProtModeInterface vbe_pm_info; -static struct VesaModeInfoBlock curr_mode_info; - -static inline int VERR(const void *p) -{ - register int retval; - __asm __volatile( - "xorl %0, %0\n\t" - "verr %1\n\t" - "setnz %b0" - :"=q"(retval) - :"m"(*(unsigned char *)p) - :"memory","cc"); - return retval; -} - -#if 0 -static inline int VERW(const void *p) -{ - register int retval; - __asm __volatile( - "xorl %0, %0\n\t" - "verw %1\n\t" - "setnz %b0" - :"=q"(retval) - :"m"(*(unsigned char *)p) - :"memory","cc"); - return retval; -} -#endif - -#define HAVE_VERBOSE_VAR 1 - -#ifdef HAVE_VERBOSE_VAR -extern int verbose; - -static void __dump_regs(struct LRMI_regs *r) -{ - printf("vbelib: eax=%08lXh ebx=%08lXh ecx=%08lXh edx=%08lXh\n" - "vbelib: edi=%08lXh esi=%08lXh ebp=%08lXh esp=%08lXh\n" - "vbelib: ds=%04Xh es=%04Xh ss=%04Xh cs:ip=%04X:%04X\n" - "vbelib: fs=%04Xh gs=%04Xh ss:sp=%04X:%04X flags=%04X\n" - ,(unsigned long)r->eax,(unsigned long)r->ebx,(unsigned long)r->ecx,(unsigned long)r->edx - ,(unsigned long)r->edi,(unsigned long)r->esi,(unsigned long)r->ebp,(unsigned long)r->reserved - ,r->ds,r->es,r->ss,r->cs,r->ip - ,r->fs,r->gs,r->ss,r->sp,r->flags); -} - -static inline int VBE_LRMI_int(int int_no, struct LRMI_regs *r) -{ - int retval; - if(verbose > 1) - { - printf("vbelib: registers before int %02X\n",int_no); - __dump_regs(r); - } - retval = LRMI_int(int_no,r); - if(verbose > 1) - { - printf("vbelib: Interrupt handler returns: %X\n",retval); - printf("vbelib: registers after int %02X\n",int_no); - __dump_regs(r); - } - return retval; -} -#else -#define VBE_LRMI_int(int_no,regs) (VBE_LRMI_int(int_no,regs)) -#endif - -/** - * Set console to graphics or text mode. - * This is a clean way to enable/disable console text output - * and cursor blinking. - * - * @param mode The new wanted mode. Can be either KD_GRAPHICS to switch - * to graphics mode or anything else to switch back to the - * original mode. - */ -static void kd_set_mode(int mode) -{ - static int old_mode = KD_TEXT; - int fd; - - if ((fd = open("/dev/tty0", O_RDWR)) < 0) - return; - if(mode == KD_GRAPHICS) - old_mode = ioctl(fd, KDGETMODE); - else - mode = old_mode; - ioctl(fd, KDSETMODE, mode); - close(fd); -} - -static unsigned hh_int_10_seg; -static int fd_mem; -/* -the list of supported video modes is stored in the reserved portion of -the SuperVGA information record by some implementations, and it may -thus be necessary to either copy the mode list or use a different -buffer for all subsequent VESA calls -*/ -static void *controller_info; -int vbeInit( void ) -{ - unsigned short iopl_port; - size_t i; - if(!LRMI_init()) return VBE_VM86_FAIL; - if(!(controller_info = LRMI_alloc_real(sizeof(struct VbeInfoBlock)))) return VBE_OUT_OF_DOS_MEM; - /* - Allow read/write to ALL io ports - */ - hh_int_10_seg = *(unsigned short *)PhysToVirtSO(0x0000,0x0042); - /* Video BIOS should be at C000:0000 and above */ - hh_int_10_seg >>= 12; - if(hh_int_10_seg < 0xC) return VBE_BROKEN_BIOS; - ioperm(0, 1024, 1); - iopl(3); - memset(&vbe_pm_info,0,sizeof(struct VesaProtModeInterface)); - vbeGetProtModeInfo(&vbe_pm_info); - i = 0; - if(vbe_pm_info.iopl_ports) /* Can be NULL !!!*/ - while((iopl_port=vbe_pm_info.iopl_ports[i]) != 0xFFFF - && vbe_pm_info.iopl_ports[i++] > 1023) ioperm(iopl_port,1,1); - iopl(3); - fd_mem = open("/dev/mem",O_RDWR); - kd_set_mode(KD_GRAPHICS); - return VBE_OK; -} - -int vbeDestroy( void ) -{ - kd_set_mode(KD_TEXT); - close(fd_mem); - LRMI_free_real(controller_info); - return VBE_OK; -} - -/* Fixme!!! This code is compatible only with mplayer's version of lrmi*/ -static inline int is_addr_valid(const void *p) -{ - return (p < (const void *)0x502) || - (p >= (const void *)0x10000 && p < (const void *)0x20000) || - (p >= (const void *)0xa0000 && p < (const void *)0x100000); -} - -static int check_str(const unsigned char *str) -{ - size_t i; - int null_found = 0; - for(i = 0;i < 256;i++) - { - if(is_addr_valid(&str[i])) - { - if(VERR(&str[i])) - { - if(!str[i]) { null_found = 1; break; } - } - else break; - } - else break; - } - return null_found; -} - -static int check_wrd(const unsigned short *str) -{ - size_t i; - int ffff_found = 0; - for(i = 0;i < 1024;i++) - { - if(is_addr_valid(&str[i])) - { - if(VERR(&str[i])) - { - if(str[i] == 0xffff) { ffff_found = 1; break; } - } - else break; - } - else break; - } - return ffff_found; -} - -static void print_str(unsigned char *str) -{ - size_t i; - fflush(stdout); - printf("vbelib: "); - for(i = 0;i < 256;i++) { printf("%02X(%c) ",str[i],isprint(str[i])?str[i]:'.'); if(!str[i]) break; } - printf("\n"); - fflush(stdout); -} - -static void print_wrd(unsigned short *str) -{ - size_t i; - fflush(stdout); - printf("vbelib: "); - for(i = 0;i < 256;i++) { printf("%04X ",str[i]); if(str[i] == 0xffff) break; } - printf("\n"); - fflush(stdout); -} - -int vbeGetControllerInfo(struct VbeInfoBlock *data) -{ - struct LRMI_regs r; - int retval; - memcpy(controller_info,data,sizeof(struct VbeInfoBlock)); - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f00; - r.es = VirtToPhysSeg(controller_info); - r.edi = VirtToPhysOff(controller_info); - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - FarPtr fpdata; - retval = VBE_OK; - memcpy(data,controller_info,sizeof(struct VbeInfoBlock)); - fpdata.seg = (unsigned long)(data->OemStringPtr) >> 16; - fpdata.off = (unsigned long)(data->OemStringPtr) & 0xffff; - data->OemStringPtr = PhysToVirt(fpdata); - if(!check_str(data->OemStringPtr)) data->OemStringPtr = NULL; -#ifdef HAVE_VERBOSE_VAR - if(verbose > 1) - { - printf("vbelib: OemStringPtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemStringPtr); - if(data->OemStringPtr) print_str(data->OemStringPtr); - fflush(stdout); - } -#endif - fpdata.seg = (unsigned long)(data->VideoModePtr) >> 16; - fpdata.off = (unsigned long)(data->VideoModePtr) & 0xffff; - data->VideoModePtr = PhysToVirt(fpdata); - if(!check_wrd(data->VideoModePtr)) - { - data->VideoModePtr = NULL; - retval = VBE_BROKEN_BIOS; - } -#ifdef HAVE_VERBOSE_VAR - if(verbose > 1) - { - printf("vbelib: VideoModePtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->VideoModePtr); - if(data->VideoModePtr) print_wrd(data->VideoModePtr); - fflush(stdout); - } -#endif - fpdata.seg = (unsigned long)(data->OemVendorNamePtr) >> 16; - fpdata.off = (unsigned long)(data->OemVendorNamePtr) & 0xffff; - data->OemVendorNamePtr = PhysToVirt(fpdata); - if(!check_str(data->OemVendorNamePtr)) data->OemVendorNamePtr = NULL; -#ifdef HAVE_VERBOSE_VAR - if(verbose > 1) - { - printf("vbelib: OemVendorNamePtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemVendorNamePtr); - if(data->OemVendorNamePtr) print_str(data->OemVendorNamePtr); - fflush(stdout); - } -#endif - fpdata.seg = (unsigned long)(data->OemProductNamePtr) >> 16; - fpdata.off = (unsigned long)(data->OemProductNamePtr) & 0xffff; - data->OemProductNamePtr = PhysToVirt(fpdata); - if(!check_str(data->OemProductNamePtr)) data->OemProductNamePtr = NULL; -#ifdef HAVE_VERBOSE_VAR - if(verbose > 1) - { - printf("vbelib: OemProductNamePtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemProductNamePtr); - if(data->OemVendorNamePtr) print_str(data->OemProductNamePtr); - fflush(stdout); - } -#endif - fpdata.seg = (unsigned long)(data->OemProductRevPtr) >> 16; - fpdata.off = (unsigned long)(data->OemProductRevPtr) & 0xffff; - data->OemProductRevPtr = PhysToVirt(fpdata); - if(!check_str(data->OemProductRevPtr)) data->OemProductRevPtr = NULL; -#ifdef HAVE_VERBOSE_VAR - if(verbose > 1) - { - printf("vbelib: OemProductRevPtr=%04X:%04X => %p\n",fpdata.seg,fpdata.off,data->OemProductRevPtr); - if(data->OemProductRevPtr) print_str(data->OemProductRevPtr); - fflush(stdout); - } -#endif - } - return retval; -} - -int vbeGetModeInfo(unsigned mode,struct VesaModeInfoBlock *data) -{ - struct LRMI_regs r; - void *rm_space; - int retval; - if(!(rm_space = LRMI_alloc_real(sizeof(struct VesaModeInfoBlock)))) return VBE_OUT_OF_DOS_MEM; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f01; - r.ecx = mode; - r.es = VirtToPhysSeg(rm_space); - r.edi = VirtToPhysOff(rm_space); - if(!VBE_LRMI_int(0x10,&r)) - { - LRMI_free_real(rm_space); - return VBE_VM86_FAIL; - } - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - retval = VBE_OK; - memcpy(data,rm_space,sizeof(struct VesaModeInfoBlock)); - } - LRMI_free_real(rm_space); - return retval; -} - - -int vbeSetTV(unsigned int vesa_mode,unsigned int TV_mode) { - -#define NR_MODES 8 - -unsigned int mode_table[NR_MODES] = - {0x101,0x103,0x111,0x114,0x120,0x121,0x122,0x123}; -unsigned int tv_table[][NR_MODES] = { - {0x201,0x202,0x211,0x212,0x221,0x231,0x222,0x232}, - {0x200,0x203,0x210,0x213,0x220,0x230,0xFFFF,0xFFFF}}; - -/* - -Alternate mode map. If modes like 320x240 and 400x300 does not work, but -640x480 and 800x600 work, then try to replace above two lines with this -lines and write email to me if it works. -r.marek et sh.cvut.cz - - {0x201,0x202,0x211,0x212,0x222,0x223,0x224,0x225}, - {0x200,0x203,0x210,0x213,0x220,0x221,0xFFFF,0xFFFF}}; - -*/ - int i,retval; - struct LRMI_regs r; - - memset(&r,0,sizeof(struct LRMI_regs)); - for (i=0;((mode_table[i]!=(vesa_mode&0x3FF))&&(i<NR_MODES));i++) ; - - if (i==NR_MODES) return 0; - if(verbose > 1) printf("vbelib: Trying to set TV mode %x\n",tv_table[TV_mode][i]); - r.eax = 0x4f14; - r.ebx = 0x20; - r.edx = 0; - r.edi = 0; - r.ecx = tv_table[TV_mode][i]; - retval = VBE_LRMI_int(0x10,&r); - if(!retval) return VBE_VM86_FAIL; - return r.eax & 0xffff; - -} -int vbeSetMode(unsigned mode,struct VesaCRTCInfoBlock *data) -{ - struct LRMI_regs r; - void *rm_space = NULL; - int retval; - memset(&r,0,sizeof(struct LRMI_regs)); - if(data) - { - if(!(rm_space = LRMI_alloc_real(sizeof(struct VesaCRTCInfoBlock)))) return VBE_OUT_OF_DOS_MEM; - r.es = VirtToPhysSeg(rm_space); - r.edi = VirtToPhysOff(rm_space); - memcpy(rm_space,data,sizeof(struct VesaCRTCInfoBlock)); - } - r.eax = 0x4f02; - r.ebx = mode; - retval = VBE_LRMI_int(0x10,&r); - LRMI_free_real(rm_space); - if(!retval) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - /* Just info for internal use (currently in SetDiplayStart func). */ - vbeGetModeInfo(mode,&curr_mode_info); - retval = VBE_OK; - } - return retval; -} - -int vbeGetMode(unsigned *mode) -{ - struct LRMI_regs r; - int retval; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f03; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - *mode = r.ebx; - retval = VBE_OK; - } - return retval; -} - -int vbeGetPixelClock(unsigned *mode,unsigned *pixel_clock) // in Hz -{ - struct LRMI_regs r; - int retval; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f0b; - r.ebx = 0; - r.edx = *mode; - r.ecx = *pixel_clock; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - *pixel_clock = r.ecx; - retval = VBE_OK; - } - return retval; -} - - -int vbeSaveState(void **data) -{ - struct LRMI_regs r; - int retval; - void *rm_space; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f04; - r.edx = 0x00; - r.ecx = 0x0f; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval != 0x4f) return retval; - if(!(rm_space = LRMI_alloc_real((r.ebx & 0xffff)*64))) return VBE_OUT_OF_DOS_MEM; - r.eax = 0x4f04; - r.edx = 0x01; - r.ecx = 0x0f; - r.es = VirtToPhysSeg(rm_space); - r.ebx = VirtToPhysOff(rm_space); - if(!VBE_LRMI_int(0x10,&r)) - { - LRMI_free_real(rm_space); - return VBE_VM86_FAIL; - } - retval = r.eax & 0xffff; - if(retval != 0x4f) - { - LRMI_free_real(rm_space); - return retval; - } - *data = rm_space; - return VBE_OK; -} - -int vbeRestoreState(void *data) -{ - struct LRMI_regs r; - int retval; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f04; - r.edx = 0x02; - r.ecx = 0x0f; - r.es = VirtToPhysSeg(data); - r.ebx = VirtToPhysOff(data); - retval = VBE_LRMI_int(0x10,&r); - LRMI_free_real(data); - if(!retval) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) retval = VBE_OK; - return retval; -} - -int vbeGetWindow(unsigned *win_num) -{ - struct LRMI_regs r; - int retval; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f05; - r.ebx = (*win_num & 0x0f) | 0x0100; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - *win_num = r.edx & 0xffff; - retval = VBE_OK; - } - return retval; -} - -int vbeSetWindow(unsigned win_num,unsigned win_gran) -{ - int retval; - if(vbe_pm_info.SetWindowCall) - { - /* Don't verbose this stuff from performance reasons */ - /* 32-bit function call is much better of int 10h */ - __asm __volatile( - "pushl %%ebx\n" - "movl %1, %%ebx\n" - ::"a"(0x4f05),"S"(win_num & 0x0f),"d"(win_gran):"memory"); - (*vbe_pm_info.SetWindowCall)(); - __asm __volatile("popl %%ebx":::"memory"); - retval = VBE_OK; - } - else - { - struct LRMI_regs r; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f05; - r.ebx = win_num & 0x0f; - r.edx = win_gran; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) retval = VBE_OK; - } - return retval; -} - -int vbeGetScanLineLength(unsigned *num_pixels,unsigned *num_bytes) -{ - struct LRMI_regs r; - int retval; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f06; - r.ebx = 1; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - if(num_bytes) *num_bytes = r.ebx & 0xffff; - if(num_pixels) *num_pixels= r.ecx & 0xffff; - retval = VBE_OK; - } - return retval; -} - -int vbeGetMaxScanLines(unsigned *num_pixels,unsigned *num_bytes, unsigned *num_lines) -{ - struct LRMI_regs r; - int retval; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f06; - r.ebx = 3; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - if(num_bytes) *num_bytes = r.ebx & 0xffff; - if(num_pixels) *num_pixels= r.ecx & 0xffff; - if(num_lines) *num_lines = r.edx & 0xffff; - retval = VBE_OK; - } - return retval; -} - -int vbeSetScanLineLength(unsigned num_pixels) -{ - int retval; - struct LRMI_regs r; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f06; - r.ebx = 0; - r.ecx = num_pixels; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) retval = VBE_OK; - return retval; -} - -int vbeSetScanLineLengthB(unsigned num_bytes) -{ - int retval; - struct LRMI_regs r; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f06; - r.ebx = 2; - r.ecx = num_bytes; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) retval = VBE_OK; - return retval; -} - -int vbeGetDisplayStart(unsigned *pixel_num,unsigned *scan_line) -{ - struct LRMI_regs r; - int retval; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f07; - r.ebx = 1; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - if(pixel_num) *pixel_num = r.ecx & 0xffff; - if(scan_line) *scan_line = r.edx & 0xffff; - retval = VBE_OK; - } - return retval; -} - -int vbeSetDisplayStart(unsigned long offset, int vsync) -{ - int retval; - if(vbe_pm_info.SetDisplayStart) - { - /* Don't verbose this stuff from performance reasons */ - /* 32-bit function call is much better of int 10h */ - __asm __volatile( - "pushl %%ebx\n" - "movl %1, %%ebx\n" - ::"a"(0x4f07),"S"(vsync ? 0x80 : 0), - "c"((offset>>2) & 0xffff),"d"((offset>>18)&0xffff):"memory"); - (*vbe_pm_info.SetDisplayStart)(); - __asm __volatile("popl %%ebx":::"memory"); - retval = VBE_OK; - } - else - { - struct LRMI_regs r; - unsigned long pixel_num; - memset(&r,0,sizeof(struct LRMI_regs)); - pixel_num = offset%(unsigned long)curr_mode_info.BytesPerScanLine; - if(pixel_num*(unsigned long)curr_mode_info.BytesPerScanLine!=offset) pixel_num++; - r.eax = 0x4f07; - r.ebx = vsync ? 0x82 : 2; - r.ecx = pixel_num; - r.edx = offset/(unsigned long)curr_mode_info.BytesPerScanLine; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) retval = VBE_OK; - else retval = VBE_BROKEN_BIOS; - } - return retval; -} - -int vbeSetScheduledDisplayStart(unsigned long offset, int vsync) -{ - int retval; - struct LRMI_regs r; - unsigned long pixel_num; - memset(&r,0,sizeof(struct LRMI_regs)); - pixel_num = offset%(unsigned long)curr_mode_info.BytesPerScanLine; - if(pixel_num*(unsigned long)curr_mode_info.BytesPerScanLine!=offset) pixel_num++; - r.eax = 0x4f07; - r.ebx = vsync ? 0x82 : 2; - r.ecx = offset; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) retval = VBE_OK; - return retval; -} - -struct realVesaProtModeInterface -{ - unsigned short SetWindowCall; - unsigned short SetDisplayStart; - unsigned short SetPaletteData; - unsigned short iopl_ports; -}__attribute__((packed)); - -int vbeGetProtModeInfo(struct VesaProtModeInterface *pm_info) -{ - struct LRMI_regs r; - int retval; - unsigned info_offset; - struct realVesaProtModeInterface *rm_info; - memset(&r,0,sizeof(struct LRMI_regs)); - r.eax = 0x4f0a; - r.ebx = 0; - if(!VBE_LRMI_int(0x10,&r)) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) - { - retval = VBE_OK; - info_offset = r.edi&0xffff; - if((r.es >> 12) != hh_int_10_seg) retval = VBE_BROKEN_BIOS; - rm_info = PhysToVirtSO(r.es,info_offset); - pm_info->SetWindowCall = PhysToVirtSO(r.es,info_offset+rm_info->SetWindowCall); - if(!is_addr_valid(pm_info->SetWindowCall)) retval = VBE_BROKEN_BIOS; -#ifdef HAVE_VERBOSE_VAR - if(verbose > 1) printf("vbelib: SetWindowCall=%04X:%04X => %p\n",r.es,info_offset+rm_info->SetWindowCall,pm_info->SetWindowCall); -#endif - pm_info->SetDisplayStart = PhysToVirtSO(r.es,info_offset+rm_info->SetDisplayStart); - if(!is_addr_valid(pm_info->SetDisplayStart)) retval = VBE_BROKEN_BIOS; -#ifdef HAVE_VERBOSE_VAR - if(verbose > 1) printf("vbelib: SetDisplayStart=%04X:%04X => %p\n",r.es,info_offset+rm_info->SetDisplayStart,pm_info->SetDisplayStart); -#endif - pm_info->SetPaletteData = PhysToVirtSO(r.es,info_offset+rm_info->SetPaletteData); - if(!is_addr_valid(pm_info->SetPaletteData)) retval = VBE_BROKEN_BIOS; -#ifdef HAVE_VERBOSE_VAR - if(verbose > 1) printf("vbelib: SetPaletteData=%04X:%04X => %p\n",r.es,info_offset+rm_info->SetPaletteData,pm_info->SetPaletteData); -#endif - pm_info->iopl_ports = PhysToVirtSO(r.es,info_offset+rm_info->iopl_ports); - if(!rm_info->iopl_ports) pm_info->iopl_ports = NULL; - else - if(!check_wrd(pm_info->iopl_ports)) - { - pm_info->iopl_ports = NULL; -/* retval = VBE_BROKEN_BIOS; <- It's for broken BIOSes only */ - } -#ifdef HAVE_VERBOSE_VAR - if(verbose > 1) - { - printf("vbelib: iopl_ports=%04X:%04X => %p\n",r.es,info_offset+rm_info->iopl_ports,pm_info->iopl_ports); - if(pm_info->iopl_ports) print_wrd(pm_info->iopl_ports); - fflush(stdout); - } -#endif - } - return retval; -} -/* --------- Standard VGA stuff -------------- */ -int vbeWriteString(int x, int y, int attr, char *str) -{ - struct LRMI_regs r; - void *rm_space = NULL; - int retval; - memset(&r,0,sizeof(struct LRMI_regs)); - r.ecx = strlen(str); - r.edx = ((y<<8)&0xff00)|(x&0xff); - r.ebx = attr; - if(!(rm_space = LRMI_alloc_real(r.ecx))) return VBE_OUT_OF_DOS_MEM; - r.es = VirtToPhysSeg(rm_space); - r.ebp = VirtToPhysOff(rm_space); - memcpy(rm_space,str,r.ecx); - r.eax = 0x1300; - retval = VBE_LRMI_int(0x10,&r); - LRMI_free_real(rm_space); - if(!retval) return VBE_VM86_FAIL; - retval = r.eax & 0xffff; - if(retval == 0x4f) retval = VBE_OK; - return retval; -} - -void * vbeMapVideoBuffer(unsigned long phys_addr,unsigned long size) -{ - void *lfb; - if(fd_mem == -1) return NULL; - if(verbose > 1) printf("vbelib: vbeMapVideoBuffer(%08lX,%08lX)\n",phys_addr,size); - /* Here we don't need with MAP_FIXED and prefered address (first argument) */ - lfb = mmap((void *)0,size,PROT_READ | PROT_WRITE,MAP_SHARED,fd_mem,phys_addr); - return lfb == (void *)-1 ? 0 : lfb; -} - -void vbeUnmapVideoBuffer(unsigned long linear_addr,unsigned long size) -{ - if(verbose > 1) printf("vbelib: vbeUnmapVideoBuffer(%08lX,%08lX)\n",linear_addr,size); - munmap((void *)linear_addr,size); -} - -#endif
--- a/osdep/vbelib.h Thu Aug 18 11:18:44 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,230 +0,0 @@ -/* - VESA VBE 2.0 compatible structures and definitions. - You can redistribute this file under terms and conditions - of GNU General Public licence v2. - Written by Nick Kurshev <nickols_k@mail.ru> -*/ -#ifndef __VESA_VBELIB_INCLUDED__ -#define __VESA_VBELIB_INCLUDED__ 1 - -/* Note: every pointer within structures is 32-bit protected mode pointer. - So you don't need to convert it from real mode. */ - -typedef struct tagFarPtr -{ - unsigned short off; - unsigned short seg; -}FarPtr; - -#define VBE_DAC_8BIT (1 << 0) -#define VBE_NONVGA_CRTC (1 << 1) -#define VBE_SNOWED_RAMDAC (1 << 2) -#define VBE_STEREOSCOPIC (1 << 3) -#define VBE_STEREO_EVC (1 << 4) - -struct VbeInfoBlock { - char VESASignature[4]; /* 'VESA' 4 byte signature */ - short VESAVersion; /* VBE version number */ - char * OemStringPtr; /* Pointer to OEM string */ - long Capabilities; /* Capabilities of video card */ - unsigned short* VideoModePtr; /* Pointer to supported modes */ - short TotalMemory; /* Number of 64kb memory blocks */ - /* VBE 2.0 and above */ - short OemSoftwareRev; - char * OemVendorNamePtr; - char * OemProductNamePtr; - char * OemProductRevPtr; - char reserved[222]; - char OemData[256]; /* Pad to 512 byte block size */ -}__attribute__ ((packed)); - -static inline FarPtr VirtToPhys(void *ptr) -{ - FarPtr retval; - retval.seg = ((unsigned long)ptr) >> 4; - retval.off = ((unsigned long)ptr) & 0x0f; - return retval; -} - -static inline unsigned short VirtToPhysSeg(void *ptr) -{ - return ((unsigned long)ptr) >> 4; -} - -static inline unsigned short VirtToPhysOff(void *ptr) -{ - return ((unsigned long)ptr) & 0x0f; -} - -static inline void * PhysToVirt(FarPtr ptr) -{ - return (void *)((ptr.seg << 4) | ptr.off); -} - -static inline void * PhysToVirtSO(unsigned short seg,unsigned short off) -{ - return (void *)((seg << 4) | off); -} - -#define MODE_ATTR_MODE_SUPPORTED (1 << 0) -#define MODE_ATTR_TTY (1 << 2) -#define MODE_ATTR_COLOR (1 << 3) -#define MODE_ATTR_GRAPHICS (1 << 4) -#define MODE_ATTR_NOT_VGA (1 << 5) -#define MODE_ATTR_NOT_WINDOWED (1 << 6) -#define MODE_ATTR_LINEAR (1 << 7) -#define MODE_ATTR_DOUBLESCAN (1 << 8) -#define MODE_ATTR_INTERLACE (1 << 9) -#define MODE_ATTR_TRIPLEBUFFER (1 << 10) -#define MODE_ATTR_STEREOSCOPIC (1 << 11) -#define MODE_ATTR_DUALDISPLAY (1 << 12) - -#define MODE_WIN_RELOCATABLE (1 << 0) -#define MODE_WIN_READABLE (1 << 1) -#define MODE_WIN_WRITEABLE (1 << 2) -#define NEO_PAL 0 -#define NEO_NTSC 1 - -/* SuperVGA mode information block */ -struct VesaModeInfoBlock { - unsigned short ModeAttributes; /* 00: Mode attributes */ - unsigned char WinAAttributes; /* 02: Window A attributes */ - unsigned char WinBAttributes; /* 03: Window B attributes */ - unsigned short WinGranularity; /* 04: Window granularity in k */ - unsigned short WinSize; /* 06: Window size in k */ - unsigned short WinASegment; /* 08: Window A segment */ - unsigned short WinBSegment; /* 0A: Window B segment */ - FarPtr WinFuncPtr; /* 0C: 16-bit far pointer to window function */ - unsigned short BytesPerScanLine; /* 10: Bytes per scanline */ - /* VBE 1.2 and above */ - unsigned short XResolution; /* 12: Horizontal resolution */ - unsigned short YResolution; /* 14: Vertical resolution */ - unsigned char XCharSize; /* 16: Character cell width */ - unsigned char YCharSize; /* 17: Character cell height */ - unsigned char NumberOfPlanes; /* 18: Number of memory planes */ - unsigned char BitsPerPixel; /* 19: Bits per pixel */ - unsigned char NumberOfBanks; /* 1A: Number of CGA style banks */ - unsigned char MemoryModel; /* 1B: Memory model type */ - unsigned char BankSize; /* 1C: Size of CGA style banks */ - unsigned char NumberOfImagePages; /* 1D: Number of images pages */ - unsigned char res1; /* 1E: Reserved */ - /* Direct Color fields (required for direct/6 and YUV/7 memory models) */ - unsigned char RedMaskSize; /* 1F: Size of direct color red mask */ - unsigned char RedFieldPosition; /* 20: Bit posn of lsb of red mask */ - unsigned char GreenMaskSize; /* 21: Size of direct color green mask */ - unsigned char GreenFieldPosition; /* 22: Bit posn of lsb of green mask */ - unsigned char BlueMaskSize; /* 23: Size of direct color blue mask */ - unsigned char BlueFieldPosition; /* 24: Bit posn of lsb of blue mask */ - unsigned char RsvdMaskSize; /* 25: Size of direct color res mask */ - unsigned char RsvdFieldPosition; /* 26: Bit posn of lsb of res mask */ - unsigned char DirectColorModeInfo; /* 27: Direct color mode attributes */ - /* VBE 2.0 and above */ - unsigned long PhysBasePtr; /* 28: physical address for flat memory frame buffer. (Should be converted to linear before using) */ - unsigned short res3[3]; /* 2C: Reserved - always set to 0 */ - /* VBE 3.0 and above */ - unsigned short LinBytesPerScanLine; /* 32: bytes per scan line for linear modes */ - unsigned char BnkNumberOfImagePages;/* 34: number of images for banked modes */ - unsigned char LinNumberOfImagePages;/* 35: number of images for linear modes */ - unsigned char LinRedMaskSize; /* 36: size of direct color red mask (linear modes) */ - unsigned char LinRedFieldPosition; /* 37: bit position of lsb of red mask (linear modes) */ - unsigned char LinGreenMaskSize; /* 38: size of direct color green mask (linear modes) */ - unsigned char LinGreenFieldPosition;/* 39: bit position of lsb of green mask (linear modes) */ - unsigned char LinBlueMaskSize; /* 40: size of direct color blue mask (linear modes) */ - unsigned char LinBlueFieldPosition; /* 41: bit position of lsb of blue mask (linear modes) */ - unsigned char LinRsvdMaskSize; /* 42: size of direct color reserved mask (linear modes) */ - unsigned char LinRsvdFieldPosition; /* 43: bit position of lsb of reserved mask (linear modes) */ - unsigned long MaxPixelClock; /* 44: maximum pixel clock (in Hz) for graphics mode */ - char res4[189]; /* 48: remainder of ModeInfoBlock */ -}__attribute__ ((packed)); - -typedef enum { - memText= 0, - memCGA = 1, - memHercules = 2, - memPL = 3, /* Planar memory model */ - memPK = 4, /* Packed pixel memory model */ - mem256 = 5, - memRGB = 6, /* Direct color RGB memory model */ - memYUV = 7, /* Direct color YUV memory model */ -} memModels; - -struct VesaCRTCInfoBlock { - unsigned short hTotal; /* Horizontal total in pixels */ - unsigned short hSyncStart; /* Horizontal sync start in pixels */ - unsigned short hSyncEnd; /* Horizontal sync end in pixels */ - unsigned short vTotal; /* Vertical total in lines */ - unsigned short vSyncStart; /* Vertical sync start in lines */ - unsigned short vSyncEnd; /* Vertical sync end in lines */ - unsigned char Flags; /* Flags (Interlaced, Double Scan etc) */ - unsigned long PixelClock; /* Pixel clock in units of Hz */ - unsigned short RefreshRate;/* Refresh rate in units of 0.01 Hz*/ - unsigned char Reserved[40];/* remainder of CRTCInfoBlock*/ -}__attribute__ ((packed)); - -#define VESA_CRTC_DOUBLESCAN 0x01 -#define VESA_CRTC_INTERLACED 0x02 -#define VESA_CRTC_HSYNC_NEG 0x04 -#define VESA_CRTC_VSYNC_NEG 0x08 - -#define VESA_MODE_CRTC_REFRESH (1 << 11) -#define VESA_MODE_USE_LINEAR (1 << 14) -#define VESA_MODE_NOT_CLEAR (1 << 15) - -/* This will contain accesible 32-bit protmode pointers */ -struct VesaProtModeInterface -{ - void (*SetWindowCall)(void); - void (*SetDisplayStart)(void); - void (*SetPaletteData)(void); - unsigned short * iopl_ports; -}; - -/* - All functions below return: - 0 if succesful - 0xffff if vm86 syscall error occurs - 0x4fxx if VESA error occurs -*/ - -#define VBE_OK 0 -#define VBE_VM86_FAIL -1 -#define VBE_OUT_OF_DOS_MEM -2 -#define VBE_OUT_OF_MEM -3 -#define VBE_BROKEN_BIOS -4 -#define VBE_VESA_ERROR_MASK 0x004f -#define VBE_VESA_ERRCODE_MASK 0xff00 - -extern int vbeInit( void ); -extern int vbeDestroy( void ); - -extern int vbeGetControllerInfo(struct VbeInfoBlock *); -extern int vbeGetModeInfo(unsigned mode,struct VesaModeInfoBlock *); -extern int vbeSetMode(unsigned mode,struct VesaCRTCInfoBlock *); -extern int vbeGetMode(unsigned *mode); -extern int vbeGetPixelClock(unsigned *mode,unsigned *pixel_clock); -extern int vbeSaveState(void **data); /* note never copy this data */ -extern int vbeRestoreState(void *data); -extern int vbeGetWindow(unsigned *win_num); /* win_A=0 or win_B=1 */ -extern int vbeSetWindow(unsigned win_num,unsigned win_gran); -extern int vbeGetScanLineLength(unsigned *num_pixels,unsigned *num_bytes); -extern int vbeGetMaxScanLines(unsigned *num_pixels,unsigned *num_bytes, unsigned *num_lines); -extern int vbeSetScanLineLength(unsigned num_pixels); -extern int vbeSetScanLineLengthB(unsigned num_bytes); -extern int vbeGetDisplayStart(unsigned *pixel_num,unsigned *scan_line); -extern int vbeSetDisplayStart(unsigned long offset, int vsync); -extern int vbeSetScheduledDisplayStart(unsigned long offset, int vsync); -extern int vbeSetTV(unsigned int vesa_mode,unsigned int TV_mode); -/* - Func 0x08-0x09: - Support of palette currently is not implemented. -*/ -extern int vbeGetProtModeInfo(struct VesaProtModeInterface *); - -/* Standard VGA stuff */ -int vbeWriteString(int x, int y, int attr, char *str); - -/* Misc stuff (For portability only) */ -void * vbeMapVideoBuffer(unsigned long phys_addr,unsigned long size); -void vbeUnmapVideoBuffer(unsigned long linear_addr,unsigned long size); - -#endif