home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / vol_300 / 343_01 / display.c < prev    next >
C/C++ Source or Header  |  1992-04-20  |  23KB  |  876 lines

  1.  
  2.  
  3.        /*****************************************************
  4.        *
  5.        *       file d:\cips\display.c
  6.        *
  7.        *       Functions: This file contains
  8.        *          display_image
  9.        *          display_image_portion
  10.        *          display_menu_for_display_image
  11.        *          map_16_shades_of_gray
  12.        *          transform_the_colors
  13.        *
  14.        *       Purpose:
  15.        *          These functions display images on a the
  16.        *          monitor.
  17.        *
  18.        *       External Calls:
  19.        *          rtiff.c - read_tiff_image
  20.        *          cips.c - clear_text_screen
  21.        *          hist.c - zero_histogram
  22.        *                   calculate_histogram
  23.        *                   perform_histogram_equalization
  24.        *
  25.        *       Modifications:
  26.        *          17 June 1987 - created
  27.        *          August 1990 - extension modifications for use
  28.        *              in the C Image Processing System.
  29.        *
  30.        ********************************************************/
  31.  
  32.  
  33. #include "d:\cips\cips.h"
  34.  
  35.  
  36.  
  37.  
  38.  
  39.    /***************************
  40.    *
  41.    *   display_image(...
  42.    *
  43.    ****************************/
  44.  
  45.  
  46. display_image(file_name, image, il, ie, ll, le,
  47.               image_header, monitor_type, color_transform,
  48.               invert, image_colors, display_colors,
  49.               show_hist)
  50.    char    color_transform[],
  51.            file_name[],
  52.            monitor_type[];
  53.    int     display_colors,
  54.            image_colors,
  55.            invert,
  56.            il,
  57.            ie,
  58.            ll,
  59.            le,
  60.        show_hist;
  61.    short   image[ROWS][COLS];
  62.    struct  tiff_header_struct *image_header;
  63. {
  64.    char  channels[80],
  65.          response[80];
  66.  
  67.    int   a,
  68.          b,
  69.          c,
  70.          channel,
  71.          count,
  72.          display_mode,
  73.          dx_offset,
  74.          dy_offset,
  75.          key,
  76.          horizontal,
  77.          len,
  78.          max_horizontal,
  79.          max_vertical,
  80.          not_finished,
  81.          q,
  82.          r,
  83.          vertical,
  84.          x_offset,
  85.          y_offset;
  86.  
  87.    unsigned int block,
  88.                 color,
  89.                 i,
  90.                 j,
  91.                 x,
  92.                 y;
  93.    unsigned long histogram[256], new_hist[256];
  94.  
  95.  
  96.      /*************************************************
  97.      *
  98.      *   If you want to display the histogram and do not
  99.      *   want to perform hist equalization, then
  100.      *   zero the histogram for calculations.
  101.      *
  102.      *************************************************/
  103.  
  104.    if(  (show_hist == 1)   &&
  105.         (color_transform[0] != 'H'))
  106.       zero_histogram(histogram);
  107.  
  108.    not_finished = 1;
  109.    while(not_finished){
  110.  
  111.  
  112.       if(display_colors == 16){
  113.          if(monitor_type[0] == 'V'){
  114.             horizontal   = 4;
  115.         vertical = 6;
  116.         display_mode = _VRES16COLOR; /* MSC 6.0 */
  117.          }  /* ends if V */
  118.          if(monitor_type[0] == 'E'){
  119.             horizontal   = 3;
  120.             vertical     = 6;
  121.             display_mode = _ERESCOLOR; /* MSC 6.0 */
  122.          }  /* ends if E */
  123.  
  124.       }  /* ends if colors == 16 */
  125.  
  126.       else{
  127.          horizontal   = 2;
  128.          vertical     = 2;
  129.          display_mode = _MAXCOLORMODE; /* MSC 6.0 */
  130.       }
  131.  
  132.         /*************************************************
  133.         *
  134.         *   Somehow, my dx and dy offsets are backwards
  135.         *   from my horizontal and vertical variables.
  136.         *   Trying to center the images on the screen.
  137.         *   March 21 1992
  138.         *
  139.         *************************************************/
  140.  
  141.       max_horizontal = (image_header->image_length+50)/COLS;
  142.       max_vertical   = (image_header->image_width+50)/ROWS;
  143.  
  144.       dy_offset = ((horizontal-max_horizontal)/2)*COLS + 50;
  145.       dx_offset = ((vertical-max_vertical)/2)*ROWS + 20;
  146.  
  147.       if(max_horizontal > horizontal) dy_offset = 0;
  148.       if(max_vertical > vertical)     dx_offset = 0;
  149.  
  150.       if(horizontal > max_horizontal) horizontal = max_horizontal;
  151.       if(vertical > max_vertical)     vertical   = max_vertical;
  152.  
  153.  
  154.         /****************************************
  155.         *
  156.         *   If color transform wants histogram
  157.         *   equalization, then read in the
  158.         *   image arrays and calculate the
  159.         *   histogram.   Zero both the histogram
  160.         *   and the new_hist.  You will need the
  161.         *   new_hist if you want to display the
  162.         *   equalized hist.
  163.         *
  164.         *****************************************/
  165.  
  166.       if(color_transform[0] == 'H'){
  167.          count = 1;
  168.          zero_histogram(histogram);
  169.          zero_histogram(new_hist);
  170.          for(a=0; a<vertical; a++){
  171.             for(b=0; b<horizontal; b++){
  172.  
  173.                x = a*COLS;
  174.                y = b*ROWS;
  175.  
  176.                printf("\nDISPLAY> Calculating histogram");
  177.                printf(" %d of %d",count,vertical*horizontal);
  178.                count++;
  179.                read_tiff_image(file_name, image, il+y,
  180.                             ie+x, ll+y, le+x);
  181.                calculate_histogram(image, histogram);
  182.  
  183.             }  /* ends loop over b */
  184.          }  /* ends loop over a */
  185.       }  /* ends if display_mode == H */
  186.  
  187. printf("\n\nDISPLAY> Enter the title\n--");
  188. read_string(response);
  189.  
  190.         /* set graphics mode */
  191.  
  192.    _setvideomode(display_mode); /* MSC 6.0 */
  193.    if(display_colors == 16) map_16_shades_of_gray(display_mode);
  194.    if(display_colors == 256) map_64_shades_of_gray();
  195.  
  196.  
  197.         /****************************************
  198.         *
  199.         *   Loop over this size and
  200.         *   read and display ROWSxCOLS arrays.
  201.         *
  202.         *   If you want to show the histogram AND
  203.         *   do not want to do hist equalization
  204.         *   then calculate the hist from the
  205.         *   original image array.
  206.         *
  207.         *   If you want to do hist equalization
  208.         *   then calculate the new_hist AFTER
  209.         *   the image has been equalized by the
  210.         *   the transform_the_colors function.
  211.         *
  212.         *   NOTE: Remember that the function
  213.         *   transform_the_colors changes the
  214.         *   gray shade values in image array.
  215.         *
  216.         *****************************************/
  217.  
  218. /*
  219. These statements place a gray background across the
  220. display area of a VGA screen.  This reduces the contrast
  221. between the screen background and the images you display.
  222. This makes it easier to take photos.
  223. */
  224. _setlinestyle(0xFFFF);
  225. _setcolor(10);
  226. for(i=0; i<640;i++){
  227. _moveto(i, 0);
  228. _lineto(i, 480);
  229. }
  230.  
  231.       for(a=0; a<vertical; a++){
  232.          for(b=0; b<horizontal; b++){
  233.  
  234.             x = a*COLS;
  235.             y = b*ROWS;
  236.             read_tiff_image(file_name, image, il+y,
  237.                             ie+x, ll+y, le+x);
  238.             if(  (show_hist == 1)  &&
  239.                  (color_transform[0] != 'H'))
  240.                calculate_histogram(image, histogram);
  241.  
  242.             transform_the_colors(image, color_transform,
  243.                                  display_colors,
  244.                                  image_colors, histogram,
  245.                                  horizontal, vertical);
  246.  
  247.             if(color_transform[0] == 'H')
  248.                calculate_histogram(image, new_hist);
  249.           display_image_portion(image, x+dx_offset, 
  250.                                 y+dy_offset, display_colors,
  251.                                 image_colors, invert);
  252.          }        /* ends loop over b */
  253.       }        /* ends loop over a */
  254.  
  255. /* 
  256. Put in these statements to print a title at the
  257. bottom of the display.  This is nice for taking 
  258. photos or articles because it tells the reader
  259. what you are trying to do. 
  260. */
  261. _settextcolor(10);
  262. _setbkcolor(1L);
  263. len = strlen(response);
  264. len = 40 - (len/2);
  265. _settextposition(28, len);
  266. _outtext(response);
  267.  
  268.          /***************************
  269.          *
  270.          *   if show_hist == 1 then
  271.          *   display the histogram
  272.          *   in the lower right hand
  273.          *   corner of screen
  274.          *
  275.          *   If hist equalization was
  276.          *   performed then show the
  277.          *   new_hist.  If it wasn't
  278.          *   done then show the original
  279.          *   histogram.
  280.          *
  281.          ****************************/
  282.  
  283.       if(show_hist == 1){
  284.          if(monitor_type[0] == 'V')
  285.             y_offset = 470;
  286.          if(monitor_type[0] == 'E')
  287.             y_offset = 310;
  288.          x_offset = 380;
  289.          if(color_transform[0] == 'H')
  290.             display_histogram(new_hist, x_offset,
  291.                    y_offset, 10, 15);
  292.          else
  293.             display_histogram(histogram, x_offset,
  294.                    y_offset, 10, 15);
  295.       }
  296.  
  297.       read_string(response);
  298.       printf("\nEnter 0 to quit 1 to do again");
  299.       get_integer(¬_finished);
  300.  
  301.           /* set display back to text mode */
  302.       clear_text_screen();
  303.  
  304.  
  305.    }  /* ends while not_finished  */
  306.  
  307. }  /* ends main  */
  308.  
  309.  
  310.  
  311.  
  312.  
  313.  
  314.    /***********************************************
  315.    *
  316.    *   display_menu_for_display_image(
  317.    *
  318.    ************************************************/
  319.  
  320.  
  321. display_menu_for_display_image(image_colors, display_colors,
  322.                               invert, color_transform,
  323.                               monitor_type,
  324.                               show_hist)
  325.    char color_transform[], monitor_type[];
  326.    int  *invert, *image_colors, *display_colors, *show_hist;
  327. {
  328.    char response[80];
  329.    int  int_response, not_finished, r;
  330.  
  331.    not_finished = 1;
  332.    while(not_finished){
  333.       printf("\n\nDISPLAY> Enter choice (0 for no change) ");
  334.       printf("\nDISPLAY> 1. Invert is %d (1=on 0=off)", *invert);
  335.       printf("\nDISPLAY> 2. Color Transform-- %s",
  336.              color_transform);
  337.       printf("\nDISPLAY> 3. Input image has %d colors",
  338.              *image_colors);
  339.       printf("\nDISPLAY> 4. Display will show %d colors",
  340.              *display_colors);
  341.       printf("\nDISPLAY> 5. Monitor type is %s",
  342.              monitor_type);
  343.       printf("\nDISPLAY> 6. Histogram is %d", *show_hist);
  344.       printf("  (1=show 0=don't show)");
  345.       printf("\nDISPLAY> _\b");
  346.       get_integer(&r);
  347.  
  348.       if(r == 0){
  349.          not_finished = 0;
  350.       }
  351.  
  352.       if(r == 1){
  353.          printf("\nDISPLAY> Enter 1 for invert on");
  354.          printf(" 0 for invert off");
  355.          printf("\nDISPLAY> ___");
  356.          get_integer(&int_response);
  357.          *invert = int_response;
  358.       }  /* ends if r == 1 */
  359.  
  360.       if(r == 2){
  361.          printf("\nDISPLAY> Enter the new color transform mode ");
  362.          printf("\nDISPLAY> (S) Straight mode");
  363.          printf("   (H) Histogram Equalization");
  364.          printf("\nDISPLAY> _\b");
  365.          read_string(response);
  366.          if((response[0] == 'S') ||
  367.             (response[0] == 's'))
  368.                strcpy(color_transform, "Straight mode");
  369.          else
  370.                strcpy(color_transform,
  371.                 "Histogram Equalization mode");
  372.       }  /* ends if r == 2  */
  373.  
  374.       if(r == 3){
  375.          printf("\nDISPLAY> Enter the number of colors");
  376.          printf(" in the input image");
  377.          printf("\nDISPLAY> ___");
  378.          get_integer(&int_response);
  379.          *image_colors = int_response;
  380.       }  /* ends if r == 3 */
  381.  
  382.       if(r == 4){
  383.          printf(
  384.           "\nDISPLAY> Enter the number of colors for the display");
  385.          printf("\nDISPLAY> ___");
  386.          get_integer(&int_response);
  387.          *display_colors = int_response;
  388.       }  /* ends if r == 4 */
  389.  
  390.       if(r == 5){
  391.          printf("\nDISPLAY> Enter the new monitor type");
  392.          printf("\nDISPLAY> (E) EGA   (V) VGA");
  393.          printf("   (C) CGA   (M) Monochrome");
  394.          printf("\nDISPLAY> _\b");
  395.          read_string(response);
  396.          if((response[0] == 'E') ||
  397.             (response[0] == 'e'))
  398.             strcpy(monitor_type, "EGA");
  399.       if((response[0] == 'V') ||
  400.          (response[0] == 'v'))
  401.             strcpy(monitor_type, "VGA");
  402.       if((response[0] == 'C') ||
  403.          (response[0] == 'c'))
  404.             strcpy(monitor_type, "CGA");
  405.       if((response[0] == 'M') ||
  406.          (response[0] == 'm'))
  407.             strcpy(monitor_type, "Monochrome");
  408.       }  /* ends if r == 5  */
  409.  
  410.       if(r == 6){
  411.          printf(
  412.             "\nDISPLAY> Enter 1 for show histogram 0 for don't");
  413.          printf("\nDISPLAY> ___");
  414.          get_integer(&int_response);
  415.          *show_hist = int_response;
  416.       }  /* ends if r == 6 */
  417.  
  418.  
  419.  
  420.    }  /* ends while not_finished  */
  421. }  /* ends display_menu  */
  422.  
  423.  
  424.  
  425.  
  426.  
  427.  
  428.  
  429.  
  430.  
  431.    /********************************
  432.    *
  433.    *   display_image_portion(...
  434.    *
  435.    *********************************/
  436.  
  437.  
  438.  
  439.  
  440. display_image_portion(image, x, y, display_colors, image_colors,
  441.                       invert)
  442.    int      invert, display_colors, image_colors;
  443.    short    image[ROWS][COLS];
  444.    unsigned int x, y;
  445. {
  446.    unsigned int color, i, j;
  447.  
  448.       if(invert == 1){
  449.         for(i=0; i<ROWS; i++)
  450.            for(j=0; j<COLS; j++)
  451.               image[i][j] = (display_colors-1)-image[i][j];
  452.       }  /* ends if invert == 1 */
  453.  
  454.  
  455.       for(i=0; i<ROWS; i++){
  456.          for(j=0; j<COLS; j++){
  457.  
  458.         _setcolor(image[i][j]);
  459.         _setpixel(j+x, i+y);
  460. /*****
  461. my_set_pixel(j+x, i+y, image[i][j]);
  462. ******/
  463.  
  464.          }  /* ends loop over j  */
  465.       }     /* ends loop over i  */
  466.  
  467. }  /* ends display_image_portion  */
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.    /**********************************************
  478.    *
  479.    *   map_16_shades_of_gray(...
  480.    *
  481.    *   This function maps 16 shades of gray into
  482.    *   the first 16 color indices.  This allows
  483.    *   you to display a true "black and white"
  484.    *   image on a color monitor.
  485.    *
  486.    *********************************************/
  487.  
  488.  
  489. map_16_shades_of_gray(display_mode)
  490.    int display_mode;
  491. {
  492.    /* all MSC 6.0 statements */
  493. _setvideomode(display_mode);
  494. _remappalette(0,  0x000000L);
  495. _remappalette(1,  0x040404L);
  496. _remappalette(2,  0x080808L);
  497. _remappalette(3,  0x0c0c0cL);
  498. _remappalette(4,  0x101010L);
  499. _remappalette(5,  0x141414L);
  500. _remappalette(6,  0x181818L);
  501. _remappalette(7,  0x1c1c1cL);
  502. _remappalette(8,  0x202020L);
  503. _remappalette(9,  0x242424L);
  504. _remappalette(10, 0x282828L);
  505. _remappalette(11, 0x2c2c2cL);
  506. _remappalette(12, 0x303030L);
  507. _remappalette(13, 0x343434L);
  508. _remappalette(14, 0x383838L);
  509. _remappalette(15, 0x3f3f3fL);
  510. }
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517.    /*********************************************
  518.    *
  519.    *   transform_the_colors(...
  520.    *
  521.    *   This function transforms the gray shades
  522.    *   in the image array for display.  It can either
  523.    *   do it in straight mode by multiplying or
  524.    *   dividing or it can do it with hist
  525.    *   equalization by calling the function
  526.    *   perform_histogram_equalization.
  527.    *
  528.    *************************************************/
  529.  
  530.  
  531. transform_the_colors(image, color_transform,
  532.                      display_colors, image_colors,
  533.                      histogram, horizontal,
  534.                      vertical)
  535.    char   color_transform[];
  536.    int    display_colors, horizontal,
  537.           image_colors, vertical;
  538.    short  image[ROWS][COLS];
  539.    unsigned long histogram[];
  540. {
  541.    int         color, i, j;
  542.    float new_grays, area;
  543.    unsigned long x;
  544.  
  545.    if(color_transform[0] == 'S'){
  546.       for(i=0; i<ROWS; i++){
  547.          for(j=0; j<COLS; j++){
  548.  
  549.  
  550.             if( (display_colors == 16) &&
  551.                 (image_colors  == 256))
  552.                color = image[i][j]/16;
  553.             if( (display_colors == 16) &&
  554.                 (image_colors  == 16))
  555.                color = image[i][j];
  556.             if( (display_colors == 256) &&
  557.                 (image_colors  == 256))
  558.                color = image[i][j];
  559.             if( (display_colors == 256) &&
  560.                 (image_colors  == 16))
  561.                color = image[i][j]*16;
  562.  
  563.             image[i][j] = color;
  564.  
  565.  
  566.          }  /* ends loop over j        */
  567.       }        /* ends loop over i        */
  568.    }  /* ends if transform is straight */
  569.  
  570.  
  571.    if(color_transform[0] == 'H'){
  572.  
  573.       area      = ((long)(vertical))*((long)(horizontal));
  574.       area      = area*10000.0;
  575.       new_grays = display_colors;
  576.  
  577.       perform_histogram_equalization(image, histogram,
  578.                                      new_grays, area);
  579.  
  580.    }  /* ends if transform is hist equalization */
  581.  
  582. }  /* ends transform_the_colors */
  583.  
  584.  
  585.  
  586.  
  587.  
  588.  
  589.    /**********************************
  590.    *
  591.    *   Modes for the SigmaVGA Legend
  592.    *               (hex)
  593.    *   10 - 640x350x64?
  594.    *   12 - 640x480x16
  595.    *   29 - 800x600x16
  596.    *   30 - 800x600x256
  597.    *   38 - 1024x768x256
  598.    *
  599.    ***********************************/
  600.  
  601. my_set_video_mode()
  602. {
  603.  
  604.    union REGS regs;
  605.  
  606.    regs.h.al = 0x29; /* mode */
  607.    regs.h.ah = 0x00;
  608.    int86(0x10, ®s, ®s);
  609.  
  610.  
  611. }  /* ends my_set_video_mode */
  612.  
  613.  
  614.  
  615.  
  616.  
  617. my_set_pixel(x, y, color)
  618.    unsigned int x, y, color;
  619. {
  620.  
  621. union REGS regs;
  622. char  r[80];
  623. int i;
  624.  
  625.    regs.h.ah = 0x0c;
  626.    regs.x.dx = y;
  627.    regs.x.cx = x;
  628.    regs.h.al = color;
  629.    regs.h.bh = 0x00;
  630.  
  631.    int86(0x10, ®s, ®s);
  632.  
  633. }  /* ends my_set_pixel */
  634.  
  635.  
  636.  
  637.  
  638. my_set_colors()
  639. {
  640.  
  641.  union REGS regs;
  642.  int i;
  643.  
  644.  
  645.       /*********************
  646.          this works for 256 color modes
  647.          it does not work for 16 color modes
  648.       *********************/
  649.  
  650.    _asm{
  651.  
  652.       mov   ax,0030h ; set graphics mode 30h=800x600x256
  653.       int   10h
  654.  
  655.       mov ax,0h
  656.       mov dx,3c8h ; select first DAC register
  657.  
  658.       out dx,al
  659.       inc dx          ; set DAC data register
  660.  
  661.       mov al,0h
  662.       out dx,al
  663.       out dx,al
  664.       out dx,al
  665.  
  666.       mov al,4h
  667.       out dx,al
  668.       out dx,al
  669.       out dx,al
  670.  
  671.       mov al,8h
  672.       out dx,al
  673.       out dx,al
  674.       out dx,al
  675.  
  676.       mov al,ch
  677.       out dx,al
  678.       out dx,al
  679.       out dx,al
  680.  
  681.       mov al,10h
  682.       out dx,al
  683.       out dx,al
  684.       out dx,al
  685.  
  686.       mov al,14h
  687.       out dx,al
  688.       out dx,al
  689.       out dx,al
  690.  
  691.       mov al,18h
  692.       out dx,al
  693.       out dx,al
  694.       out dx,al
  695.  
  696.       mov al,1ch
  697.       out dx,al
  698.       out dx,al
  699.       out dx,al
  700.  
  701.       mov al,20h
  702.       out dx,al
  703.       out dx,al
  704.       out dx,al
  705.  
  706.       mov al,24h
  707.       out dx,al
  708.       out dx,al
  709.       out dx,al
  710.  
  711.       mov al,28h
  712.       out dx,al
  713.       out dx,al
  714.       out dx,al
  715.  
  716.       mov al,2ch
  717.       out dx,al
  718.       out dx,al
  719.       out dx,al
  720.  
  721.       mov al,30h
  722.       out dx,al
  723.       out dx,al
  724.       out dx,al
  725.  
  726.       mov al,34h
  727.       out dx,al
  728.       out dx,al
  729.       out dx,al
  730.  
  731.       mov al,38h
  732.       out dx,al
  733.       out dx,al
  734.       out dx,al
  735.  
  736.       mov al,3ch
  737.       out dx,al
  738.       out dx,al
  739.       out dx,al
  740.    } /* ends asm */
  741.  
  742.  
  743.  
  744. }  /* ends my_set_colors */
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753. put_pixel(ppx, ppy, color)
  754.    int color, ppx, ppy;
  755. {
  756.  
  757. int RW_Page=0x0ff;
  758. int W_Page=0x0ff;
  759. int R_Page=0x0ff;
  760. int PAGE_SEL_PORT=0x3cd;
  761.  
  762. printf("\ny=%d x=%d color=%d Page=%d offset=%d", ppy, ppx, color, (ppy*800
  763. + ppx)/0x10000, (ppy*800 + ppx)%0x10000);
  764.  
  765. /******************
  766.  
  767.    _asm{
  768.              ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  769.              ;
  770.              ;         taken from file
  771.              ;         d:\supervga\256col\wpixel.asm
  772.              ;
  773.              ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  774.  
  775.  
  776.         PUSH        BP                        ;Preserve BP
  777.         MOV     BP,SP                   ;Preserve stack pointer
  778.  
  779.         PUSH    ES                      ;Preserve segment and index registers
  780.         PUSH    DS
  781.         PUSH    DI
  782.         PUSH    SI
  783.         ; Convert x,y pixel address to Page and Offset
  784.  
  785.         MOV        AX,ppy                        ;Fetch y coordinate
  786.                                         ;Video_Pitch=SCREEN_PITCH=800
  787.         MUL        cs:800                        ;multiply by width in bytes
  788.         ADD        AX,ppx                        ;add x coordinate to compute offset
  789.         ADC        DX,0                        ;add overflow to upper 16 bits
  790.                                         ;Graph_Seg=0aoooh
  791.         MOV        DS,CS:0a000h                ;Put new address in DS:SI
  792.         MOV        DI,AX
  793.         MOV     AL,DL                   ;Copy page number into AL
  794.         JMP        Select_Page                ;Select proper page
  795. Ret_Page:
  796.  
  797.  
  798.         ; Set pixel to supplied value
  799.  
  800.         MOV        AL,color                ;Fetch color to use
  801.         MOV     [DI],AL                 ;Set the pixel
  802.  
  803.         ; Clean up and return
  804.  
  805.         POP     SI                      ;Restore segment and index registers
  806.         POP     DI
  807.         POP     DS
  808.         POP     ES
  809.  
  810.         MOV     SP,BP                   ;Restore stack pointer
  811.         POP     BP                      ;Restore BP
  812.  
  813.         JMP        The_End
  814.  
  815.  
  816. Select_Page:
  817.         CMP        AL,CS:RW_Page                ;Check if already selected
  818.         JNE        SP_Go
  819.         JMP        Ret_Page
  820. SP_Go:
  821.         PUSH        AX
  822.         PUSH        DX
  823.         MOV        DX,PAGE_SEL_PORT        ;Fetch address of page select
  824.         AND        AL,7                        ;Force page number into 0-7
  825.         MOV        CS:RW_Page,AL                ;Save most recently selected page
  826.         MOV        CS:R_Page,0FFh
  827.         MOV        CS:W_Page,0FFh
  828.         MOV        AH,AL                        ;Copy page into AH
  829.         SHL        AH,1                        ;Shift page number
  830.         SHL        AH,1
  831.         SHL        AH,1
  832.         OR        AL,AH                        ;Move page number into "write" bits
  833.         OR        AL,40h                        ;Force bit 6
  834.         OUT        DX,AL                        ;Write out the new page select
  835.         POP        DX
  836.         POP        AX
  837.         JMP        Ret_Page
  838.  
  839. The_End:
  840.  
  841.    }*******/        /* ends _asm */
  842.  
  843. }  /* ends put_pixel */
  844.  
  845.  
  846.  
  847.  
  848.  
  849.  
  850.    /*******************************************
  851.    *
  852.    *   map_64_shades_of_gray()
  853.    *
  854.    *   This function maps 256 DAC registers to
  855.    *   gray shades.  Taken from p. 73 of
  856.    *   Sutty and Blair's text on superVGA
  857.    *
  858.    ********************************************/
  859.  
  860.  
  861. map_64_shades_of_gray()
  862. {
  863.  
  864.    _asm{
  865.       mov ax,0013h ;mod 13h is 320x200x256
  866.       int 10h
  867.  
  868.       mov ah,10h   ; function 10h
  869.       mov al,1bh   ; sub function 1bh
  870.       mov bx,0h    ; first DAC register to change
  871.       mov cx,100h  ; change 256 DAC registers
  872.       int 10h
  873.  
  874.    } /* ends asm */
  875. }  /* ends map_64_shades_of_gray */
  876.