changeset 2632:6e3cee9e07ef

Double buffering interface
author nick
date Fri, 02 Nov 2001 17:34:17 +0000
parents d0490d3aa5e1
children fe5ab8c660de
files linux/vbelib.c linux/vbelib.h
diffstat 2 files changed, 132 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/linux/vbelib.c	Fri Nov 02 15:50:59 2001 +0000
+++ b/linux/vbelib.c	Fri Nov 02 17:34:17 2001 +0000
@@ -4,7 +4,7 @@
    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
-   GNU General Public licence v2.
+   of GNU General Public licence v2.
    Written by Nick Kurshev <nickols_k@mail.ru>
 */
 #include "vbelib.h"
@@ -21,6 +21,7 @@
 #include <fcntl.h>
 
 static struct VesaProtModeInterface vbe_pm_info;
+static struct VesaModeInfoBlock curr_mode_info;
 
 static inline int VERR(const void *p)
 {
@@ -322,7 +323,12 @@
   if(rm_space) LRMI_free_real(rm_space);
   if(!retval) return VBE_VM86_FAIL;
   retval = r.eax & 0xffff;
-  if(retval == 0x4f) retval = VBE_OK;
+  if(retval == 0x4f)
+  {
+    /* Just info for internal use (currently in SetDiplayStart func). */
+    vbeGetModeInfo(mode&0x1f,&curr_mode_info);
+    retval = VBE_OK;
+  }
   return retval;
 }
 
@@ -439,6 +445,123 @@
   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 & 0xffff),"d"((offset>>16)&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));
+    r.eax = 0x4f07;
+    r.ebx = vsync ? 0x80 : 0;
+    pixel_num = offset%(unsigned long)curr_mode_info.BytesPerScanLine;
+    if(pixel_num*(unsigned long)curr_mode_info.BytesPerScanLine!=offset) pixel_num++;
+    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;
+  }
+  return retval;
+}
+
 struct realVesaProtModeInterface
 {
   unsigned short SetWindowCall;
--- a/linux/vbelib.h	Fri Nov 02 15:50:59 2001 +0000
+++ b/linux/vbelib.h	Fri Nov 02 17:34:17 2001 +0000
@@ -1,7 +1,7 @@
 /*
    VESA VBE 2.0 compatible structures and definitions.
    You can redistribute this file under terms and conditions
-   GNU General Public licence v2.
+   of GNU General Public licence v2.
    Written by Nick Kurshev <nickols_k@mail.ru>
 */
 #ifndef __VESA_VBELIB_INCLUDED__
@@ -203,17 +203,12 @@
 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);
-/*
-   Func 0x06:
-   Support of logical scan line length is not implemented.
-   We assume that logical scan line length == physical scan line length.
-   (Logical display memory == displayed area).
-*/ 
-/*
-   Func 0x07:
-   Support of disply start is not implemented.
-   We assume that display start always == 0, 0.
-*/ 
+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);
 /*
    Func 0x08-0x09:
    Support of palette currently is not implemented.