www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1993/07/23/07:00:08

Date: Thu, 22 Jul 1993 14:59:14 +0200
Conversion: Prohibited
From: "22-JUL-1993 13:55:32.83" <phc27 AT rz DOT uni-kiel DOT d400 DOT de>
To: DJGPP AT SUN DOT SOE DOT CLARKSON DOT edu
Subject: RE: ET4000/W32

Hi,

>Does anybody have any experience with a VESA bus E4000/W32 card?  I've
>been told that it's got the best raw VGA performance on the market for
>non-Windows uses.  Does it support more resolution than the ET4000?

Yes, the ET4000/W32 is quite fast. My card supports the following modes:

320x200     16  256   32K                 Should also work with 64K & 16.7M
640x350     16  256   32K                 Should also work with 64K & 16.7M
640x400     16  256   32K                 Should also work with 64K & 16.7M
640x480     16  256   32K   64K  16.7M    Couldn't test 64K & 16.7M
800x600     16  256   32K   64K
1024x768    16  256
1280x1024   16

A modern HiColor ET4000 should have all the modes up to 64K colors I think.
I don't know about ET4000 (non W32) and 16.7M modes.

Question: Did anyone write the 24bit low level support for the GRX
          package? (Weren't there true color routines announced on
          this channel? LIBGR or LIBGRX ones ?)

>As an aside, would anyone like to volunteer to write a blit
>performance tester?  It would need to put the screen into 320x200x256
>mode and access the memory with stosb, stosw, and stosl, giving
>kbytes/sec for each transfer type.

I'll include a short test program at the end of this message.

I've got another question:
  Does go32 call the graphics driver init routine before any
  of the variables in the header are used?

One could write more intelligent drivers if so. Eg. the wd90c3x and
wdvanila drivers may be merged by seletecing the correct paging
routine or stupid BIOS differences won't give another driver (see
MVGA-S3.GRN)!

Hartmut

