From: Bernd Schmidt (crux@Pool.Informatik.RWTH-Aachen.DE)
Date: Mon 20 Jul 1998 - 13:58:19 IDT
With the following patch, the VESA driver included in svgalib-1.3.0 works with my Millenium II. The problem was that the BIOS did an interrupt call and the driver wasn't prepared for that. Programs that work: koules, lincity, xaos, zgv. Unfortunately, the function vga_draw_scanline doesn't seem to work with the VESA driver. The patch contains a bit of noise at the top that makes the file compile with glibc-2.0.94 together with linux-2.1.109 headers and egcs-1.0.3. Bernd diff -dru svgalib-1.3.0/src/lrmi.c svgalib-1.3.0.hacked/src/lrmi.c --- svgalib-1.3.0/src/lrmi.c Thu Jun 11 16:36:27 1998 +++ svgalib-1.3.0.hacked/src/lrmi.c Mon Jul 20 00:12:41 1998 @@ -22,17 +22,24 @@ #include <sys/mman.h> #include <unistd.h> #include <fcntl.h> +#include <errno.h> -#include <syscall.h> +#include <sys/syscall.h> -#ifndef SYS_vm86old -#define SYS___svgalib_vm86old SYS_vm86 -#else -#define SYS___svgalib_vm86old SYS_vm86old -#endif +#define __NR___svgalib_vm86old SYS_vm86old -_syscall1(int, __svgalib_vm86old, struct vm86_struct *, vs) +int __svgalib_vm86old (struct vm86_struct *arg1) +{ + long __res; + + __asm__ volatile ("pushl %%ebx\n\tmovl %%ecx,%%ebx\n\tint $0x80\n\tpopl %%ebx" + : "=a" (__res) + : "0" (__NR_vm86old), "c" ((long)(arg1))); + + __syscall_return (int,__res); +} + #define vm86 __svgalib_vm86old @@ -603,6 +610,14 @@ "d" (context.vm.regs.edx)); } +static unsigned char *get_insn_ptr (struct vm86_struct *ctx) +{ + unsigned char *insn; + insn = (unsigned char *)((unsigned int)ctx->regs.cs << 4); + insn += ctx->regs.eip; + return insn; +} + static int emulate(void) { @@ -614,8 +629,7 @@ } prefix = { 0, 0 }; int i = 0; - insn = (unsigned char *)((unsigned int)context.vm.regs.cs << 4); - insn += context.vm.regs.eip; + insn = get_insn_ptr (&context.vm); while (1) { @@ -736,25 +750,50 @@ static int run_vm86(void) - { - unsigned int vret; - - while (1) - { - vret = vm86(&context.vm); +{ + while (1) { + unsigned int vret = vm86(&context.vm); if (VM86_TYPE(vret) == VM86_INTx - && VM86_ARG(vret) == RETURN_TO_32_INT) + && VM86_ARG(vret) == RETURN_TO_32_INT) return 1; + if (VM86_TYPE(vret) == VM86_INTx) { + unsigned int oldcs, oldeip; + unsigned int vret1; + unsigned int seg, off; + unsigned char *insn = get_insn_ptr (&context.vm); + + seg = get_int_seg(VM86_ARG(vret)); + off = get_int_off(VM86_ARG(vret)); + + if (seg < 0xa000) { + return 0; + } + oldcs = context.vm.regs.cs; + oldeip = context.vm.regs.eip; + context.vm.regs.cs = seg; + context.vm.regs.eip = off; + + pushw(DEFAULT_VM86_FLAGS); + pushw(context.ret_seg); + pushw(context.ret_off); + + vret1 = run_vm86(); + if (vret1 == 0) + return 0; + context.vm.regs.cs = oldcs; + context.vm.regs.eip = oldeip; + continue; + } + if (VM86_TYPE(vret) != VM86_UNKNOWN) return 0; if (!emulate()) return 0; - } } - +} int __svgalib_LRMI_call(struct LRMI_regs *r) @@ -765,8 +804,8 @@ set_regs(r); - context.vm.regs.cs = r->cs; - context.vm.regs.eip = r->ip; + context.vm.regs.cs = r->cs; + context.vm.regs.eip = r->ip; if (r->ss == 0 && r->sp == 0) {
This archive was generated by hypermail 2.1.4 : Wed 21 Jan 2004 - 22:10:22 IST