Date: Thu, 22 Jul 1993 14:59:14 +0200 Conversion: Prohibited From: "22-JUL-1993 13:55:32.83" 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 #include #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 # include # 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)); }