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(&regs, &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(&regs, 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,&regs,&regs);
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, &regs, &regs);
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