(Hmm, the first local bus machine must have several memory wait
 states. I'll check it out ... )

/*
**  et4w32.c - determine video memory transfer rate
**
** results :
**
** 486DX2 66MHz               ET4000/W32 VLB    Cirrus 5426 VLB
** ------------------------------------------------------------
**     move byte (mem->mem) :  4698.43 kb/s       9103.20 kb/s
**     move word (mem->mem) :  8567.72 kb/s      17135.44 kb/s
**     move long (mem->mem) : 15331.71 kb/s      26482.05 kb/s
**     move byte (mem->scr) :  5711.81 kb/s       5022.46 kb/s
**     move word (mem->scr) : 10044.91 kb/s       9396.85 kb/s
**     move long (mem->scr) : 17135.44 kb/s       9396.85 kb/s
**     move byte (scr->mem) :  2080.73 kb/s       1744.33 kb/s
**     move word (scr->mem) :  4161.46 kb/s       3467.89 kb/s
**     move long (scr->mem) :  8091.74 kb/s       4221.78 kb/s
**     move byte (scr->scr) :  2229.58 kb/s       1592.56 kb/s
**     move word (scr->scr) :  4391.61 kb/s       3185.12 kb/s
**     move long (scr->scr) :  8051.28 kb/s       3293.70 kb/s
**     set  byte (memory)   :  5110.57 kb/s      10788.98 kb/s
**     set  word (memory)   : 10044.91 kb/s      20807.32 kb/s
**     set  long (memory)   : 20807.32 kb/s      41614.64 kb/s
**     set  byte (screen)   :  6473.39 kb/s       5394.49 kb/s
**     set  word (screen)   : 13241.02 kb/s      10788.98 kb/s
**     set  long (screen)   : 26482.05 kb/s      10788.98 kb/s
**
**
** ET4000 card                  386DX 33MHz     486DX 33MHz
** ---------------------------------------------------------
**     move byte (mem->mem) :  5110.57 kb/s    8827.35 kb/s
**     move word (mem->mem) : 10403.66 kb/s   15331.71 kb/s
**     move long (mem->mem) : 20807.32 kb/s   22407.88 kb/s
**     move byte (mem->scr) :  2577.90 kb/s    1501.56 kb/s
**     move word (mem->scr) :  5201.83 kb/s    2913.03 kb/s
**     move long (mem->scr) :  6197.93 kb/s    2913.03 kb/s
**     move byte (scr->mem) :  1272.06 kb/s     971.01 kb/s
**     move word (scr->mem) :  2447.92 kb/s    1903.94 kb/s
**     move long (scr->mem) :  2942.45 kb/s    2141.93 kb/s
**     move byte (scr->scr) :   956.59 kb/s     645.54 kb/s
**     move word (scr->scr) :  1882.12 kb/s    1271.25 kb/s
**     move long (scr->scr) :  2163.03 kb/s    1323.50 kb/s
**     set  byte (memory)   :  6332.66 kb/s    8091.74 kb/s
**     set  word (memory)   : 12137.60 kb/s   16183.47 kb/s
**     set  long (memory)   : 24275.21 kb/s   32366.94 kb/s
**     set  byte (screen)   :  2600.92 kb/s    1557.77 kb/s
**     set  word (screen)   :  5110.57 kb/s    3132.29 kb/s
**     set  long (screen)   :  6197.93 kb/s    3098.96 kb/s
**
**
** 386SX 16MHz               Trident 9000 (16bit)     Video 7 V7VEGA (8bit)
** -------------------------------------------------------------------------------
**     move byte (mem->mem) :  2240.79 kb/s              2293.72 kb/s
**     move word (mem->mem) :  4481.58 kb/s              4551.60 kb/s
**     move long (mem->mem) :  5496.27 kb/s              5601.97 kb/s
**     move byte (mem->scr) :   793.74 kb/s               745.02 kb/s
**     move word (mem->scr) :  1583.17 kb/s               764.57 kb/s
**     move long (mem->scr) :  1664.59 kb/s               768.61 kb/s
**     move byte (scr->mem) :   730.08 kb/s               722.83 kb/s
**     move word (scr->mem) :  1463.83 kb/s               754.67 kb/s
**     move long (scr->mem) :  1627.39 kb/s               746.93 kb/s
**     move byte (scr->scr) :   484.69 kb/s               380.88 kb/s
**     move word (scr->scr) :   969.38 kb/s               385.95 kb/s
**     move long (scr->scr) :   992.62 kb/s               384.41 kb/s
**     set  byte (memory)   :  2913.03 kb/s              3003.12 kb/s
**     set  word (memory)   :  5826.05 kb/s              5944.95 kb/s
**     set  long (memory)   : 11652.10 kb/s             12137.60 kb/s
**     set  byte (screen)   :   984.13 kb/s               776.81 kb/s
**     set  word (screen)   :  1968.26 kb/s               778.88 kb/s
**     set  long (screen)   :  1968.26 kb/s               778.88 kb/s
** -------------------------------------------------------------------------------
*/

#include <stdio.h>
#include <grx.h>

#define LOOPS 256
#define KB(x) ((double)(x)/1024.0)
#define SCR screen->gc_baseaddr

#define UL unsigned long
#define RUL register UL
#define VUL volatile UL

#ifdef USE_CLOCK
#  include <std.h>
#  include <time.h>
#  define RAWTIMER() clock()
#  define TICKTIME   (1.0 / CLOCKS_PER_SEC)
#else
#  define RAWTIMER() (*((UL *) 0xE000046c))
#  define TICKTIME   (838.1e-9*65536.0)
#endif

static unsigned char buf[320*200+4];
static unsigned char scratch[320*200+4];

#define _ClrDir()       asm volatile("cld")

#define _MOVE_(SZ,source,dest,bytes,loops) do {                         \
   RUL _esi asm("%esi");                                                \
   RUL _edi asm("%edi");                                                \
   RUL _ecx asm("%ecx");                                                \
   RUL _edx asm("%edx");                                                \
   _ClrDir();                                                           \
   _esi = (UL) (source);                                                \
   _edi = (UL) (dest);                                                  \
   _ecx = (UL) (bytes);                                                 \
   _edx = (UL) (loops);                                                 \
   asm volatile("                                                       \
     mv_"#SZ":                                                          \
        pushl   %%edi;                                                  \
        pushl   %%esi;                                                  \
        pushl   %%ecx;                                                  \
        rep; movs"#SZ";                                                 \
        popl    %%ecx;                                                  \
        popl    %%esi;                                                  \
        popl    %%edi;                                                  \
        dec     %%edx;                                                  \
        jne     mv_"#SZ"                                               "\
        : /* NOTHING */                                                 \
        : "g" (_esi), "g" (_edi), "g" (_ecx), "g" (_edx)                \
        : "di", "si", "cx", "dx"                                        \
  );                                                                    \
} while (0)

#define _SET_(SZ,dest,bytes,loop,val) do {                              \
   RUL _edi asm("%edi");                                                \
   RUL _eax asm("%eax");                                                \
   RUL _ecx asm("%ecx");                                                \
   RUL _edx asm("%edx");                                                \
   _ClrDir();                                                           \
   _edi = (UL) (dest);                                                  \
   _ecx = (UL) (bytes);                                                 \
   _edx = (UL) (loops);                                                 \
   _eax = (UL) (val);                                                   \
   asm volatile("                                                       \
     st_"#SZ":                                                          \
        pushl   %%edi;                                                  \
        pushl   %%ecx;                                                  \
        rep; stos"#SZ";                                                 \
        popl    %%ecx;                                                  \
        popl    %%edi;                                                  \
        dec     %%edx;                                                  \
        jne     st_"#SZ"                                               "\
        : /* NOTHING */                                                 \
        : "g" (_eax), "g" (_edi), "g" (_ecx), "g" (_edx)                \
        : "di", "ax", "cx", "dx"                                        \
  );                                                                    \
} while (0)

unsigned long do_move_b( void *dest, void *source, int bytes, int loops)
{
  VUL start, stop;

  start = RAWTIMER();
  _MOVE_(b,source,dest,bytes,loops);
  stop = RAWTIMER();
  if (start == stop) return 0;
  return (UL) (((double)bytes*loops)/((double)(stop-start)*TICKTIME) + 0.5);
}

unsigned long do_move_w(void *dest, void *source, int bytes, int loops)
{
  VUL start, stop;

  start = RAWTIMER();
  _MOVE_(w,source,dest,bytes>>1,loops);
  stop = RAWTIMER();
  if (start == stop) return 0;
  return (UL) (((double)bytes*loops)/((double)(stop-start)*TICKTIME) + 0.5);
}

unsigned long do_move_l(void *dest, void *source, int bytes, int loops)
{
  VUL start, stop;

  start = RAWTIMER();
  _MOVE_(l,source,dest,bytes>>2,loops);
  stop = RAWTIMER();
  if (start == stop) return 0;
  return (UL) (((double)bytes*loops)/((double)(stop-start)*TICKTIME) + 0.5);
}

unsigned long do_set_b ( void *mem, int val, int bytes, int loops)
{
  VUL start, stop;

  start = RAWTIMER();
  _SET_(b,mem,bytes,loop,val);
  stop = RAWTIMER();
  if (start == stop) return 0;
  return (UL) (((double)bytes*loops)/((double)(stop-start)*TICKTIME) + 0.5);
}

unsigned long do_set_w (void *mem, int val, int bytes, int loops)
{
  VUL start, stop;

  start = RAWTIMER();
  _SET_(w,mem,bytes>>1,loop,val);
  stop = RAWTIMER();
  if (start == stop) return 0;
  return (UL) (((double)bytes*loops)/((double)(stop-start)*TICKTIME) + 0.5);
}

unsigned long do_set_l (void *mem, int val, int bytes, int loops)
{
  VUL start, stop;

  start = RAWTIMER();
  _SET_(l,mem,bytes>>2,loop,val);
  stop = RAWTIMER();
  if (start == stop) return 0;
  return (UL) (((double)bytes*loops)/((double)(stop-start)*TICKTIME) + 0.5);
}

void main(void)
{
  int        i, white, black;
  UL         move_b_ms, move_b_sm, move_b_mm, move_b_ss;
  UL         set_b_s, set_b_m;
  UL         move_w_ms, move_w_sm, move_w_mm, move_w_ss;
  UL         set_w_s, set_w_m;
  UL         move_l_ms, move_l_sm, move_l_mm, move_l_ss;
  UL         set_l_s, set_l_m;
  GrContext *screen;

  if (RAWTIMER() == 0) ;
  GrSetMode( GR_width_height_color_graphics, 320, 200, 256);
  screen = GrSaveContext(NULL);
  white = GrWhite();
  black = GrBlack();
  for (i=0; i < sizeof(buf); ++i)
    buf[i] = ((i&1) == 0) ? black : white;
  white *= 0x1010101;

  do_move_b( SCR, buf, 320*200, 1);
  move_b_ms = do_move_b( SCR, buf, 320*200, LOOPS);
  move_w_ms = do_move_w( SCR, buf, 320*200, LOOPS);
  move_l_ms = do_move_l( SCR, buf, 320*200, LOOPS);

  do_move_b( scratch, SCR, 320*200, 1);
  move_b_sm = do_move_b( scratch, SCR, 320*200, LOOPS);
  move_w_sm = do_move_w( scratch, SCR, 320*200, LOOPS);
  move_l_sm = do_move_l( scratch, SCR, 320*200, LOOPS);

  do_move_b( scratch, buf, 320*200, 1);
  move_b_mm = do_move_b( scratch, buf, 320*200, LOOPS);
  move_w_mm = do_move_w( scratch, buf, 320*200, LOOPS);
  move_l_mm = do_move_l( scratch, buf, 320*200, LOOPS);

  do_move_b( SCR, SCR+320, 320*199, 1);
  move_b_ss = do_move_b( SCR,     SCR+320, 320*199, LOOPS);
  move_w_ss = do_move_w( SCR,     SCR+320, 320*199, LOOPS);
  move_l_ss = do_move_l( SCR,     SCR+320, 320*199, LOOPS);

  do_set_b ( scratch, white, 320*200, 1);
  set_b_m   = do_set_b ( scratch, white,   320*200, LOOPS);
  set_w_m   = do_set_w ( scratch, white,   320*200, LOOPS);
  set_l_m   = do_set_l ( scratch, white,   320*200, LOOPS);

  do_set_b ( SCR, black, 320*200, 1);
  set_b_s   = do_set_b ( SCR,     white,   320*200, LOOPS);
  set_w_s   = do_set_w ( SCR,     white,   320*200, LOOPS);
  set_l_s   = do_set_l ( SCR,     white,   320*200, LOOPS);

  GrSetMode( GR_80_25_text);

  printf( "move byte (memory -> memory) : %8.2f kb/s\n", KB(move_b_mm));
  printf( "move word (memory -> memory) : %8.2f kb/s\n", KB(move_w_mm));
  printf( "move long (memory -> memory) : %8.2f kb/s\n", KB(move_l_mm));
  printf( "move byte (memory -> screen) : %8.2f kb/s\n", KB(move_b_ms));
  printf( "move word (memory -> screen) : %8.2f kb/s\n", KB(move_w_ms));
  printf( "move long (memory -> screen) : %8.2f kb/s\n", KB(move_l_ms));
  printf( "move byte (screen -> memory) : %8.2f kb/s\n", KB(move_b_sm));
  printf( "move word (screen -> memory) : %8.2f kb/s\n", KB(move_w_sm));
  printf( "move long (screen -> memory) : %8.2f kb/s\n", KB(move_l_sm));
  printf( "move byte (screen -> screen) : %8.2f kb/s\n", KB(move_b_ss));
  printf( "move word (screen -> screen) : %8.2f kb/s\n", KB(move_w_ss));
  printf( "move long (screen -> screen) : %8.2f kb/s\n", KB(move_l_ss));
  printf( "set  byte (memory)           : %8.2f kb/s\n", KB(set_b_m));
  printf( "set  word (memory)           : %8.2f kb/s\n", KB(set_w_m));
  printf( "set  long (memory)           : %8.2f kb/s\n", KB(set_l_m));
  printf( "set  byte (screen)           : %8.2f kb/s\n", KB(set_b_s));
  printf( "set  word (screen)           : %8.2f kb/s\n", KB(set_w_s));
  printf( "set  long (screen)           : %8.2f kb/s\n", KB(set_l_s));
}

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019