14d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 24d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 34d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* VBE 2.0 Linear Framebuffer Profiler 44d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* By Kendall Bennett and Brian Hook 54d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 64d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Filename: LFBPROF.C 74d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Language: ANSI C 84d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Environment: Watcom C/C++ 10.0a with DOS4GW 94d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Simple program to profile the speed of screen clearing 114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* and full screen BitBlt operations using a VESA VBE 2.0 124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* linear framebuffer from 32 bit protected mode. 134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* For simplicity, this program only supports 256 color 154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* SuperVGA video modes that support a linear framebuffer. 164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2002/02/18: Jeroen Janssen <japj at xs4all dot nl> 194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* - fixed unsigned short for mode list (-1 != 0xffff otherwise) 204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* - fixed LfbMapRealPointer macro mask problem (some modes were skipped) 214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <stdio.h> 254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <stdlib.h> 264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <string.h> 274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <conio.h> 284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include <dos.h> 294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#include "lfbprof.h" 304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/*---------------------------- Global Variables ---------------------------*/ 324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint VESABuf_len = 1024; /* Length of VESABuf */ 344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint VESABuf_sel = 0; /* Selector for VESABuf */ 354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint VESABuf_rseg; /* Real mode segment of VESABuf */ 364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaunsigned short modeList[50]; /* List of available VBE modes */ 374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimafloat clearsPerSec; /* Number of clears per second */ 384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimafloat clearsMbPerSec; /* Memory transfer for clears */ 394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimafloat bitBltsPerSec; /* Number of BitBlt's per second */ 404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimafloat bitBltsMbPerSec; /* Memory transfer for bitblt's */ 414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint xres,yres; /* Video mode resolution */ 424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint bytesperline; /* Bytes per scanline for mode */ 434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong imageSize; /* Length of the video image */ 444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimachar *LFBPtr; /* Pointer to linear framebuffer */ 454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/*------------------------- DPMI interface routines -----------------------*/ 474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid DPMI_allocRealSeg(int size,int *sel,int *r_seg) 494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: DPMI_allocRealSeg 524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: size - Size of memory block to allocate 534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* sel - Place to return protected mode selector 544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* r_seg - Place to return real mode segment 554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Allocates a block of real mode memory using DPMI services. 574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* This routine returns both a protected mode selector and 584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* real mode segment for accessing the memory block. 594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima union REGS r; 634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.ax = 0x100; /* DPMI allocate DOS memory */ 654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.bx = (size + 0xF) >> 4; /* number of paragraphs */ 664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int386(0x31, &r, &r); 674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (r.w.cflag) 684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima FatalError("DPMI_allocRealSeg failed!"); 694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *sel = r.w.dx; /* Protected mode selector */ 704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *r_seg = r.w.ax; /* Real mode segment */ 714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid DPMI_freeRealSeg(unsigned sel) 744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: DPMI_allocRealSeg 774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: sel - Protected mode selector of block to free 784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Frees a block of real mode memory. 804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima union REGS r; 844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.ax = 0x101; /* DPMI free DOS memory */ 864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.dx = sel; /* DX := selector from 0x100 */ 874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int386(0x31, &r, &r); 884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimatypedef struct { 914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long edi; 924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long esi; 934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long ebp; 944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long reserved; 954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long ebx; 964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long edx; 974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long ecx; 984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long eax; 994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima short flags; 1004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima short es,ds,fs,gs,ip,cs,sp,ss; 1014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } _RMREGS; 1024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define IN(reg) rmregs.e##reg = in->x.reg 1044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima#define OUT(reg) out->x.reg = rmregs.e##reg 1054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint DPMI_int86(int intno, RMREGS *in, RMREGS *out) 1074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 1084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 1094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: DPMI_int86 1104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: intno - Interrupt number to issue 1114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* in - Pointer to structure for input registers 1124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* out - Pointer to structure for output registers 1134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Returns: Value returned by interrupt in AX 1144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 1154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Issues a real mode interrupt using DPMI services. 1164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 1174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 1184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 1194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima _RMREGS rmregs; 1204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima union REGS r; 1214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima struct SREGS sr; 1224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima memset(&rmregs, 0, sizeof(rmregs)); 1244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); 1254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima segread(&sr); 1274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.ax = 0x300; /* DPMI issue real interrupt */ 1284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.h.bl = intno; 1294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.h.bh = 0; 1304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.cx = 0; 1314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sr.es = sr.ds; 1324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.x.edi = (unsigned)&rmregs; 1334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int386x(0x31, &r, &r, &sr); /* Issue the interrupt */ 1344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); 1364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima out->x.cflag = rmregs.flags & 0x1; 1374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return out->x.ax; 1384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 1394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint DPMI_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs) 1414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 1424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 1434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: DPMI_int86 1444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: intno - Interrupt number to issue 1454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* in - Pointer to structure for input registers 1464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* out - Pointer to structure for output registers 1474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* sregs - Values to load into segment registers 1484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Returns: Value returned by interrupt in AX 1494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 1504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Issues a real mode interrupt using DPMI services. 1514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 1524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 1534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 1544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima _RMREGS rmregs; 1554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima union REGS r; 1564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima struct SREGS sr; 1574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima memset(&rmregs, 0, sizeof(rmregs)); 1594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di); 1604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima rmregs.es = sregs->es; 1614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima rmregs.ds = sregs->ds; 1624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima segread(&sr); 1644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.ax = 0x300; /* DPMI issue real interrupt */ 1654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.h.bl = intno; 1664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.h.bh = 0; 1674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.cx = 0; 1684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sr.es = sr.ds; 1694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.x.edi = (unsigned)&rmregs; 1704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int386x(0x31, &r, &r, &sr); /* Issue the interrupt */ 1714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di); 1734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sregs->es = rmregs.es; 1744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sregs->cs = rmregs.cs; 1754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sregs->ss = rmregs.ss; 1764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sregs->ds = rmregs.ds; 1774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima out->x.cflag = rmregs.flags & 0x1; 1784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return out->x.ax; 1794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 1804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint DPMI_allocSelector(void) 1824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 1834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 1844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: DPMI_allocSelector 1854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Returns: Newly allocated protected mode selector 1864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 1874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Allocates a new protected mode selector using DPMI 1884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* services. This selector has a base address and limit of 0. 1894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 1904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 1914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 1924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int sel; 1934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima union REGS r; 1944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 1954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.ax = 0; /* DPMI allocate selector */ 1964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.cx = 1; /* Allocate a single selector */ 1974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int386(0x31, &r, &r); 1984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (r.x.cflag) 1994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima FatalError("DPMI_allocSelector() failed!"); 2004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sel = r.w.ax; 2014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.ax = 9; /* DPMI set access rights */ 2034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.bx = sel; 2044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.cx = 0x8092; /* 32 bit page granular */ 2054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int386(0x31, &r, &r); 2064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return sel; 2074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimalong DPMI_mapPhysicalToLinear(long physAddr,long limit) 2104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 2114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: DPMI_mapPhysicalToLinear 2134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: physAddr - Physical memory address to map 2144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* limit - Length-1 of physical memory region to map 2154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Returns: Starting linear address for mapped memory 2164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Maps a section of physical memory into the linear address 2184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* space of a process using DPMI calls. Note that this linear 2194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* address cannot be used directly, but must be used as the 2204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* base address for a selector. 2214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 2234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 2244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima union REGS r; 2254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.ax = 0x800; /* DPMI map physical to linear */ 2274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.bx = physAddr >> 16; 2284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.cx = physAddr & 0xFFFF; 2294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.si = limit >> 16; 2304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.di = limit & 0xFFFF; 2314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int386(0x31, &r, &r); 2324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (r.x.cflag) 2334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima FatalError("DPMI_mapPhysicalToLinear() failed!"); 2344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return ((long)r.w.bx << 16) + r.w.cx; 2354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid DPMI_setSelectorBase(int sel,long linAddr) 2384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 2394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: DPMI_setSelectorBase 2414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: sel - Selector to change base address for 2424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* linAddr - Linear address used for new base address 2434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Sets the base address for the specified selector. 2454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 2474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 2484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima union REGS r; 2494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.ax = 7; /* DPMI set selector base address */ 2514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.bx = sel; 2524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.cx = linAddr >> 16; 2534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.dx = linAddr & 0xFFFF; 2544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int386(0x31, &r, &r); 2554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (r.x.cflag) 2564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima FatalError("DPMI_setSelectorBase() failed!"); 2574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid DPMI_setSelectorLimit(int sel,long limit) 2604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 2614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: DPMI_setSelectorLimit 2634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: sel - Selector to change limit for 2644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* limit - Limit-1 for the selector 2654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Sets the memory limit for the specified selector. 2674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 2694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 2704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima union REGS r; 2714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.ax = 8; /* DPMI set selector limit */ 2734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.bx = sel; 2744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.cx = limit >> 16; 2754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima r.w.dx = limit & 0xFFFF; 2764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int386(0x31, &r, &r); 2774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (r.x.cflag) 2784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima FatalError("DPMI_setSelectorLimit() failed!"); 2794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/*-------------------------- VBE Interface routines -----------------------*/ 2824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid FatalError(char *msg) 2844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 2854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima fprintf(stderr,"%s\n", msg); 2864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima exit(1); 2874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimastatic void ExitVBEBuf(void) 2904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 2914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima DPMI_freeRealSeg(VESABuf_sel); 2924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 2934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 2944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid VBE_initRMBuf(void) 2954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 2964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 2974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: VBE_initRMBuf 2984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Initialises the VBE transfer buffer in real mode memory. 2994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* This routine is called by the VESAVBE module every time 3004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* it needs to use the transfer buffer, so we simply allocate 3014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* it once and then return. 3024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 3044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 3054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (!VESABuf_sel) { 3064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima DPMI_allocRealSeg(VESABuf_len, &VESABuf_sel, &VESABuf_rseg); 3074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima atexit(ExitVBEBuf); 3084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 3094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid VBE_callESDI(RMREGS *regs, void *buffer, int size) 3124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 3134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: VBE_callESDI 3154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: regs - Registers to load when calling VBE 3164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* buffer - Buffer to copy VBE info block to 3174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* size - Size of buffer to fill 3184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Calls the VESA VBE and passes in a buffer for the VBE to 3204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* store information in, which is then copied into the users 3214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* buffer space. This works in protected mode as the buffer 3224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* passed to the VESA VBE is allocated in conventional 3234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* memory, and is then copied into the users memory block. 3244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 3264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 3274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima RMSREGS sregs; 3284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima VBE_initRMBuf(); 3304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima sregs.es = VESABuf_rseg; 3314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima regs->x.di = 0; 3324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima _fmemcpy(MK_FP(VESABuf_sel,0),buffer,size); 3334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima DPMI_int86x(0x10, regs, regs, &sregs); 3344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima _fmemcpy(buffer,MK_FP(VESABuf_sel,0),size); 3354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint VBE_detect(void) 3384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 3394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: VBE_detect 3414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: vgaInfo - Place to store the VGA information block 3424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Returns: VBE version number, or 0 if not detected. 3434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Detects if a VESA VBE is out there and functioning 3454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* correctly. If we detect a VBE interface we return the 3464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* VGAInfoBlock returned by the VBE and the VBE version number. 3474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 3494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 3504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima RMREGS regs; 3514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima unsigned short *p1,*p2; 3524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima VBE_vgaInfo vgaInfo; 3534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima /* Put 'VBE2' into the signature area so that the VBE 2.0 BIOS knows 3554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * that we have passed a 512 byte extended block to it, and wish 3564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * the extended information to be filled in. 3574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima */ 3584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima strncpy(vgaInfo.VESASignature,"VBE2",4); 3594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima /* Get the SuperVGA Information block */ 3614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima regs.x.ax = 0x4F00; 3624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima VBE_callESDI(®s, &vgaInfo, sizeof(VBE_vgaInfo)); 3634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (regs.x.ax != 0x004F) 3644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return 0; 3654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0) 3664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return 0; 3674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima /* Now that we have detected a VBE interface, copy the list of available 3694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * video modes into our local buffer. We *must* copy this mode list, 3704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * since the VBE will build the mode list in the VBE_vgaInfo buffer 3714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * that we have passed, so the next call to the VBE will trash the 3724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima * list of modes. 3734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima */ 3744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("videomodeptr %x\n",vgaInfo.VideoModePtr); 3754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima p1 = LfbMapRealPointer(vgaInfo.VideoModePtr); 3764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima p2 = modeList; 3774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while (*p1 != -1) 3784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima { 3794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("found mode %x\n",*p1); 3804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *p2++ = *p1++; 3814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 3824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima *p2 = -1; 3834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return vgaInfo.VESAVersion; 3844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 3854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 3864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimaint VBE_getModeInfo(int mode,VBE_modeInfo *modeInfo) 3874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 3884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: VBE_getModeInfo 3904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: mode - VBE mode to get information for 3914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* modeInfo - Place to store VBE mode information 3924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Returns: 1 on success, 0 if function failed. 3934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Obtains information about a specific video mode from the 3954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* VBE. You should use this function to find the video mode 3964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* you wish to set, as the new VBE 2.0 mode numbers may be 3974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* completely arbitrary. 3984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 3994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 4004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 4014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima RMREGS regs; 4024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima regs.x.ax = 0x4F01; /* Get mode information */ 4044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima regs.x.cx = mode; 4054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima VBE_callESDI(®s, modeInfo, sizeof(VBE_modeInfo)); 4064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (regs.x.ax != 0x004F) 4074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return 0; 4084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if ((modeInfo->ModeAttributes & vbeMdAvailable) == 0) 4094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return 0; 4104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return 1; 4114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid VBE_setVideoMode(int mode) 4144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 4154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: VBE_setVideoMode 4174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: mode - VBE mode number to initialise 4184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 4204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 4214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima RMREGS regs; 4224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima regs.x.ax = 0x4F02; 4234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima regs.x.bx = mode; 4244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima DPMI_int86(0x10,®s,®s); 4254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/*-------------------- Application specific routines ----------------------*/ 4284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid *GetPtrToLFB(long physAddr) 4304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 4314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: GetPtrToLFB 4334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: physAddr - Physical memory address of linear framebuffer 4344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Returns: Far pointer to the linear framebuffer memory 4354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 4374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 4384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int sel; 4394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long linAddr,limit = (4096 * 1024) - 1; 4404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// sel = DPMI_allocSelector(); 4424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima linAddr = DPMI_mapPhysicalToLinear(physAddr,limit); 4434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// DPMI_setSelectorBase(sel,linAddr); 4444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// DPMI_setSelectorLimit(sel,limit); 4454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima// return MK_FP(sel,0); 4464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return (void*)linAddr; 4474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid AvailableModes(void) 4504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 4514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: AvailableModes 4534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Display a list of available LFB mode resolutions. 4554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 4574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 4584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima unsigned short *p; 4594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima VBE_modeInfo modeInfo; 4604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("Usage: LFBPROF <xres> <yres>\n\n"); 4624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("Available 256 color video modes:\n"); 4634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima for (p = modeList; *p != -1; p++) { 4644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (VBE_getModeInfo(*p, &modeInfo)) { 4654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima /* Filter out only 8 bit linear framebuffer modes */ 4664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) 4674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima continue; 4684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (modeInfo.MemoryModel != vbeMemPK 4694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima || modeInfo.BitsPerPixel != 8 4704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima || modeInfo.NumberOfPlanes != 1) 4714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima continue; 4724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf(" %4d x %4d %d bits per pixel\n", 4734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima modeInfo.XResolution, modeInfo.YResolution, 4744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima modeInfo.BitsPerPixel); 4754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 4774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima exit(1); 4784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 4794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid InitGraphics(int x,int y) 4814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 4824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: InitGraphics 4844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Parameters: x,y - Requested video mode resolution 4854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Initialise the specified video mode. We search through 4874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* the list of available video modes for one that matches 4884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* the resolution and color depth are are looking for. 4894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 4904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 4914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 4924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima unsigned short *p; 4934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima VBE_modeInfo modeInfo; 4944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("InitGraphics\n"); 4954d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 4964d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima for (p = modeList; *p != -1; p++) { 4974d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (VBE_getModeInfo(*p, &modeInfo)) { 4984d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima /* Filter out only 8 bit linear framebuffer modes */ 4994d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if ((modeInfo.ModeAttributes & vbeMdLinear) == 0) 5004d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima continue; 5014d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (modeInfo.MemoryModel != vbeMemPK 5024d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima || modeInfo.BitsPerPixel != 8 5034d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima || modeInfo.NumberOfPlanes != 1) 5044d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima continue; 5054d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (modeInfo.XResolution != x || modeInfo.YResolution != y) 5064d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima continue; 5074d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima xres = x; 5084d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima yres = y; 5094d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima bytesperline = modeInfo.BytesPerScanLine; 5104d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima imageSize = bytesperline * yres; 5114d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima VBE_setVideoMode(*p | vbeUseLFB); 5124d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima LFBPtr = GetPtrToLFB(modeInfo.PhysBasePtr); 5134d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima return; 5144d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 5154d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 5164d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("Valid video mode not found\n"); 5174d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima exit(1); 5184d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 5194d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 5204d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid EndGraphics(void) 5214d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 5224d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 5234d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: EndGraphics 5244d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 5254d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Restores text mode. 5264d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 5274d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 5284d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 5294d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima RMREGS regs; 5304d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("EndGraphics\n"); 5314d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima regs.x.ax = 0x3; 5324d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima DPMI_int86(0x10, ®s, ®s); 5334d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 5344d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 5354d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid ProfileMode(void) 5364d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima/**************************************************************************** 5374d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 5384d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Function: ProfileMode 5394d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 5404d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* Description: Profiles framebuffer performance for simple screen clearing 5414d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* and for copying from system memory to video memory (BitBlt). 5424d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* This routine thrashes the CPU cache by cycling through 5434d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* enough system memory buffers to invalidate the entire 5444d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* CPU external cache before re-using the first memory buffer 5454d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* again. 5464d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima* 5474d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima****************************************************************************/ 5484d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 5494d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima int i,numClears,numBlts,maxImages; 5504d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima long startTicks,endTicks; 5514d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima void *image[10],*dst; 5524d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("ProfileMode\n"); 5534d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 5544d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima /* Profile screen clearing operation */ 5554d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima startTicks = LfbGetTicks(); 5564d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima numClears = 0; 5574d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while ((LfbGetTicks() - startTicks) < 182) 5584d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima LfbMemset(LFBPtr,numClears++,imageSize); 5594d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima endTicks = LfbGetTicks(); 5604d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima clearsPerSec = numClears / ((endTicks - startTicks) * 0.054925); 5614d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima clearsMbPerSec = (clearsPerSec * imageSize) / 1048576.0; 5624d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 5634d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima /* Profile system memory to video memory copies */ 5644d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima maxImages = ((512 * 1024U) / imageSize) + 2; 5654d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima for (i = 0; i < maxImages; i++) { 5664d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima image[i] = malloc(imageSize); 5674d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (image[i] == NULL) 5684d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima FatalError("Not enough memory to profile BitBlt!"); 5694d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima memset(image[i],i+1,imageSize); 5704d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima } 5714d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima startTicks = LfbGetTicks(); 5724d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima numBlts = 0; 5734d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima while ((LfbGetTicks() - startTicks) < 182) 5744d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima LfbMemcpy(LFBPtr,image[numBlts++ % maxImages],imageSize); 5754d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima endTicks = LfbGetTicks(); 5764d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima bitBltsPerSec = numBlts / ((endTicks - startTicks) * 0.054925); 5774d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima bitBltsMbPerSec = (bitBltsPerSec * imageSize) / 1048576.0; 5784d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 5794d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 5804d07f569799aaae0d7fccf8e76386d450664987fJun Nakajimavoid main(int argc, char *argv[]) 5814d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima{ 5824d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (VBE_detect() < 0x200) 5834d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima FatalError("This program requires VBE 2.0; Please install UniVBE 5.1."); 5844d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima if (argc != 3) 5854d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima AvailableModes(); /* Display available modes */ 5864d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 5874d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima InitGraphics(atoi(argv[1]),atoi(argv[2])); /* Start graphics */ 5884d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima ProfileMode(); /* Profile the video mode */ 5894d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima EndGraphics(); /* Restore text mode */ 5904d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima 5914d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("Profiling results for %dx%d 8 bits per pixel.\n",xres,yres); 5924d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("%3.2f clears/s, %2.2f Mb/s\n", clearsPerSec, clearsMbPerSec); 5934d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima printf("%3.2f bitBlt/s, %2.2f Mb/s\n", bitBltsPerSec, bitBltsMbPerSec); 5944d07f569799aaae0d7fccf8e76386d450664987fJun Nakajima} 595