home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_03 / 2n03038a < prev    next >
Text File  |  1991-01-31  |  18KB  |  421 lines

  1.  
  2. /* plot1024.c Copyright 1990 by Gary R. Olhoeft */
  3. /* 
  4.    Compile with the MicroWay NDP C-386 v2.1.0 compiler and run
  5.    with the Phar Lap 386|DOS extender. 
  6. */
  7. #include <dos.h>
  8. #include <stdio.h>
  9. #include <math.h>
  10. #include <grex.h>    /* MicroWay NDP C-386 extended graphics library */
  11. #include <reg8514.h> /* VESA 8514/A registers after Richter & Smith (1990) */
  12. #define outpw(p,v) dx = p; ax = v; asm(dx,ax,"     out     dx,ax")
  13. unsigned char **image();
  14. void free_image();
  15. void plot_image_tseng();
  16. void grey_vga();
  17. void plot_image_hgsc();
  18. void grey_hgsc();
  19. void plot_image_8514();
  20. void grey_8514();
  21. void set_hgsc();
  22.   union REGS reg;                      /* required by DOS INT */
  23.   int _pmode;
  24. /* VESA 8514/A 1024x768x256 timing control register parameters */
  25.   static short  initRegs[] =
  26.       { DISP_CNTL, ADVFUNC_CNTL, V_TOTAL, V_SYNC_STRT,
  27.         V_DISP, H_TOTAL, H_SYNC_STRT, H_DISP,
  28.         H_SYNC_WID, V_SYNC_WID, DISP_CNTL, 0 };
  29.   static short  mode1024x8[] =
  30.       { 0x0053, 0x0007, 0x0660, 0x0600,
  31.         0x05FB, 0x009D, 0x0081, 0x007F,
  32.         0x0016, 0x0008, 0x0033 };
  33.   int _pmode;
  34.   unsigned char hpgl_page;
  35.  
  36. main ()
  37.   {
  38.   reg$eax unsigned short ax, v; /* required by inline assembler */
  39.   reg$edx unsigned short dx, p;
  40.   FILE *stream_in;
  41.   char file_in[80];  
  42.   unsigned char str[4096], **image_array;
  43.   int i,j,k;
  44.   char hstr[20];
  45.   asm("hstdata  equ  0C7000h");  /* HGSC 34010 host addresses */
  46.   asm("hstctrl  equ  0C7D00h");  /* for inline assembler use */
  47.   asm("hstadrl  equ  0C7E00h");
  48.   asm("hstadrh  equ  0C7F00h");  
  49.   _pmode=0x8000;                 /* binary disk access */
  50.  
  51. /* read in the image to be displayed (Jupiter's moon Io from Voyager I) */
  52.     strcpy(file_in,"e:\\img\\c1636828.img\0"); 
  53.     if ((stream_in = fopen(file_in,"r")) == NULL)
  54.        {
  55.          printf("Cannot find File %s\n",file_in); exit(0);
  56.        }
  57.     else
  58.        {
  59.          printf("Reading Image File %s\n",file_in);
  60.          i=fread(str,1,2*836,stream_in); /* ignore PDS header */
  61.          image_array = image(768,1024);  /* create space for image */
  62.          for (i=0; i<768; i++) fread(&image_array[i][0], 1, 836, stream_in);
  63.          i=fclose(stream_in);
  64.        }
  65.      
  66. /* Tseng 4000 STB EM-16 Plus PowerGraph 1024x768x256 */
  67.     blk_mb(str, 0x34, 0xC0000, 500); /* read BIOS area */
  68.     k = -1;
  69.     strcpy(hstr," STB \0");
  70.     for (i=0; i<480; i++) {j = memcmp(str+i,hstr,5); if (j==0) k=j;}
  71.     if (k != -1)
  72.       {
  73.         k = -1;
  74.         strcpy(hstr,"AWARD\0");
  75.         for (i=0; i<480; i++) { j = memcmp(str+i,hstr,5); if (j==0) k = j;}
  76.         if (k != -1) /* Tseng 4000 (STB EM-16 Plus PowerGraph) found */
  77.           {
  78.             reg.b.ah = 0;
  79.             reg.b.al = 56; 
  80.             int386(0x10,®,®);        /* set mode */
  81.             /* set grey scale using MicroWay libGREX palette function */
  82.             /* up to 2. sec */    
  83.             for (i=0; i<256; i++) {j = i>>2; vga_palette(i,j,j,j);}
  84.             plot_image_tseng(image_array); /* plot image in 0.193 sec */
  85.             getch();                       /* wait for keypress */
  86.           }
  87.       }
  88.  
  89. /* IBM 8514/A 1024x768x256 setup after Richter and Smith (1990) */
  90.     outp(DAC_MASK, 0x00); /* blank screen by turning all planes off */
  91.     outpw(SUBSYS_CNTL, GPCTRL_RESET | CHPTEST_NORMAL); /* reset 8514/A */
  92.     outpw(SUBSYS_CNTL, GPCTRL_ENAB | CHPTEST_NORMAL);
  93.     outpw(ERR_TERM, 0xFFFF);      /* test for 8514/A card */
  94.     if (inpw(ERR_TERM) == 0xFFFF) /* 8514/A card found */
  95.       {
  96.         i = inpw(SUBSYS_STAT);        /* get board status information */
  97.         if ((i & MONITORID_MASK) == MONITORID_8514) /* 1024x768 monitor */
  98.           {
  99.             outpw(MULTIFUNC_CNTL, MEM_CNTL | VRTCFG_4 | HORCFG_8);
  100.             i = 0; /* setup 1024x768 timing parameters */
  101.             while (initRegs[i]) { outpw(initRegs[i], mode1024x8[i]); i++;}
  102.             outpw(DAC_MASK, 0xFF);        /* enable all 8 planes */
  103.             outpw(FRGD_MIX, FSS_FRGDCOL | MIX_REPLACE);
  104.             outpw(BKGD_MIX, BSS_BKGDCOL | MIX_REPLACE);
  105.             /* clip to full drawable space (0,0 to 1023,1023) */
  106.             outpw(MULTIFUNC_CNTL, SCISSORS_T | 0x000);
  107.             outpw(MULTIFUNC_CNTL, SCISSORS_L | 0x000);
  108.             outpw(MULTIFUNC_CNTL, SCISSORS_B | 0x3FF);
  109.             outpw(MULTIFUNC_CNTL, SCISSORS_R | 0x3FF);
  110.             outpw(WRT_MASK, 0xFFFF);      /* enable writes to all planes */
  111.             outpw(MULTIFUNC_CNTL, PIX_CNTL | 0); /* clear lower bits */
  112.             WaitQueue(6);                 /* wait until 8514 queue ready */
  113.             outpw(FRGD_COLOR, 0);         /* set color */
  114.             outpw(CUR_X, 0);              /* set origin */
  115.             outpw(CUR_Y, 0);
  116.             outpw(MAJ_AXIS_PCNT, 1023);   /* set size */
  117.             outpw(MULTIFUNC_CNTL, MIN_AXIS_PCNT | 1023);
  118.             outpw(CMD, CMD_RECT | INC_Y | INC_X | DRAW | PLANAR | WRTDATA);
  119.             WaitQueue(4);
  120.             outpw(CUR_X, 0);              /* reset draw position to (0,0) */
  121.             outpw(CUR_Y, 0);
  122.             outpw(FRGD_COLOR, 0xFFFF);    /* foreground all on */
  123.             outpw(BKGD_COLOR, 0);         /* background all off */
  124.             grey_8514();                  /* setup 8514 grey scale 0.00087 sec*/
  125.             outpw(FRGD_MIX, FSS_PCDATA | MIX_REPLACE);
  126.             plot_image_8514(image_array); /* plot image in 0.385 sec */
  127.             getch();                      /* wait for key press */
  128.             outpw(ADVFUNC_CNTL, 6);       /* restore 8514/A to VGA */
  129.           }
  130.       }
  131.  
  132. /* Hercules Graphics Station Card GB1024 TI34010 1024x768x256 */
  133.     blk_mb(str, 0x34, 0xC0000, 500); /* read BIOS area */
  134.     k = -1;
  135.     strcpy(hstr,"Hercules\0");
  136.     for (i=0; i<480; i++) {j = memcmp(str+i,hstr,8); if (j==0) k=j;}
  137.     if (k != -1)
  138.       {
  139.         k = -1;
  140.         strcpy(hstr,"Graphics Station\0");
  141.         for (i=0; i<480; i++) { j = memcmp(str+i,hstr,16); if (j==0) k = j;}
  142.         if (k != -1)                       /* HGSC found */
  143.           {
  144.             set_hgsc();                    /* set 34010 mode 1024x768 */
  145.             grey_hgsc();                   /* setup grey scale 0.00082 sec */
  146.             plot_image_hgsc(image_array);  /* plot image in 0.275 sec */
  147.             getch();                       /* wait for key press */
  148.             setvga();                      /* restore HGSC to VGA modes */
  149.             /* setvga is found in TECH Specialist, v.1, n.5, p.35 */
  150.           }
  151.       }
  152.  
  153.     free_image(image_array, 768);     /* free image memory */
  154.     set_video_mode(0x02);             /* restore text mode */
  155.  
  156. unsigned char **image(row,col)
  157. int row,col;
  158. {   /* allocates 8-bit 2D image matrix with range [0...row-1][0...col-1] */
  159.     int i;
  160.     unsigned char **m; /* no error checking: assumes enough memory exists */
  161.     m = (unsigned char **) malloc((unsigned)(row)*sizeof(unsigned char *));
  162.     for (i=0; i<row; i++)
  163.        m[i] = (unsigned char *) malloc((unsigned)(col)*sizeof(unsigned char));
  164.     return m;
  165. }
  166.  
  167. void free_image(m,row)
  168. unsigned char **m;
  169. int row;
  170. {        /* frees memory malloc'd by image function in Listing 2 */
  171.     int i;
  172.     for (i=row-1; i>=0; i--) free(m[i]);
  173.     free(m);
  174. }
  175.  
  176. void plot_image_tseng(image_array) /* Tseng 4000 chipset 1024x768x256 */
  177. unsigned char **image_array;
  178.     reg$eax unsigned short ax; /* required by inline assembler */
  179.     reg$esi unsigned esi;
  180.     reg$edi unsigned edi;
  181.     reg$ecx unsigned ecx;
  182.     int j, jj, k, vcol, row;
  183.     unsigned int cm;
  184.     unsigned short pel;
  185.     vcol = 1024;                        /* length of horizontal screen row */
  186.     row = -vcol;
  187.     asm("     push   es");              /* save es register */
  188.     asm("     mov    ax, 034h");        /* set Phar Lap LDT to access */
  189.     asm("     mov    es, ax");          /* first megabyte of real memory */
  190.     hpgl_page = 99;                     /* force first page */
  191.     for (j=0; j<768; j++)               /* vertical lines (rows) on screen */
  192.       {
  193.         row += vcol;
  194.         ax = (unsigned char)(row >> 16);/* divide by 64k to determine page */ 
  195.         if (ax!=hpgl_page)              /* don't page unless changed */
  196.           {
  197.             hpgl_page = ax;             /* save new page */
  198.             asm("     pushfd");         /* save flags */
  199.             asm("     cli     ");       /* clear interrupts */
  200.          asm(ax,"     or      al,40h"); /* 8 64k pages */
  201.             asm("     mov     dx,3cdh");/* GDC segment select register */
  202.             asm("     out     dx,al");  /* select page */
  203.             asm("     popfd     ");     /* restore flags */
  204.           }
  205.         esi = &image_array[j][0];       /* 386 address of image row */
  206.         cm = (row % 65536);             /* determine where in 64k page */
  207.         edi = 655360 + cm;              /* VGA video address of row */
  208.         ecx = 256;                      /* number of pixels/4 to move */
  209.         asm(ecx,esi,edi, " rep movsd"); /* 256 double word mov's */
  210.       }
  211.     asm("     pop    es");              /* restore es register */
  212. }
  213.  
  214.  
  215. void grey_8514()
  216. {
  217.   asm("     xor    eax,eax");        /* eax = 0 */
  218.   asm("     mov    dx,02ECh");          
  219.   asm("     out    dx,al");          /* starting palette index */
  220.   asm("     mov    dx,02EDh");
  221.   asm("     xor    ebx,ebx");        /* ebx = 0 */
  222.   asm("lll: mov    eax,ebx");
  223.   asm("     shr    eax,2");          /* divide by 4 for 6-bit palette */
  224.   asm("     out    dx,al");          /* red */
  225.   asm("     out    dx,al");          /* green */
  226.   asm("     out    dx,al");          /* blue */
  227.   asm("     inc    ebx"); 
  228.   asm("     cmp    ebx,256");        /* 256 palette entries */
  229.   asm("     jl     lll");
  230. }
  231.  
  232. void plot_image_8514(image_array)
  233. unsigned char **image_array;
  234.   reg$eax unsigned eax;                /* required by inline assembler */
  235.   reg$eax unsigned short ax, v;
  236.   reg$ecx unsigned ecx;
  237.   reg$edx unsigned short dx, p;
  238.   reg$esi unsigned esi;
  239.   int i;
  240.   unsigned short pel;
  241.   WaitQueue(8);                        /* wait until queue is empty */
  242.   outpw(MULTIFUNC_CNTL, 0);            /* line width 0 = single pixel */
  243.   outpw(MAJ_AXIS_PCNT, 1023);          /* line length = 1024 pixels */
  244.   pel = BYTSEQ | _16BIT | CMD_LINE | PCDATA | LINETYPE | DRAW | WRTDATA;
  245.   for (i=0; i<768; i++)                /* cycle through rows (y) */
  246.     {
  247.       outpw(CUR_Y, (short)(i));        /* y position in 8514/A memory */
  248.       outpw(CUR_X, 0);                 /* x position in 8514/A memory */
  249.       outpw(CMD, pel);                 /* setup transfer command */
  250.       dx = PIX_TRANS;                  /* port for transfer to 8514 */
  251.       ecx = 512;                       /* 16-bit words to move */
  252.       esi = &image_array[i][0];        /* address of line in 386 memory */
  253.       asm(dx, esi, ecx, "rep   outsw");/* send whole line of pixel pairs */
  254.     }
  255. }
  256.  
  257. void set_hgsc()
  258. {
  259.   asm("     push    es");        /* save es register */
  260.   asm("     mov     ax,034h");   /* setup Phar Lap LDT to first MByte */
  261.   asm("     mov     es,ax");
  262.   asm("     mov     cx,0C000h");
  263.   asm("     mov     ax,0B040h"); /* dpyctl = enable video, interlaced */
  264.   asm("     and     ax,7FFFh");  /* blank video */
  265.   asm("     mov     bx,80h");
  266.   asm("     call    write");     /* write ax to cx:bx in 34010 */
  267.   asm("     mov     ax,157");    /* htotal */
  268.   asm("     mov     bx,30h");   
  269.   asm("     call    write");  
  270.   asm("     mov     ax,156");    /* hsblnk; hsblnk-heblnk = 1024/8 */
  271.   asm("     mov     bx,20h");   
  272.   asm("     call    write");     
  273.   asm("     mov     ax,28");     /* heblnk; increase to move screen right */
  274.   asm("     mov     bx,10h");   
  275.   asm("     call    write");     
  276.   asm("     mov     ax,21");     /* hesync */
  277.   asm("     mov     bx,0");     
  278.   asm("     call    write"); 
  279.   asm("     mov     ax,407");    /* vtotal */
  280.   asm("     mov     bx,70h");   
  281.   asm("     call    write");   
  282.   asm("     mov     ax,405");    /* vsblnk; vsblnk-veblnk = 768/2 */
  283.   asm("     mov     bx,60h");   
  284.   asm("     call    write");   
  285.   asm("     mov     ax,21");     /* veblnk; increase to move screen down */
  286.   asm("     mov     bx,50h");   
  287.   asm("     call    write");    
  288.   asm("     mov     ax,4");      /* vesync */
  289.   asm("     mov     bx,40h");   
  290.   asm("     call    write");   
  291.   asm("     mov     ax,0");      /* dpytap */
  292.   asm("     mov     bx,1B0h");  
  293.   asm("     call    write");   
  294.   asm("     mov     ax,0FFFCh"); /* dpystrt; 1 scan line per refresh */
  295.   asm("     mov     bx,90h"); 
  296.   asm("     call    write");   
  297.   asm("     mov     cx,600h");      
  298.   asm("     mov     bx,0E0h");   /* 0600:00E0 write config.2 reg. */
  299.   asm("     mov     ax,0Fh");    /* bppsync = 8 bpp, -horz, -vert sync */
  300.   asm("     call    write");
  301.   asm("     mov     bx,0C0h");   /* 0600:00C0 write config.1 reg. */
  302.   asm("     mov     ax,12");     /* cmdfreq = 44.9 MHz, cmd & overlay */
  303.   asm("     call    write");
  304.   asm("     mov     bx,20h");    /* 0600:0020 = cmd register in DAC */
  305.   asm("     mov     ax,05Bh");   /* daclut = 8bpp + 24-bit LUT, no overlay */
  306.   asm("     call    write");
  307.   asm("     mov     bx,0C0h");   /* 0600:00C0 = write config. 1 */
  308.   asm("     mov     ax,4");      /* normfreq = 44.9 Mhz, normal palette */
  309.   asm("     call    write");
  310.   asm("     mov     ax,0C000h"); /* no autoincrement */
  311.   asm("     mov     es:hstctrl,ax"); /* setup 34010 */
  312.   asm("     mov     cx,0C000h");
  313.   asm("     mov     ax,0B040h"); /* dpyctl */
  314.   asm("     mov     bx,80h");
  315.   asm("     call    write");     /* enable video */
  316.   asm("     pop     es");        /* restore es register */
  317.   asm("     ret");               /* return to calling program */
  318.  
  319.   asm("write   proc    near");   /* create subroutine */
  320.   asm("        mov     es:hstadrl,bx");  
  321.   asm("        mov     es:hstadrh,cx");  
  322.   asm("        mov     es:hstdata,ax"); /* write ax to cx:bx */
  323.   asm("        ret");
  324.   asm("write   endp");
  325. }
  326.  
  327. void grey_hgsc()
  328. {
  329.   asm("     push   es");             /* save es register */
  330.   asm("     mov    ax,034h");        /* setup Phar Lap LDT to first Mbyte */
  331.   asm("     mov    es,ax");
  332.   asm("     pushfd");                /* save flags */
  333.   asm("     cli");                   /* disable interrupts */
  334.   asm("     mov    ax,0C000h");
  335.   asm("     mov    es:hstctrl,ax");  /* turn off autoincrement */
  336.   asm("     mov    ax,01E0h");
  337.   asm("     mov    es:hstadrl,ax");
  338.   asm("     mov    ax,0600h");
  339.   asm("     mov    es:hstadrh,ax");  
  340.   asm("     mov    cx,es:hstdata");  /* read & save config 2 */
  341.   asm("     mov    ax,80h");
  342.   asm("     mov    es:hstadrl,ax");
  343.   asm("     mov    ax,0C000h");
  344.   asm("     mov    es:hstadrh,ax");
  345.   asm("     mov    ax,es:hstdata");  /* read dpyctl */
  346.   asm("     push   eax");            /* save eax (dpyctl) */
  347.   asm("     and    ax,7FFFh");
  348.   asm("     mov    es:hstdata,ax");  /* blank video */
  349.   asm("     mov    ax,00E0h");
  350.   asm("     mov    es:hstadrl,ax");
  351.   asm("     mov    ax,0600h");
  352.   asm("     mov    es:hstadrh,ax");  
  353.   asm("     mov    ax,0Ch");         /* -H -V sync VGA control VRAM */
  354.   asm("     mov    es:hstdata,ax");  /* write config 2 for VGA */
  355.   asm("     xor    eax,eax");        /* can only change palette in VGA */
  356.   asm("     mov    dx,03C8h");
  357.   asm("     out    dx,al");          /* starting palette index */
  358.   asm("     mov    dx,03C9h");
  359.   asm("     xor    eax,eax");
  360.   asm("ll:  out    dx,al");          /* red */
  361.   asm("     out    dx,al");          /* green */
  362.   asm("     out    dx,al");          /* blue */
  363.   asm("     inc    eax"); 
  364.   asm("     cmp    eax,256");        /* 256 palette entries */
  365.   asm("     jl     ll");
  366.   asm("     mov    es:hstdata,cx");  /* restore original config 2 */
  367.   asm("     mov    ax,80h");
  368.   asm("     mov    es:hstadrl,ax");
  369.   asm("     mov    ax,0C000h");
  370.   asm("     mov    es:hstadrh,ax");
  371.   asm("     pop    eax");            /* get saved eax */
  372.   asm("     mov    es:hstdata,ax");  /* restore dpyctl, enable video */
  373.   asm("     popfd");                 /* restore flags (interrupts) */
  374.   asm("     pop    es");             /* restore es register */
  375. }
  376.  
  377. void plot_image_hgsc(image_array)   /* 1024x768x256 HGSC */
  378. unsigned char **image_array;
  379.   reg$ebx unsigned ebx;             /* required by inline assembler */
  380.   reg$esi unsigned esi;
  381.   esi = &image_array[0][0];         /* image array address in 386 memory */
  382.   ebx = 12;                         /* lines = height/64 */
  383.   asm(esi,ebx,"     push   es");    /* send esi & ebx to assembler, save es */
  384.   asm("     mov    ax,034h");       /* setup Phar Lap LDT to first Mbyte */
  385.   asm("     mov    es,ax");
  386.   asm("     mov    ax,0D800h");
  387.   asm("     mov    es:hstctrl,ax"); /* setup 34010 for transfer */
  388.   asm("     cld");                  /* set direction of movsd */
  389.   asm("     xor    eax,eax");       /* eax = 0 */
  390.   asm("     mov    es:hstadrl,ax");
  391.   asm("     mov    es:hstadrh,ax"); /* starting address in 34010 memory */
  392.   asm("     mov    dx,46E8h");
  393.   asm("     out    dx,ax");         /* disable VGA */ 
  394.  
  395.   asm("     align  4");
  396.   asm("slp: lea    edi,es:[655360]"); /* starting address of hstdata shadow */
  397.   asm("     mov    eax,64");        /* 64 lines per shadow page */
  398.   asm("llp: mov    ecx,256");       /* 256 double words per 1024 pixel line */
  399.   asm("rep  movsd");                /* move 1024 pixel line */
  400.   asm("     add    esi,8");         /* skip array pointers */
  401.   asm("     dec    eax");
  402.   asm("     cmp    eax,0");
  403.   asm("     jnz    llp");           /* loop 64 lines/page */
  404.   asm("     dec    ebx");
  405.   asm("     cmp    ebx,0");
  406.   asm("     jnz    slp");           /* loop 12 pages/image */
  407.  
  408.   asm("     mov    dx,46E8h");
  409.   asm("     mov    ax,0Eh");
  410.   asm("     out    dx,ax");         /* enable VGA */
  411.   asm("     mov    ax,0C000h");     /* turn off autoincrement */
  412.   asm("     mov    es:hstctrl,ax");
  413.   asm("     pop    es");            /* restore es register */
  414. }
  415.  
  416.  
  417.