home *** CD-ROM | disk | FTP | other *** search
/ GRIPS 2: Government Rast…rocessing Software & Data / GRIPS_2.cdr / dos / imdisp / source / dispio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-08  |  42.5 KB  |  1,436 lines

  1. /*************************************************************/
  2. /*  Copyright (C) 1989, California Institute of Technology   */
  3. /*  U. S. Government Sponsorship under NASA Contract         */
  4. /*  NAS7-918 is acknowledged.                                */
  5. /*************************************************************/
  6.  
  7. /***  IMDISP module DISPIO.C  
  8.  
  9.         DISPIO contains the device dependent display routines for the
  10.     Color Graphics Adapter (CGA), the Enhanced Graphics Adapter (EGA),
  11.     the Professional Graphics Adapter (PGA) and the Video Graphics Array
  12.     (VGA).  The global variables that define the device are allocated
  13.     and initialized here.
  14.  
  15. ***/
  16.  
  17. /* * * * INCLUDE files * * * */
  18.  
  19. #include <conio.h>
  20. #include <dos.h>
  21. #include <graph.h>
  22. #include <malloc.h>
  23. #include <math.h>
  24. #include <memory.h>
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include "imdef.h"
  29. #include "imdisp.h"
  30. #include "disputil.h"
  31. #include "evgaio.h"
  32. #include "refresh.h"
  33. #include "ativga.h"
  34. #include "dispsub.h"
  35. #include "paradise.h"
  36.  
  37. /* * * *  Defined Constants * * * */
  38. #define CGA          0
  39. #define EGA350       1
  40. #define PGA          2
  41. #define VGA480       3
  42. #define VGA200       4
  43. #define BIOS         5
  44. #define ORCHID480    6
  45. #define ORCHID600    7
  46. #define EVGA640      8
  47. #define EVGA512      9
  48. #define EVGA800     10
  49. #define EGA480      11
  50. #define ATI640      12
  51. #define ATI800      13
  52. #define ATI1024     14
  53. #define PARADISE    15
  54. #define ORCHID768   16
  55.  
  56. /* * * * External functions * * * */
  57.  
  58. /* * * * Function declarations * * * */
  59.  
  60. int DisplayOn (void);
  61. int DisplayOff (void);
  62. int ReadPalette (struct Color *);
  63. int WritePalette (struct Color *);
  64. int WritePixel (int, int, int);
  65. int ReadPixel (int, int, int *);
  66. int DisplayLine (unsigned char *,int ,int ,int );
  67. int FormatLine (unsigned char *, int, int, int, int, char *);
  68. int ClearDisplay (int );
  69. int PGAreceive (unsigned char *, int *);
  70.  
  71. /* * * * Global Variables * * * */
  72.  
  73. int    atibank;
  74.  
  75. /*
  76.    DisplayDevice indicates the type of display (CGA=0, EGA=1, PGA=2, etc).
  77.    dispnl        is the number of lines in the display.
  78.    dispns        is the number of samples in the display.
  79.    numDN         is the number of unique pixel values (e.g. 4 bits ->
  80.                  numDN=16).
  81.    numshades     is the number of shades each of red, green, and blue
  82.                  (e.g.  numshades=16 gives 16**3 = 4096 possible colors).
  83.    OneScreen     is true if there is only one screen, i.e. there is not
  84.                  image screen and a text screen.
  85. */
  86.  
  87. int      DisplayDevice, dispnl, dispns, numDN, numshades, OneScreen;
  88.  
  89. struct   Color
  90. /*
  91.    This is the structure for the color palette.
  92.    The current palette is stored in PaletteTable.
  93. */
  94.          {
  95.                 unsigned char  r, g, b;
  96.          } DefaultPalette[256], PaletteTable[256];
  97.  
  98.  
  99. int DisplayOn(void)
  100.  
  101. /***
  102.     DisplayOn figures out which display device is on the system and then
  103.     initializes for that device.  The device is turned on. The global
  104.     variables that define the display characteristics and the default
  105.     color palette are initialized.  The refresh buffer is zeroed.
  106. ***/
  107.  
  108. {
  109.     int             i;
  110.     unsigned char   cmd[7], EVGApalette[17];
  111.     union  REGS     inreg, outreg;
  112.     struct SREGS    segregs;
  113.     struct Color    DP[16];
  114.  
  115.     /* Test for Enhanced Graphics Adapter (EGA) */
  116.     if (DisplayDevice == CGA)
  117.     {
  118.         inreg.x.ax = 0x1200;
  119.         inreg.x.bx = 0x0FF10;
  120.         inreg.x.cx = 0x000F;
  121.         int86 (0x10, &inreg, &outreg);
  122.         if ( (outreg.h.cl < 0x0C) && (outreg.h.bh <= 1) && (outreg.h.bl <= 3) )
  123.             DisplayDevice = EGA350;
  124.     }
  125.  
  126. /* moved from before ega test to avoid conflicts with memory boards*/
  127. /* mdm 2-19-88 */
  128.  
  129. /* Test for Professional Graphics Adapter (PGA) */
  130. /*    if (DisplayDevice == CGA && devname == NULL) */
  131.     if (DisplayDevice == CGA)
  132.     {
  133.         putmem (0x0C000, 0x63DB, 0x0AD);
  134.         if (getmem (0x0C000, 0x63DB) == 0x0AD)
  135.             DisplayDevice = PGA;
  136.     }
  137.  
  138.           /* Initialize for the appropriate device */
  139.     switch (DisplayDevice)
  140.     {
  141.     case CGA :    /* for standard cga display */
  142.  
  143.           dispnl     = 200;
  144.           dispns     = 640;
  145.           numDN      = 2;
  146.           numshades  = 2;
  147.           OneScreen  = 1;
  148.           _setvideomode( _HRESBW );
  149.           DefaultPalette[0].r = 0;    DefaultPalette[1].r = 255;
  150.           DefaultPalette[0].g = 0;    DefaultPalette[1].g = 255;
  151.           DefaultPalette[0].b = 0;    DefaultPalette[1].b = 255;
  152.           break;
  153.  
  154.     case EGA350 :     /* for standard ega displays */
  155.  
  156.           dispnl     = 350;
  157.           dispns     = 640;
  158.           numDN      = 16;
  159.           numshades  = 4;
  160.           OneScreen  = 1;
  161.           _setvideomode( _ERESCOLOR );
  162.  
  163.           DP[0].r  = 32;   DP[0].g  = 32;    DP[0].b  = 32;
  164.           DP[1].r  = 96;   DP[1].g  = 32;    DP[1].b  = 32;
  165.           DP[2].r  = 160;  DP[2].g  = 32;    DP[2].b  = 32;
  166.           DP[3].r  = 224;  DP[3].g  = 32;    DP[3].b  = 32;
  167.           DP[4].r  = 224;  DP[4].g  = 96;    DP[4].b  = 32;
  168.           DP[5].r  = 224;  DP[5].g  = 160;   DP[5].b  = 32;
  169.           DP[6].r  = 224;  DP[6].g  = 224;   DP[6].b  = 32;
  170.           DP[7].r  = 160;  DP[7].g  = 224;   DP[7].b  = 32;
  171.           DP[8].r  = 32;   DP[8].g  = 224;   DP[8].b  = 32;
  172.           DP[9].r  = 32;   DP[9].g  = 224;   DP[9].b  = 160;
  173.           DP[10].r = 32;   DP[10].g = 160;   DP[10].b = 160;
  174.           DP[11].r = 32;   DP[11].g = 160;   DP[11].b = 224;
  175.           DP[12].r = 32;   DP[12].g = 32;    DP[12].b = 224;
  176.           DP[13].r = 160;  DP[13].g = 32;    DP[13].b = 224;
  177.           DP[14].r = 224;  DP[14].g = 32;    DP[14].b = 224;
  178.           DP[15].r = 224;  DP[15].g = 224;   DP[15].b = 224;
  179.           for (i = 0; i <= 15; i++)
  180.             {
  181.              DefaultPalette[i].r = DP[i].r;
  182.              DefaultPalette[i].g = DP[i].g;
  183.              DefaultPalette[i].b = DP[i].b;
  184.             }
  185.  
  186.           break;
  187.  
  188.     case EGA480 :     /* for extended ega displays */
  189.  
  190.           /* if environment variable EGA480 is not null, then
  191.              initialize for 480 line mode.  Requires crystal
  192.              upgrade on EGA board and multisync monitor.      */
  193.  
  194.           dispnl     = 480;
  195.           dispns     = 640;
  196.           numDN      = 16;
  197.           numshades  = 4;
  198.           OneScreen  = 1;
  199.           egainit(); /* special init routines in dispsub.asm */
  200.  
  201.           DP[0].r  = 32;   DP[0].g  = 32;    DP[0].b  = 32;
  202.           DP[1].r  = 96;   DP[1].g  = 32;    DP[1].b  = 32;
  203.           DP[2].r  = 160;  DP[2].g  = 32;    DP[2].b  = 32;
  204.           DP[3].r  = 224;  DP[3].g  = 32;    DP[3].b  = 32;
  205.           DP[4].r  = 224;  DP[4].g  = 96;    DP[4].b  = 32;
  206.           DP[5].r  = 224;  DP[5].g  = 160;   DP[5].b  = 32;
  207.           DP[6].r  = 224;  DP[6].g  = 224;   DP[6].b  = 32;
  208.           DP[7].r  = 160;  DP[7].g  = 224;   DP[7].b  = 32;
  209.           DP[8].r  = 32;   DP[8].g  = 224;   DP[8].b  = 32;
  210.           DP[9].r  = 32;   DP[9].g  = 224;   DP[9].b  = 160;
  211.           DP[10].r = 32;   DP[10].g = 160;   DP[10].b = 160;
  212.           DP[11].r = 32;   DP[11].g = 160;   DP[11].b = 224;
  213.           DP[12].r = 32;   DP[12].g = 32;    DP[12].b = 224;
  214.           DP[13].r = 160;  DP[13].g = 32;    DP[13].b = 224;
  215.           DP[14].r = 224;  DP[14].g = 32;    DP[14].b = 224;
  216.           DP[15].r = 224;  DP[15].g = 224;   DP[15].b = 224;
  217.           for (i = 0; i <= 15; i++)
  218.             {
  219.              DefaultPalette[i].r = DP[i].r;
  220.              DefaultPalette[i].g = DP[i].g;
  221.              DefaultPalette[i].b = DP[i].b;
  222.             }
  223.  
  224.           break;
  225.  
  226.     case EVGA800 :     /* for Everex EV-673 hi-res ega mode */
  227.  
  228.           dispns = 800;
  229.           dispnl = 600;
  230.           numDN      = 16;
  231.           numshades  = 4;
  232.           OneScreen  = 1;
  233.           inreg.x.ax = 0x0070;  /* turn on EVGA MODE */
  234.           inreg.x.bx = 0x0002;  /* at 800x600 res */
  235.           int86 (0x10, &inreg, &outreg);
  236.  
  237.           DP[0].r  = 32;   DP[0].g  = 32;    DP[0].b  = 32;
  238.           DP[1].r  = 96;   DP[1].g  = 32;    DP[1].b  = 32;
  239.           DP[2].r  = 160;  DP[2].g  = 32;    DP[2].b  = 32;
  240.           DP[3].r  = 224;  DP[3].g  = 32;    DP[3].b  = 32;
  241.           DP[4].r  = 224;  DP[4].g  = 96;    DP[4].b  = 32;
  242.           DP[5].r  = 224;  DP[5].g  = 160;   DP[5].b  = 32;
  243.           DP[6].r  = 224;  DP[6].g  = 224;   DP[6].b  = 32;
  244.           DP[7].r  = 160;  DP[7].g  = 224;   DP[7].b  = 32;
  245.           DP[8].r  = 32;   DP[8].g  = 224;   DP[8].b  = 32;
  246.           DP[9].r  = 32;   DP[9].g  = 224;   DP[9].b  = 160;
  247.           DP[10].r = 32;   DP[10].g = 160;   DP[10].b = 160;
  248.           DP[11].r = 32;   DP[11].g = 160;   DP[11].b = 224;
  249.           DP[12].r = 32;   DP[12].g = 32;    DP[12].b = 224;
  250.           DP[13].r = 160;  DP[13].g = 32;    DP[13].b = 224;
  251.           DP[14].r = 224;  DP[14].g = 32;    DP[14].b = 224;
  252.           DP[15].r = 224;  DP[15].g = 224;   DP[15].b = 224;
  253.           for (i = 0; i <= 15; i++)
  254.             {
  255.              DefaultPalette[i].r = DP[i].r;
  256.              DefaultPalette[i].g = DP[i].g;
  257.              DefaultPalette[i].b = DP[i].b;
  258.             }
  259.  
  260.           break;
  261.  
  262.     case VGA480 :     /* for standard vga displays */
  263.     case BIOS :     /* for standard vga displays */
  264.  
  265.           dispnl     = 480;
  266.           dispns     = 640;
  267.           numDN      = 16;
  268.           numshades  = 64;
  269.           OneScreen  = 1;
  270.           _setvideomode( _VRES16COLOR );
  271.  
  272.           /* load default gray level palette with 17 dn increments */
  273.           for (i = 0; i <= 15; i++)
  274.             {
  275.                 DefaultPalette[i].r = i*16+i;
  276.                 DefaultPalette[i].g = i*16+i;
  277.                 DefaultPalette[i].b = i*16+i;
  278.             }
  279.           break;
  280.  
  281.     case PGA:     /* for standard pga display */
  282.  
  283.           dispnl = 480;
  284.           dispns = 640;
  285.           numDN = 256;
  286.           numshades = 16;
  287.           OneScreen = 1;
  288.  
  289.           cmd[0] = 0x43; cmd[1] = 0x58; cmd[2] = 0x20;
  290.           cmd[3] = 0x0D0; cmd[4] = 0x00;
  291.           cmd[5] = 0x0F; cmd[6] = 0x00;
  292.           PGAsend (cmd, 7);      /* 'CA DISPLA 0  CLEARS 0 '  */
  293.  
  294.           for (i = 0; i <= 255; i++)
  295.             {
  296.              DefaultPalette[i].r = i;
  297.              DefaultPalette[i].g = i;
  298.              DefaultPalette[i].b = i;
  299.             }
  300.           break;
  301.  
  302.     case ORCHID480 :   /* for Orchid ProDesigner enhanced VGA mode */
  303.  
  304.           dispnl = 480;
  305.           dispns = 640;
  306.           numDN = 256;
  307.           numshades = 64;
  308.           OneScreen = 1;
  309.           inreg.x.ax = 0x002E;  /* set 256 color 640 x480 mode */
  310.           int86 (0x10, &inreg, &outreg);
  311.           inreg.x.ax = 0x0500;  /* select page */
  312.           int86 (0x10, &inreg, &outreg);
  313.  
  314.           for (i = 0; i <= 255; i++)
  315.             {
  316.              DefaultPalette[i].r = i;
  317.              DefaultPalette[i].g = i;
  318.              DefaultPalette[i].b = i;
  319.             }
  320.           break;
  321.  
  322.     case ORCHID600 :   /* for Orchid ProDesigner+ with 512K */
  323.  
  324.           dispnl = 600;
  325.           dispns = 800;
  326.           numDN = 256;
  327.           numshades = 64;
  328.           OneScreen = 1;
  329.           inreg.x.ax = 0x0030;  /* set 256 color 800 x 600 mode */
  330.           int86 (0x10, &inreg, &outreg);
  331.           inreg.x.ax = 0x0500;  /* select page */
  332.           int86 (0x10, &inreg, &outreg);
  333.  
  334.           for (i = 0; i <= 255; i++)
  335.             {
  336.              DefaultPalette[i].r = i;
  337.              DefaultPalette[i].g = i;
  338.              DefaultPalette[i].b = i;
  339.             }
  340.           break;
  341.  
  342.     case ORCHID768 :   /* for Orchid ProDesigner+ with 1024K */
  343.  
  344.           dispnl = 768;
  345.           dispns = 1024;
  346.           numDN = 256;
  347.           numshades = 64;
  348.           OneScreen = 1;
  349.           inreg.x.ax = 0x0038;  /* set 256 color 1024 x 768 mode */
  350.           int86 (0x10, &inreg, &outreg);
  351.           inreg.x.ax = 0x0500;  /* select page */
  352.           int86 (0x10, &inreg, &outreg);
  353.  
  354.           for (i = 0; i <= 255; i++)
  355.             {
  356.              DefaultPalette[i].r = i;
  357.              DefaultPalette[i].g = i;
  358.              DefaultPalette[i].b = i;
  359.             }
  360.           break;
  361.  
  362.     case VGA200 :   /* for standard VGA displays */
  363.  
  364.           dispnl = 200;
  365.           dispns = 320;
  366.           numDN = 256;
  367.           numshades = 64;
  368.           OneScreen = 1;
  369.           _setvideomode( _MRES256COLOR );
  370.           for (i = 0; i <= 255; i++)
  371.             {
  372.              DefaultPalette[i].r = i;
  373.              DefaultPalette[i].g = i;
  374.              DefaultPalette[i].b = i;
  375.             }
  376.           break;
  377.  
  378.     case EVGA640 :  /* for Everex EV-673 enhanced vga mode */
  379.  
  380.           dispns = 640;
  381.           dispnl = 400;
  382.           numDN = 256;
  383.           numshades = 64;
  384.           OneScreen = 1;
  385.           inreg.x.ax = 0x0070;
  386.           inreg.x.bx = 0x0014;
  387.           int86 (0x10, &inreg, &outreg);
  388.           for (i = 0; i <= 255; i++)
  389.             {
  390.               DefaultPalette[i].r = i;
  391.               DefaultPalette[i].g = i;
  392.               DefaultPalette[i].b = i;
  393.             }
  394.           EVGASetPage(0);
  395.           break;
  396.  
  397.     case EVGA512 :  /* for Everex EV-673 almost image proc mode */
  398.  
  399.           dispns = 512;
  400.           dispnl = 480;
  401.           numDN = 256;
  402.           numshades = 64;
  403.           OneScreen = 1;
  404.           inreg.x.ax = 0x0070;
  405.           inreg.x.bx = 0x0015;
  406.           int86 (0x10, &inreg, &outreg);
  407.           for (i = 0; i <= 255; i++)
  408.             {
  409.               DefaultPalette[i].r = i;
  410.               DefaultPalette[i].g = i;
  411.               DefaultPalette[i].b = i;
  412.             }
  413.           EVGASetPage(0);
  414.           break;
  415.  
  416.     case ATI640:     /* for ATI VGA Wonder */
  417.  
  418.           dispns = 640;
  419.           dispnl = 480;
  420.           numDN = 256;
  421.           numshades = 16;
  422.           OneScreen = 1;
  423.  
  424.           ATI_Init();
  425.  
  426.           for (i = 0; i <= 255; i++)
  427.             {
  428.              DefaultPalette[i].r = i;
  429.              DefaultPalette[i].g = i;
  430.              DefaultPalette[i].b = i;
  431.             }
  432.           break;
  433.  
  434.     case ATI800:     /* for ATI VGA Wonder */
  435.  
  436.           dispns = 800;
  437.           dispnl = 600;
  438.           numDN = 256;
  439.           numshades = 16;
  440.           OneScreen = 1;
  441.  
  442.           ATI_Init();
  443.  
  444.           for (i = 0; i <= 255; i++)
  445.             {
  446.              DefaultPalette[i].r = i;
  447.              DefaultPalette[i].g = i;
  448.              DefaultPalette[i].b = i;
  449.             }
  450.           break;
  451.  
  452.     case ATI1024:     /* for ATI VGA Wonder */
  453.  
  454.           dispns     = 1024;
  455.           dispnl     = 768;
  456.           numDN      = 16;
  457.           numshades  = 4;
  458.           OneScreen  = 1;
  459.  
  460.           ATI_Init();
  461.  
  462.           /* load default gray level palette */
  463.           for (i = 0; i <= 255; i++)
  464.             {
  465.                 DefaultPalette[i].r = i;
  466.                 DefaultPalette[i].g = i;
  467.                 DefaultPalette[i].b = i;
  468.             }
  469.           break;
  470.  
  471.     case PARADISE : /* for SUPER VGA board */
  472.     
  473.           dispnl = 480;
  474.           dispns = 640;
  475.           numDN = 256;
  476.           numshades = 64;
  477.           OneScreen = 1;
  478.           inreg.x.ax=0x007F;                   /*BIOS check on board memory */
  479.           inreg.x.bx=0x0200;
  480.           int86 (0x10, &inreg, &outreg);
  481.           if(outreg.h.ch >= 5)                /*return number of 64k units */
  482.           {
  483.                inreg.x.ax = 0x005F;           /*we have at least 309k for this mode */
  484.                int86 (0x10, &inreg, &outreg); /*set 256 color 640 x480 mode */
  485.           }
  486.           else
  487.           {
  488.                inreg.x.ax = 0x005E;           /*board has only 256k of memory */
  489.                int86 (0x10, &inreg, &outreg); /*set 256 color 640 x400 mode */
  490.                dispnl=400;
  491.           }
  492.           for (i = 0; i <= 255; i++)
  493.           {
  494.                DefaultPalette[i].r = i;
  495.                DefaultPalette[i].g = i;
  496.                DefaultPalette[i].b = i;
  497.           }
  498.           break;
  499.  
  500.  
  501.     }
  502. /*
  503.     i = 0;
  504.  
  505.     while ( ((RefreshBuf[i] = (unsigned char *) calloc( dispns, sizeof(char)) ) != NULL)
  506.           && (i < dispnl) )  i++;
  507.     if (i == dispnl)
  508.        RefreshLines = i + 1;
  509.     else
  510.        RefreshLines = i;
  511. */
  512.     RefreshLines = AllocRefresh();
  513.  
  514.     if (dispnl >= 768)
  515.     {
  516.         TextHeight = 15;
  517.         BigChars   = 20;
  518.         SmallChars = 12;
  519.     }
  520.     else if (dispnl >= 600)
  521.     {
  522.         TextHeight = 12;
  523.         BigChars   = 15;
  524.         SmallChars = 10;
  525.     }
  526.     else if (dispnl >= 480)
  527.     {
  528.         TextHeight =  9;
  529.         BigChars   = 12;
  530.         SmallChars =  6;
  531.     }
  532.     else if (dispnl >= 400)
  533.     {
  534.         TextHeight =  8;
  535.         BigChars   = 12;
  536.         SmallChars =  6;
  537.     }
  538.     else if (dispnl >= 350)
  539.     {
  540.         TextHeight =  8;
  541.         BigChars   = 10;
  542.         SmallChars =  6;
  543.     }
  544.     else
  545.     {
  546.         TextHeight = 6;
  547.         BigChars   = 8;
  548.         SmallChars = 5;
  549.     }
  550.  
  551. }
  552.  
  553.  
  554. int DisplayOff(void)
  555.  
  556. /***
  557.     DisplayOff turns off the display device returning the screen
  558.     to text mode.
  559. ***/
  560.  
  561. {
  562.     unsigned   char    cmd[2];
  563.     union      REGS    inreg, outreg;
  564.     int        i;
  565.  
  566.     switch (DisplayDevice)
  567.     {
  568.     case BIOS    :    /* for plain vga display */
  569.     case CGA     :    /* for cga display */
  570.     case EGA350  :    /* for ega and vga displays */
  571.     case VGA480  :    /* for ega and vga displays */
  572.     case VGA200  :    /* for ega and vga displays */
  573.     case EGA480  :    /* for enhanced ega */
  574.     case EVGA640 :    /* for Everex EVGA */
  575.     case EVGA512 :    /* for Everex EVGA */
  576.     case EVGA800 :    /* for Everex EVGA */
  577.     case ATI640  :    /* For ATI VGA Wonder */
  578.     case ATI800  :    /* For ATI VGA Wonder */
  579.     case ATI1024 :    /* For ATI VGA Wonder */
  580.     case PARADISE :   /* for Paradise Super VGA */
  581.  
  582.           _setvideomode( _DEFAULTMODE );
  583.           break;
  584.  
  585.     case ORCHID480 :    /* for orchid designer */
  586.     case ORCHID600 :    /* for orchid designer */
  587.     case ORCHID768 :    /* for orchid designer */
  588.  
  589.           ClearDisplay( 0 );              /* Keep Seiko monitor from */
  590.                                           /* shutting off */
  591.           inreg.x.ax = 0x0003;
  592.           int86 (0x10, &inreg, &outreg);
  593.           break;
  594.  
  595.  
  596.     case PGA:     /* for pga display */
  597.  
  598.           cmd[0] = 0x0D0;   cmd[1] = 1;
  599.           PGAsend (cmd, 2);  /* 'DISPLA 1' */
  600.           break;
  601.  
  602.     }
  603.     OneScreen = 0;
  604.  
  605.     /* clear out the refreshbuffer */
  606.     for (i = 0;  i < RefreshLines;  i++)
  607.       free (RefreshBuf[i]);
  608.     RefreshLines = 0;
  609. }
  610.  
  611. int ReadPalette (struct Color * coltab)
  612.  
  613. /***  ReadPalette returns the current color palette in coltab.
  614.       coltab is of type Color.
  615. ***/
  616.  
  617. {
  618.     int  i;
  619.  
  620.     for (i = 0; i < numDN; i++)
  621.     {
  622.         coltab[i].r = PaletteTable[i].r;
  623.         coltab[i].g = PaletteTable[i].g;
  624.         coltab[i].b = PaletteTable[i].b;
  625.     }
  626. }
  627.  
  628. int WritePalette (struct Color * coltab)
  629.  
  630. /***
  631.     WritePalette updates the display device palette with the
  632.     palette passed in coltab.  coltab must be of type Color.
  633. ***/
  634.  
  635. {
  636.     int   i;
  637.     unsigned char   cmd[5],  red, green, blue;
  638.     long  pal_color;
  639.     union  REGS  inreg, outreg;
  640.     struct SREGS segregs;
  641.     struct Color    DP[256];
  642.     unsigned int   x,y;
  643.     unsigned char *colors, palbuf[256][3];
  644.  
  645.     for (i = 0; i < numDN; i++)
  646.     {
  647.         PaletteTable[i].r = coltab[i].r;
  648.         PaletteTable[i].g = coltab[i].g;
  649.         PaletteTable[i].b = coltab[i].b;
  650.     }
  651.  
  652.     switch (DisplayDevice)
  653.     {
  654.     case EGA350 :     /* for ega displays */
  655.     case EGA480 :     /* for ega displays */
  656.     case EVGA800 :   /* for Everex EVGA */
  657.  
  658.           for (i = 0; i <= 15; i++)
  659.           {
  660. /*        Old ega palette routine.  Changed to DISPLAY.LIB routine to see
  661.           it fixes problems with original IBM EGA.
  662.               inreg.x.ax = 0x1010;
  663.               inreg.x.bx = i;
  664.               inreg.h.dh = coltab[i].r/4;
  665.               inreg.h.ch = coltab[i].g/4;
  666.               inreg.h.cl = coltab[i].b/4;
  667.               int86 (0x10, &inreg, &outreg);
  668. */
  669.                red   = (coltab[i].r >> 2) & 0x3f;
  670.                green = (coltab[i].g >> 2) & 0x3f;
  671.                blue  = (coltab[i].b >> 2) & 0x3f;
  672.                pal_color = ( ((long)blue)  << 16)
  673.                          | ( ((long)green) <<  8)
  674.                          |   ((long)red) ;
  675.                _remappalette( i, pal_color) ;
  676.           }
  677.           return;
  678.  
  679.     case VGA480 :      /* for vga displays */
  680.  
  681.           for (i = 0; i <= 15; i++)
  682.           {
  683.               palbuf[i][0] = (coltab[i].r >> 2) & 0xff;
  684.               palbuf[i][1] = (coltab[i].g >> 2) & 0xff;
  685.               palbuf[i][2] = (coltab[i].b >> 2) & 0xff;
  686.           }
  687.           colors = &palbuf[0][0];
  688.           segregs.es = FP_SEG( colors );
  689.           inreg.x.dx = FP_OFF( colors );
  690.           inreg.x.ax = 0x1012;
  691.           inreg.x.bx = 0x0;
  692.           inreg.x.cx = 16;
  693.           int86x(0x10, &inreg, &outreg, &segregs);
  694.           return;
  695.  
  696.     case BIOS :     /* for vga displays */
  697.  
  698.           for (i = 0; i <= 15; i++)
  699.           {
  700.                red   = (coltab[i].r >> 2) & 0x3f;
  701.                green = (coltab[i].g >> 2) & 0x3f;
  702.                blue  = (coltab[i].b >> 2) & 0x3f;
  703.                pal_color = ( ((long)blue)  << 16)
  704.                          | ( ((long)green) <<  8)
  705.                          |   ((long)red) ;
  706.                _remappalette( i, pal_color) ;
  707.           }
  708.           return;
  709.  
  710.     case VGA200 :   /* for vga displays */
  711.     case ORCHID480 :    /* for orchid designer */
  712.     case ORCHID600 :    /* for orchid designer */
  713.     case ORCHID768 :    /* for orchid designer */
  714.     case EVGA640 :   /* for Everex EVGA */
  715.     case EVGA512 :   /* for Everex EVGA */
  716.     case PARADISE :
  717.  
  718.           for (i = 0; i <= 255; i++)
  719.           {
  720.  
  721.               palbuf[i][0] = (coltab[i].r >> 2) & 0xff;
  722.               palbuf[i][1] = (coltab[i].g >> 2) & 0xff;
  723.               palbuf[i][2] = (coltab[i].b >> 2) & 0xff;
  724.           }
  725.           colors = &palbuf[0][0];
  726.           segregs.es = FP_SEG( colors );
  727.           inreg.x.dx = FP_OFF( colors );
  728.           inreg.x.ax = 0x1012;
  729.           inreg.x.bx = 0x0;
  730.           inreg.x.cx = 256;
  731.           int86x(0x10, &inreg, &outreg, &segregs);
  732.           return;
  733.  
  734.     case PGA :    /* for pga display */
  735.           for (i = 0; i <= 255; i++)
  736.           {
  737.               cmd[0] = 0x0EE;
  738.               cmd[1] = i;
  739.               cmd[2] = coltab[i].r >> 4;
  740.               cmd[3] = coltab[i].g >> 4;
  741.               cmd[4] = coltab[i].b >> 4;
  742.               PGAsend (cmd, 5);        /* 'LUT numcol red green blue' */
  743.           }
  744.           return;
  745.  
  746.     case ATI640 :   /* for ATI VGA Wonder */
  747.     case ATI800 :   /* for ATI VGA Wonder */
  748.     case ATI1024:   /* for ATI VGA Wonder */
  749.  
  750.          for(i=0;i<256;i++)
  751.          {
  752.               palbuf[i][0] = (coltab[i].r >> 2) & 0xff;
  753.               palbuf[i][1] = (coltab[i].g >> 2) & 0xff;
  754.               palbuf[i][2] = (coltab[i].b >> 2) & 0xff;
  755.          }
  756.          ATI_WritePalette(palbuf,0,256);
  757.          return ;
  758.  
  759.     }
  760. }
  761.  
  762. int WritePixel (int line, int sample, int DN)
  763.  
  764. /***  WritePixel writes a pixel on the display screen.
  765.       Parameter   type       description
  766.         line     integer     The line coordinate of the pixel
  767.         sample   integer     The sample coordinate of the pixel
  768.         DN       integer     The DN value of the pixel
  769. ***/
  770.  
  771. {
  772.     unsigned int  x, y;
  773.     unsigned int  segment;
  774.     unsigned long laddress;
  775.     int           address, bit, mask, useBIOS;
  776.     unsigned char   cmd[9];
  777.     unsigned char far *faraddr;
  778.     unsigned int  color;
  779.  
  780.     switch (DisplayDevice)
  781.     {
  782.  
  783.     case CGA :     /* for cga display */
  784.  
  785.           line--;
  786.           sample--;
  787.           bit = 7 - (sample & 7);
  788.           DN = (DN & 1) << bit;
  789.           mask = ~(1 << bit);
  790.  
  791.           if ((line & 1) == 0)
  792.               address = 0x8000 + 40*line + (sample >> 3);
  793.           else
  794.               address = 0x0A000 + 40*(line-1) + (sample >> 3);
  795.           putmem (0x0B000, address, (getmem(0xB000,address) & mask) | DN);
  796.           return;
  797.  
  798.     case EGA350 :   /* for ega and vga displays */
  799.     case EGA480 :   /* for ega and vga displays */
  800.     case VGA480 :   /* for ega and vga displays */
  801.     case BIOS :   /* for ega and vga displays */
  802.  
  803.             WritePixelEGA (line, sample, DN);
  804.             return;
  805.  
  806.     case PGA :    /* for pga display */
  807.  
  808.           x = sample - 1;
  809.           y = 480 - line;
  810.           cmd[0] = 0x0D9;
  811.             cmd[1] = y;  cmd[2] = y >> 8;
  812.             cmd[3] = x;  cmd[4] = x >> 8;
  813.             cmd[5] = x;  cmd[6] = x >> 8;
  814.             cmd[7] = 0;       cmd[8] = DN;
  815.           PGAsend (cmd, 9);       /* 'IMAGEW y x x ' */
  816.           return;
  817.  
  818.     case VGA200 :   /* for ega and vga displays */
  819.     case ORCHID480 :    /* for orchid designer */
  820.     case ORCHID600 :    /* for orchid designer */
  821.     case ORCHID768 :    /* for orchid designer */
  822.  
  823.           laddress = ((long)dispns*(long)(line-1))+(long)(sample-1);
  824.           segment  = laddress >> 16;
  825.           laddress = laddress & 0x0FFFF;
  826.           faraddr  = (unsigned char far *) (0x0a0000000L + laddress);
  827.           outp(0x3cd,0x40 | segment);
  828.           *(faraddr) = (unsigned char)DN;
  829.           return;
  830.  
  831.     case EVGA640 :    /* for Everex EVGA */
  832.     case EVGA512 :    /* for Everex EVGA */
  833.  
  834.           EVGAWritePixel256(sample, line, DN);
  835. /*
  836.           laddress = ((long)dispns*(long)(line-1))+(long)(sample-1);
  837.           segment  = laddress >> 0x10;
  838.           laddress = laddress & 0xFFFF;
  839.           EVGASetPage(segment);
  840.           faraddr = (unsigned char far *) (0xA0000000 + laddress);
  841.           *(faraddr) = (unsigned char)DN;
  842. */
  843.           return ;
  844.  
  845.     case EVGA800 :    /* for Everex EVGA */
  846.  
  847.           useBIOS = 0;
  848.           EVGAWritePixelEGA (sample, line, DN, useBIOS);
  849.           return ;
  850.  
  851.     case ATI640 :    /* for ATI VGA Wonder */
  852.     case ATI800 :    /* for ATI VGA Wonder */
  853.     case ATI1024:    /* for ATI VGA Wonder */
  854.  
  855.           x = (unsigned int) sample;
  856.           y = (unsigned int) line;
  857.           color = (unsigned int) DN;
  858.  
  859.           ATI_WritePixel(x,y,color);
  860.           return ;
  861.  
  862.     case PARADISE :   /* for Super VGA */
  863.  
  864.             WritePixelPAR (line-1, sample-1, DN);
  865.             outp( 0x3ce, 0x0000f);                 /* added - mwm */
  866.             return;
  867.  
  868.     }
  869. }
  870.  
  871. int ReadPixel (int line, int sample, int * p_DN)
  872.  
  873. /***  ReadPixel read a pixel value from the display screen.
  874.       Parameter   type       description
  875.         line     integer     The line coordinate of the pixel
  876.         sample   integer     The sample coordinate of the pixel
  877.         p_DN     int ptr     The DN value of the pixel is returned
  878. **/
  879.  
  880. {
  881.     int   address, y, x, mask, bit;
  882.     int   len;
  883.     unsigned int  segment;
  884.     unsigned long laddress;
  885.     unsigned char   cmd[256];
  886.     unsigned char far *faraddr;
  887.  
  888.     switch (DisplayDevice)
  889.     {
  890.     case CGA :     /* for cga display */
  891.  
  892.           line--;
  893.           sample--;
  894.           bit = 7 - (sample & 7);
  895.  
  896.           if ((line & 1) == 0)
  897.               address = 0x8000 + 40*line + (sample >> 3);
  898.           else
  899.               address = 0x0A000 + 40*(line-1) + (sample >> 3);
  900.  
  901.           *p_DN = (getmem(0x0B000,address) & (1 << bit)) >> bit;
  902.           return;
  903.  
  904.     case EGA350 :   /* for ega and vga displays */
  905.     case EGA480 :   /* for ega and vga displays */
  906.     case VGA480 :   /* for ega and vga displays */
  907.     case BIOS :   /* for ega and vga displays */
  908.     case EVGA640 :    /* for Everex EVGA */
  909.     case EVGA512 :    /* for Everex EVGA */
  910.     case EVGA800 :    /* for Everex EVGA */
  911.  
  912.           y = line - 1;
  913.           x = sample - 1;
  914.           address = (y << 6) + (y << 4) + (x >> 3);
  915.           mask = 0x80 >> (x & 7);
  916.           *p_DN = 0;
  917.           for (bit = 3;  bit >= 0;  bit--)
  918.           {
  919.               outp (0x3CE, 4);
  920.               outp (0x3CF, bit);
  921.               if ( (getmem (0x0A000,address) & mask) > 0 )
  922.                   *p_DN = (*p_DN << 1) | 1;
  923.               else
  924.                   *p_DN = *p_DN << 1;
  925.           }
  926.           return;
  927.  
  928.     case ATI640 :   /* for ATI VGA Wonder */
  929.     case ATI800 :   /* for ATI VGA Wonder */
  930.     case ATI1024:   /* for ATI VGA Wonder */
  931.  
  932.           *p_DN = ATI_ReadPixel(sample,line);
  933.           return;
  934.  
  935.     case PGA :     /* for pga display */
  936.  
  937.           x = sample - 1;     y = 480 - line;
  938.           cmd[0] = 0x0D8;
  939.             cmd[1] = y;  cmd[2] = y >> 8;
  940.             cmd[3] = x;  cmd[4] = x >> 8;
  941.             cmd[5] = x;  cmd[6] = x >> 8;
  942.           PGAsend (cmd, 7);          /* 'IMAGER y x x ' */
  943.           for (x = 0; x < 1000; x++) ;    /* delay loop */
  944.           PGAreceive (cmd, &len);
  945.           *p_DN = cmd[8];
  946.           return;
  947.  
  948.     case VGA200 :   /* for ega and vga displays */
  949.     case ORCHID480 :     /* for orchid designer */
  950.     case ORCHID600 :     /* for orchid designer */
  951.     case ORCHID768 :     /* for orchid designer */
  952.  
  953.           laddress = ((long)dispns*(long)(line-1))+(long)(sample-1);
  954.           segment  = laddress >> 16;
  955.           laddress = laddress & 0x0FFFF;
  956.           faraddr  = (unsigned char far *) (0x0a0000000L + laddress);
  957.           outp(0x3cd,0x40 | segment << 3);
  958.           *p_DN = *(faraddr);
  959.           return;
  960.  
  961.     case PARADISE : /* for Super VGA */
  962.  
  963.          ReadPixelPAR(line-1,sample-1,p_DN);
  964.          *p_DN &= 0xFF;                         /* Remove garbage - mwm */
  965.          return;
  966.  
  967.     }
  968. }
  969.  
  970. int DisplayLine (unsigned char * buffer, int line, int sample, int ns)
  971.  
  972. /***  DisplayLine writes a line of pixels on the display screen.
  973.       Parameter   type       description
  974.         buffer   char ptr    The array of pixel values
  975.         line     integer     The line coordinate of the first pixel
  976.         sample   integer     The sample coordinate of the first pixel
  977.         ns       integer     The number of pixels to display
  978. ***/
  979.  
  980. {
  981.     unsigned char   cmd[7];
  982.     unsigned int   x,y, x1, x2, len, s;
  983.     int            i, address, mask, bit;
  984.     unsigned int  segment;
  985.     unsigned long laddress;
  986.     unsigned char far *faraddr;
  987.     unsigned int  color;
  988.  
  989.     switch (DisplayDevice)
  990.     {
  991.     case CGA :     /* for cga display */
  992.  
  993.           line--;
  994.           sample--;
  995.           if ((line & 1) == 0)
  996.               address = 0x8000 + 40*line + (sample >> 3);
  997.           else
  998.               address = 0x0A000 + 40*(line-1) + (sample >> 3);
  999.           bit = 7 - (sample & 7);
  1000.           mask = getmem(0x0B000,address) & ~((1 << (bit+1)) - 1);
  1001.           for (i = 0;  i < ns;  i++)
  1002.           {
  1003.               mask |= (buffer[i] & 1) << bit;
  1004.               bit--;
  1005.               if (bit < 0)
  1006.               {
  1007.                   putmem(0x0B000,address, mask);
  1008.                   address++;
  1009.                   bit = 7;
  1010.                   mask = 0;
  1011.               }
  1012.           }
  1013.           putmem(0x0B000,address,
  1014.                   mask | (getmem(0x0B000,address) & ((1 << (bit+1)) - 1)) );
  1015.           return;
  1016.  
  1017.     case EGA350 :   /* for ega and vga displays */
  1018.     case EGA480 :   /* for ega and vga displays */
  1019.     case VGA480 :   /* for ega and vga displays */
  1020.     case BIOS :   /* for ega and vga displays */
  1021.     case EVGA800 :    /* for Everex EVGA */
  1022.  
  1023.           DisplayLineEGA (FP_SEG(buffer),FP_OFF(buffer), line, sample, ns);
  1024.           return;
  1025.  
  1026.     case ATI640 :
  1027.     case ATI800 :
  1028.     case ATI1024:
  1029.  
  1030.           y = line;
  1031.           for (i=0; i<ns; i++)
  1032.           {
  1033.              x = sample + i;
  1034.              color = (unsigned int)(buffer[i]);
  1035.              ATI_WritePixel(x,y,color);
  1036.           }
  1037.           return;
  1038.  
  1039.     case PGA :     /* for pga display */
  1040.           y = 480 - line;  x1 = sample - 1;  x2 = x1 + ns - 1;
  1041.           cmd[0] = 0x0D9;
  1042.            cmd[1] = y;   cmd[2] = y >> 8;
  1043.            cmd[3] = x1;  cmd[4] = x1 >> 8;
  1044.            cmd[5] = x2;  cmd[6] = x2 >> 8;
  1045.           PGAsend (cmd, 7);       /* 'IMAGEW y x1 x2 ' */
  1046.           s = 0;
  1047.           while (s < ns)
  1048.           {
  1049.               len = ns - s;   if (len > 128)  len = 128;
  1050.               cmd[0] = 127 + len;
  1051.               PGAsend (cmd, 1);
  1052.               PGAsend (&buffer[s], len);
  1053.               s += 128;
  1054.           }
  1055.           return;
  1056.  
  1057.     case VGA200 :   /* for ega and vga displays */
  1058.     case ORCHID480 :     /* for orchid designer */
  1059.     case ORCHID600 :     /* for orchid designer */
  1060.     case ORCHID768 :     /* for orchid designer */
  1061.  
  1062.           laddress = ((long)dispns*(long)(line-1))+(long)(sample-1);
  1063.           segment  = laddress >> 16;
  1064.           laddress = laddress & 0x0FFFF;
  1065.           if ((laddress + (long)ns) > 65535L)
  1066.           /* this line will overlap a segment so write it pixel by pixel */
  1067.             for (i = 0; i < ns; i++) WritePixel(line,sample+i,(int)buffer[i]);
  1068.           else
  1069.             {
  1070.              faraddr  = (unsigned char far *) (0x0a0000000L + laddress);
  1071.              outp(0x3cd,0x40 | segment);
  1072.              memcpy (faraddr,buffer,ns);
  1073.             }
  1074.           return;
  1075.  
  1076.     case EVGA640 :    /* for Everex EVGA */
  1077.     case EVGA512 :    /* for Everex EVGA */
  1078.  
  1079.           laddress = ((long)dispns*(long)(line))+(long)(sample-1);
  1080.           segment  = laddress >> 16;
  1081.           laddress = laddress & 0x0FFFF;
  1082.           if ((laddress + (long)ns) > 65535L)
  1083.           /* this line will overlap a segment so write it pixel by pixel */
  1084.             for (i = 0; i < ns; i++) EVGAWritePixel256(sample+i,line,(int)buffer[i]);
  1085.           else
  1086.             {
  1087.              faraddr  = (unsigned char far *) (0x0a0000000L + laddress);
  1088.              EVGASetPage(segment);
  1089.              memcpy (faraddr,buffer,ns);
  1090.             }
  1091.           return;
  1092.  
  1093.     case PARADISE : /* for Super VGA */
  1094.  
  1095.           WriteLinePAR (sample-1,ns,line-1,buffer);
  1096.           outp( 0x3ce, 0x0000f);                 /* added - mwm */
  1097.           return;
  1098.     }
  1099. }
  1100.  
  1101. int FormatLine (unsigned char * buffer, int nsdd, int nsd, int bitshift,
  1102.                 int NoScale, char * status)
  1103.  
  1104. /*  FormatLine converts the line of pixels in the buffer into
  1105.     byte format for display.  It also performs subsampling
  1106.     or zooming if needed.
  1107. */
  1108.  
  1109. {
  1110.     int   samp, j, k, DN, scale, absbitshift;
  1111.     int   mult;
  1112.     float fscale;
  1113.     unsigned char  tmpbuf[2048];
  1114.     union {
  1115.                unsigned char   *b;
  1116.                int             *i;
  1117.           }  buf;
  1118.     buf.b = buffer;
  1119.  
  1120.  
  1121.     status[0] = 0;
  1122.     TurnCursorOff = 0; /* always reinitialize the cursor fn to be on */
  1123.  
  1124. /* For 16 bit images */
  1125. /* scaling is done by dividing by a scale factor if the dn range specified
  1126.    is greater than the display range and by multiplying if the range
  1127.    specified is less than the display range
  1128. */
  1129.     if (bitsperpix == 16 || bitsperpix ==32)
  1130.     {
  1131.        fscale = ((float)(DNhigh - DNlow) / (float)numDN);
  1132.        if (fscale < 1)
  1133.        {
  1134.           mult = 1;
  1135.           scale = 1.0/fscale;
  1136.        }
  1137.        else
  1138.        {
  1139.           mult = 0;
  1140.           scale = fscale + 1;
  1141.        }
  1142.  
  1143.        if (zoom == 1 )
  1144.        {
  1145.            samp = 0;
  1146.            for (j = 0;  j < nsdd;  j++)
  1147.            {
  1148.                DN = buf.i[samp];
  1149.                if (DN >= DNhigh)
  1150.                    DN = DNhigh - 1;
  1151.                else
  1152.                    if (DN <= DNlow)
  1153.                        DN = DNlow;
  1154.  
  1155.                if (mult)
  1156.                    buf.b[j] = ((long)DN-DNlow) *  scale;
  1157.                else
  1158.                    buf.b[j] = ((long)DN-DNlow) /  scale;
  1159.                samp += subsample;
  1160.            }
  1161.        }
  1162.        else
  1163.        {
  1164.            j = nsd*zoom-1;
  1165.            for (samp = nsd-1;  samp >= 0;  samp--)
  1166.            {
  1167.                DN = buf.i[samp];
  1168.                if (DN >= DNhigh)
  1169.                    DN = DNhigh - 1;
  1170.                else
  1171.                    if (DN <= DNlow)
  1172.                        DN = DNlow;
  1173.                if (mult)
  1174.                    DN = ((long)DN-DNlow) *  scale;
  1175.                else
  1176.                    DN = ((long)DN-DNlow) /  scale;
  1177.  
  1178.                for (k = 1;  k <= zoom;  k++)
  1179.                   buf.b[j--] = DN;
  1180.            }
  1181.        }
  1182.  
  1183.     }
  1184.  
  1185. /* For byte images (no offset) */
  1186.  
  1187.     else if ( (bitsperpix == 8) && NoScale )
  1188.     {
  1189.         if ( (subsample == 1) && (zoom == 1) )
  1190.         {
  1191.             if (bitshift > 0)
  1192.                 for (j = 0;  j < nsdd;  j++)
  1193.                     buf.b[j] >>= bitshift;
  1194.         }
  1195.         else if (zoom == 1)
  1196.         {
  1197.             samp = 0;
  1198.             for (j = 0;  j < nsdd;  j++)
  1199.             {
  1200.                 buf.b[j] = buf.b[samp] >> bitshift;
  1201.                 samp += subsample;
  1202.             }
  1203.         }
  1204.         else
  1205.         {
  1206.             j = nsd*zoom - 1;
  1207.             for (samp = nsd-1;  samp >= 0;  samp--)
  1208.             {
  1209.                 DN = buf.b[samp] >> bitshift;
  1210.                 for (k = 1;  k <= zoom;  k++)
  1211.                     buf.b[j--] = DN;
  1212.             }
  1213.         }
  1214.     }
  1215.  
  1216.  
  1217. /* For byte images (with offset) */
  1218.  
  1219. /* scaling is done by dividing by a scale factor if the dn range specified
  1220.    is greater than the display range and by multiplying if the range
  1221.    specified is less than the display range
  1222. */
  1223.     else if ( (bitsperpix == 8) && !NoScale )
  1224.     {
  1225.        fscale = ((float)(DNhigh - DNlow) / (float)numDN);
  1226.        if (fscale < 1)
  1227.        {
  1228.            mult = 1;
  1229.            scale = 1.0/fscale;
  1230.        }
  1231.        else
  1232.        {
  1233.            mult = 0;
  1234.            scale = fscale + 1;
  1235.        }
  1236.        if (zoom == 1)
  1237.        {
  1238.            samp = 0;
  1239.            for (j = 0;  j < nsdd;  j++)
  1240.            {
  1241.                DN = buf.b[samp];
  1242.                if (DN >= DNhigh)
  1243.                    DN = DNhigh - 1;
  1244.                else
  1245.                    if (DN <= DNlow)
  1246.                        DN = DNlow;
  1247.                if (mult)
  1248.                    buf.b[j] = (DN-DNlow) *  scale;
  1249.                else
  1250.                    buf.b[j] = (DN-DNlow) /  scale;
  1251.                samp += subsample;
  1252.            }
  1253.        }
  1254.        else
  1255.        {
  1256.            j = nsd*zoom - 1;
  1257.            for (samp = nsd-1;  samp >= 0;  samp--)
  1258.            {
  1259.                DN = buf.b[samp];
  1260.                if (DN >= DNhigh)
  1261.                    DN = DNhigh - 1;
  1262.                else
  1263.                    if (DN <= DNlow)
  1264.                        DN = DNlow;
  1265.                if (mult)
  1266.                    buf.b[j] = (DN-DNlow) * scale;
  1267.                else
  1268.                    DN = (DN-DNlow) / scale;
  1269.                for (k = 1;  k <= zoom;  k++)
  1270.                {     /* 256 color bug fix - Ron Baalke - 07/15/90  */
  1271.                    if ((numDN == 256) && ((DNlow >0) || (DNhigh < 255)))
  1272.                        buf.b[j--] = (DN - DNlow) * scale;
  1273.                    else
  1274.                        buf.b[j--] = DN;
  1275.                }
  1276.            }
  1277.        }
  1278.  
  1279.     }
  1280.  
  1281.  
  1282. /*  For 4 bit and 1 bit images */
  1283.     else
  1284.     {
  1285.        absbitshift = abs(bitshift);
  1286.        ConvertLine (buf.b, tmpbuf, bitsperpix, 8, nsd, status);
  1287.        if (zoom == 1)
  1288.        {
  1289.            samp = 0;
  1290.            for (j = 0;  j < nsdd;  j++)
  1291.            {
  1292.                if (DisplayDevice == 0)
  1293.                {
  1294.                    buf.b[j] = tmpbuf[samp];
  1295.                }
  1296.                else
  1297.                {
  1298.                    buf.b[j] = tmpbuf[samp] << absbitshift;
  1299.                }
  1300.                samp += subsample;
  1301.            }
  1302.        }
  1303.        else
  1304.        {
  1305.            j = nsd*zoom - 1;
  1306.            for (samp = nsd-1;  samp >= 0;  samp--)
  1307.            {
  1308.                if (DisplayDevice == 0)
  1309.                {
  1310.                    DN = tmpbuf[samp];
  1311.                }
  1312.                else
  1313.                {
  1314.                    DN = tmpbuf[samp] << absbitshift;
  1315.                }
  1316.                for (k = 1;  k <= zoom;  k++)
  1317.                    buf.b[j--] = DN;
  1318.            }
  1319.        }
  1320.     }
  1321. }
  1322.  
  1323.  
  1324. int ClearDisplay (int DN)
  1325.  
  1326. /***  ClearDisplay sets the whole display to a particular value.
  1327.       Parameter   type       description
  1328.         DN       integer     The DN value to set (usually 0)
  1329. ***/
  1330.  
  1331. {
  1332.     int      address, junk;
  1333.     unsigned char   cmd[2];
  1334.     unsigned int  i,j,segment;
  1335.     unsigned char far *faraddr;
  1336.  
  1337.     switch (DisplayDevice)
  1338.     {
  1339.  
  1340.     case CGA :    /* for cga display */
  1341.           junk = 0x0FF*(DN & 1);
  1342.           for (address = 0; address < 8000;  address++)
  1343.           {
  1344.               putmem(0x0B800,address, junk);
  1345.               putmem(0x0BA00,address, junk);
  1346.           }
  1347.           return;
  1348.  
  1349.     case EGA350 :   /* for ega and vga displays */
  1350.     case EGA480 :   /* for ega and vga displays */
  1351.     case VGA480 :   /* for ega and vga displays */
  1352.     case BIOS :     /* for ega and vga displays */
  1353.  
  1354.           ClearDisplayEGA (DN,dispnl);
  1355.           return;
  1356.  
  1357.     case ATI640 :
  1358.     case ATI800 :
  1359.     case ATI1024:
  1360.  
  1361.           faraddr  = (unsigned char far *) 0x0a0000000L ;
  1362.           for (i=0; i < 8; i++)
  1363.             {
  1364.              atibank = i;
  1365.              ATI_Bank();
  1366.              memset(faraddr,DN,32768);
  1367.              memset(faraddr+32768L,DN,32768);
  1368.             }
  1369.           return;
  1370.  
  1371.     case PGA :
  1372.  
  1373.           cmd[0] = 0x0F;  cmd[1] = DN;
  1374.           PGAsend (cmd, 2);
  1375.           return;
  1376.  
  1377.     case VGA200 :   /* for ega and vga displays */
  1378.     case ORCHID480 :      /* for orchid designer */
  1379.     case ORCHID600 :      /* for orchid designer */
  1380.     case ORCHID768 :      /* for orchid designer */
  1381.  
  1382.           faraddr  = (unsigned char far *) 0x0a0000000L ;
  1383.           for (i = 0; i < 5; i++)
  1384.             {
  1385.              outp(0x3cd,0x40 | i);
  1386.              memset(faraddr,'\0',32768);
  1387.              memset(faraddr+32768L,'\0',32768);
  1388.             }
  1389.           if (dispnl > 480)
  1390.             for (i = 5; i < 8; i++)
  1391.               {
  1392.                outp(0x3cd,0x40 | i);
  1393.                memset(faraddr,'\0',32768);
  1394.                memset(faraddr+32768L,'\0',32768);
  1395.               }
  1396.  
  1397.           return;
  1398.  
  1399.     case EVGA640 :    /* for ega and vga displays */
  1400.     case EVGA512 :    /* for ega and vga displays */
  1401.     case EVGA800 :    /* for ega and vga displays */
  1402.  
  1403.           EVGAClearDisplay(DN);
  1404.           return;
  1405.  
  1406.     case PARADISE:
  1407.  
  1408.           ClearDisplayPAR(DN);
  1409.           return;
  1410.     }
  1411. }
  1412.  
  1413.  
  1414. int PGAreceive (unsigned char * answer, int * p_len)
  1415. /*
  1416.     This routine receives data from the PGA device.
  1417.     Only used by ReadPixel routine.
  1418. */
  1419.  
  1420. {
  1421.     unsigned char   i, InWritePtr, InReadPtr, numbytes;
  1422.  
  1423.     do
  1424.     {
  1425.         InReadPtr  = getmem (0x0C600,0x0303);
  1426.         InWritePtr = getmem (0x0C600,0x0302);
  1427.         numbytes   = InWritePtr - InReadPtr;
  1428.     } while (numbytes == 0);
  1429.  
  1430.     for (i = 0; i < numbytes; i++)
  1431.        answer[i] = getmem (0x0C610,InReadPtr++);
  1432.  
  1433.     putmem (0x0C600, 0x0303, InReadPtr);
  1434.     *p_len = numbytes;
  1435. }
  1436.