summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/CVS/Entries2
-rw-r--r--tests/CVS/Repository1
-rw-r--r--tests/CVS/Root1
-rw-r--r--tests/lfbprof/CVS/Entries4
-rw-r--r--tests/lfbprof/CVS/Repository1
-rw-r--r--tests/lfbprof/CVS/Root1
-rw-r--r--tests/lfbprof/Makefile5
-rw-r--r--tests/lfbprof/lfbprof.c594
-rw-r--r--tests/lfbprof/lfbprof.h149
-rw-r--r--tests/testbios.c353
10 files changed, 1111 insertions, 0 deletions
diff --git a/tests/CVS/Entries b/tests/CVS/Entries
new file mode 100644
index 0000000..374c8f3
--- /dev/null
+++ b/tests/CVS/Entries
@@ -0,0 +1,2 @@
+/testbios.c/1.1/Mon Feb 18 10:31:49 2002//
+D/lfbprof////
diff --git a/tests/CVS/Repository b/tests/CVS/Repository
new file mode 100644
index 0000000..ca7e6ea
--- /dev/null
+++ b/tests/CVS/Repository
@@ -0,0 +1 @@
+vgabios/tests
diff --git a/tests/CVS/Root b/tests/CVS/Root
new file mode 100644
index 0000000..544303b
--- /dev/null
+++ b/tests/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sv.gnu.org:/sources/vgabios
diff --git a/tests/lfbprof/CVS/Entries b/tests/lfbprof/CVS/Entries
new file mode 100644
index 0000000..9584a67
--- /dev/null
+++ b/tests/lfbprof/CVS/Entries
@@ -0,0 +1,4 @@
+/Makefile/1.1/Mon Feb 18 22:07:33 2002//
+/lfbprof.c/1.3/Sun Apr 18 09:15:22 2004//
+/lfbprof.h/1.2/Mon Feb 18 22:26:31 2002//
+D
diff --git a/tests/lfbprof/CVS/Repository b/tests/lfbprof/CVS/Repository
new file mode 100644
index 0000000..1dc40e3
--- /dev/null
+++ b/tests/lfbprof/CVS/Repository
@@ -0,0 +1 @@
+vgabios/tests/lfbprof
diff --git a/tests/lfbprof/CVS/Root b/tests/lfbprof/CVS/Root
new file mode 100644
index 0000000..544303b
--- /dev/null
+++ b/tests/lfbprof/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.sv.gnu.org:/sources/vgabios
diff --git a/tests/lfbprof/Makefile b/tests/lfbprof/Makefile
new file mode 100644
index 0000000..7c42e38
--- /dev/null
+++ b/tests/lfbprof/Makefile
@@ -0,0 +1,5 @@
+# Very simple makefile for LFBPROF.C using Watcom C++ 10.0a with DOS4GW
+
+lfbprof.exe: lfbprof.c lfbprof.h
+ wcl386 -zq -s -d2 lfbprof.c
+
diff --git a/tests/lfbprof/lfbprof.c b/tests/lfbprof/lfbprof.c
new file mode 100644
index 0000000..df37452
--- /dev/null
+++ b/tests/lfbprof/lfbprof.c
@@ -0,0 +1,594 @@
+/****************************************************************************
+*
+* VBE 2.0 Linear Framebuffer Profiler
+* By Kendall Bennett and Brian Hook
+*
+* Filename: LFBPROF.C
+* Language: ANSI C
+* Environment: Watcom C/C++ 10.0a with DOS4GW
+*
+* Description: Simple program to profile the speed of screen clearing
+* and full screen BitBlt operations using a VESA VBE 2.0
+* linear framebuffer from 32 bit protected mode.
+*
+* For simplicity, this program only supports 256 color
+* SuperVGA video modes that support a linear framebuffer.
+*
+*
+* 2002/02/18: Jeroen Janssen <japj at xs4all dot nl>
+* - fixed unsigned short for mode list (-1 != 0xffff otherwise)
+* - fixed LfbMapRealPointer macro mask problem (some modes were skipped)
+*
+****************************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <conio.h>
+#include <dos.h>
+#include "lfbprof.h"
+
+/*---------------------------- Global Variables ---------------------------*/
+
+int VESABuf_len = 1024; /* Length of VESABuf */
+int VESABuf_sel = 0; /* Selector for VESABuf */
+int VESABuf_rseg; /* Real mode segment of VESABuf */
+unsigned short modeList[50]; /* List of available VBE modes */
+float clearsPerSec; /* Number of clears per second */
+float clearsMbPerSec; /* Memory transfer for clears */
+float bitBltsPerSec; /* Number of BitBlt's per second */
+float bitBltsMbPerSec; /* Memory transfer for bitblt's */
+int xres,yres; /* Video mode resolution */
+int bytesperline; /* Bytes per scanline for mode */
+long imageSize; /* Length of the video image */
+char *LFBPtr; /* Pointer to linear framebuffer */
+
+/*------------------------- DPMI interface routines -----------------------*/
+
+void DPMI_allocRealSeg(int size,int *sel,int *r_seg)
+/****************************************************************************
+*
+* Function: DPMI_allocRealSeg
+* Parameters: size - Size of memory block to allocate
+* sel - Place to return protected mode selector
+* r_seg - Place to return real mode segment
+*
+* Description: Allocates a block of real mode memory using DPMI services.
+* This routine returns both a protected mode selector and
+* real mode segment for accessing the memory block.
+*
+****************************************************************************/
+{
+ union REGS r;
+
+ r.w.ax = 0x100; /* DPMI allocate DOS memory */
+ r.w.bx = (size + 0xF) >> 4; /* number of paragraphs */
+ int386(0x31, &r, &r);
+ if (r.w.cflag)
+ FatalError("DPMI_allocRealSeg failed!");
+ *sel = r.w.dx; /* Protected mode selector */
+ *r_seg = r.w.ax; /* Real mode segment */
+}
+
+void DPMI_freeRealSeg(unsigned sel)
+/****************************************************************************
+*
+* Function: DPMI_allocRealSeg
+* Parameters: sel - Protected mode selector of block to free
+*
+* Description: Frees a block of real mode memory.
+*
+****************************************************************************/
+{
+ union REGS r;
+
+ r.w.ax = 0x101; /* DPMI free DOS memory */
+ r.w.dx = sel; /* DX := selector from 0x100 */
+ int386(0x31, &r, &r);
+}
+
+typedef struct {
+ long edi;
+ long esi;
+ long ebp;
+ long reserved;
+ long ebx;
+ long edx;
+ long ecx;
+ long eax;
+ short flags;
+ short es,ds,fs,gs,ip,cs,sp,ss;
+ } _RMREGS;
+
+#define IN(reg) rmregs.e##reg = in->x.reg
+#define OUT(reg) out->x.reg = rmregs.e##reg
+
+int DPMI_int86(int intno, RMREGS *in, RMREGS *out)
+/****************************************************************************
+*
+* Function: DPMI_int86
+* Parameters: intno - Interrupt number to issue
+* in - Pointer to structure for input registers
+* out - Pointer to structure for output registers
+* Returns: Value returned by interrupt in AX
+*
+* Description: Issues a real mode interrupt using DPMI services.
+*
+****************************************************************************/
+{
+ _RMREGS rmregs;
+ union REGS r;
+ struct SREGS sr;
+
+ memset(&rmregs, 0, sizeof(rmregs));
+ IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
+
+ segread(&sr);
+ r.w.ax = 0x300; /* DPMI issue real interrupt */
+ r.h.bl = intno;
+ r.h.bh = 0;
+ r.w.cx = 0;
+ sr.es = sr.ds;
+ r.x.edi = (unsigned)&rmregs;
+ int386x(0x31, &r, &r, &sr); /* Issue the interrupt */
+
+ OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
+ out->x.cflag = rmregs.flags & 0x1;
+ return out->x.ax;
+}
+
+int DPMI_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs)
+/****************************************************************************
+*
+* Function: DPMI_int86
+* Parameters: intno - Interrupt number to issue
+* in - Pointer to structure for input registers
+* out - Pointer to structure for output registers
+* sregs - Values to load into segment registers
+* Returns: Value returned by interrupt in AX
+*
+* Description: Issues a real mode interrupt using DPMI services.
+*
+****************************************************************************/
+{
+ _RMREGS rmregs;
+ union REGS r;
+ struct SREGS sr;
+
+ memset(&rmregs, 0, sizeof(rmregs));
+ IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
+ rmregs.es = sregs->es;
+ rmregs.ds = sregs->ds;
+
+ segread(&sr);
+ r.w.ax = 0x300; /* DPMI issue real interrupt */
+ r.h.bl = intno;
+ r.h.bh = 0;
+ r.w.cx = 0;
+ sr.es = sr.ds;
+ r.x.edi = (unsigned)&rmregs;
+ int386x(0x31, &r, &r, &sr); /* Issue the interrupt */
+
+ OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
+ sregs->es = rmregs.es;
+ sregs->cs = rmregs.cs;
+ sregs->ss = rmregs.ss;
+ sregs->ds = rmregs.ds;
+ out->x.cflag = rmregs.flags & 0x1;
+ return out->x.ax;
+}
+
+int DPMI_allocSelector(void)
+/****************************************************************************
+*
+* Function: DPMI_allocSelector
+* Returns: Newly allocated protected mode selector
+*
+* Description: Allocates a new protected mode selector using DPMI
+* services. This selector has a base address and limit of 0.
+*
+****************************************************************************/
+{
+ int sel;
+ union REGS r;
+
+ r.w.ax = 0; /* DPMI allocate selector */
+ r.w.cx = 1; /* Allocate a single selector */
+ int386(0x31, &r, &r);
+ if (r.x.cflag)
+ FatalError("DPMI_allocSelector() failed!");
+ sel = r.w.ax;
+
+ r.w.ax = 9; /* DPMI set access rights */
+ r.w.bx = sel;
+ r.w.cx = 0x8092; /* 32 bit page granular */
+ int386(0x31, &r, &r);
+ return sel;
+}
+
+long DPMI_mapPhysicalToLinear(long physAddr,long limit)
+/****************************************************************************
+*
+* Function: DPMI_mapPhysicalToLinear
+* Parameters: physAddr - Physical memory address to map
+* limit - Length-1 of physical memory region to map
+* Returns: Starting linear address for mapped memory
+*
+* Description: Maps a section of physical memory into the linear address
+* space of a process using DPMI calls. Note that this linear
+* address cannot be used directly, but must be used as the
+* base address for a selector.
+*
+****************************************************************************/
+{
+ union REGS r;
+
+ r.w.ax = 0x800; /* DPMI map physical to linear */
+ r.w.bx = physAddr >> 16;
+ r.w.cx = physAddr & 0xFFFF;
+ r.w.si = limit >> 16;
+ r.w.di = limit & 0xFFFF;
+ int386(0x31, &r, &r);
+ if (r.x.cflag)
+ FatalError("DPMI_mapPhysicalToLinear() failed!");
+ return ((long)r.w.bx << 16) + r.w.cx;
+}
+
+void DPMI_setSelectorBase(int sel,long linAddr)
+/****************************************************************************
+*
+* Function: DPMI_setSelectorBase
+* Parameters: sel - Selector to change base address for
+* linAddr - Linear address used for new base address
+*
+* Description: Sets the base address for the specified selector.
+*
+****************************************************************************/
+{
+ union REGS r;
+
+ r.w.ax = 7; /* DPMI set selector base address */
+ r.w.bx = sel;
+ r.w.cx = linAddr >> 16;
+ r.w.dx = linAddr & 0xFFFF;
+ int386(0x31, &r, &r);
+ if (r.x.cflag)
+ FatalError("DPMI_setSelectorBase() failed!");
+}
+
+void DPMI_setSelectorLimit(int sel,long limit)
+/****************************************************************************
+*
+* Function: DPMI_setSelectorLimit
+* Parameters: sel - Selector to change limit for
+* limit - Limit-1 for the selector
+*
+* Description: Sets the memory limit for the specified selector.
+*
+****************************************************************************/
+{
+ union REGS r;
+
+ r.w.ax = 8; /* DPMI set selector limit */
+ r.w.bx = sel;
+ r.w.cx = limit >> 16;
+ r.w.dx = limit & 0xFFFF;
+ int386(0x31, &r, &r);
+ if (r.x.cflag)
+ FatalError("DPMI_setSelectorLimit() failed!");
+}
+
+/*-------------------------- VBE Interface routines -----------------------*/
+
+void FatalError(char *msg)
+{
+ fprintf(stderr,"%s\n", msg);
+ exit(1);
+}
+
+static void ExitVBEBuf(void)
+{
+ DPMI_freeRealSeg(VESABuf_sel);
+}
+
+void VBE_initRMBuf(void)
+/****************************************************************************
+*
+* Function: VBE_initRMBuf
+* Description: Initialises the VBE transfer buffer in real mode memory.
+* This routine is called by the VESAVBE module every time
+* it needs to use the transfer buffer, so we simply allocate
+* it once and then return.
+*
+****************************************************************************/
+{
+ if (!VESABuf_sel) {
+ DPMI_allocRealSeg(VESABuf_len, &VESABuf_sel, &VESABuf_rseg);
+ atexit(ExitVBEBuf);
+ }
+}
+
+void VBE_callESDI(RMREGS *regs, void *buffer, int size)
+/****************************************************************************
+*
+* Function: VBE_callESDI
+* Parameters: regs - Registers to load when calling VBE
+* buffer - Buffer to copy VBE info block to
+* size - Size of buffer to fill
+*
+* Description: Calls the VESA VBE and passes in a buffer for the VBE to
+* store information in, which is then copied into the users
+* buffer space. This works in protected mode as the buffer
+* passed to the VESA VBE is allocated in conventional
+* memory, and is then copied into the users memory block.
+*
+****************************************************************************/
+{
+ RMSREGS sregs;
+
+ VBE_initRMBuf();
+ sregs.es = VESABuf_rseg;
+ regs->x.di = 0;
+ _fmemcpy(MK_FP(VESABuf_sel,0),buffer,size);
+ DPMI_int86x(0x10, regs, regs, &sregs);
+ _fmemcpy(buffer,MK_FP(VESABuf_sel,0),size);
+}
+
+int VBE_detect(void)
+/****************************************************************************
+*
+* Function: VBE_detect
+* Parameters: vgaInfo - Place to store the VGA information block
+* Returns: VBE version number, or 0 if not detected.
+*
+* Description: Detects if a VESA VBE is out there and functioning
+* correctly. If we detect a VBE interface we return the
+* VGAInfoBlock returned by the VBE and the VBE version number.
+*
+****************************************************************************/
+{
+ RMREGS regs;
+ unsigned short *p1,*p2;
+ VBE_vgaInfo vgaInfo;
+
+ /* Put 'VBE2' into the signature area so that the VBE 2.0 BIOS knows
+ * that we have passed a 512 byte extended block to it, and wish
+ * the extended information to be filled in.
+ */
+ strncpy(vgaInfo.VESASignature,"VBE2",4);
+
+ /* Get the SuperVGA Information block */
+ regs.x.ax = 0x4F00;
+ VBE_callESDI(&regs, &vgaInfo, sizeof(VBE_vgaInfo));
+ if (regs.x.ax != 0x004F)
+ return 0;
+ if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0)
+ return 0;
+
+ /* Now that we have detected a VBE interface, copy the list of available
+ * video modes into our local buffer. We *must* copy this mode list,
+ * since the VBE will build the mode list in the VBE_vgaInfo buffer
+ * that we have passed, so the next call to the VBE will trash the
+ * list of modes.
+ */
+ printf("videomodeptr %x\n",vgaInfo.VideoModePtr);
+ p1 = LfbMapRealPointer(vgaInfo.VideoModePtr);
+ p2 = modeList;
+ while (*p1 != -1)
+ {
+ printf("found mode %x\n",*p1);
+ *p2++ = *p1++;
+ }
+ *p2 = -1;
+ return vgaInfo.VESAVersion;
+}
+
+int VBE_getModeInfo(int mode,VBE_modeInfo *modeInfo)
+/****************************************************************************
+*
+* Function: VBE_getModeInfo
+* Parameters: mode - VBE mode to get information for
+* modeInfo - Place to store VBE mode information
+* Returns: 1 on success, 0 if function failed.
+*
+* Description: Obtains information about a specific video mode from the
+* VBE. You should use this function to find the video mode
+* you wish to set, as the new VBE 2.0 mode numbers may be
+* completely arbitrary.
+*
+****************************************************************************/
+{
+ RMREGS regs;
+
+ regs.x.ax = 0x4F01; /* Get mode information */
+ regs.x.cx = mode;
+ VBE_callESDI(&regs, modeInfo, sizeof(VBE_modeInfo));
+ if (regs.x.ax != 0x004F)
+ return 0;
+ if ((modeInfo->ModeAttributes & vbeMdAvailable) == 0)
+ return 0;
+ return 1;
+}
+
+void VBE_setVideoMode(int mode)
+/****************************************************************************
+*
+* Function: VBE_setVideoMode
+* Parameters: mode - VBE mode number to initialise
+*
+****************************************************************************/
+{
+ RMREGS regs;
+ regs.x.ax = 0x4F02;
+ regs.x.bx = mode;
+ DPMI_int86(0x10,&regs,&regs);
+}
+
+/*-------------------- Application specific routines ----------------------*/
+
+void *GetPtrToLFB(long physAddr)
+/****************************************************************************
+*
+* Function: GetPtrToLFB
+* Parameters: physAddr - Physical memory address of linear framebuffer
+* Returns: Far pointer to the linear framebuffer memory
+*
+****************************************************************************/
+{
+ int sel;
+ long linAddr,limit = (4096 * 1024) - 1;
+
+// sel = DPMI_allocSelector();
+ linAddr = DPMI_mapPhysicalToLinear(physAddr,limit);
+// DPMI_setSelectorBase(sel,linAddr);
+// DPMI_setSelectorLimit(sel,limit);
+// return MK_FP(sel,0);
+ return (void*)linAddr;
+}
+
+void AvailableModes(void)
+/****************************************************************************
+*
+* Function: AvailableModes
+*
+* Description: Display a list of available LFB mode resolutions.
+*
+****************************************************************************/
+{
+ unsigned short *p;
+ VBE_modeInfo modeInfo;
+
+ printf("Usage: LFBPROF <xres> <yres>\n\n");
+ printf("Available 256 color video modes:\n");
+ for (p = modeList; *p != -1; p++) {
+ if (VBE_getModeInfo(*p, &modeInfo)) {
+ /* Filter out only 8 bit linear framebuffer modes */
+ if ((modeInfo.ModeAttributes & vbeMdLinear) == 0)
+ continue;
+ if (modeInfo.MemoryModel != vbeMemPK
+ || modeInfo.BitsPerPixel != 8
+ || modeInfo.NumberOfPlanes != 1)
+ continue;
+ printf(" %4d x %4d %d bits per pixel\n",
+ modeInfo.XResolution, modeInfo.YResolution,
+ modeInfo.BitsPerPixel);
+ }
+ }
+ exit(1);
+}
+
+void InitGraphics(int x,int y)
+/****************************************************************************
+*
+* Function: InitGraphics
+* Parameters: x,y - Requested video mode resolution
+*
+* Description: Initialise the specified video mode. We search through
+* the list of available video modes for one that matches
+* the resolution and color depth are are looking for.
+*
+****************************************************************************/
+{
+ unsigned short *p;
+ VBE_modeInfo modeInfo;
+ printf("InitGraphics\n");
+
+ for (p = modeList; *p != -1; p++) {
+ if (VBE_getModeInfo(*p, &modeInfo)) {
+ /* Filter out only 8 bit linear framebuffer modes */
+ if ((modeInfo.ModeAttributes & vbeMdLinear) == 0)
+ continue;
+ if (modeInfo.MemoryModel != vbeMemPK
+ || modeInfo.BitsPerPixel != 8
+ || modeInfo.NumberOfPlanes != 1)
+ continue;
+ if (modeInfo.XResolution != x || modeInfo.YResolution != y)
+ continue;
+ xres = x;
+ yres = y;
+ bytesperline = modeInfo.BytesPerScanLine;
+ imageSize = bytesperline * yres;
+ VBE_setVideoMode(*p | vbeUseLFB);
+ LFBPtr = GetPtrToLFB(modeInfo.PhysBasePtr);
+ return;
+ }
+ }
+ printf("Valid video mode not found\n");
+ exit(1);
+}
+
+void EndGraphics(void)
+/****************************************************************************
+*
+* Function: EndGraphics
+*
+* Description: Restores text mode.
+*
+****************************************************************************/
+{
+ RMREGS regs;
+ printf("EndGraphics\n");
+ regs.x.ax = 0x3;
+ DPMI_int86(0x10, &regs, &regs);
+}
+
+void ProfileMode(void)
+/****************************************************************************
+*
+* Function: ProfileMode
+*
+* Description: Profiles framebuffer performance for simple screen clearing
+* and for copying from system memory to video memory (BitBlt).
+* This routine thrashes the CPU cache by cycling through
+* enough system memory buffers to invalidate the entire
+* CPU external cache before re-using the first memory buffer
+* again.
+*
+****************************************************************************/
+{
+ int i,numClears,numBlts,maxImages;
+ long startTicks,endTicks;
+ void *image[10],*dst;
+ printf("ProfileMode\n");
+
+ /* Profile screen clearing operation */
+ startTicks = LfbGetTicks();
+ numClears = 0;
+ while ((LfbGetTicks() - startTicks) < 182)
+ LfbMemset(LFBPtr,numClears++,imageSize);
+ endTicks = LfbGetTicks();
+ clearsPerSec = numClears / ((endTicks - startTicks) * 0.054925);
+ clearsMbPerSec = (clearsPerSec * imageSize) / 1048576.0;
+
+ /* Profile system memory to video memory copies */
+ maxImages = ((512 * 1024U) / imageSize) + 2;
+ for (i = 0; i < maxImages; i++) {
+ image[i] = malloc(imageSize);
+ if (image[i] == NULL)
+ FatalError("Not enough memory to profile BitBlt!");
+ memset(image[i],i+1,imageSize);
+ }
+ startTicks = LfbGetTicks();
+ numBlts = 0;
+ while ((LfbGetTicks() - startTicks) < 182)
+ LfbMemcpy(LFBPtr,image[numBlts++ % maxImages],imageSize);
+ endTicks = LfbGetTicks();
+ bitBltsPerSec = numBlts / ((endTicks - startTicks) * 0.054925);
+ bitBltsMbPerSec = (bitBltsPerSec * imageSize) / 1048576.0;
+}
+
+void main(int argc, char *argv[])
+{
+ if (VBE_detect() < 0x200)
+ FatalError("This program requires VBE 2.0; Please install UniVBE 5.1.");
+ if (argc != 3)
+ AvailableModes(); /* Display available modes */
+
+ InitGraphics(atoi(argv[1]),atoi(argv[2])); /* Start graphics */
+ ProfileMode(); /* Profile the video mode */
+ EndGraphics(); /* Restore text mode */
+
+ printf("Profiling results for %dx%d 8 bits per pixel.\n",xres,yres);
+ printf("%3.2f clears/s, %2.2f Mb/s\n", clearsPerSec, clearsMbPerSec);
+ printf("%3.2f bitBlt/s, %2.2f Mb/s\n", bitBltsPerSec, bitBltsMbPerSec);
+}
diff --git a/tests/lfbprof/lfbprof.h b/tests/lfbprof/lfbprof.h
new file mode 100644
index 0000000..bae0e09
--- /dev/null
+++ b/tests/lfbprof/lfbprof.h
@@ -0,0 +1,149 @@
+/****************************************************************************
+*
+* VBE 2.0 Linear Framebuffer Profiler
+* By Kendall Bennett and Brian Hook
+*
+* Filename: LFBPROF.H
+* Language: ANSI C
+* Environment: Watcom C/C++ 10.0a with DOS4GW
+*
+* Description: Header file for the LFBPROF.C progam.
+*
+****************************************************************************/
+
+#ifndef __LFBPROF_H
+#define __LFBPROF_H
+
+/*---------------------- Macros and type definitions ----------------------*/
+
+#pragma pack(1)
+
+/* SuperVGA information block */
+
+typedef struct {
+ char VESASignature[4]; /* 'VESA' 4 byte signature */
+ short VESAVersion; /* VBE version number */
+ long OemStringPtr; /* Pointer to OEM string */
+ long Capabilities; /* Capabilities of video card */
+ long VideoModePtr; /* Pointer to supported modes */
+ short TotalMemory; /* Number of 64kb memory blocks */
+
+ /* VBE 2.0 extensions */
+
+ short OemSoftwareRev; /* OEM Software revision number */
+ long OemVendorNamePtr; /* Pointer to Vendor Name string */
+ long OemProductNamePtr; /* Pointer to Product Name string */
+ long OemProductRevPtr; /* Pointer to Product Revision str */
+ char reserved[222]; /* Pad to 256 byte block size */
+ char OemDATA[256]; /* Scratch pad for OEM data */
+ } VBE_vgaInfo;
+
+/* SuperVGA mode information block */
+
+typedef struct {
+ short ModeAttributes; /* Mode attributes */
+ char WinAAttributes; /* Window A attributes */
+ char WinBAttributes; /* Window B attributes */
+ short WinGranularity; /* Window granularity in k */
+ short WinSize; /* Window size in k */
+ short WinASegment; /* Window A segment */
+ short WinBSegment; /* Window B segment */
+ long WinFuncPtr; /* Pointer to window function */
+ short BytesPerScanLine; /* Bytes per scanline */
+ short XResolution; /* Horizontal resolution */
+ short YResolution; /* Vertical resolution */
+ char XCharSize; /* Character cell width */
+ char YCharSize; /* Character cell height */
+ char NumberOfPlanes; /* Number of memory planes */
+ char BitsPerPixel; /* Bits per pixel */
+ char NumberOfBanks; /* Number of CGA style banks */
+ char MemoryModel; /* Memory model type */
+ char BankSize; /* Size of CGA style banks */
+ char NumberOfImagePages; /* Number of images pages */
+ char res1; /* Reserved */
+ char RedMaskSize; /* Size of direct color red mask */
+ char RedFieldPosition; /* Bit posn of lsb of red mask */
+ char GreenMaskSize; /* Size of direct color green mask */
+ char GreenFieldPosition; /* Bit posn of lsb of green mask */
+ char BlueMaskSize; /* Size of direct color blue mask */
+ char BlueFieldPosition; /* Bit posn of lsb of blue mask */
+ char RsvdMaskSize; /* Size of direct color res mask */
+ char RsvdFieldPosition; /* Bit posn of lsb of res mask */
+ char DirectColorModeInfo; /* Direct color mode attributes */
+
+ /* VBE 2.0 extensions */
+
+ long PhysBasePtr; /* Physical address for linear buf */
+ long OffScreenMemOffset; /* Pointer to start of offscreen mem*/
+ short OffScreenMemSize; /* Amount of offscreen mem in 1K's */
+ char res2[206]; /* Pad to 256 byte block size */
+ } VBE_modeInfo;
+
+#define vbeMemPK 4 /* Packed Pixel memory model */
+#define vbeUseLFB 0x4000 /* Enable linear framebuffer mode */
+
+/* Flags for the mode attributes returned by VBE_getModeInfo. If
+ * vbeMdNonBanked is set to 1 and vbeMdLinear is also set to 1, then only
+ * the linear framebuffer mode is available.
+ */
+
+#define vbeMdAvailable 0x0001 /* Video mode is available */
+#define vbeMdColorMode 0x0008 /* Mode is a color video mode */
+#define vbeMdGraphMode 0x0010 /* Mode is a graphics mode */
+#define vbeMdNonBanked 0x0040 /* Banked mode is not supported */
+#define vbeMdLinear 0x0080 /* Linear mode supported */
+
+/* Structures for issuing real mode interrupts with DPMI */
+
+struct _RMWORDREGS {
+ unsigned short ax, bx, cx, dx, si, di, cflag;
+ };
+
+struct _RMBYTEREGS {
+ unsigned char al, ah, bl, bh, cl, ch, dl, dh;
+ };
+
+typedef union {
+ struct _RMWORDREGS x;
+ struct _RMBYTEREGS h;
+ } RMREGS;
+
+typedef struct {
+ unsigned short es;
+ unsigned short cs;
+ unsigned short ss;
+ unsigned short ds;
+ } RMSREGS;
+
+/* Inline assembler block fill/move routines */
+
+void LfbMemset(void *p,int c,int n);
+#pragma aux LfbMemset = \
+ "shr ecx,2" \
+ "xor eax,eax" \
+ "mov al,bl" \
+ "shl ebx,8" \
+ "or ax,bx" \
+ "mov ebx,eax" \
+ "shl ebx,16" \
+ "or eax,ebx" \
+ "rep stosd" \
+ parm [edi] [ebx] [ecx];
+
+void LfbMemcpy(void *dst,void *src,int n);
+#pragma aux LfbMemcpy = \
+ "shr ecx,2" \
+ "rep movsd" \
+ parm [edi] [esi] [ecx];
+
+/* Map a real mode pointer into address space */
+
+#define LfbMapRealPointer(p) (void*)(((unsigned)((p) & 0xFFFF0000) >> 12) + ((p) & 0xFFFF))
+
+/* Get the current timer tick count */
+
+#define LfbGetTicks() *((long*)0x46C)
+
+#pragma pack()
+
+#endif /* __LFBPROF_H */
diff --git a/tests/testbios.c b/tests/testbios.c
new file mode 100644
index 0000000..99da5a6
--- /dev/null
+++ b/tests/testbios.c
@@ -0,0 +1,353 @@
+/*
+ This is a little turbo C program that executes
+ several int10, and let you inspect the content
+ of the vgabios area
+
+ It is used to test the behavior of the vgabios
+*/
+
+#include <stdio.h>
+#include <dos.h>
+#include <conio.h>
+
+
+typedef unsigned char Bit8u;
+typedef unsigned short Bit16u;
+
+typedef struct
+{Bit8u initial;
+ Bit8u current;
+ Bit16u nbcols;
+ Bit16u regen;
+ Bit16u start;
+ Bit16u curpos[8];
+ Bit8u curtyp;
+ Bit8u curpage;
+ Bit16u crtc;
+ Bit16u msr;
+ Bit16u cgapal;
+ Bit8u nbrows;
+ Bit16u cheight;
+ Bit8u ctl;
+ Bit8u switches;
+ Bit8u modeset;
+ Bit8u dcc;
+ Bit16u vsseg;
+ Bit16u vsoffset;
+} BIOSAREA;
+
+void int10ax0003(struct REGPACK *regs)
+{
+ regs->r_ax=0x0003;
+ intr(0x10,regs);
+}
+
+void int10ax02(struct REGPACK *regs)
+{
+ regs->r_ax=0x0200;
+ regs->r_bx=0x0000;
+ regs->r_dx=0x1710;
+ intr(0x10,regs);
+ printf("We are now at 24/17");
+}
+
+void int10ax03(struct REGPACK *regs)
+{
+ regs->r_ax=0x0300;
+ regs->r_bx=0x0000;
+ intr(0x10,regs);
+ printf("\nCursor is ax%04x cx%04x dx%04x\n",regs->r_ax,regs->r_cx,regs->r_dx);
+}
+
+void int10ax0501(struct REGPACK *regs)
+{
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ regs->r_ax=0x0e61;
+ regs->r_bx=0x0000;
+ intr(0x10,regs);
+ printf("We are now on page 2");
+}
+
+void int10ax0602(struct REGPACK *regs)
+{
+ regs->r_ax=0x0602;
+ regs->r_bx=0x0700;
+ regs->r_cx=0x0101;
+ regs->r_dx=0x0a0a;
+ intr(0x10,regs);
+ printf("Scrolled 2 up");
+}
+
+void int10ax0702(struct REGPACK *regs)
+{
+ regs->r_ax=0x0702;
+ regs->r_bx=0x0700;
+ regs->r_cx=0x0101;
+ regs->r_dx=0x0a0a;
+ intr(0x10,regs);
+ printf("Scrolled 2 down");
+}
+
+void int10ax08(struct REGPACK *regs)
+{
+ regs->r_ax=0x0800;
+ regs->r_bx=0x0000;
+ intr(0x10,regs);
+}
+
+void int10ax09(struct REGPACK *regs)
+{
+ char attr;
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ for(attr=0;attr<16;attr++)
+ {printf("%02x ",attr);
+ regs->r_ax=0x0961+attr;
+ regs->r_bx=0x0100+attr;
+ regs->r_cx=0x0016;
+ intr(0x10,regs);
+ printf("\n");
+ }
+}
+
+void int10ax0a(struct REGPACK *regs)
+{
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ regs->r_ax=0x0a62;
+ regs->r_bx=0x0101;
+ regs->r_cx=0x0016;
+ intr(0x10,regs);
+}
+
+void int10ax0f(struct REGPACK *regs)
+{
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ regs->r_ax=0x0f00;
+ intr(0x10,regs);
+}
+
+void int10ax1b(struct REGPACK *regs)
+{unsigned char table[64];
+ unsigned char far *ptable;
+ int i;
+
+ regs->r_ax=0x0501;
+ intr(0x10,regs);
+ regs->r_ax=0x1b00;
+ regs->r_bx=0x0000;
+ ptable=&table;
+ regs->r_es=FP_SEG(ptable);
+ regs->r_di=FP_OFF(ptable);
+ printf("Read state info in %04x:%04x\n",regs->r_es,regs->r_di);
+ intr(0x10,regs);
+
+ for(i=0;i<64;i++)
+ {if(i%16==0)printf("\n%02x ",i);
+ printf("%02x ",table[i]);
+ }
+ printf("\n");
+}
+
+static unsigned char var[64];
+
+void int10ax13(struct REGPACK *regs)
+{unsigned char far *pvar;
+
+ pvar=&var;
+
+ regs->r_ax=0x1300;
+ regs->r_bx=0x000b;
+ regs->r_dx=0x1010;
+ regs->r_cx=0x0002;
+ regs->r_es=FP_SEG(pvar);
+ regs->r_bp=FP_OFF(pvar);
+ pokeb(regs->r_es,regs->r_bp,'t');
+ pokeb(regs->r_es,regs->r_bp+1,'b');
+ printf("Writing from %04x:%04x\n",regs->r_es,regs->r_bp);
+ intr(0x10,regs);
+
+}
+
+void switch_50(struct REGPACK *regs)
+{
+ regs->r_ax=0x1202;
+ regs->r_bx=0x3000;
+ intr(0x10,regs);
+ regs->r_ax=0x0003;
+ intr(0x10,regs);
+ regs->r_ax=0x1112;
+ regs->r_bx=0x0000;
+ intr(0x10,regs);
+}
+
+char exec_function(struct REGPACK *regs)
+{char c;
+
+ printf("--- Functions --------------------\n");
+ printf("a. int10 ax0003\t");
+ printf("b. int10 ax02\t");
+ printf("c. int10 ax03\t");
+ printf("d. int10 ax0501\n");
+ printf("e. int10 ax0602\t");
+ printf("f. int10 ax0702\t");
+ printf("g. int10 ax08\t");
+ printf("h. int10 ax09\t");
+ printf("i. int10 ax0a\n");
+ printf("j. int10 ax0f\t");
+ printf("k. int10 ax1b\t");
+ printf("l. int10 ax13\n");
+ printf("q. Quit\t");
+ printf("r. switch to 50 lines\n");
+ c=getche();
+
+ switch(c)
+ {case 'a':
+ int10ax0003(regs);
+ break;
+ case 'b':
+ int10ax02(regs);
+ break;
+ case 'c':
+ int10ax03(regs);
+ break;
+ case 'd':
+ int10ax0501(regs);
+ break;
+ case 'e':
+ int10ax0602(regs);
+ break;
+ case 'f':
+ int10ax0702(regs);
+ break;
+ case 'g':
+ int10ax08(regs);
+ break;
+ case 'h':
+ int10ax09(regs);
+ break;
+ case 'i':
+ int10ax0a(regs);
+ break;
+ case 'j':
+ int10ax0f(regs);
+ break;
+ case 'k':
+ int10ax1b(regs);
+ break;
+ case 'l':
+ int10ax13(regs);
+ break;
+ case 'q':
+ break;
+ case 'r':
+ switch_50(regs);
+ break;
+ default:
+ printf("No such function!\n");
+ }
+
+ if(c=='q')return 1;
+ while(kbhit()==0);
+ c=getch();
+
+ return 0;
+}
+
+void read_bios_area(BIOSAREA *biosarea)
+{
+ biosarea->initial=peekb(0x40,0x10);
+ biosarea->current=peekb(0x40,0x49);
+ biosarea->nbcols=peek(0x40,0x4a);
+ biosarea->regen=peek(0x40,0x4c);
+ biosarea->start=peek(0x40,0x4e);
+ biosarea->curpos[0]=peek(0x40,0x50);
+ biosarea->curpos[1]=peek(0x40,0x52);
+ biosarea->curpos[2]=peek(0x40,0x54);
+ biosarea->curpos[3]=peek(0x40,0x56);
+ biosarea->curpos[4]=peek(0x40,0x58);
+ biosarea->curpos[5]=peek(0x40,0x5a);
+ biosarea->curpos[6]=peek(0x40,0x5c);
+ biosarea->curpos[7]=peek(0x40,0x5e);
+ biosarea->curtyp=peek(0x40,0x60);
+ biosarea->curpage=peekb(0x40,0x62);
+ biosarea->crtc=peek(0x40,0x63);
+ biosarea->msr=peekb(0x40,0x65);
+ biosarea->cgapal=peekb(0x40,0x66);
+ biosarea->nbrows=peekb(0x40,0x84);
+ biosarea->cheight=peek(0x40,0x85);
+ biosarea->ctl=peekb(0x40,0x87);
+ biosarea->switches=peekb(0x40,0x88);
+ biosarea->modeset=peekb(0x40,0x89);
+ biosarea->dcc=peekb(0x40,0x8a);
+ biosarea->vsseg=peek(0x40,0xa8);
+ biosarea->vsoffset=peek(0x40,0xaa);
+}
+
+void show_bios_area(BIOSAREA *biosarea)
+{
+ printf("--- BIOS area --------------------\n");
+ printf("initial : %02x\t",biosarea->initial);
+ printf("current : %02x\t",biosarea->current);
+ printf("nbcols : %04x\t",biosarea->nbcols);
+ printf("regen : %04x\t",biosarea->regen);
+ printf("start : %04x\n",biosarea->start);
+ printf("curpos : %04x %04x %04x %04x %04x %04x %04x %04x\n",
+ biosarea->curpos[0], biosarea->curpos[1], biosarea->curpos[2], biosarea->curpos[3],
+ biosarea->curpos[4], biosarea->curpos[5], biosarea->curpos[6], biosarea->curpos[7]);
+ printf("curtyp : %04x\t",biosarea->curtyp);
+ printf("curpage : %02x\t",biosarea->curpage);
+ printf("crtc : %04x\t",biosarea->crtc);
+ printf("msr : %04x\n",biosarea->msr);
+ printf("cgapal : %04x\t",biosarea->cgapal);
+ printf("nbrows-1: %02x\t",biosarea->nbrows);
+ printf("cheight : %04x\t",biosarea->cheight);
+ printf("ctl : %02x\n",biosarea->ctl);
+ printf("switches: %02x\t",biosarea->switches);
+ printf("modeset : %02x\t",biosarea->modeset);
+ printf("dcc : %02x\t",biosarea->dcc);
+ printf("vs : %04x:%04x\n",biosarea->vsseg,biosarea->vsoffset);
+}
+
+void show_regs(struct REGPACK *regs)
+{
+ printf("--- Registers --------------------\n");
+ printf("ax %04x\t",regs->r_ax);
+ printf("bx %04x\t",regs->r_bx);
+ printf("cx %04x\t",regs->r_cx);
+ printf("dx %04x\t",regs->r_dx);
+ printf("ds %04x\t",regs->r_ds);
+ printf("si %04x\t",regs->r_si);
+ printf("es %04x\t",regs->r_es);
+ printf("di %04x\n",regs->r_di);
+}
+
+void reset_videomode()
+{
+ struct REGPACK regs;
+
+ regs.r_ax=0x0003;
+ intr(0x10,&regs);
+}
+
+void main()
+{
+
+ BIOSAREA biosarea;
+ struct REGPACK regs;
+
+ directvideo=0;
+
+ while(1)
+ {
+ read_bios_area(&biosarea);
+
+ reset_videomode();
+ show_bios_area(&biosarea);
+ show_regs(&regs);
+
+ if(exec_function(&regs)!=0)break;
+ }
+}