home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_08_10 / 8n10101a < prev    next >
Text File  |  1990-07-28  |  10KB  |  294 lines

  1.  
  2. /* Copyright 1990 by Gary R. Olhoeft 
  3.  * This code may be freely copied for personal,
  4.  * non-commercial use. compile using MicroWay's 
  5.  * NDP C-386 compiler:
  6.  *   cc graphics.c -w -v -rt2 -n2 -n3 -lGREX.LIB
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <dos.h>
  11. #include <grex.h>
  12.  
  13. void plot_pixel();
  14. void graphics();  
  15. void spectrum();
  16. void ext_palette();
  17.  
  18. union REGS reg;    /* required by inline assembly */
  19. int v_mode, v_color, v_rowy, v_colx, page;
  20. unsigned short ati_extreg;
  21. char ega_palette[17] = {0,1,9,11,3,19,2,18,6,54,38,
  22.                         52,4,36,41,13,0};
  23. int modes[] = {0x0d,0x0e,0x10,0x12,0x13,0x54,
  24.                0x62,0x63,0x65};
  25. void main()
  26. {
  27.   int i,x,y,key;
  28.   unsigned char color;
  29.   for (i=0; i<9; i++)
  30.     {
  31.       graphics(modes[i]); /* cycle through ATI VGA 
  32.                             Wonder graphics modes */
  33.       printf("Mode %d %dx%dx%d\n",v_mode,v_colx+1,
  34.                v_rowy+1,v_color+1);
  35.       /* printing shrinks as pixel count increases */
  36.       spectrum();
  37.       /* draw banded color lines on screen */
  38.       for (x = 0; x<=v_colx>>2; x++) 
  39.         {
  40.           for (y = 0; y<=v_rowy; y++)
  41.             {
  42.                color = y % v_color;    
  43.                plot_pixel(x+y,y,color);
  44.             }  
  45.         }
  46.       /* pause loop until keypress; 
  47.           exit with ^C or Esc */
  48.       if ((key=pauseb())==27) {
  49.           set_video_mode(0x02); exit();
  50.           }
  51.       }
  52.   set_video_mode(0x02); /* restore text mode */
  53.   exit();
  54. }
  55.  
  56. void graphics(mode)
  57. unsigned char mode;
  58. {
  59.    unsigned char buffer[2];
  60.    switch (mode) /* note: not all possible modes shown */
  61.      {
  62.        case 0x0d: /* EGA */
  63.           v_colx = 320;
  64.           v_rowy = 200;
  65.           v_color = 16;
  66.           break;
  67.        case 0x0e: /* EGA */
  68.           v_colx = 640;
  69.           v_rowy = 200;
  70.           v_color = 16;
  71.           break;
  72.        case 0x10: /* EGA high resolution */
  73.           v_colx = 640;
  74.           v_rowy = 350;
  75.           v_color = 16;
  76.           break;
  77.        case 0x12: /* VGA */
  78.           v_colx = 640;
  79.           v_rowy = 480;
  80.           v_color = 16;
  81.           break;
  82.        case 0x13: /* MCGA */
  83.           v_colx = 320;
  84.           v_rowy = 200;
  85.           v_color = 256;
  86.           break;
  87.        case 0x54: /* ATI SVGA */  
  88.           v_colx = 800; 
  89.           v_rowy = 600;
  90.           v_color = 16;
  91.           break;
  92.        case 0x62: /* ATI SVGA */  
  93.           v_colx = 640;
  94.           v_rowy = 480;
  95.           v_color = 256;
  96.           break;
  97.        case 0x63: /* ATI SVGA */  
  98.           v_colx = 800;
  99.           v_rowy = 600;
  100.           v_color = 256;
  101.           break;
  102.        case 0x65: /* ATI SVGA */
  103.           v_colx = 1024;
  104.           v_rowy = 768;
  105.           v_color = 16;
  106.           break;
  107.        default:
  108.           mode = 0x02; /* text mode */
  109.           v_colx = 80;
  110.           v_rowy = 25;
  111.           v_color = 1;
  112.           break;
  113.      }
  114.      v_mode = mode;
  115.      v_colx--; /* set ranges 0 to pixels-1 */
  116.      v_rowy--;
  117.      v_color--;
  118.  
  119.      reg.b.ah = 0;
  120.      reg.b.al = mode;
  121.      int386(0x10,®,®); /* call BIOS video 
  122.                          interrupt to set mode */
  123.  
  124.      blk_mb(buffer, 0x34, 786448, 2);
  125.      ati_extreg = buffer[0]+256*buffer[1];
  126.          /* find ATI extended_reg address 
  127.                (could use peek() instead)*/
  128.      page = 99; /* force paging first plot cycle */
  129.  } 
  130.  
  131. /* plot pixel of color at (x,y) display units */
  132. void plot_pixel(x,y,color) 
  133. int x,y;
  134. unsigned char color;
  135. {
  136. #define peek(addr, val) asm("     push   es"); \
  137.         asm("     mov   ax, 034h"); asm("     mov   \
  138.         es, ax"); ebx = addr; asm(ebx, "     mov   \
  139.         cl, byte ptr es:[ebx]", cl); val = cl; asm\
  140.         ("     pop   es")
  141. #define poke(addr, val) asm("     push   es"); \
  142.         cl = val; asm("     mov   ax, 034h"); \
  143.         asm("     mov   es, ax"); ebx = addr; \
  144.         asm(ebx, cl, "     mov   byte ptr es:[ebx], \
  145.         cl"); asm("     pop   es")
  146.      /* required by inline assembly */
  147.      reg$eax unsigned short ax; 
  148.      reg$eax unsigned char al;
  149.      reg$ah unsigned char ah;
  150.      reg$ecx unsigned short cx;
  151.      reg$ch unsigned char ch;
  152.      reg$ecx unsigned char cl;
  153.      reg$edx unsigned short dx;
  154.      reg$edx unsigned char dl, val;
  155.      reg$ebx unsigned ebx, addr;
  156.      int i,vcol,yvx;
  157.      if ((y < 0) || (y > v_rowy) || (x < 0) || 
  158.         (x > v_colx)) return; 
  159.            /* clip physical display boundaries */
  160.      y = v_rowy-y; /* put (0,0) at lower left corner of plotter */
  161.      vcol = v_colx+1;
  162.      yvx = y*vcol + x;
  163.      switch (v_mode)
  164.        {
  165.          case 0x65: /* ATI 1024x768x16 */
  166.            ch = (char)(y >> 6);
  167.            if (ch!=page) /* only change page if different */
  168.              {
  169.                dx = ati_extreg; /* location of ATI card external register */
  170.                asm("     cli     ");         /* disable interrupts */
  171.                asm("     mov     al,0b2h");  /* page select */
  172.             asm(dx,"     out     dx,al");    /* ATI extended register */
  173.                asm("     inc     dl");
  174.                asm("     in      al,dx");
  175.                asm("     mov     ah,al");
  176.                asm("     and     ah,0e1h");  /* page mask */
  177.             asm(ch,"     or      ah,ch");    /* ch = memory page desired */
  178.                asm("     mov     al,0b2h");  /* page select */
  179.                asm("     dec     dl");
  180.                asm("     out     dx,ax");
  181.                asm("     sti     ");         /* enable interrupts */
  182.                page = ch;
  183.              }
  184.            addr = 655360 + ((y << 9) % 65536) + (x >> 1);
  185.            peek(addr, val); /* read existing color of pixel pair */
  186.            if (x % 2) val = color | (val & 0xF0); /* change addressed pixel */
  187.            else val = (color << 4) | (val & 0x0F);
  188.            poke(addr, val); /* write pixel pair */
  189.            break;
  190.          case 0x13: /* MCGA 320x200x256 */
  191.            addr = 655360 + yvx;
  192.            poke(addr, color); /* write direct to real video memory */
  193.            break;
  194.          case 0x62: /* ATI 640x480x256 */
  195.          case 0x63: /* ATI 800x600x256 */
  196.            ch = (unsigned char)(yvx >> 15); 
  197.            if (ch!=page)
  198.              {
  199.                dx = ati_extreg; /* location of ATI card external register */
  200.                asm("     cli     ");         /* disable interrupts */
  201.                asm("     mov     al,0b2h");  /* page select */
  202.             asm(dx,"     out     dx,al");    /* ATI extended register */
  203.                asm("     inc     dl");
  204.                asm("     in      al,dx");
  205.                asm("     mov     ah,al");
  206.                asm("     and     ah,0e1h");  /* page mask */
  207.             asm(ch,"     or      ah,ch");    /* ch = memory page desired */
  208.                asm("     mov     al,0b2h");  /* page select */
  209.                asm("     dec     dl");
  210.                asm("     out     dx,ax");
  211.                asm("     sti     ");         /* enable interrupts */
  212.                page = ch;
  213.              }
  214.            addr = 655360 + (yvx % 65536);
  215.            poke(addr, color); /* write direct to real video memory */
  216.            break;
  217.          default:
  218.          /* 0x10 EGA 640x350x16, 0x12 VGA 640x480x16, 0x54 ATI 800x600x16 */
  219.             asm("     push   es");       /* save segment register */
  220.             asm("     mov    ax, 034h"); /* use Phar Lap LDT to */
  221.             asm("     mov    es, ax");   /* access real memory */
  222.             dx = 0x3ce;                  /* EGA graphics register */
  223.             ebx= 655360 + (yvx >> 3);    /* memory position of pixel */
  224.         asm(ebx, "     mov    cl, byte ptr es:[ebx]"); /* load EGA registers */
  225.             ax = color << 8;
  226.     asm(dx, ax, "     out    dx, ax");   /* set color */
  227.             ax = 0x0F01;
  228.     asm(dx, ax, "     out    dx, ax");   /* enable */
  229.             ax = 0x0003; /* 0x00 = replace, 0x10 OR, 0x18 XOR, 0x08 AND */
  230.     asm(dx, ax, "     out    dx, ax");   /* pixel write mode */
  231.             ax = ((0x80 >> (x%8)) << 8 ) + 8;
  232.     asm(dx, ax, "     out    dx, ax");   /* bit mask (8 pixels/byte) */
  233.        asm(ebx, "     mov    byte ptr es:[ebx], 255"); /* write EGA regs */
  234.             asm("     pop    es");       /* restore segment register */
  235.        }
  236. }
  237.  
  238. void spectrum() /* create color spectrum palette */
  239. {
  240.      int i;
  241.      if (v_mode == 0x65) /* 1024x768x16 mode only */
  242.        {
  243.          ext_palette( 0,  0,  0,  0); /* black */
  244.          ext_palette( 1, 63,  0,  0); /* red */
  245.          ext_palette( 2, 63, 21,  0);
  246.          ext_palette( 3, 63, 42,  0);
  247.          ext_palette( 4, 63, 63,  0); /* yellow */
  248.          ext_palette( 5, 42, 63,  0);
  249.          ext_palette( 6, 21, 63,  0);
  250.          ext_palette( 7,  0, 63,  0); /* green */
  251.          ext_palette( 8,  0, 63, 21);
  252.          ext_palette( 9,  0, 63, 42);
  253.          ext_palette(10,  0, 63, 63); /* cyan */
  254.          ext_palette(11,  0, 42, 63);
  255.          ext_palette(12,  0, 21, 63);
  256.          ext_palette(13,  0,  0, 63); /* blue */
  257.          ext_palette(14, 21,  0, 63);
  258.          ext_palette(15, 42,  0, 63); /* magenta */
  259.        }
  260.      else
  261.        {
  262.          if (v_color == 255) /* all 256 color modes */
  263.            {
  264.              vga_palette(0,0,0,0);
  265.              for (i=1; i<=64; i++) { vga_palette(i,63,i-1,0); }
  266.              for (i=65; i<=128; i++) { vga_palette(i,128-i,63,0); }
  267.              for (i=129; i<=192; i++) { vga_palette(i,0,63,i-129); }
  268.              for (i=193; i<=255; i++) { vga_palette(i,0,255-i,63); }
  269.            }
  270.          else
  271.            { /* 16 color EGA modes except 1024x768 */
  272.              set_palette(ega_palette);
  273.            }
  274.        }
  275. }
  276.  
  277. void ext_palette(i,r,g,b) /* write to external palette registers */
  278. unsigned char i,r,g,b;
  279. {
  280. #define outp(p,v) dx = p; al = v; asm(dx,al,"     out     dx,al")
  281.      reg$eax unsigned char al,v;
  282.      reg$edx unsigned short dx,p;
  283.      outp(0x3C8, i);
  284.      outp(0x3C9, r);
  285.      outp(0x3C9, g);
  286.      outp(0x3C9, b);
  287.      outp(0x3C8, i<<4);
  288.      outp(0x3C9, r);
  289.      outp(0x3C9, g);
  290.      outp(0x3C9, b);
  291. }
  292.  
  293.  
  294.