svgalib 1.3.0 VESA driver and Millenium II

Search this archive.

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