home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1997 February / PCO2_97.ISO / filesbbs / os2 / sysb091c.arj / SYSBENCH / SRC / PMB_DIVE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-07  |  35.0 KB  |  1,098 lines

  1.  
  2. // SysBench DIVE test module
  3. // made for the warp II beta toolkit. Must probably be modified to run on OS/2 3.0
  4. // corrected bug where paint_rot tried to paint horizontal lines not vertical 28/06/96
  5.  
  6.  
  7. #define INCL_WIN
  8. #define INCL_GPI
  9. #define INCL_DOS
  10. #include <os2.h>
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #define  _MEERROR_H_
  15. #include "mmioos2.h"                   /* It is from MMPM toolkit           */
  16. #include "dive.h"
  17. #include "fourcc.h"
  18. #include "pmb.h"
  19. #include "types.h"
  20.  
  21. #define ID_WINDOW1 8000
  22. #define PMB_DIVE_CLASS "SysBench dive winclass"
  23. #define MIN_DIVE_TIME 10.0
  24. #define MIN_DIVE2_TIME 1.0
  25. #define MIN_MEASURE 0.1
  26. #define MARGINAL 1.1
  27. #define PI 3.14159265358979323846
  28.  
  29. //static HAB  hab;
  30.  
  31. extern double cos(double);
  32. extern double sin(double);
  33. extern void err(char* s);
  34. extern void warn(char* s);
  35. extern void logit(char* s);
  36. //extern HAB anchorblock(void);
  37. extern double rtime(void);    // real time in seconds
  38. extern double dtime(void);    // used CPU time in seconds
  39. extern double test_time;
  40.  
  41. void APIENTRY paint_videobw(ULONG unused);
  42. void APIENTRY paint_rot(ULONG unused);
  43. void APIENTRY paint_ms12(ULONG unused);
  44.  
  45. static MRESULT EXPENTRY DiveWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 );
  46. static void Open(void *paintfun);
  47. static void Close(void);
  48. void end_Win(HDIVE hDive, char *p, HWND hwndClient);
  49. void clr_lines(s32 y, s32 lines);
  50. void disp_lines(u8* buf, s32 y, s32 lines);
  51. _Inline void disp_lines2(u8* src, u8* dest, s32 yin, s32 yout);
  52. _Inline s32 fun(s32 x, double param);
  53.  
  54. static HWND hwndClient = NULLHANDLE;         /* Client area window handle    */
  55. static HWND hwndFrame = NULLHANDLE;          /* Frame window handle          */
  56. static HMQ  hmq;
  57. static ULONG flCreate;                       /* Window creation control flags*/
  58. static HAB bkHab;
  59. static TID paint_tid;
  60. static double result;
  61. static char* framebuf; // the main framebuffer
  62. static DIVE_CAPS dc;
  63. static HDIVE hDive;
  64. static RECTL rect;
  65. static char szName[50];
  66.  
  67. static void Open(void *paintfun) {
  68.   s32 w,h, x,y;
  69.   RECTL rctl, rctlScreen;
  70.   QMSG qmsg;                            /* Message from message queue   */
  71.   hwndClient = NULLHANDLE;         /* Client area window handle    */
  72.   hwndFrame = NULLHANDLE;          /* Frame window handle          */
  73. //  hab = anchorblock();
  74.  
  75.   if ((bkHab = WinInitialize(0)) == 0L) /* Initialize PM     */
  76.     err("Can't get anchor block handle for background thread");
  77.  
  78.   if ((hmq = WinCreateMsgQueue( bkHab, 0 )) == 0L)/* Create a msg queue */
  79.     err("Can't create message queue for graphics test window");
  80.  
  81.   if (!WinRegisterClass(bkHab, (PSZ)PMB_DIVE_CLASS, (PFNWP)DiveWindowProc, 0, 0)) {
  82.     err("DIVE test error: can't register class for child test window");
  83.   }
  84.  
  85.   flCreate = FCF_TASKLIST;
  86.  
  87.   if ((hwndFrame = WinCreateStdWindow(
  88.                HWND_DESKTOP,            /* Desktop window is parent     */
  89.                0,                       /* window styles           */
  90.                &flCreate,               /* Frame control flag           */
  91.                PMB_DIVE_CLASS,    /* Client window class name     */
  92.                "SysBench dive test window",    /* window text               */
  93.                0,                       /* No special class style       */
  94.                (HMODULE)0L,             /* Resource is in .EXE file     */
  95.                ID_WINDOW1,               /* Frame window identifier      */
  96.                &hwndClient              /* Client window handle         */
  97.                )) == 0L)
  98.     err("Can't create dive test window");
  99.  
  100.   WinQueryWindowRect(HWND_DESKTOP, &rect);
  101.   WinSetWindowPos(hwndFrame, HWND_TOP, rect.xLeft, rect.yBottom,
  102.     rect.xRight-rect.xLeft+1, rect.yTop-rect.yBottom+1, SWP_SIZE | SWP_MOVE | SWP_ACTIVATE | SWP_SHOW | SWP_ZORDER);
  103.  
  104.   DosCreateThread(&paint_tid, (PFNTHREAD)paintfun, 0, 0, 64000);
  105.   while( WinGetMsg( bkHab, &qmsg, 0L, 0, 0 ) )
  106.     WinDispatchMsg( bkHab, &qmsg );
  107. }
  108.  
  109. static void Close(void) {
  110.   WinDestroyWindow(hwndFrame);           /* Tidy up...                   */
  111.   WinDestroyMsgQueue( hmq );             /* Tidy up...                   */
  112.   WinTerminate(bkHab);
  113. }
  114.  
  115. double pmb_dive_bw(void) {
  116.   Open((void*)paint_videobw);
  117.   Close();
  118.   return result;
  119. }
  120.  
  121. double pmb_dive_rot(void) {
  122.   Open((void*)paint_rot);
  123.   Close();
  124.   return result;
  125. }
  126.  
  127. double pmb_dive_ms11(void) {
  128.   Open((void*)paint_ms12);
  129.   Close();
  130.   return result;
  131. }
  132.  
  133. static MRESULT EXPENTRY DiveWindowProc( HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2 )
  134. {
  135.   switch( msg )
  136.   {
  137.     case WM_CREATE:
  138.       break;
  139.  
  140.     case WM_COMMAND:
  141.       break;
  142.  
  143.     case WM_ERASEBACKGROUND:
  144.       return (MRESULT)( FALSE ); // TRUE -> yes, erase the background
  145.  
  146.     case WM_PAINT:
  147.       {
  148.         HPS    hps;
  149.         RECTL  rc;
  150.         POINTL pt;
  151.  
  152.         hps = WinBeginPaint( hwnd, 0L, &rc );
  153.         GpiSetColor( hps, CLR_BLACK );      // colour of the text,
  154.         GpiSetBackColor( hps, CLR_BLACK );   // its background and
  155.         GpiSetBackMix( hps, BM_OVERPAINT );  // how it mixes,
  156.         GpiSetMix( hps, FM_OVERPAINT );  // how it mixes,
  157. //        WinFillRect(hps, &rc, CLR_BLACK);
  158.         WinEndPaint( hps );                  // Drawing is complete
  159.         break;
  160.       }
  161.     case WM_CLOSE:
  162.       WinPostMsg( hwnd, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  163.       break;
  164.     default:
  165.       return WinDefWindowProc( hwnd, msg, mp1, mp2 );
  166.   }
  167.   return (MRESULT)FALSE;
  168. }
  169.  
  170. void APIENTRY paint_videobw(ULONG unused) {
  171.   HPS hps;
  172.   POINTL p1, p2;
  173.   double t1, t2, test_time;
  174.   RECTL rc;
  175.   PVOID apa;
  176.   ULONG ret;
  177.   PDIVE_CAPS pdc;
  178.   s32    i, j, c, runs, runs_10, framesize,
  179.          sh, scanlen, frames, numApertures,
  180.          ApertureNum, Datalen, Offset,
  181.          ApertureOffset, RemainLen, z, zz;
  182.   char* framecopy;
  183.   char* framecopy1;
  184.   APIRET rc1 = 0UL;
  185.   int notstop = 1;
  186.  
  187.   memset(&dc, 0, sizeof(dc));
  188.   dc.ulStructLen = sizeof(dc);
  189.   dc.ulFormatLength = 0;
  190.   ret = DiveQueryCaps(&dc, DIVE_BUFFER_SCREEN);
  191.   if (DIVE_SUCCESS != ret) {
  192.     if (ret == DIVE_ERR_INSUFFICIENT_LENGTH) {
  193.       dc.pFormatData = calloc(dc.ulFormatLength,1);
  194.       ret = DiveQueryCaps(&dc, DIVE_BUFFER_SCREEN); // let's try again
  195.       if (DIVE_SUCCESS != ret) {
  196.         err("Error in call to DiveQueryCaps()");
  197.       }
  198.     } else {
  199.       err("Error in call to DiveQueryCaps()");
  200.     }
  201.   }
  202.  
  203.   rc1 = DiveOpen(&hDive, FALSE, &apa);
  204.  
  205.   if (rc1 != DIVE_SUCCESS)
  206.      {
  207.      if (rc1 == DIVE_ERR_TOO_MANY_INSTANCES)
  208.         {
  209.         logit("Dive error - too many instances");
  210.         result = -1;
  211.         }
  212.      if (rc1 == DIVE_ERR_SSMDD_NOT_INSTALLED)
  213.         {
  214.         logit("Dive error - SSMDD.SYS not installed");
  215.         result = -1;
  216.         }
  217.      if (rc1 == DIVE_ERR_NO_DIRECT_ACCESS)
  218.         {
  219.         logit("Dive error - no direct access");
  220.         result = -1;
  221.         }
  222.      if (rc1 == DIVE_ERR_ALLOCATION_ERROR)
  223.         {
  224.         logit("Dive error - allocation error, check MMOS/2 installed");
  225.         result = -1;
  226.         }
  227.      if (rc1 != DIVE_SUCCESS)
  228.         {
  229.         result = -1;
  230.         free(dc.pFormatData);
  231.         WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  232.         return;
  233.          }
  234.   }
  235.  
  236.   framebuf = (char*)apa;
  237.  
  238.   WinQueryWindowRect(HWND_DESKTOP, &rect);
  239.      ret = DiveAcquireFrameBuffer(hDive, &rect);
  240.      if (ret != DIVE_SUCCESS)
  241.         {
  242.         logit("Error in DiveAcquireFrameBuffer()");
  243.         result = -1;
  244.         end_Win(hDive,dc.pFormatData,hwndClient);
  245.         return;
  246.         }
  247.  
  248.   framesize = dc.ulVerticalResolution * dc.ulScanLineBytes;
  249.   framecopy = malloc(framesize);
  250.   if (framecopy == null) {
  251.     logit("Can't get memory for copy of frame buffer");
  252.     result = -1;
  253.     end_Win(hDive,dc.pFormatData,hwndClient);
  254.     return;
  255.   }
  256.  
  257.   if (dc.fScreenDirect)
  258.      {                                                /* if direct access allowed */
  259.      if (dc.ulApertureSize >= framesize)
  260.         {                    /* and if video buffer larger or equal to our buffer */
  261.         memcpy(framecopy, framebuf, framesize); /* copy from video buffer to ours */
  262.         }
  263.      else
  264.         {                               /* if our buffer larger than video buffer */
  265.          framecopy1 = framecopy;
  266.          numApertures =  framesize/dc.ulApertureSize;
  267.          for (i = 0; i < numApertures; i++)
  268.             {
  269.              rc1 = DiveSwitchBank(hDive, i);
  270.              if (rc1 != DIVE_SUCCESS)
  271.                 {
  272.                 logit("DiveSwitchBank 1 returned an error");
  273.                 }
  274.              memcpy(framecopy1, framebuf, dc.ulApertureSize);
  275.              framecopy1 += dc.ulApertureSize;
  276.              }
  277.          if (framesize%dc.ulApertureSize) /* if not an exact multiple of aperture size */
  278.             {
  279.             rc1 = DiveSwitchBank(hDive, numApertures); /* switch to last bank */
  280.             memcpy(framecopy1, framebuf, framesize%dc.ulApertureSize);    /* and copy last bit */
  281.             }
  282.          }
  283.       }
  284.   else
  285.      {
  286.      logit("No Direct Screen access possible.");
  287.      result = -1;
  288.      end_Win(hDive,dc.pFormatData,hwndClient);
  289.      return;
  290.      }
  291.  
  292.   frames = 0;
  293.   sh = dc.ulVerticalResolution;
  294.   scanlen = dc.ulScanLineBytes;
  295.  
  296.   runs = 200;
  297.  
  298.   while (notstop)
  299.      {
  300.      frames = 0;
  301.      t1 = dtime();
  302.  
  303.      if (dc.ulApertureSize >= framesize)
  304.         {                                     /* old style behaviour - copy in one block */
  305.         for (i = 0; i < runs; i++) {
  306.            frames++;
  307.            j = i % (sh-1) + 1;
  308.            memcpy(framebuf, framecopy+(sh-j)*scanlen, j*scanlen);
  309.            memcpy(framebuf + j*scanlen, framecopy, (sh-j)*scanlen);
  310.            }
  311.         }
  312.      else
  313.         {      /* video memory is accessible in multiple banks of y lots of xKb (64Kb?) */
  314.         numApertures = (framesize/dc.ulApertureSize);
  315.         if (framesize%dc.ulApertureSize) /* if not exact number to buffer */
  316.            {
  317.            numApertures++;              /* increase by 1 */
  318.            }
  319.  
  320.         framecopy1 = framecopy;
  321.         for (i = 0; i < runs; i++)
  322.            {
  323.            frames++;
  324.            j = (i % (sh-1)) + 1;
  325.            Datalen = j * scanlen;
  326.            ApertureNum = 0;
  327.            rc1 = DiveSwitchBank(hDive, ApertureNum);           /* switch to correct bank */
  328.            if (rc1 != DIVE_SUCCESS)
  329.               {
  330.               logit("DiveSwitchBank 2 returned an error");
  331.               }
  332.  
  333.            Offset = 0;
  334.            while (Datalen > 0)
  335.               {
  336.                if (Datalen < dc.ulApertureSize)
  337.                   {
  338.                   memcpy(framebuf,framecopy+Offset+((sh-j)*scanlen), Datalen);
  339.                   Datalen = 0;
  340.                   }
  341.                else
  342.                   {  /* first part of data > 64Kb */
  343.                   memcpy(framebuf,framecopy+Offset+((sh-j)*scanlen), dc.ulApertureSize);
  344.                   Datalen -= dc.ulApertureSize;
  345.                   ApertureNum++;
  346.                   Offset += dc.ulApertureSize;
  347.                   rc1 = DiveSwitchBank(hDive, ApertureNum);
  348.                   if (rc1 != DIVE_SUCCESS)
  349.                      {
  350.                      logit("DiveSwitchBank 3 returned an error");
  351.                      }
  352.                   }
  353.                }     /* end While (Datalen > 0) */
  354.  
  355.            Datalen = (sh-j) * scanlen;     /* length of rest of screen */
  356. //          RemainLen = Datalen%dc.ulApertureSize; /* length of data in first block */
  357.            ApertureOffset = (j*dc.ulScanLineBytes)%dc.ulApertureSize; /* length of data in first block */
  358.            RemainLen = dc.ulApertureSize-ApertureOffset; /* offset into aperture to write to */
  359.            if (RemainLen != 0)
  360.               {
  361.               memcpy(framebuf+ApertureOffset, framecopy, RemainLen); /* copy first block */
  362.               ApertureNum++;
  363.               }
  364.            z = 0;
  365.            for (c = ApertureNum; c < numApertures; c++)
  366.               {
  367.                rc1 = DiveSwitchBank(hDive, c);           /* switch to correct bank */
  368.                if (rc1 != DIVE_SUCCESS)
  369.                   {
  370.                   logit("DiveSwitchBank 5 returned an error");
  371.                   }
  372.                if (c == numApertures-1) /* if last frame */
  373.                   {
  374.                   zz = (dc.ulVerticalResolution * dc.ulScanLineBytes) % dc.ulApertureSize;
  375.                   }
  376.                else
  377.                   {
  378.                   zz = dc.ulApertureSize;
  379.                   }
  380.                memcpy(framebuf,framecopy + RemainLen + (z * dc.ulApertureSize) , zz);
  381.                z++;
  382.                }
  383.             }        /* end For (i=0;i<runs)    */
  384.          }           /* end Else if (dc.ulApertureSize >= framesize) */
  385.  
  386.     t2 = dtime();
  387.     test_time = (t2-t1);
  388.  
  389.     if ((test_time) < MIN_DIVE_TIME) {
  390.       if ((test_time) < MIN_MEASURE) {
  391.         runs = MIN_DIVE_TIME/MIN_MEASURE*runs;
  392.       } else {
  393.         runs = MIN_DIVE_TIME*MARGINAL/(test_time)*runs;
  394.       }
  395.     } else {
  396.       break;
  397.     }
  398.   }
  399.  
  400.   result = ((double) frames * scanlen * sh) / (test_time);
  401.  
  402.   DiveDeacquireFrameBuffer(hDive);
  403.  
  404.   end_Win(hDive,dc.pFormatData,hwndClient); /*
  405.   DiveClose(hDive);
  406.   free(dc.pFormatData);
  407.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 ); */
  408. }
  409.  
  410. void APIENTRY paint_rot(ULONG unused) {
  411.   HPS hps;
  412.   POINTL p1, p2;
  413.   double t1, t2, test_time;
  414.   RECTL rc;
  415.   PVOID apa;
  416.   ULONG ret;
  417.   PDIVE_CAPS pdc;
  418.   s32 i, j, c, runs, runs_10, framesize, sh, scanlen, frames, yin, yout, x, y, i1, numApertures;
  419.   char* framecopy;
  420.   char* framecopy1;
  421.   s32 speed, rev, arg_nrev, sh2, wh, wh2;
  422.   double phase = 0.0, phase_steps, c1, c2, c3, c4, c5, c6, c7, c8;
  423.   bool forw;
  424.   APIRET rc1 = 0UL;
  425.   int notstop = 1;
  426.  
  427.   memset(&dc, 0, sizeof(dc));
  428.   dc.ulStructLen = sizeof(dc);
  429.   dc.ulFormatLength = 0;
  430.   ret = DiveQueryCaps(&dc, DIVE_BUFFER_SCREEN);
  431.   if (DIVE_SUCCESS != ret) {
  432.     if (ret == DIVE_ERR_INSUFFICIENT_LENGTH) {
  433.       dc.pFormatData = calloc(dc.ulFormatLength,1);
  434.       ret = DiveQueryCaps(&dc, DIVE_BUFFER_SCREEN); // let's try again
  435.       if (DIVE_SUCCESS != ret) {
  436.         err("Error in call to DiveQueryCaps()");
  437.       }
  438.     } else {
  439.       err("Error in call to DiveQueryCaps()");
  440.     }
  441.   }
  442.  
  443.   rc1 = DiveOpen(&hDive, FALSE, &apa);
  444.  
  445.   if (rc1 != DIVE_SUCCESS) {
  446.      if (rc1 == DIVE_ERR_TOO_MANY_INSTANCES)
  447.         {
  448.         logit("Dive error - too many instances");
  449.         }
  450.      if (rc1 == DIVE_ERR_SSMDD_NOT_INSTALLED)
  451.         {
  452.         logit("Dive error - SSMDD.SYS not installed");
  453.         }
  454.      if (rc1 == DIVE_ERR_NO_DIRECT_ACCESS)
  455.         {
  456.         logit("Dive error - no direct access");
  457.         }
  458.      if (rc1 == DIVE_ERR_ALLOCATION_ERROR)
  459.         {
  460.         logit("Dive error - allocation error, check MMOS/2 installed");
  461.         result = -1;
  462.         }
  463.      if (rc1 != DIVE_SUCCESS)
  464.         {
  465.          result = -1;
  466.          free(dc.pFormatData);
  467.          WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  468.          return;
  469.          }
  470.   }
  471.  
  472.   framebuf = (char*)apa;
  473.  
  474.    WinQueryWindowRect(HWND_DESKTOP, &rect);
  475.       ret = DiveAcquireFrameBuffer(hDive, &rect);
  476.       if (ret != DIVE_SUCCESS)
  477.          {
  478.           logit("Error in DiveAcquireFrameBuffer()");
  479.           result = -1;
  480.           end_Win(hDive,dc.pFormatData,hwndClient);
  481.           return;
  482.           }
  483.  
  484.   framesize = dc.ulVerticalResolution * dc.ulScanLineBytes;
  485.   framecopy = malloc(framesize);
  486.   if (framecopy == null) {
  487.     logit("Can't get memory for copy of frame buffer");
  488.     result = -1;
  489.     end_Win(hDive,dc.pFormatData,hwndClient);
  490.     return;
  491.   }
  492.  
  493.   if (dc.fScreenDirect)
  494.      {                                                /* if direct access allowed */
  495.      if (dc.ulApertureSize >= framesize)
  496.         {                    /* and if video buffer larger or equal to our buffer */
  497.         memcpy(framecopy, framebuf, framesize); /* copy from video buffer to ours */
  498.         }
  499.      else
  500.         {                               /* if our buffer larger than video buffer */
  501.          framecopy1 = framecopy;
  502.          numApertures =  framesize/dc.ulApertureSize;
  503.          for (i = 0; i < numApertures; i++)
  504.             {
  505.              rc1 = DiveSwitchBank(hDive, i);
  506.              if (rc1 != DIVE_SUCCESS)
  507.                 {
  508.                 logit("DiveSwitchBank 1 returned an error");
  509.                 }
  510.              memcpy(framecopy1, framebuf, dc.ulApertureSize);
  511.              framecopy1 += dc.ulApertureSize;
  512.              }
  513.           if (framesize%dc.ulApertureSize)
  514.              {
  515.              rc1 = DiveSwitchBank(hDive, numApertures);
  516.              memcpy(framecopy1, framebuf, framesize%dc.ulApertureSize);
  517.              }
  518.          }        /* end else our buffer > video aperture */
  519.       }           /* end if fScreenDirect */
  520.   else
  521.      {
  522.      logit("No Direct Screen access possible.");
  523.      result = -1;
  524.      end_Win(hDive,dc.pFormatData,hwndClient);
  525.      return;
  526.      }
  527.  
  528.   frames = 0;
  529.   sh = dc.ulVerticalResolution;
  530.   scanlen = dc.ulScanLineBytes;
  531.  
  532.   runs = 10;
  533.  
  534.   // First, find out the approximate speed of this display
  535.   while (notstop)
  536.     {
  537.     frames = 0;
  538.     t1 = dtime();
  539.     for (i = 0; i < runs; i++)
  540.       {
  541.       frames++;
  542.  
  543.       if (dc.fScreenDirect)
  544.          {                                                /* if direct access allowed */
  545.          if (dc.ulApertureSize >= framesize)
  546.             {                    /* and if video buffer larger or equal to our buffer */
  547.             memcpy(framebuf, framecopy, framesize); /* copy from video buffer to ours */
  548.             }
  549.          else
  550.             {                               /* if our buffer larger than video buffer */
  551.             framecopy1 = framecopy;
  552.             for (i1 = 0; i1 < framesize/dc.ulApertureSize; i1++)
  553.                {
  554.                 rc1 = DiveSwitchBank(hDive, i1);
  555.                 if (rc1 != DIVE_SUCCESS)
  556.                    {
  557.                    logit("DiveSwitchBank 1 returned an error");
  558.                    }
  559.                 memcpy(framebuf, framecopy+(i1*dc.ulApertureSize), dc.ulApertureSize);
  560.                 }
  561.             }
  562.          }
  563.      else
  564.         {
  565.         logit("No Direct Screen access possible.");
  566.         result = -1;
  567.         end_Win(hDive,dc.pFormatData,hwndClient);
  568.         return;
  569.         }
  570.     }  /* end for i = 0 to runs */
  571.     t2 = dtime();
  572.     test_time = (t2-t1);
  573.     if ((test_time) < MIN_DIVE2_TIME)
  574.        {
  575.        if ((test_time) < MIN_MEASURE)
  576.           {
  577.           runs = MIN_DIVE2_TIME/MIN_MEASURE*runs;
  578.           }
  579.        else
  580.           {
  581.           runs = MIN_DIVE2_TIME*MARGINAL/(test_time)*runs;
  582.           }
  583.        }
  584.      else
  585.         {
  586.         break;
  587.         }
  588.      }
  589.  
  590.   // speed = ((double) frames * scanlen * sh) / (t2-t1); // MB/s
  591.   speed = ((double)frames)/(test_time); // fps
  592.  
  593.   sh = dc.ulVerticalResolution;
  594.   sh2 = sh/2;
  595.  
  596.   phase_steps = .35/speed;
  597.   arg_nrev = 1;
  598.  
  599.   t1 = dtime();
  600.   frames = 0;
  601.  
  602.   for (rev = 0; rev < arg_nrev; rev++)
  603.     {
  604.     for (phase = 0.0; phase < 2.0*PI; phase += phase_steps)
  605.       {
  606.       frames++;
  607.       wh2 = sh2 * cos(phase);
  608.       if (wh2 < 0)
  609.         {
  610.         forw = false;
  611.         wh2 = -wh2;
  612.         }
  613.       else
  614.         {
  615.         forw = true;
  616.         }
  617.       wh = wh2 << 1;
  618.       if (forw)
  619.         {
  620.         clr_lines(0, sh2-wh2);
  621.         for (i = 0; i < wh; i++)
  622.             {
  623.             disp_lines(framecopy+((i*sh)/wh)*dc.ulScanLineBytes, i+sh2-wh2, 1);
  624.             }
  625.         clr_lines(sh2+wh2, sh2-wh2);
  626.         }
  627.       else
  628.         {      /* if not forw */
  629.          clr_lines(0, sh2-wh2);
  630.          for (i = 0; i < wh; i++)
  631.              {
  632.              disp_lines(framecopy+(((wh-1-i)*sh)/wh)*dc.ulScanLineBytes, i+sh2-wh2, 1);
  633.              }
  634.          clr_lines(sh2+wh2, sh2-wh2);
  635.          }     /* end else if not forw */
  636.       }        /* end for phase =0  */
  637.   }            /* end for rev = 0 */
  638.   phase_steps *= 1.4; // a little faster than the rotation
  639.  
  640.   c1 = 24.0 * (double)dc.ulVerticalResolution / 768.0;
  641.   c2 = 2.0 * (double)dc.ulVerticalResolution / 768.0;
  642.   c3 = 4.0/(dc.ulVerticalResolution/6.0/PI);
  643.   c4 = .7/(dc.ulVerticalResolution/6.0/PI);
  644.   c5 = 1.0;
  645.   c6 = 2.3;
  646.   c7 = 0.0;
  647.   c8 = 1.0;
  648.   for (rev = 0; rev < arg_nrev; rev++)
  649.      {
  650.      for (phase = 0.0; phase < 2.0*PI; phase += phase_steps)
  651.         {
  652.         frames++;
  653.         for (yin = 0; yin < sh; yin++)
  654.            {
  655.            double tt, hh;
  656. //           FILE* fp;
  657. //           fp = fopen("dive.dbg", "a+");
  658. //           fprintf(fp, "c5 = %f c7 = %f yin = %f c4 = %f", c5, c7, yin, c4);
  659. //           fclose(fp);
  660.            tt = sin(phase * c5 + c7 + yin * c4);
  661. //           fp = fopen("dive.dbg", "a+");
  662. //           fprintf(fp, "c6 = %f c8 = %f yin = %f c3 = %f", c6, c8, yin, c3);
  663. //           fclose(fp);
  664.            hh = sin(phase * c6 + c8 + yin * c3);
  665.            yout = ((double)yin) + c1 * tt + c2 * hh;
  666.            if (yout < 0 || yout >= dc.ulVerticalResolution)
  667.               {
  668.               clr_lines(yin, 1);
  669.               }
  670.            else
  671.               {
  672.               disp_lines2(framecopy, framebuf, yout, yin);
  673.               }
  674.            }
  675.         }
  676.      }
  677.  
  678.   t2 = dtime();
  679.   test_time = (t2-t1);
  680.  
  681.   // normalise result to 640 x 480 @ 256 colours with 640 bytes/scanline
  682.   result = ((double) frames * sh * scanlen ) / (test_time * 480 * 640);
  683.  
  684.   DiveDeacquireFrameBuffer(hDive);
  685.  
  686.   end_Win(hDive,dc.pFormatData,hwndClient);
  687.  
  688. }
  689.  
  690.  /* _Inline */
  691. void clr_lines(s32 y, s32 lines)
  692.  {
  693.   s32 n /* = (lines*dc.ulScanLineBytes) >> 4 */;
  694. /*   u32* p = (u32*)(framebuf + y*dc.ulScanLineBytes); */
  695.   s32 i, j, k, m, q, framesize, ll;
  696.   APIRET rc;
  697.  
  698.   framesize = dc.ulVerticalResolution * dc.ulScanLineBytes;
  699.   if (dc.fScreenDirect)
  700.      {                                                /* if direct access allowed */
  701.      if (dc.ulApertureSize >= framesize)
  702.         {                    /* and if video buffer larger or equal to our buffer */
  703.  
  704.         j = y*dc.ulScanLineBytes;          /* offset into screen image */
  705.         n = lines;
  706.         for (i = 0; i < n; i++)
  707.            {
  708.            memset(framebuf + j, 0, dc.ulScanLineBytes);
  709.            j += dc.ulScanLineBytes;
  710.            }                             /* end for i = 0; i < n  */
  711.         }
  712.      else
  713.         {                 /* otherwise we have a bank switched video card */
  714.         j = y*dc.ulScanLineBytes;          /* offset into screen image */
  715.         k = j/dc.ulApertureSize;          /* k is Aperture number we want */
  716.         DiveSwitchBank(hDive, k);         /* set it active */
  717.         n = lines;
  718.         for (i = 0; i < n; i++)
  719.            {
  720.            m = j/dc.ulApertureSize;        /* current aperture number */
  721.            q = j%dc.ulApertureSize;        /* offset into aperture    */
  722.            if (m != k)
  723.               {                            /* if not same aperture as before */
  724.               rc = DiveSwitchBank(hDive, m);  /* switch to correct aperture */
  725.               if (ll != dc.ulScanLineBytes)
  726.                  {
  727.                  memset(framebuf, 0, dc.ulScanLineBytes-ll);
  728.                  }
  729.               k = m;
  730.               }
  731.            if (q+dc.ulScanLineBytes > dc.ulApertureSize)
  732.               {
  733.               ll = dc.ulApertureSize-q;
  734.               }
  735.            else
  736.               {
  737.               ll = dc.ulScanLineBytes;
  738.               }
  739.            memset(framebuf + q, 0, ll);
  740.            j += dc.ulScanLineBytes;
  741.            }                             /* end for i = 0; i < n  */
  742.         }                                /* end else */
  743.      }                                      /* end if dc.ulScreenDirect */
  744.   }                                         /* end clr_lines */
  745.  
  746.  
  747. /* _Inline  */
  748. void disp_lines(u8* buf, s32 y, s32 lines)
  749.  {
  750.  s32 framesize, datalen, ApertureNum, ApertureDisp, copylen;
  751.  char* aframe;
  752.  u8* buf1;
  753.  
  754.   framesize = dc.ulVerticalResolution * dc.ulScanLineBytes;
  755.   if (dc.fScreenDirect)
  756.      {                                                /* if direct access allowed */
  757.      if (dc.ulApertureSize >= framesize)
  758.         {                    /* and if video buffer larger or equal to our buffer */
  759.         memcpy(framebuf + y*dc.ulScanLineBytes, buf, lines*dc.ulScanLineBytes);
  760.         }                    /* just copy from one to the other */
  761.      else
  762.         {                    /* we have a banked switched video card */
  763.         buf1 = buf;
  764.         aframe = framebuf;   /* + (y*dc.ulScanLineBytes); */
  765.         ApertureNum = (y*dc.ulScanLineBytes)/dc.ulApertureSize;
  766.         ApertureDisp = (y*dc.ulScanLineBytes)%dc.ulApertureSize;
  767.         datalen = lines*dc.ulScanLineBytes;
  768. /*        sprintf(szName, "Ap = %d, apdisp= %x, len = %d", ApertureNum, ApertureDisp, datalen);
  769.         logit(szName); */
  770.         while (datalen > 0)
  771.            {
  772.            if (ApertureDisp > 0)
  773.               {
  774.               DiveSwitchBank(hDive, ApertureNum);
  775.               if (datalen > dc.ulApertureSize-ApertureDisp)
  776.                  {
  777.                  copylen = dc.ulApertureSize-ApertureDisp;
  778.                  ApertureNum++;
  779.                  }
  780.               else
  781.                  {
  782.                  copylen = datalen;
  783.                  }
  784.               memcpy(aframe + ApertureDisp, buf1, copylen);
  785.               datalen = datalen - copylen;
  786.               ApertureDisp = 0;
  787.               buf1 = buf1 + copylen;
  788.               }
  789.            else
  790.               {                /* if ApertureDisp = 0 */
  791.               DiveSwitchBank(hDive, ApertureNum);
  792.               if (datalen > dc.ulApertureSize)
  793.                  {
  794.                  copylen = dc.ulApertureSize;
  795.                  ApertureNum++;
  796.                  }
  797.               else
  798.                  {
  799.                  copylen = datalen;
  800.                  }
  801.               memcpy(aframe, buf1, copylen);
  802.               datalen = datalen - copylen;
  803.               buf1 = buf1 + copylen;
  804.               }            /* end if ApertureDisp != 0 */
  805.            }               /* end while datalen > 0  */
  806.         }                  /* end else for banked video card */
  807.      }                     /* end if directScreen */
  808.   }                        /* end function */
  809.  
  810.  
  811. _Inline void disp_lines2(u8* src, u8* dest, s32 yin, s32 yout)
  812.  {
  813.  s32  ApertureNum, ApertureDisp, scanlen, framesize, aframe, sl;
  814.  
  815.  scanlen = dc.ulScanLineBytes;
  816.  framesize = dc.ulVerticalResolution * dc.ulScanLineBytes;
  817.  
  818.  if (dc.fScreenDirect)
  819.     {                                                /* if direct access allowed */
  820.     if (dc.ulApertureSize >= framesize)
  821.        {                    /* and if video buffer larger or equal to our buffer */
  822.        memcpy(dest + (yout * scanlen), src + (yin * scanlen), scanlen);
  823.        }
  824.     else
  825.        {
  826.        aframe = yout * scanlen;
  827.        ApertureNum = aframe/dc.ulApertureSize;
  828.        ApertureDisp = aframe%dc.ulApertureSize;
  829.        if (dc.ulApertureSize-ApertureDisp < scanlen)
  830.           {
  831.           sl = dc.ulApertureSize-ApertureDisp;
  832.           }
  833.        else
  834.           {
  835.           sl = scanlen;
  836.           }
  837.        DiveSwitchBank(hDive, ApertureNum);
  838.        memcpy(dest + ApertureDisp, src + (yin * scanlen), sl);
  839.        }
  840.     }
  841. }
  842.  
  843. _Inline s32 fun(s32 x, double param)
  844.  {
  845.   s32 yout;
  846.   yout = ((double)x) + 20.0 * sin(param+x/(dc.ulVerticalResolution/6.0/PI)) +
  847.          10.0 * sin(param*2.3+1.0+3*x/(dc.ulVerticalResolution/6.0/PI));
  848.   if (yout < 0 || yout >= dc.ulHorizontalResolution)
  849.     yout = -1;
  850.   return yout;
  851. }
  852.  
  853. // this function is NOT ready! It is under construction
  854. void APIENTRY paint_ms12(ULONG unused) {
  855.   HPS hps;
  856.   POINTL p1, p2;
  857.   double t1, t2, test_time;
  858.   RECTL rc;
  859.   PVOID apa;
  860.   ULONG ret;
  861.   PDIVE_CAPS pdc;
  862.   s32   i, j, c, runs, runs_10, framesize,
  863.         sh, scanlen, frames, numApertures,
  864.         ApertureNum, Datalen, Offset,
  865.         ApertureOffset, RemainLen, z, zz;
  866.   char* framecopy;
  867.   char* framecopy1;
  868.   APIRET rc1 = 0UL;
  869.   int notstop = 1;
  870.  
  871.   memset(&dc, 0, sizeof(dc));
  872.   dc.ulStructLen = sizeof(dc);
  873.   dc.ulFormatLength = 0;
  874.   ret = DiveQueryCaps(&dc, DIVE_BUFFER_SCREEN);
  875.   if (DIVE_SUCCESS != ret) {
  876.     if (ret == DIVE_ERR_INSUFFICIENT_LENGTH) {
  877.       dc.pFormatData = calloc(dc.ulFormatLength,1);
  878.       ret = DiveQueryCaps(&dc, DIVE_BUFFER_SCREEN); // let's try again
  879.       if (DIVE_SUCCESS != ret) {
  880.         err("Error in call to DiveQueryCaps()");
  881.       }
  882.     } else {
  883.       err("Error in call to DiveQueryCaps()");
  884.     }
  885.   }
  886.  
  887.   rc1 = DiveOpen(&hDive, FALSE, &apa);
  888.  
  889.   if (rc1 != DIVE_SUCCESS)
  890.      {
  891.      if (rc1 == DIVE_ERR_TOO_MANY_INSTANCES)
  892.         {
  893.         logit("Dive error - too many instances");
  894.         result = -1;
  895.         }
  896.      if (rc1 == DIVE_ERR_SSMDD_NOT_INSTALLED)
  897.         {
  898.         logit("Dive error - SSMDD.SYS not installed");
  899.         result = -1;
  900.         }
  901.      if (rc1 == DIVE_ERR_NO_DIRECT_ACCESS)
  902.         {
  903.         logit("Dive error - no direct access");
  904.         result = -1;
  905.         }
  906.      if (rc1 == DIVE_ERR_ALLOCATION_ERROR)
  907.         {
  908.         logit("Dive error - allocation error, check MMOS/2 installed");
  909.         result = -1;
  910.         }
  911.      if (rc1 != DIVE_SUCCESS)
  912.         {
  913.         result = -1;
  914.         free(dc.pFormatData);
  915.         WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  916.         return;
  917.         }
  918.      }
  919.  
  920.   framebuf = (char*)apa;
  921.  
  922.   WinQueryWindowRect(HWND_DESKTOP, &rect);
  923.      ret = DiveAcquireFrameBuffer(hDive, &rect);
  924.      if (ret != DIVE_SUCCESS)
  925.         {
  926.         logit("Error in DiveAcquireFrameBuffer()");
  927.         result = -1;
  928.         end_Win(hDive,dc.pFormatData,hwndClient);
  929.         return;
  930.         }
  931.  
  932.   framesize = dc.ulVerticalResolution * dc.ulScanLineBytes;
  933.   framecopy = malloc(framesize);
  934.   if (framecopy == null)
  935.      {
  936.      logit("Can't get memory for copy of frame buffer");
  937.      result = -1;
  938.      end_Win(hDive,dc.pFormatData,hwndClient);
  939.      return;
  940.      }
  941.  
  942.   if (dc.fScreenDirect)
  943.      {                                                /* if direct access allowed */
  944.      if (dc.ulApertureSize >= framesize)
  945.         {                    /* and if video buffer larger or equal to our buffer */
  946.         memcpy(framecopy, framebuf, framesize); /* copy from video buffer to ours */
  947.         }
  948.      else
  949.         {                               /* if our buffer larger than video buffer */
  950.         framecopy1 = framecopy;
  951.         numApertures =  framesize/dc.ulApertureSize;
  952.         for (i = 0; i < numApertures; i++)
  953.             {
  954.             rc1 = DiveSwitchBank(hDive, i);
  955.             if (rc1 != DIVE_SUCCESS)
  956.                {
  957.                logit("DiveSwitchBank 1 returned an error");
  958.                }
  959.             memcpy(framecopy1, framebuf, dc.ulApertureSize);
  960.             framecopy1 += dc.ulApertureSize;
  961.             }
  962.          if (framesize%dc.ulApertureSize)
  963.             {
  964.             rc1 = DiveSwitchBank(hDive, numApertures);
  965.             memcpy(framecopy1, framebuf, framesize%dc.ulApertureSize);
  966.             }
  967.         }
  968.      }
  969.   else
  970.      {
  971.      logit("No Direct Screen access possible.");
  972.      result = -1;
  973.      end_Win(hDive,dc.pFormatData,hwndClient);
  974.      return;
  975.      }
  976.  
  977.   frames = 0;
  978.   sh = dc.ulVerticalResolution;
  979.   scanlen = dc.ulScanLineBytes;
  980.  
  981.   runs = 200;
  982.  
  983.   while (notstop)
  984.      {
  985.      frames = 0;
  986.      t1 = dtime();
  987.  
  988.      if (dc.ulApertureSize >= framesize)
  989.         {                                     /* old style behaviour - copy in one block */
  990.         for (i = 0; i < runs; i++) {
  991.            frames++;
  992.            j = i % (sh-1) + 1;
  993.            memcpy(framebuf, framecopy+(sh-j)*scanlen, j*scanlen);
  994.            memcpy(framebuf + j*scanlen, framecopy, (sh-j)*scanlen);
  995.            }
  996.         }
  997.      else
  998.         {      /* video memory is accessible in multiple banks of y lots of xKb (64Kb?) */
  999.         numApertures = (framesize/dc.ulApertureSize);
  1000.         if (framesize%dc.ulApertureSize)
  1001.            {
  1002.            numApertures++;
  1003.            }
  1004.  
  1005.         framecopy1 = framecopy;
  1006.         for (i = 0; i < runs; i++)
  1007.            {
  1008.            frames++;
  1009.            j = i % (sh-1) + 1;
  1010.            Datalen = j * scanlen;
  1011.            ApertureNum = 0;
  1012.            rc1 = DiveSwitchBank(hDive, ApertureNum);           /* switch to correct bank */
  1013.            if (rc1 != DIVE_SUCCESS)
  1014.               {
  1015.               logit("DiveSwitchBank 2 returned an error");
  1016.               }
  1017.  
  1018.            Offset = 0;
  1019.            while (Datalen > 0)
  1020.               {
  1021.                if (Datalen < dc.ulApertureSize)
  1022.                   {
  1023.                   memcpy(framebuf,framecopy+Offset+((sh-j)*scanlen), Datalen);
  1024.                   Datalen -= dc.ulApertureSize;
  1025.                   }
  1026.                else
  1027.                   {  /* first part of data > 64Kb */
  1028.                   memcpy(framebuf,framecopy+Offset+((sh-j)*scanlen), dc.ulApertureSize);
  1029.                   Datalen -= dc.ulApertureSize;
  1030.                   ApertureNum++;
  1031.                   Offset += dc.ulApertureSize;
  1032.                   rc1 = DiveSwitchBank(hDive, ApertureNum);
  1033.                   if (rc1 != DIVE_SUCCESS)
  1034.                      {
  1035.                      logit("DiveSwitchBank 3 returned an error");
  1036.                      }
  1037.                   }
  1038.                }     /* end While (Datalen > 0) */
  1039.  
  1040.            Datalen = (sh-j) * scanlen;     /* length of rest of screen */
  1041. //          RemainLen = Datalen%dc.ulApertureSize; /* length of data in first block */
  1042.            ApertureOffset = (j*dc.ulScanLineBytes)%dc.ulApertureSize; /* length of data in first block */
  1043.            RemainLen = dc.ulApertureSize-ApertureOffset; /* offset into aperture to write to */
  1044.            if (RemainLen != 0)
  1045.               {
  1046.               memcpy(framebuf+ApertureOffset, framecopy, RemainLen); /* copy first block */
  1047.               ApertureNum++;
  1048.               }
  1049.            z = 0;
  1050.            for (c = ApertureNum; c < numApertures; c++)
  1051.               {
  1052.                rc1 = DiveSwitchBank(hDive, c);           /* switch to correct bank */
  1053.                if (rc1 != DIVE_SUCCESS)
  1054.                   {
  1055.                   logit("DiveSwitchBank 5 returned an error");
  1056.                   }
  1057.                if (c == numApertures-1) /* if last frame */
  1058.                   {
  1059.                   zz = (dc.ulVerticalResolution * dc.ulScanLineBytes) % dc.ulApertureSize;
  1060.                   }
  1061.                else
  1062.                   {
  1063.                   zz = dc.ulApertureSize;
  1064.                   }
  1065.                memcpy(framebuf,framecopy + RemainLen + (z * dc.ulApertureSize) , zz);
  1066.                z++;
  1067.                }
  1068.             }        /* end For (i=0;i<runs)    */
  1069.          }           /* end Else if (dc.ulApertureSize >= framesize) */
  1070.  
  1071.     t2 = dtime();
  1072.     test_time = (t2-t1);
  1073.  
  1074.     if ((test_time) < MIN_DIVE_TIME) {
  1075.       if ((test_time) < MIN_MEASURE) {
  1076.         runs = MIN_DIVE_TIME/MIN_MEASURE*runs;
  1077.       } else {
  1078.         runs = MIN_DIVE_TIME*MARGINAL/(test_time)*runs;
  1079.       }
  1080.     } else {
  1081.       break;
  1082.     }
  1083.   }
  1084.   // return result normalised for a 640x480 screen @ 256 colours
  1085.   result = ((double) frames * scanlen * sh) / (test_time * 480 * 640);
  1086.  
  1087.   DiveDeacquireFrameBuffer(hDive);
  1088.  
  1089.   end_Win(hDive,dc.pFormatData,hwndClient);
  1090. }
  1091.  
  1092. void end_Win(HDIVE hDive, char *p, HWND hwndClient)
  1093. {
  1094.   DiveClose(hDive);
  1095.   free(dc.pFormatData);
  1096.   WinPostMsg( hwndClient, WM_QUIT, (MPARAM)0,(MPARAM)0 );
  1097. }
  1098.