Annotation of qemu/roms/vgabios/tests/lfbprof/lfbprof.c, revision 1.1.1.1

1.1       root        1: /****************************************************************************
                      2: *
                      3: *                   VBE 2.0 Linear Framebuffer Profiler
                      4: *                    By Kendall Bennett and Brian Hook
                      5: *
                      6: * Filename:     LFBPROF.C
                      7: * Language:     ANSI C
                      8: * Environment:  Watcom C/C++ 10.0a with DOS4GW
                      9: *
                     10: * Description:  Simple program to profile the speed of screen clearing
                     11: *               and full screen BitBlt operations using a VESA VBE 2.0
                     12: *               linear framebuffer from 32 bit protected mode.
                     13: *
                     14: *               For simplicity, this program only supports 256 color
                     15: *               SuperVGA video modes that support a linear framebuffer.
                     16: *
                     17: *
                     18: * 2002/02/18: Jeroen Janssen <japj at xs4all dot nl>
                     19: *               - fixed unsigned short for mode list (-1 != 0xffff otherwise)
                     20: *               - fixed LfbMapRealPointer macro mask problem (some modes were skipped)
                     21: *
                     22: ****************************************************************************/
                     23: 
                     24: #include <stdio.h>
                     25: #include <stdlib.h>
                     26: #include <string.h>
                     27: #include <conio.h>
                     28: #include <dos.h>
                     29: #include "lfbprof.h"
                     30: 
                     31: /*---------------------------- Global Variables ---------------------------*/
                     32: 
                     33: int     VESABuf_len = 1024;         /* Length of VESABuf                */
                     34: int     VESABuf_sel = 0;            /* Selector for VESABuf             */
                     35: int     VESABuf_rseg;               /* Real mode segment of VESABuf     */
                     36: unsigned short   modeList[50];      /* List of available VBE modes      */
                     37: float   clearsPerSec;               /* Number of clears per second      */
                     38: float   clearsMbPerSec;             /* Memory transfer for clears       */
                     39: float   bitBltsPerSec;              /* Number of BitBlt's per second    */
                     40: float   bitBltsMbPerSec;            /* Memory transfer for bitblt's     */
                     41: int     xres,yres;                  /* Video mode resolution            */
                     42: int     bytesperline;               /* Bytes per scanline for mode      */
                     43: long    imageSize;                  /* Length of the video image        */
                     44: char    *LFBPtr;                       /* Pointer to linear framebuffer    */
                     45: 
                     46: /*------------------------- DPMI interface routines -----------------------*/
                     47: 
                     48: void DPMI_allocRealSeg(int size,int *sel,int *r_seg)
                     49: /****************************************************************************
                     50: *
                     51: * Function:     DPMI_allocRealSeg
                     52: * Parameters:   size    - Size of memory block to allocate
                     53: *               sel     - Place to return protected mode selector
                     54: *               r_seg   - Place to return real mode segment
                     55: *
                     56: * Description:  Allocates a block of real mode memory using DPMI services.
                     57: *               This routine returns both a protected mode selector and
                     58: *               real mode segment for accessing the memory block.
                     59: *
                     60: ****************************************************************************/
                     61: {
                     62:     union REGS      r;
                     63: 
                     64:     r.w.ax = 0x100;                 /* DPMI allocate DOS memory         */
                     65:     r.w.bx = (size + 0xF) >> 4;     /* number of paragraphs             */
                     66:     int386(0x31, &r, &r);
                     67:     if (r.w.cflag)
                     68:         FatalError("DPMI_allocRealSeg failed!");
                     69:     *sel = r.w.dx;                  /* Protected mode selector          */
                     70:     *r_seg = r.w.ax;                /* Real mode segment                */
                     71: }
                     72: 
                     73: void DPMI_freeRealSeg(unsigned sel)
                     74: /****************************************************************************
                     75: *
                     76: * Function:     DPMI_allocRealSeg
                     77: * Parameters:   sel - Protected mode selector of block to free
                     78: *
                     79: * Description:  Frees a block of real mode memory.
                     80: *
                     81: ****************************************************************************/
                     82: {
                     83:     union REGS  r;
                     84: 
                     85:     r.w.ax = 0x101;                 /* DPMI free DOS memory             */
                     86:     r.w.dx = sel;                   /* DX := selector from 0x100        */
                     87:     int386(0x31, &r, &r);
                     88: }
                     89: 
                     90: typedef struct {
                     91:     long    edi;
                     92:     long    esi;
                     93:     long    ebp;
                     94:     long    reserved;
                     95:     long    ebx;
                     96:     long    edx;
                     97:     long    ecx;
                     98:     long    eax;
                     99:     short   flags;
                    100:     short   es,ds,fs,gs,ip,cs,sp,ss;
                    101:     } _RMREGS;
                    102: 
                    103: #define IN(reg)     rmregs.e##reg = in->x.reg
                    104: #define OUT(reg)    out->x.reg = rmregs.e##reg
                    105: 
                    106: int DPMI_int86(int intno, RMREGS *in, RMREGS *out)
                    107: /****************************************************************************
                    108: *
                    109: * Function:     DPMI_int86
                    110: * Parameters:   intno   - Interrupt number to issue
                    111: *               in      - Pointer to structure for input registers
                    112: *               out     - Pointer to structure for output registers
                    113: * Returns:      Value returned by interrupt in AX
                    114: *
                    115: * Description:  Issues a real mode interrupt using DPMI services.
                    116: *
                    117: ****************************************************************************/
                    118: {
                    119:     _RMREGS         rmregs;
                    120:     union REGS      r;
                    121:     struct SREGS    sr;
                    122: 
                    123:     memset(&rmregs, 0, sizeof(rmregs));
                    124:     IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
                    125: 
                    126:     segread(&sr);
                    127:     r.w.ax = 0x300;                 /* DPMI issue real interrupt        */
                    128:     r.h.bl = intno;
                    129:     r.h.bh = 0;
                    130:     r.w.cx = 0;
                    131:     sr.es = sr.ds;
                    132:     r.x.edi = (unsigned)&rmregs;
                    133:     int386x(0x31, &r, &r, &sr);     /* Issue the interrupt              */
                    134: 
                    135:     OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
                    136:     out->x.cflag = rmregs.flags & 0x1;
                    137:     return out->x.ax;
                    138: }
                    139: 
                    140: int DPMI_int86x(int intno, RMREGS *in, RMREGS *out, RMSREGS *sregs)
                    141: /****************************************************************************
                    142: *
                    143: * Function:     DPMI_int86
                    144: * Parameters:   intno   - Interrupt number to issue
                    145: *               in      - Pointer to structure for input registers
                    146: *               out     - Pointer to structure for output registers
                    147: *               sregs   - Values to load into segment registers
                    148: * Returns:      Value returned by interrupt in AX
                    149: *
                    150: * Description:  Issues a real mode interrupt using DPMI services.
                    151: *
                    152: ****************************************************************************/
                    153: {
                    154:     _RMREGS         rmregs;
                    155:     union REGS      r;
                    156:     struct SREGS    sr;
                    157: 
                    158:     memset(&rmregs, 0, sizeof(rmregs));
                    159:     IN(ax); IN(bx); IN(cx); IN(dx); IN(si); IN(di);
                    160:     rmregs.es = sregs->es;
                    161:     rmregs.ds = sregs->ds;
                    162: 
                    163:     segread(&sr);
                    164:     r.w.ax = 0x300;                 /* DPMI issue real interrupt        */
                    165:     r.h.bl = intno;
                    166:     r.h.bh = 0;
                    167:     r.w.cx = 0;
                    168:     sr.es = sr.ds;
                    169:     r.x.edi = (unsigned)&rmregs;
                    170:     int386x(0x31, &r, &r, &sr);     /* Issue the interrupt */
                    171: 
                    172:     OUT(ax); OUT(bx); OUT(cx); OUT(dx); OUT(si); OUT(di);
                    173:     sregs->es = rmregs.es;
                    174:     sregs->cs = rmregs.cs;
                    175:     sregs->ss = rmregs.ss;
                    176:     sregs->ds = rmregs.ds;
                    177:     out->x.cflag = rmregs.flags & 0x1;
                    178:     return out->x.ax;
                    179: }
                    180: 
                    181: int DPMI_allocSelector(void)
                    182: /****************************************************************************
                    183: *
                    184: * Function:     DPMI_allocSelector
                    185: * Returns:      Newly allocated protected mode selector
                    186: *
                    187: * Description:  Allocates a new protected mode selector using DPMI
                    188: *               services. This selector has a base address and limit of 0.
                    189: *
                    190: ****************************************************************************/
                    191: {
                    192:     int         sel;
                    193:     union REGS  r;
                    194: 
                    195:     r.w.ax = 0;                     /* DPMI allocate selector           */
                    196:     r.w.cx = 1;                     /* Allocate a single selector       */
                    197:     int386(0x31, &r, &r);
                    198:     if (r.x.cflag)
                    199:         FatalError("DPMI_allocSelector() failed!");
                    200:     sel = r.w.ax;
                    201: 
                    202:     r.w.ax = 9;                     /* DPMI set access rights           */
                    203:     r.w.bx = sel;
                    204:     r.w.cx = 0x8092;                /* 32 bit page granular             */
                    205:     int386(0x31, &r, &r);
                    206:     return sel;
                    207: }
                    208: 
                    209: long DPMI_mapPhysicalToLinear(long physAddr,long limit)
                    210: /****************************************************************************
                    211: *
                    212: * Function:     DPMI_mapPhysicalToLinear
                    213: * Parameters:   physAddr    - Physical memory address to map
                    214: *               limit       - Length-1 of physical memory region to map
                    215: * Returns:      Starting linear address for mapped memory
                    216: *
                    217: * Description:  Maps a section of physical memory into the linear address
                    218: *               space of a process using DPMI calls. Note that this linear
                    219: *               address cannot be used directly, but must be used as the
                    220: *               base address for a selector.
                    221: *
                    222: ****************************************************************************/
                    223: {
                    224:     union REGS  r;
                    225: 
                    226:     r.w.ax = 0x800;                 /* DPMI map physical to linear      */
                    227:     r.w.bx = physAddr >> 16;
                    228:     r.w.cx = physAddr & 0xFFFF;
                    229:     r.w.si = limit >> 16;
                    230:     r.w.di = limit & 0xFFFF;
                    231:     int386(0x31, &r, &r);
                    232:     if (r.x.cflag)
                    233:         FatalError("DPMI_mapPhysicalToLinear() failed!");
                    234:     return ((long)r.w.bx << 16) + r.w.cx;
                    235: }
                    236: 
                    237: void DPMI_setSelectorBase(int sel,long linAddr)
                    238: /****************************************************************************
                    239: *
                    240: * Function:     DPMI_setSelectorBase
                    241: * Parameters:   sel     - Selector to change base address for
                    242: *               linAddr - Linear address used for new base address
                    243: *
                    244: * Description:  Sets the base address for the specified selector.
                    245: *
                    246: ****************************************************************************/
                    247: {
                    248:     union REGS  r;
                    249: 
                    250:     r.w.ax = 7;                     /* DPMI set selector base address   */
                    251:     r.w.bx = sel;
                    252:     r.w.cx = linAddr >> 16;
                    253:     r.w.dx = linAddr & 0xFFFF;
                    254:     int386(0x31, &r, &r);
                    255:     if (r.x.cflag)
                    256:         FatalError("DPMI_setSelectorBase() failed!");
                    257: }
                    258: 
                    259: void DPMI_setSelectorLimit(int sel,long limit)
                    260: /****************************************************************************
                    261: *
                    262: * Function:     DPMI_setSelectorLimit
                    263: * Parameters:   sel     - Selector to change limit for
                    264: *               limit   - Limit-1 for the selector
                    265: *
                    266: * Description:  Sets the memory limit for the specified selector.
                    267: *
                    268: ****************************************************************************/
                    269: {
                    270:     union REGS  r;
                    271: 
                    272:     r.w.ax = 8;                     /* DPMI set selector limit          */
                    273:     r.w.bx = sel;
                    274:     r.w.cx = limit >> 16;
                    275:     r.w.dx = limit & 0xFFFF;
                    276:     int386(0x31, &r, &r);
                    277:     if (r.x.cflag)
                    278:         FatalError("DPMI_setSelectorLimit() failed!");
                    279: }
                    280: 
                    281: /*-------------------------- VBE Interface routines -----------------------*/
                    282: 
                    283: void FatalError(char *msg)
                    284: {
                    285:     fprintf(stderr,"%s\n", msg);
                    286:     exit(1);
                    287: }
                    288: 
                    289: static void ExitVBEBuf(void)
                    290: {
                    291:     DPMI_freeRealSeg(VESABuf_sel);
                    292: }
                    293: 
                    294: void VBE_initRMBuf(void)
                    295: /****************************************************************************
                    296: *
                    297: * Function:     VBE_initRMBuf
                    298: * Description:  Initialises the VBE transfer buffer in real mode memory.
                    299: *               This routine is called by the VESAVBE module every time
                    300: *               it needs to use the transfer buffer, so we simply allocate
                    301: *               it once and then return.
                    302: *
                    303: ****************************************************************************/
                    304: {
                    305:     if (!VESABuf_sel) {
                    306:         DPMI_allocRealSeg(VESABuf_len, &VESABuf_sel, &VESABuf_rseg);
                    307:         atexit(ExitVBEBuf);
                    308:         }
                    309: }
                    310: 
                    311: void VBE_callESDI(RMREGS *regs, void *buffer, int size)
                    312: /****************************************************************************
                    313: *
                    314: * Function:     VBE_callESDI
                    315: * Parameters:   regs    - Registers to load when calling VBE
                    316: *               buffer  - Buffer to copy VBE info block to
                    317: *               size    - Size of buffer to fill
                    318: *
                    319: * Description:  Calls the VESA VBE and passes in a buffer for the VBE to
                    320: *               store information in, which is then copied into the users
                    321: *               buffer space. This works in protected mode as the buffer
                    322: *               passed to the VESA VBE is allocated in conventional
                    323: *               memory, and is then copied into the users memory block.
                    324: *
                    325: ****************************************************************************/
                    326: {
                    327:     RMSREGS sregs;
                    328: 
                    329:     VBE_initRMBuf();
                    330:     sregs.es = VESABuf_rseg;
                    331:     regs->x.di = 0;
                    332:     _fmemcpy(MK_FP(VESABuf_sel,0),buffer,size);
                    333:     DPMI_int86x(0x10, regs, regs, &sregs);
                    334:     _fmemcpy(buffer,MK_FP(VESABuf_sel,0),size);
                    335: }
                    336: 
                    337: int VBE_detect(void)
                    338: /****************************************************************************
                    339: *
                    340: * Function:     VBE_detect
                    341: * Parameters:   vgaInfo - Place to store the VGA information block
                    342: * Returns:      VBE version number, or 0 if not detected.
                    343: *
                    344: * Description:  Detects if a VESA VBE is out there and functioning
                    345: *               correctly. If we detect a VBE interface we return the
                    346: *               VGAInfoBlock returned by the VBE and the VBE version number.
                    347: *
                    348: ****************************************************************************/
                    349: {
                    350:     RMREGS      regs;
                    351:     unsigned    short    *p1,*p2;
                    352:     VBE_vgaInfo vgaInfo;
                    353: 
                    354:     /* Put 'VBE2' into the signature area so that the VBE 2.0 BIOS knows
                    355:      * that we have passed a 512 byte extended block to it, and wish
                    356:      * the extended information to be filled in.
                    357:      */
                    358:     strncpy(vgaInfo.VESASignature,"VBE2",4);
                    359: 
                    360:     /* Get the SuperVGA Information block */
                    361:     regs.x.ax = 0x4F00;
                    362:     VBE_callESDI(&regs, &vgaInfo, sizeof(VBE_vgaInfo));
                    363:     if (regs.x.ax != 0x004F)
                    364:         return 0;
                    365:     if (strncmp(vgaInfo.VESASignature,"VESA",4) != 0)
                    366:         return 0;
                    367: 
                    368:     /* Now that we have detected a VBE interface, copy the list of available
                    369:      * video modes into our local buffer. We *must* copy this mode list,
                    370:      * since the VBE will build the mode list in the VBE_vgaInfo buffer
                    371:      * that we have passed, so the next call to the VBE will trash the
                    372:      * list of modes.
                    373:      */
                    374:     printf("videomodeptr %x\n",vgaInfo.VideoModePtr);
                    375:     p1 = LfbMapRealPointer(vgaInfo.VideoModePtr);
                    376:     p2 = modeList;
                    377:     while (*p1 != -1)
                    378:     {
                    379:         printf("found mode %x\n",*p1);
                    380:         *p2++ = *p1++;
                    381:     }
                    382:     *p2 = -1;
                    383:     return vgaInfo.VESAVersion;
                    384: }
                    385: 
                    386: int VBE_getModeInfo(int mode,VBE_modeInfo *modeInfo)
                    387: /****************************************************************************
                    388: *
                    389: * Function:     VBE_getModeInfo
                    390: * Parameters:   mode        - VBE mode to get information for
                    391: *               modeInfo    - Place to store VBE mode information
                    392: * Returns:      1 on success, 0 if function failed.
                    393: *
                    394: * Description:  Obtains information about a specific video mode from the
                    395: *               VBE. You should use this function to find the video mode
                    396: *               you wish to set, as the new VBE 2.0 mode numbers may be
                    397: *               completely arbitrary.
                    398: *
                    399: ****************************************************************************/
                    400: {
                    401:     RMREGS  regs;
                    402: 
                    403:     regs.x.ax = 0x4F01;             /* Get mode information         */
                    404:     regs.x.cx = mode;
                    405:     VBE_callESDI(&regs, modeInfo, sizeof(VBE_modeInfo));
                    406:     if (regs.x.ax != 0x004F)
                    407:         return 0;
                    408:     if ((modeInfo->ModeAttributes & vbeMdAvailable) == 0)
                    409:         return 0;
                    410:     return 1;
                    411: }
                    412: 
                    413: void VBE_setVideoMode(int mode)
                    414: /****************************************************************************
                    415: *
                    416: * Function:     VBE_setVideoMode
                    417: * Parameters:   mode    - VBE mode number to initialise
                    418: *
                    419: ****************************************************************************/
                    420: {
                    421:     RMREGS  regs;
                    422:     regs.x.ax = 0x4F02;
                    423:     regs.x.bx = mode;
                    424:     DPMI_int86(0x10,&regs,&regs);
                    425: }
                    426: 
                    427: /*-------------------- Application specific routines ----------------------*/
                    428: 
                    429: void *GetPtrToLFB(long physAddr)
                    430: /****************************************************************************
                    431: *
                    432: * Function:     GetPtrToLFB
                    433: * Parameters:   physAddr    - Physical memory address of linear framebuffer
                    434: * Returns:      Far pointer to the linear framebuffer memory
                    435: *
                    436: ****************************************************************************/
                    437: {
                    438:     int     sel;
                    439:     long    linAddr,limit = (4096 * 1024) - 1;
                    440: 
                    441: //     sel = DPMI_allocSelector();
                    442:        linAddr = DPMI_mapPhysicalToLinear(physAddr,limit);
                    443: //     DPMI_setSelectorBase(sel,linAddr);
                    444: //     DPMI_setSelectorLimit(sel,limit);
                    445: //     return MK_FP(sel,0);
                    446:        return (void*)linAddr;
                    447: }
                    448: 
                    449: void AvailableModes(void)
                    450: /****************************************************************************
                    451: *
                    452: * Function:     AvailableModes
                    453: *
                    454: * Description:  Display a list of available LFB mode resolutions.
                    455: *
                    456: ****************************************************************************/
                    457: {
                    458:     unsigned short           *p;
                    459:     VBE_modeInfo    modeInfo;
                    460: 
                    461:     printf("Usage: LFBPROF <xres> <yres>\n\n");
                    462:     printf("Available 256 color video modes:\n");
                    463:     for (p = modeList; *p != -1; p++) {
                    464:         if (VBE_getModeInfo(*p, &modeInfo)) {
                    465:             /* Filter out only 8 bit linear framebuffer modes */
                    466:             if ((modeInfo.ModeAttributes & vbeMdLinear) == 0)
                    467:                 continue;
                    468:             if (modeInfo.MemoryModel != vbeMemPK
                    469:                 || modeInfo.BitsPerPixel != 8
                    470:                 || modeInfo.NumberOfPlanes != 1)
                    471:                 continue;
                    472:             printf("    %4d x %4d %d bits per pixel\n",
                    473:                 modeInfo.XResolution, modeInfo.YResolution,
                    474:                 modeInfo.BitsPerPixel);
                    475:             }
                    476:         }
                    477:     exit(1);
                    478: }
                    479: 
                    480: void InitGraphics(int x,int y)
                    481: /****************************************************************************
                    482: *
                    483: * Function:     InitGraphics
                    484: * Parameters:   x,y - Requested video mode resolution
                    485: *
                    486: * Description:  Initialise the specified video mode. We search through
                    487: *               the list of available video modes for one that matches
                    488: *               the resolution and color depth are are looking for.
                    489: *
                    490: ****************************************************************************/
                    491: {
                    492:     unsigned short           *p;
                    493:     VBE_modeInfo    modeInfo;
                    494:     printf("InitGraphics\n");
                    495: 
                    496:     for (p = modeList; *p != -1; p++) {
                    497:         if (VBE_getModeInfo(*p, &modeInfo)) {
                    498:             /* Filter out only 8 bit linear framebuffer modes */
                    499:             if ((modeInfo.ModeAttributes & vbeMdLinear) == 0)
                    500:                 continue;
                    501:             if (modeInfo.MemoryModel != vbeMemPK
                    502:                 || modeInfo.BitsPerPixel != 8
                    503:                 || modeInfo.NumberOfPlanes != 1)
                    504:                 continue;
                    505:             if (modeInfo.XResolution != x || modeInfo.YResolution != y)
                    506:                 continue;
                    507:             xres = x;
                    508:             yres = y;
                    509:             bytesperline = modeInfo.BytesPerScanLine;
                    510:             imageSize = bytesperline * yres;
                    511:             VBE_setVideoMode(*p | vbeUseLFB);
                    512:             LFBPtr = GetPtrToLFB(modeInfo.PhysBasePtr);
                    513:             return;
                    514:             }
                    515:         }
                    516:     printf("Valid video mode not found\n");
                    517:     exit(1);
                    518: }
                    519: 
                    520: void EndGraphics(void)
                    521: /****************************************************************************
                    522: *
                    523: * Function:     EndGraphics
                    524: *
                    525: * Description:  Restores text mode.
                    526: *
                    527: ****************************************************************************/
                    528: {
                    529:     RMREGS  regs;
                    530:     printf("EndGraphics\n");
                    531:     regs.x.ax = 0x3;
                    532:     DPMI_int86(0x10, &regs, &regs);
                    533: }
                    534: 
                    535: void ProfileMode(void)
                    536: /****************************************************************************
                    537: *
                    538: * Function:     ProfileMode
                    539: *
                    540: * Description:  Profiles framebuffer performance for simple screen clearing
                    541: *               and for copying from system memory to video memory (BitBlt).
                    542: *               This routine thrashes the CPU cache by cycling through
                    543: *               enough system memory buffers to invalidate the entire
                    544: *               CPU external cache before re-using the first memory buffer
                    545: *               again.
                    546: *
                    547: ****************************************************************************/
                    548: {
                    549:     int     i,numClears,numBlts,maxImages;
                    550:     long    startTicks,endTicks;
                    551:     void    *image[10],*dst;
                    552:     printf("ProfileMode\n");
                    553: 
                    554:     /* Profile screen clearing operation */
                    555:     startTicks = LfbGetTicks();
                    556:     numClears = 0;
                    557:     while ((LfbGetTicks() - startTicks) < 182)
                    558:                LfbMemset(LFBPtr,numClears++,imageSize);
                    559:        endTicks = LfbGetTicks();
                    560:        clearsPerSec = numClears / ((endTicks - startTicks) * 0.054925);
                    561:        clearsMbPerSec = (clearsPerSec * imageSize) / 1048576.0;
                    562: 
                    563:        /* Profile system memory to video memory copies */
                    564:        maxImages = ((512 * 1024U) / imageSize) + 2;
                    565:        for (i = 0; i < maxImages; i++) {
                    566:                image[i] = malloc(imageSize);
                    567:                if (image[i] == NULL)
                    568:                        FatalError("Not enough memory to profile BitBlt!");
                    569:                memset(image[i],i+1,imageSize);
                    570:                }
                    571:        startTicks = LfbGetTicks();
                    572:        numBlts = 0;
                    573:        while ((LfbGetTicks() - startTicks) < 182)
                    574:                LfbMemcpy(LFBPtr,image[numBlts++ % maxImages],imageSize);
                    575:     endTicks = LfbGetTicks();
                    576:     bitBltsPerSec = numBlts / ((endTicks - startTicks) * 0.054925);
                    577:     bitBltsMbPerSec = (bitBltsPerSec * imageSize) / 1048576.0;
                    578: }
                    579: 
                    580: void main(int argc, char *argv[])
                    581: {
                    582:     if (VBE_detect() < 0x200)
                    583:         FatalError("This program requires VBE 2.0; Please install UniVBE 5.1.");
                    584:     if (argc != 3)
                    585:         AvailableModes();       /* Display available modes              */
                    586: 
                    587:     InitGraphics(atoi(argv[1]),atoi(argv[2]));  /* Start graphics       */
                    588:     ProfileMode();              /* Profile the video mode               */
                    589:     EndGraphics();              /* Restore text mode                    */
                    590: 
                    591:     printf("Profiling results for %dx%d 8 bits per pixel.\n",xres,yres);
                    592:     printf("%3.2f clears/s, %2.2f Mb/s\n", clearsPerSec, clearsMbPerSec);
                    593:     printf("%3.2f bitBlt/s, %2.2f Mb/s\n", bitBltsPerSec, bitBltsMbPerSec);
                    594: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.