home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 409_01 / paranoid.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-10-22  |  23.4 KB  |  852 lines

  1. /****************************************************************************
  2. *
  3. *                  Paranoid - VESA VBE stress test program
  4. *
  5. *                   Copyright (C) 1993 SciTech Software.
  6. *                           All rights reserved.
  7. *
  8. * Filename:     $RCSfile: paranoid.c $
  9. * Version:      $Revision: 1.1 $
  10. *
  11. * Language:     ANSI C
  12. * Environment:  IBM PC (MS DOS)
  13. *
  14. * Description:    Paranoid test program. This program is designed to stress
  15. *                test a VESA VBE implementation, and check it for full
  16. *                conformance with the VBE standard that it claims to conform
  17. *                to (supports only standards >= 1.2 standard).
  18. *
  19. *                This program uses the SuperVGA test kit to perform all
  20. *                graphics output when testing the appropriate video modes
  21. *                for conformance (and thus only works on 386 and above
  22. *                machines).
  23. *
  24. *               MUST be compiled in the large memory model.
  25. *
  26. *                This program is freely distributable in the executable
  27. *                form. The source code is under the same restrictions as
  28. *                the SuperVGA kit it belong in.
  29. *
  30. * $Id: paranoid.c 1.1 1993/10/22 08:59:44 kjb release $
  31. *
  32. ****************************************************************************/
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <stdarg.h>
  37. #include <dos.h>
  38. #include <string.h>
  39. #include <conio.h>
  40. #include "svga.h"
  41. #include "vesavbe.h"
  42.  
  43. /*----------------------------- Implementation ----------------------------*/
  44.  
  45. typedef struct {
  46.     int        ax,bx,cx,dx,si,di,es,ds;
  47.     } regs;
  48.  
  49. FILE    *logfile = NULL;
  50. int        CP_x,CP_y,VBEVersion,maxbanks,VBEFunc = 0,numErrors = 0;
  51. bool    failed = false;
  52. short    modelist[100];
  53. char    *signon =    "Paranoid v1.0 - VESA VBE stress test program\n"
  54.                     "                Copyright (C) 1993 SciTech Software\n\n";
  55.  
  56. /* Table of memory model names */
  57.  
  58. char *memModelNames[] = {
  59.     "Text Mode",
  60.     "CGA Graphics",
  61.     "Hercules Graphics",
  62.     "4-plane planar",
  63.     "Packed Pixel",
  64.     "Non-chain 4, 256 color",
  65.     "Direct Color RGB",
  66.     "Direct Color YUV",
  67.     };
  68.  
  69. int queryCpu(void);
  70.  
  71. void out(const char *fmt, ... )
  72. {
  73.     va_list argptr;
  74.  
  75.     va_start(argptr, fmt);
  76.     vfprintf(stdout, fmt, argptr);
  77.     vfprintf(logfile, fmt, argptr);
  78.     va_end(argptr);
  79. }
  80.  
  81. void log(const char *fmt, ... )
  82. {
  83.     va_list argptr;
  84.  
  85.     va_start(argptr, fmt);
  86.     vfprintf(logfile, fmt, argptr);
  87.     va_end(argptr);
  88. }
  89.  
  90. /* Routine to convert the input value to its binary representation */
  91.  
  92. char *binary(unsigned value)
  93. {
  94.     static char    buf[11] = "00000000b";
  95.     unsigned    mask = 0x80;
  96.     int         i;
  97.  
  98.     for (i = 0; i < 8; i++) {
  99.         buf[i] = value & mask ? '1' : '0';
  100.         mask >>= 1;
  101.         }
  102.  
  103.     return buf;
  104. }
  105.  
  106. void startCheck(int _VBEFunc)
  107. /****************************************************************************
  108. *
  109. * Function:        startCheck
  110. * Parameters:    _VBEFunc    - VBE Function number we are currently checking
  111. *
  112. * Description:    Begins the logging of errors for this function.
  113. *
  114. ****************************************************************************/
  115. {
  116.     log("Checking function %02Xh ... ", VBEFunc = _VBEFunc);
  117.     numErrors = 0;
  118. }
  119.  
  120. void endCheck(void)
  121. /****************************************************************************
  122. *
  123. * Function:        endCheck
  124. *
  125. * Description:    Ends the checking of a particular VBE function.
  126. *
  127. ****************************************************************************/
  128. {
  129.     if (numErrors == 0)
  130.         log("Passed.\n");
  131.     else
  132.         log("\n%d errors logged for function %02Xh.\n", numErrors, VBEFunc);
  133. }
  134.  
  135. void fail(const char *msg, ... )
  136. /****************************************************************************
  137. *
  138. * Function:        fail
  139. * Parameters:    msg    - Message describing error
  140. *
  141. * Description:    Logs a failure message to the log file outlining the problem
  142. *                that was encountered.
  143. *
  144. ****************************************************************************/
  145. {
  146.     va_list argptr;
  147.  
  148.     if (numErrors == 0)
  149.         log("\n\n");
  150.     numErrors++;
  151.     failed = true;
  152.  
  153.     va_start(argptr, msg);
  154.     fprintf(logfile,"    ");
  155.     vfprintf(logfile, msg, argptr);
  156.     va_end(argptr);
  157. }
  158.  
  159. bool callVBE(regs *r)
  160. /****************************************************************************
  161. *
  162. * Function:        callVBE
  163. * Parameters:    r    - Structure holding register values to load
  164. * Returns:        True if successful, false if function failed
  165. *
  166. * Description:    Loads the appropriate registers with the values from
  167. *                the register structure and executes and int 10h to call
  168. *                the VBE. It checks to ensure that register values are
  169. *                preserved across all calls correctly and ensures that the
  170. *               function executed successfully.
  171. *
  172. ****************************************************************************/
  173. {
  174.     union REGS        rg;
  175.     struct SREGS    sr;
  176.     int                mask;
  177.  
  178.     rg.x.ax = r->ax;    rg.x.bx = r->bx;
  179.     rg.x.cx = r->cx;    rg.x.dx = r->dx;
  180.     rg.x.si = r->si;    rg.x.di = r->di;
  181.     sr.es = r->es;        sr.ds = r->ds;
  182.     int86x(0x10,&rg,&rg,&sr);
  183.  
  184.     /* Check to ensure all register are preserved across call. We define
  185.      * the mask to be a one for a register that must be preserved, and
  186.      * a zero for a register that can change. AX is always the result
  187.      * code, so this leave 7 bits to represent each register.
  188.      */
  189.  
  190.     switch (r->ax & 0xFF) {
  191.         case 0x00:    mask = 0x7F;    break;
  192.         case 0x01:    mask = 0x7F;    break;
  193.         case 0x02:    mask = 0x7F;    break;
  194.         case 0x03:    mask = 0x7E;    break;
  195.         case 0x04:    if ((r->dx & 0xFF) == 0)
  196.                         mask = 0x7E;        /* State size call        */
  197.                     else mask = 0x7F;        /* Other calls            */
  198.                     break;
  199.         case 0x05:    if ((r->bx >> 8) == 0)
  200.                         mask = 0x7F;        /* Set window call        */
  201.                     else mask = 0x7B;        /* Get window call        */
  202.                     break;
  203.         case 0x06:    mask = 0x78;    break;
  204.         case 0x07:    if (r->bx == 0)
  205.                         mask = 0x7F;        /* Set display start    */
  206.                     else mask = 0x78;        /* Get display start    */
  207.                     break;
  208.         case 0x08:    mask = 0x7E;    break;
  209.         default:    mask = 0;
  210.         }
  211.  
  212.     if ((mask & 0x01) && (r->bx != rg.x.bx))
  213.         fail("Function %02Xh failed to preserve BX\n", r->ax & 0xFF);
  214.     if ((mask & 0x02) && (r->cx != rg.x.cx))
  215.         fail("Function %02Xh failed to preserve CX\n", r->ax & 0xFF);
  216.     if ((mask & 0x04) && (r->dx != rg.x.dx))
  217.         fail("Function %02Xh failed to preserve DX\n", r->ax & 0xFF);
  218.     if (r->si != rg.x.si)
  219.         fail("Function %02Xh failed to preserve SI\n", r->ax & 0xFF);
  220.     if (r->di != rg.x.di)
  221.         fail("Function %02Xh failed to preserve DI\n", r->ax & 0xFF);
  222.     if (r->ds != sr.ds)
  223.         fail("Function %02Xh failed to preserve DS\n", r->ax & 0xFF);
  224.     if (r->es != sr.es)
  225.         fail("Function %02Xh failed to preserve ES\n", r->ax & 0xFF);
  226.  
  227.     r->ax = rg.x.ax;    r->bx = rg.x.bx;
  228.     r->cx = rg.x.cx;    r->dx = rg.x.dx;
  229.     r->si = rg.x.si;    r->di = rg.x.di;
  230.     r->es = sr.es;        r->ds = sr.ds;
  231.  
  232.     return (r->ax == 0x004F);
  233. }
  234.  
  235. void checkFunction00h(void)
  236. /****************************************************************************
  237. *
  238. * Function:        checkFunction00h
  239. *
  240. * Description:    Calls function 00h to determine if a VESA VBE is present,
  241. *                and check it for conformance.
  242. *
  243. ****************************************************************************/
  244. {
  245.     VgaInfoBlock    vgaInfo;
  246.     regs            r;
  247.     short            i,*modes;
  248.  
  249.     r.es = SEG(&vgaInfo);
  250.     r.di = OFF(&vgaInfo);
  251.     r.ax = 0x4F00;
  252.     if (callVBE(&r)) {
  253.         if (vgaInfo.VESAVersion < 0x102) {
  254.             out("Detected a VBE %d.%d interface. This program only checks interfaces that\n",
  255.                 vgaInfo.VESAVersion >> 0x8,vgaInfo.VESAVersion & 0xF);
  256.             out("conform to the VBE 1.2 or later specifications.\n");
  257.             exit(1);
  258.             }
  259.  
  260.         printf("VBE %d.%d Interface detected - checking for conformance\n\n",
  261.             vgaInfo.VESAVersion >> 0x8,vgaInfo.VESAVersion & 0xF);
  262.  
  263.         log("VBE Version:  %d.%d\n",vgaInfo.VESAVersion >> 0x8,
  264.             vgaInfo.VESAVersion & 0xF);
  265.         log("OEMString:    %s\n",vgaInfo.OEMStringPtr);
  266.         log("Capabilities: %s (%04Xh)\n",binary(vgaInfo.Capabilities),
  267.             vgaInfo.Capabilities);
  268.         log("Total Memory: %d Kb\n",memory = vgaInfo.TotalMemory * 64);
  269.         log("\nAvailable Modes:\n\n");
  270.  
  271.         modes = vgaInfo.VideoModePtr;
  272.         i = 0;
  273.         while (*modes != -1) {
  274.             modelist[i] = *modes;
  275.             log("%04Xh ",*modes++);
  276.             if ((++i % 10) == 0)
  277.                 log("\n");
  278.             }
  279.         modelist[i] = -1;
  280.         log("\n\n");
  281.         startCheck(0x00);
  282.         if (vgaInfo.TotalMemory == 0)
  283.             fail("TotalMemory field is zero!");
  284.         endCheck();
  285.  
  286.         VBEVersion = vgaInfo.VESAVersion;
  287.         maxbanks = vgaInfo.TotalMemory;
  288.         }
  289.     else {
  290.         out("VESA VBE interface not detected.\n");
  291.         exit(1);
  292.         }
  293. }
  294.  
  295. void checkFunction01h(void)
  296. /****************************************************************************
  297. *
  298. * Function:        checkFunction01h
  299. *
  300. * Description:    Calls function 01h to obtain information about all
  301. *                available video modes, checking the values returned in the
  302. *                structure.
  303. *
  304. ****************************************************************************/
  305. {
  306.     ModeInfoBlock    modeInfo;
  307.     regs            r;
  308.     short            *modes;
  309.  
  310.     startCheck(0x01);
  311.     for (modes = modelist; *modes != -1; modes++) {
  312.         r.es = SEG(&modeInfo);
  313.         r.di = OFF(&modeInfo);
  314.         r.ax = 0x4F01;
  315.         r.cx = *modes;
  316.         if (callVBE(&r)) {
  317.             if ((modeInfo.ModeAttributes & 0x1) == 0)
  318.                 continue;
  319.             if (modeInfo.WinGranularity > 64 || modeInfo.WinGranularity == 0)
  320.                 fail("Bad window granularity factor: %d\n",modeInfo.WinGranularity);
  321.             if (modeInfo.WinSize > 64 || modeInfo.WinSize == 0)
  322.                 fail("Bad window size: %d\n",modeInfo.WinSize);
  323.             if ((modeInfo.WinAAttributes & 0x1) && modeInfo.WinASegment == 0)
  324.                 fail("Bad window A segment value: %04Xh\n", modeInfo.WinASegment);
  325.             if ((modeInfo.WinBAttributes & 0x1) && modeInfo.WinBSegment == 0)
  326.                 fail("Bad window B segment value: %04Xh\n", modeInfo.WinBSegment);
  327.             if (modeInfo.WinFuncPtr == NULL)
  328.                 fail("NULL window function pointer\n");
  329.             }
  330.         else
  331.             fail("Video mode %03h not available yet listed in mode list\n", *modes);
  332.         }
  333.     endCheck();
  334. }
  335.  
  336. void checkFunction02h(void)
  337. /****************************************************************************
  338. *
  339. * Function:        checkFunction02h
  340. *
  341. * Description:    Calls function 02h to set each of the available video modes,
  342. *                draw a pattern and display status information about each
  343. *                video mode.
  344. *
  345. ****************************************************************************/
  346. {
  347.     ModeInfoBlock    modeInfo;
  348.     regs            r;
  349.     short            *modes;
  350.  
  351.     startCheck(0x02);
  352.     for (modes = modelist; *modes != -1; modes++) {
  353.         r.es = SEG(&modeInfo);
  354.         r.di = OFF(&modeInfo);
  355.         r.ax = 0x4F01;
  356.         r.cx = *modes;
  357.         if (callVBE(&r)) {
  358.             if ((modeInfo.ModeAttributes & 0x1) == 0)
  359.                 continue;
  360.             r.ax = 0x4F02;
  361.             r.bx = *modes;
  362.             if (callVBE(&r)) {
  363.                 r.ax = 0x4F03;
  364.                 callVBE(&r);
  365.                 if (r.bx != *modes)
  366.                     fail("Function 03h did not return the same video mode number\n");
  367.                 }
  368.             }
  369.         }
  370.     r.ax = 0x3;
  371.     callVBE(&r);
  372.     endCheck();
  373. }
  374.  
  375. void checkFunction04h(void)
  376. /****************************************************************************
  377. *
  378. * Function:        checkFunction04h
  379. *
  380. * Description:    Calls function 04h to save and restore the SuperVGA
  381. *                video state.
  382. *
  383. ****************************************************************************/
  384. {
  385.     regs            r;
  386.     int                size;
  387.     void            *savebuf;
  388.  
  389.     startCheck(0x04);
  390.     r.ax = 0x4F04;
  391.     r.dx = 0x0000;
  392.     r.cx = 0x000F;
  393.     if (!callVBE(&r))
  394.         fail("Function 04h subfunction 00h failed.\n");
  395.     size = r.bx * 64;
  396.     if (size < 960)
  397.         fail("Invalid buffer size.\n");
  398.     if ((savebuf = malloc(size)) == NULL)
  399.         exit(1);
  400.  
  401.     r.ax = 0x4F04;
  402.     r.dx = 0x0001;
  403.     r.cx = 0x000F;
  404.     r.es = SEG(savebuf);
  405.     r.bx = OFF(savebuf);
  406.     if (!callVBE(&r))
  407.         fail("Function 04h subfunction 01h failed.\n");
  408.  
  409.     r.ax = 0x4F04;
  410.     r.dx = 0x0002;
  411.     r.cx = 0x000F;
  412.     r.es = SEG(savebuf);
  413.     r.bx = OFF(savebuf);
  414.     if (!callVBE(&r))
  415.         fail("Function 04h subfunction 02h failed.\n");
  416.  
  417.     r.ax = 0x3;
  418.     callVBE(&r);
  419.  
  420.     free(savebuf);
  421.     endCheck();
  422. }
  423.  
  424. void checkFunction05h(void)
  425. /****************************************************************************
  426. *
  427. * Function:        checkFunction05h
  428. *
  429. * Description:    Calls function 05h to change the video memory banks from
  430. *                the first bank all the way down to the last bank, and
  431. *                to read the bank values back again.
  432. *
  433. ****************************************************************************/
  434. {
  435.     ModeInfoBlock    modeInfo;
  436.     regs            r;
  437.     int                bank;
  438.     bool            twobanks;
  439.  
  440.     startCheck(0x05);
  441.  
  442.     r.es = SEG(&modeInfo);
  443.     r.di = OFF(&modeInfo);
  444.     r.ax = 0x4F01;
  445.     r.cx = 0x102;
  446.     callVBE(&r);
  447.     twobanks = modeInfo.WinBAttributes & 0x1;
  448.  
  449.     r.ax = 0x4F02;
  450.     r.bx = 0x102;
  451.     if (!callVBE(&r))
  452.         fail("Could not set 800x600x16 color mode\n");
  453.  
  454.     for (bank = 0; bank < maxbanks; bank++) {
  455.         r.ax = 0x4F05;
  456.         r.bx = 0x0000;
  457.         r.dx = bank;
  458.         if (!callVBE(&r))
  459.             fail("Bank switch routine failed.\n");
  460.         r.ax = 0x4F05;
  461.         r.bx = 0x0100;
  462.         if (!callVBE(&r))
  463.             fail("Bank switch routine failed.\n");
  464.         if (r.dx != bank)
  465.             fail("Differing bank 1 value returned\n");
  466.  
  467.         if (twobanks) {
  468.             r.ax = 0x4F05;
  469.             r.bx = 0x0001;
  470.             r.dx = bank;
  471.             if (!callVBE(&r))
  472.                 fail("Bank switch routine failed.\n");
  473.             r.ax = 0x4F05;
  474.             r.bx = 0x0101;
  475.             if (!callVBE(&r))
  476.                 fail("Bank switch routine failed.\n");
  477.             if (r.dx != bank)
  478.                 fail("Differing bank 2 value returned\n");
  479.             }
  480.         }
  481.  
  482.     r.ax = 0x3;
  483.     callVBE(&r);
  484.     endCheck();
  485. }
  486.  
  487. void moire(void)
  488. /****************************************************************************
  489. *
  490. * Function:     moire
  491. *
  492. * Description:  Draws a simple Moire pattern on the display screen using
  493. *               lines.
  494. *
  495. ****************************************************************************/
  496. {
  497.     int     i,value;
  498.  
  499.     clear();
  500.     if (maxcolor <= 255) {
  501.         for (i = 0; i < maxx; i += 10) {
  502.             line(maxx/2,maxy/2,i,0,i % maxcolor);
  503.             line(maxx/2,maxy/2,i,maxy,(i+1) % maxcolor);
  504.             }
  505.         for (i = 0; i < maxy; i += 10) {
  506.             line(maxx/2,maxy/2,0,i,(i+2) % maxcolor);
  507.             line(maxx/2,maxy/2,maxx,i,(i+3) % maxcolor);
  508.             }
  509.         }
  510.     else {
  511.         for (i = 0; i < maxx; i++) {
  512.             line(maxx/2,maxy/2,i,0,rgbColor(((i*255L)/maxx),0,0));
  513.             line(maxx/2,maxy/2,i,maxy,rgbColor(0,((i*255L)/maxx),0));
  514.             }
  515.         for (i = 0; i < maxy; i++) {
  516.             value = (i*255L)/maxy;
  517.             line(maxx/2,maxy/2,0,i,rgbColor(value,0,255 - value));
  518.             line(maxx/2,maxy/2,maxx,i,rgbColor(0,255 - value,value));
  519.             }
  520.         }
  521.     line(0,0,maxx,0,defcolor);
  522.     line(0,0,0,maxy,defcolor);
  523.     line(maxx,0,maxx,maxy,defcolor);
  524.     line(0,maxy,maxx,maxy,defcolor);
  525. }
  526.  
  527. void gprintf(const char *fmt, ... )
  528. /****************************************************************************
  529. *
  530. * Function:        gprintf
  531. * Parameters:    fmt    - Format string to display
  532. *
  533. * Description:    Displays a string in the current display mode.
  534. *
  535. ****************************************************************************/
  536. {
  537.     va_list argptr;
  538.     char    buf[255];
  539.  
  540.     va_start(argptr, fmt);
  541.     vsprintf(buf,fmt,argptr);
  542.     writeText(CP_x,CP_y,buf,defcolor);
  543.     CP_y += 16;
  544.     va_end(argptr);
  545. }
  546.  
  547. void dumpModeInfo(int mode)
  548. /****************************************************************************
  549. *
  550. * Function:     dumpModeInfo
  551. * Parameters:   mode    - Mode number to dump info for
  552. *
  553. * Description:  Dumps the information about the specific mode to the
  554. *               display.
  555. *
  556. ****************************************************************************/
  557. {
  558.     ModeInfoBlock   modeInfo;
  559.     union REGS      regs;
  560.     struct SREGS    sregs;
  561.  
  562.     sregs.es = FP_SEG(&modeInfo);
  563.     regs.x.di = FP_OFF(&modeInfo);
  564.     regs.x.ax = 0x4F01;
  565.     regs.x.cx = mode;
  566.     int86x(0x10,®s,®s,&sregs);
  567.     if ((modeInfo.ModeAttributes & 0x1) == 0)
  568.         return;
  569.     CP_x = CP_y = 5;
  570.     gprintf("Mode number:     %04Xh",mode);
  571.     gprintf("ModeAttributes:  %s (%04Xh)",binary(modeInfo.ModeAttributes),
  572.         modeInfo.ModeAttributes);
  573.     gprintf("WinAAttributes:  %s (%04Xh)",binary(modeInfo.WinAAttributes),
  574.         modeInfo.WinAAttributes);
  575.     gprintf("WinBAttributes:  %s (%04Xh)",binary(modeInfo.WinBAttributes),
  576.         modeInfo.WinBAttributes);
  577.     gprintf("WinGranulatiry:  %d",modeInfo.WinGranularity);
  578.     gprintf("WinSize:         %d",modeInfo.WinSize);
  579.     gprintf("WinASegment:     %04Xh",modeInfo.WinASegment);
  580.     gprintf("WinBSegment:     %04Xh",modeInfo.WinBSegment);
  581.     gprintf("WinFuncPtr:      %04X:%04X",FP_SEG(modeInfo.WinFuncPtr),
  582.         FP_OFF(modeInfo.WinFuncPtr));
  583.     if (modeInfo.ModeAttributes & 0x10) {
  584.         gprintf("Resolution:      %d x %d x %d bits per pixel (%02Xh BytesPerLine)",
  585.             modeInfo.XResolution,modeInfo.YResolution,modeInfo.BitsPerPixel,
  586.             modeInfo.BytesPerScanLine);
  587.         gprintf("MemoryModel:     %s",memModelNames[modeInfo.MemoryModel]);
  588.         gprintf("");
  589.         gprintf("CharSize:        %d x %d",
  590.             modeInfo.XCharSize,modeInfo.YCharSize);
  591.         if (modeInfo.MemoryModel >= 6) {
  592.             gprintf("Red Component:   %d bits, position %d",
  593.                 modeInfo.RedMaskSize,modeInfo.RedFieldPosition);
  594.             gprintf("Green Component: %d bits, position %d",
  595.                 modeInfo.GreenMaskSize,modeInfo.GreenFieldPosition);
  596.             gprintf("Blue Component:  %d bits, position %d",
  597.                 modeInfo.BlueMaskSize,modeInfo.BlueFieldPosition);
  598.             gprintf("Rsvd Component:  %d bits, position %d",
  599.                 modeInfo.RsvdMaskSize,modeInfo.RsvdFieldPosition);
  600.             gprintf("DirectColorInfo: %s (%d)",
  601.                 binary(modeInfo.DirectColorModeInfo),
  602.                 modeInfo.DirectColorModeInfo);
  603.             }
  604.         }
  605.     else {
  606.         gprintf("Resolution:      %d x %d Text Mode (%d x %d charsize)",
  607.             modeInfo.XResolution,modeInfo.YResolution,
  608.             modeInfo.XCharSize,modeInfo.YCharSize);
  609.         }
  610.     gprintf("NumberOfPages:   %d",modeInfo.NumberOfImagePages+1);
  611. }
  612.  
  613. void setDisplayStart(int x,int y)
  614. /****************************************************************************
  615. *
  616. * Function:     setDisplayStart
  617. * Parameters:   x,y - Position of the first pixel to display
  618. *
  619. * Description:  Sets the new starting display position to implement
  620. *               hardware scrolling.
  621. *
  622. ****************************************************************************/
  623. {
  624.     regs    r;
  625.  
  626.     if (extendedflipping) {
  627.         r.ax = 0x4F07;
  628.         r.bx = 0x0000;
  629.         r.cx = x;
  630.         r.dx = y;
  631.         callVBE(&r);
  632.         r.ax = 0x4F07;
  633.         r.bx = 0x0001;
  634.         callVBE(&r);
  635.         if (abs(r.cx-x) > 8 || r.dx != y)
  636.             fail("Invalid values returnd by Function 07h subfunction 01h\n");
  637.         }
  638. }
  639.  
  640. void setScanlineLength(int width,int *bytesperline,int *maxx,int *maxy)
  641. /****************************************************************************
  642. *
  643. * Function:        setScanlineLength
  644. * Parameters:    width            - New scanline width to set in pixels
  645. *                bytesperline    - New bytes per line value
  646. *                maxx            - New maximum X coordinate
  647. *                maxy            - New maximum Y coordinate
  648. *
  649. * Description:    Attempts to set the logical scanline length using the
  650. *                VBE function 06h to set up a logical display buffer.
  651. *
  652. ****************************************************************************/
  653. {
  654.     regs    r,r2;
  655.  
  656.     r.ax = 0x4F06;
  657.     r.bx = 0x0000;
  658.     r.cx = width;
  659.     if (!callVBE(&r))
  660.         fail("Function 06h subfunction 00h failed.\n");
  661.  
  662.     r2.ax = 0x4F06;
  663.     r2.bx = 0x0001;
  664.     if (!callVBE(&r2))
  665.         fail("Function 06h subfunction 01h failed.\n");
  666.  
  667.     if (r.bx != r2.bx)
  668.         fail("Differing bytes per scanline values (%d - %d).\n",
  669.             r.bx, r2.bx);
  670.     if (r.cx != r2.cx)
  671.         fail("Differing pixels per scanline values (%d - %d).\n",
  672.             r.cx, r2.cx);
  673.     if (r.dx != r2.dx)
  674.         fail("Differing maximum scanline values (%d - %d).\n",
  675.             r.dx, r2.dx);
  676.  
  677.     *bytesperline = r.bx;
  678.     *maxx = r.cx-1;
  679.     *maxy = r.dx-1;
  680. }
  681.  
  682. void scrollTest(void)
  683. /****************************************************************************
  684. *
  685. * Function:        scrollTest
  686. *
  687. * Description:    Checks the CRT display start routines to scroll the display
  688. *                page up and then back down again.
  689. *
  690. ****************************************************************************/
  691. {
  692.     int        i,max;
  693.  
  694.     if (extendedflipping) {
  695.         if (maxcolor == 15)
  696.             max = (memory*256L) / bytesperline - maxy;
  697.         else
  698.             max = (memory*1024L) / bytesperline - maxy;
  699.         if (max > maxy) max = maxy+1;
  700.         if (max < 0)    return;
  701.  
  702.         for (i = 0; i < max; i++) {            /* Scroll the display up    */
  703.             setDisplayStart(0,i);
  704.             delay(4);
  705.             }
  706.         for (i--; i >= 0; i--) {             /* Scroll the display down  */
  707.             setDisplayStart(0,i);
  708.             delay(4);
  709.             }
  710.         }
  711. }
  712.  
  713. void virtualTest(void)
  714. /****************************************************************************
  715. *
  716. * Function:        virtualTest
  717. *
  718. * Description:    Checks the CRT logical scanline length routines, setting
  719. *                up a virtual display buffer and scrolling around within
  720. *                this buffer.
  721. *
  722. ****************************************************************************/
  723. {
  724.     int        i,x,y,width,scrollx,scrolly,oldmaxx,oldmaxy;
  725.     char    buf[80];
  726.  
  727.     if (extendedflipping) {
  728.         switch (maxcolor) {
  729.             case 0x7FFF:
  730.             case 0xFFFF:    if (memory > 1024)
  731.                                 width = 1024;
  732.                             else width = 800;
  733.                             break;
  734.             case 0xFFFFFF:    if (memory > 1024)
  735.                                 width = 1024;
  736.                             else width = 700;
  737.                             break;
  738.             default:        if (maxx == 1279)
  739.                                 width = 1400;
  740.                             else width = 1024;
  741.                             break;
  742.             }
  743.         oldmaxx = maxx;
  744.         oldmaxy = maxy;
  745.         setScanlineLength(width,&bytesperline,&maxx,&maxy);
  746.         clear();
  747.         moire();
  748.         writeText(20,20,"Function 06h - Set/Get Logical Scan Line Length",defcolor);
  749.         sprintf(buf,"Virtual buffer now set to %d x %d pixels",maxx+1,maxy+1);
  750.         writeText(20,40,buf,defcolor);
  751.         scrollx = maxx-oldmaxx;
  752.         scrolly = maxy-oldmaxy;
  753.         for (x = y = 0; x <= scrollx; x++) {
  754.             setDisplayStart(x,y);
  755.             delay(4);
  756.             }
  757.         for (x = scrollx,y = 0; y <= scrolly; y++) {
  758.             setDisplayStart(x,y);
  759.             delay(4);
  760.             }
  761.         for (x = scrollx,y = scrolly; x >= 0; x--) {
  762.             setDisplayStart(x,y);
  763.             delay(4);
  764.             }
  765.         for (x = 0,y = scrolly; y >= 0; y--) {
  766.             setDisplayStart(x,y);
  767.             delay(4);
  768.             }
  769.         }
  770. }
  771.  
  772. void checkGraphicsFunctions(void)
  773. /****************************************************************************
  774. *
  775. * Function:        checkGraphicsFunctions
  776. *
  777. * Description:    Intialises all of the available video modes, and performs
  778. *                testing on all the modes. We call upon the SuperVGA
  779. *                test kit to perform the graphics output for us for each
  780. *                video mode.
  781. *
  782. ****************************************************************************/
  783. {
  784.     ModeInfoBlock    modeInfo;
  785.     regs            r;
  786.     short            *modes;
  787.  
  788.     initSuperVGA();
  789.  
  790.     for (modes = modelist; *modes != -1; modes++) {
  791.         r.es = SEG(&modeInfo);
  792.         r.di = OFF(&modeInfo);
  793.         r.ax = 0x4F01;
  794.         r.cx = *modes;
  795.         if (callVBE(&r)) {
  796.             if ((modeInfo.ModeAttributes & 0x1) == 0)
  797.                 continue;
  798.             if (modeInfo.MemoryModel < 3)
  799.                 continue;
  800.             setSuperVGAMode(*modes);
  801.             moire();
  802.             dumpModeInfo(*modes);
  803.             scrollTest();
  804.             delay(750);
  805.             virtualTest();
  806.             delay(750);
  807.             restoreMode();
  808.             }
  809.         }
  810. }
  811.  
  812. void main(void)
  813. {
  814.     if (queryCpu() < 4) {
  815.         printf("This program contains '386 specific instructions, and will not work on\n");
  816.         printf("this machine - sorry\n");
  817.         }
  818.  
  819.     if ((logfile = fopen("paranoid.log","wt")) == NULL) {
  820.         out("Unable to open log file!!\n");
  821.         exit(1);
  822.         }
  823.  
  824.     out(signon);
  825.     printf("This program will test every funtion in the VESA VBE interface specifications\n");
  826.     printf("for correct conformance. If any errors are encountered, they will be logged to\n");
  827.     printf("the file 'paranoid.log' in the current directory.\n\n");
  828.     printf("Hit any key to start, ESC to cancel.\n\n");
  829.  
  830.     if (getch() == 0x1B)
  831.         exit(1);
  832.  
  833.     checkFunction00h();
  834.     checkFunction01h();
  835.     checkFunction02h();
  836.     checkFunction04h();
  837.     checkFunction05h();
  838.  
  839.     checkGraphicsFunctions();
  840.  
  841.     log("\n");
  842.     if (failed)
  843.         out("Video BIOS failed conformance test. Check log report for details.\n");
  844.     else if (!extendedflipping) {
  845.         out("Video BIOS passed most tests, but does not implement extended CRT\n");
  846.         out("addressing, used by some newer programs (like Microsoft Flight\n");
  847.         out("simulator\n");
  848.         }
  849.     else
  850.         out("Congratulations! Video BIOS passed all conformance tests.\n");
  851. }
  852.