Annotation of qemu/roms/vgabios/tests/lfbprof/lfbprof.c, revision 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.