Category : C Source Code
Archive   : IMDSRC78.ZIP
Filename : DISPIO.C

 
Output of file : DISPIO.C contained in archive : IMDSRC78.ZIP
/*** IMDISP module DISPIO.C

DISPIO contains the device dependent display routines for the
Color Graphics Adapter (CGA), the Enhanced Graphics Adapter (EGA),
the Professional Graphics Adapter (PGA) and the Video Graphics Array
(VGA). The global variables that define the device are allocated
and initialized here.

***/

#define __MSC

/* * * * INCLUDE files * * * */

#include
#include

#ifdef __TURBOC__
#include
#else
#include
#endif

#include
#include
#include
#include
#include "mshell.h"
#include "imdef.h"
#include "imdisp.h"
#include "imageio.h"
#include "evgaio.h"
#include "ativga.h"
#include "dispsub.h"
#include "paradise.h"
#include "textutil.h"
#include "keywutil.h"
#include "trident.h"
#include "refresh.h"
#include "buffer.h"
#include "vesa.h"
#include "mem.h"

#include "ev629.h"

/* * * * Defined Constants * * * */

/* * * * External functions * * * */

/* * * * Function declarations * * * */

int DisplayOn (void);
int DisplayOff (void);
int WritePixel (int, int, int);
int ReadPixel (int, int, int *);
int DisplayLine (unsigned char *,int ,int ,int );
int GetLine (unsigned char *,int ,int ,int );
int FormatLine (unsigned char *, int, int, int, int, char *);
int ClearDisplay (int );
int PGAreceive (unsigned char *, int *);
int Which_Tseng(void);

/* * * * Global Variables * * * */

int atibank;
unsigned int LastPage;
int tseng;

/*
DisplayDevice indicates the type of display (CGA=0, EGA=1, PGA=2, etc).
dispnl is the number of lines in the display.
dispns is the number of samples in the display.
numDN is the number of unique pixel values (e.g. 4 bits ->
numDN=16).
numshades is the number of shades each of red, green, and blue
(e.g. numshades=16 gives 16**3 = 4096 possible colors).
OneScreen is true if there is only one screen, i.e. there is not
image screen and a text screen.
*/

int dispnl, dispns, numDN, numshades, OneScreen;

Color DefaultPalette[256], PaletteTable[256];

enum Display
{ DISPLAY_MIN = -1, CGA200, EGA350, PGA, VGA480, VGA200, BIOS,
ORCHID480, ORCHID600, EVGA640, EVGA512, EVGA800, EGA480,
ATI640, ATI800, ATI1024, PARADISE, ORCHID768, TRIDENT, VESA,
VESA800, VESA640, EV629, TEST, DISPLAY_MAX };

enum Display DisplayDevice;

int DisplayOn(void)

/***
DisplayOn figures out which display device is on the system and then
initializes for that device. The device is turned on. The global
variables that define the display characteristics and the default
color palette are initialized.
***/

{
int i, VESA_mode;
unsigned char cmd[7], EVGApalette[17];
union REGS inreg, outreg, regs;
struct SREGS segregs;
Color DP[16];

/* Test for Enhanced Graphics Adapter (EGA) */
if (DisplayDevice == CGA200)
{
inreg.x.ax = 0x1200;
inreg.x.bx = 0x0FF10;
inreg.x.cx = 0x000F;
int86 (0x10, &inreg, &outreg);
if ( (outreg.h.cl < 0x0C) && (outreg.h.bh <= 1) && (outreg.h.bl <= 3) )
DisplayDevice = EGA350;
}

/* moved from before ega test to avoid conflicts with memory boards*/
/* mdm 2-19-88 */

/* Test for Professional Graphics Adapter (PGA) */
/* if (DisplayDevice == CGA200 && devname == NULL) */
if (DisplayDevice == CGA200)
{
putmem (0x0C000, 0x63DB, 0x0AD);
if (getmem (0x0C000, 0x63DB) == 0x0AD)
DisplayDevice = PGA;
}

/* Initialize for the appropriate device */
switch (DisplayDevice)
{
case CGA200 : /* for standard cga display */

dispnl = 200;
dispns = 640;
numDN = 2;
numshades = 2;
OneScreen = 1;
_setvideomode( _HRESBW );
DefaultPalette[0].r = 0; DefaultPalette[1].r = 255;
DefaultPalette[0].g = 0; DefaultPalette[1].g = 255;
DefaultPalette[0].b = 0; DefaultPalette[1].b = 255;
break;

case EGA350 : /* for standard ega displays */

dispnl = 350;
dispns = 640;
numDN = 16;
numshades = 4;
OneScreen = 1;
_setvideomode( _ERESCOLOR );

DP[0].r = 32; DP[0].g = 32; DP[0].b = 32;
DP[1].r = 96; DP[1].g = 32; DP[1].b = 32;
DP[2].r = 160; DP[2].g = 32; DP[2].b = 32;
DP[3].r = 224; DP[3].g = 32; DP[3].b = 32;
DP[4].r = 224; DP[4].g = 96; DP[4].b = 32;
DP[5].r = 224; DP[5].g = 160; DP[5].b = 32;
DP[6].r = 224; DP[6].g = 224; DP[6].b = 32;
DP[7].r = 160; DP[7].g = 224; DP[7].b = 32;
DP[8].r = 32; DP[8].g = 224; DP[8].b = 32;
DP[9].r = 32; DP[9].g = 224; DP[9].b = 160;
DP[10].r = 32; DP[10].g = 160; DP[10].b = 160;
DP[11].r = 32; DP[11].g = 160; DP[11].b = 224;
DP[12].r = 32; DP[12].g = 32; DP[12].b = 224;
DP[13].r = 160; DP[13].g = 32; DP[13].b = 224;
DP[14].r = 224; DP[14].g = 32; DP[14].b = 224;
DP[15].r = 224; DP[15].g = 224; DP[15].b = 224;
for (i = 0; i <= 15; i++)
{
DefaultPalette[i].r = DP[i].r;
DefaultPalette[i].g = DP[i].g;
DefaultPalette[i].b = DP[i].b;
}

break;

case EGA480 : /* for extended ega displays */

/* if environment variable EGA480 is not null, then
initialize for 480 line mode. Requires crystal
upgrade on EGA board and multisync monitor. */

dispnl = 480;
dispns = 640;
numDN = 16;
numshades = 4;
OneScreen = 1;
egainit(); /* special init routines in dispsub.asm */

DP[0].r = 32; DP[0].g = 32; DP[0].b = 32;
DP[1].r = 96; DP[1].g = 32; DP[1].b = 32;
DP[2].r = 160; DP[2].g = 32; DP[2].b = 32;
DP[3].r = 224; DP[3].g = 32; DP[3].b = 32;
DP[4].r = 224; DP[4].g = 96; DP[4].b = 32;
DP[5].r = 224; DP[5].g = 160; DP[5].b = 32;
DP[6].r = 224; DP[6].g = 224; DP[6].b = 32;
DP[7].r = 160; DP[7].g = 224; DP[7].b = 32;
DP[8].r = 32; DP[8].g = 224; DP[8].b = 32;
DP[9].r = 32; DP[9].g = 224; DP[9].b = 160;
DP[10].r = 32; DP[10].g = 160; DP[10].b = 160;
DP[11].r = 32; DP[11].g = 160; DP[11].b = 224;
DP[12].r = 32; DP[12].g = 32; DP[12].b = 224;
DP[13].r = 160; DP[13].g = 32; DP[13].b = 224;
DP[14].r = 224; DP[14].g = 32; DP[14].b = 224;
DP[15].r = 224; DP[15].g = 224; DP[15].b = 224;
for (i = 0; i <= 15; i++)
{
DefaultPalette[i].r = DP[i].r;
DefaultPalette[i].g = DP[i].g;
DefaultPalette[i].b = DP[i].b;
}

break;

case EVGA800 : /* for Everex EV-673 hi-res ega mode */

dispns = 800;
dispnl = 600;
numDN = 16;
numshades = 4;
OneScreen = 1;
inreg.x.ax = 0x0070; /* turn on EVGA MODE */
inreg.x.bx = 0x0002; /* at 800x600 res */
int86 (0x10, &inreg, &outreg);

DP[0].r = 32; DP[0].g = 32; DP[0].b = 32;
DP[1].r = 96; DP[1].g = 32; DP[1].b = 32;
DP[2].r = 160; DP[2].g = 32; DP[2].b = 32;
DP[3].r = 224; DP[3].g = 32; DP[3].b = 32;
DP[4].r = 224; DP[4].g = 96; DP[4].b = 32;
DP[5].r = 224; DP[5].g = 160; DP[5].b = 32;
DP[6].r = 224; DP[6].g = 224; DP[6].b = 32;
DP[7].r = 160; DP[7].g = 224; DP[7].b = 32;
DP[8].r = 32; DP[8].g = 224; DP[8].b = 32;
DP[9].r = 32; DP[9].g = 224; DP[9].b = 160;
DP[10].r = 32; DP[10].g = 160; DP[10].b = 160;
DP[11].r = 32; DP[11].g = 160; DP[11].b = 224;
DP[12].r = 32; DP[12].g = 32; DP[12].b = 224;
DP[13].r = 160; DP[13].g = 32; DP[13].b = 224;
DP[14].r = 224; DP[14].g = 32; DP[14].b = 224;
DP[15].r = 224; DP[15].g = 224; DP[15].b = 224;
for (i = 0; i <= 15; i++)
{
DefaultPalette[i].r = DP[i].r;
DefaultPalette[i].g = DP[i].g;
DefaultPalette[i].b = DP[i].b;
}

break;

case VGA480 : /* for standard vga displays */
#ifndef __TURBOC__
case BIOS : /* for standard vga displays */
#endif
dispnl = 480;
dispns = 640;
numDN = 16;
numshades = 64;
OneScreen = 1;
_setvideomode( _VRES16COLOR );

/* load default gray level palette with 17 dn increments */
for (i = 0; i <= 15; i++)
{
DefaultPalette[i].r = i*16+i;
DefaultPalette[i].g = i*16+i;
DefaultPalette[i].b = i*16+i;
}
break;

case PGA: /* for standard pga display */

dispnl = 480;
dispns = 640;
numDN = 256;
numshades = 16;
OneScreen = 1;

cmd[0] = 0x43; cmd[1] = 0x58; cmd[2] = 0x20;
cmd[3] = 0x0D0; cmd[4] = 0x00;
cmd[5] = 0x0F; cmd[6] = 0x00;
PGAsend (cmd, 7); /* 'CA DISPLA 0 CLEARS 0 ' */

for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
break;

case ORCHID480 : /* for Orchid ProDesigner enhanced VGA mode */

dispnl = 480;
dispns = 640;
numDN = 256;
numshades = 64;
OneScreen = 1;
inreg.x.ax = 0x002E; /* set 256 color 640 x480 mode */
int86 (0x10, &inreg, &outreg);
inreg.x.ax = 0x0500; /* select page */
int86 (0x10, &inreg, &outreg);

for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}

tseng = Which_Tseng(); /* Ron Baalke - 04/22/91 */
break;

case ORCHID600 : /* for Orchid ProDesigner+ with 512K */

dispnl = 600;
dispns = 800;
numDN = 256;
numshades = 64;
OneScreen = 1;
inreg.x.ax = 0x0030; /* set 256 color 800 x 600 mode */
int86 (0x10, &inreg, &outreg);
inreg.x.ax = 0x0500; /* select page */
int86 (0x10, &inreg, &outreg);

for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
tseng = Which_Tseng(); /* Ron Baalke - 04/22/91 */
break;

case ORCHID768 : /* for Orchid ProDesigner+ with 1024K */

dispnl = 768;
dispns = 1024;
numDN = 256;
numshades = 64;
OneScreen = 1;
inreg.x.ax = 0x0038; /* set 256 color 1024 x 768 mode */
int86 (0x10, &inreg, &outreg);
inreg.x.ax = 0x0500; /* select page */
int86 (0x10, &inreg, &outreg);

for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
tseng = Which_Tseng(); /* Ron Baalke - 04/22/91 */
break;

case VGA200 : /* for standard VGA displays */

dispnl = 200;
dispns = 320;
numDN = 256;
numshades = 64;
OneScreen = 1;
_setvideomode( _MRES256COLOR );
for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
break;

case EVGA640 : /* for Everex EV-673 enhanced vga mode */

dispns = 640;
dispnl = 400;
numDN = 256;
numshades = 64;
OneScreen = 1;
inreg.x.ax = 0x0070;
inreg.x.bx = 0x0014;
int86 (0x10, &inreg, &outreg);
for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
EVGASetPage(0);
break;

case EVGA512 : /* for Everex EV-673 almost image proc mode */

dispns = 512;
dispnl = 480;
numDN = 256;
numshades = 64;
OneScreen = 1;
inreg.x.ax = 0x0070;
inreg.x.bx = 0x0015;
int86 (0x10, &inreg, &outreg);
for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
EVGASetPage(0);
break;

case ATI640: /* for ATI VGA Wonder */

dispns = 640;
dispnl = 480;
numDN = 256;
numshades = 16;
OneScreen = 1;

ATI_Init();

for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
break;

case ATI800: /* for ATI VGA Wonder */

dispns = 800;
dispnl = 600;
numDN = 256;
numshades = 16;
OneScreen = 1;


ATI_Init();

for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
break;

case ATI1024: /* for ATI VGA Wonder */

dispns = 1024;
dispnl = 768;
numDN = 16;
numshades = 4;
OneScreen = 1;

ATI_Init();

/* load default gray level palette */
for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
break;

case PARADISE : /* for SUPER VGA board */

dispnl = 480;
dispns = 640;
numDN = 256;
numshades = 64;
OneScreen = 1;
inreg.x.ax=0x007F; /*BIOS check on board memory */
inreg.x.bx=0x0200;
int86 (0x10, &inreg, &outreg);
if(outreg.h.ch >= 5) /*return number of 64k units */
{
inreg.x.ax = 0x005F; /*we have at least 309k for this mode */
int86 (0x10, &inreg, &outreg); /*set 256 color 640 x480 mode */
}
else
{
inreg.x.ax = 0x005E; /*board has only 256k of memory */
int86 (0x10, &inreg, &outreg); /*set 256 color 640 x400 mode */
dispnl=400;
}
for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
break;

case TRIDENT: /* for Trident boards */

dispns = 640;
dispnl = 480;
numDN = 256;
numshades = 16;
OneScreen = 1;

InitTRI();

for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}
break;

case VESA : /* VESA SVGA Driver */

dispns = 1024;
dispnl = 768;
numDN = 256;
numshades = 64;
OneScreen = 1;
inreg.x.ax = 0x4F02; /* SVGA set video mode */
inreg.x.bx = 0x0105; /* 1024x768 mode, clear memory */
int86 (0x10, &inreg, &outreg);
for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}

break;

case VESA800 : /* VESA SVGA Driver */

dispns = 800;
dispnl = 600;
numDN = 256;
numshades = 64;
OneScreen = 1;
inreg.x.ax = 0x4F02; /* SVGA set video mode */
inreg.x.bx = 0x0103; /* 800x600 mode, clear memory */
int86 (0x10, &inreg, &outreg);
for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}

break;

case VESA640 : /* VESA SVGA Driver */

dispns = 640;
dispnl = 480;
numDN = 256;
numshades = 64;
OneScreen = 1;
inreg.x.ax = 0x4F02; /* SVGA set video mode */
inreg.x.bx = 0x0101; /* 640x480 mode, clear memory */
int86 (0x10, &inreg, &outreg);
for (i = 0; i <= 255; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}

break;

case EV629 : /* for Everex EV-629 24-bit board */

dispns = 640;
dispnl = 480;
numDN = 256;
numshades = 256;
OneScreen = 1;

setbits(24);
setwide(640);

init629();
ClearDisplay( 0 );

for (i = 0; i <= numDN; i++)
{
DefaultPalette[i].r = i;
DefaultPalette[i].g = i;
DefaultPalette[i].b = i;
}

break;

}

if (dispnl >= 768)
{
TextHeight = 15;
BigChars = 20;
SmallChars = 12;
}
else if (dispnl >= 600)
{
TextHeight = 12;
BigChars = 15;
SmallChars = 10;
}
else if (dispnl >= 480)
{
TextHeight = 9;
BigChars = 12;
SmallChars = 6;
}
else if (dispnl >= 400)
{
TextHeight = 8;
BigChars = 12;
SmallChars = 6;
}
else if (dispnl >= 350)
{
TextHeight = 8;
BigChars = 10;
SmallChars = 6;
}
else
{
TextHeight = 6;
BigChars = 8;
SmallChars = 5;
}

}


int DisplayOff(void)

/***
DisplayOff turns off the display device returning the screen
to text mode.
***/

{
unsigned char cmd[2];
union REGS inreg, outreg;
int i;

switch (DisplayDevice)
{
#ifndef __TURBOC__
case BIOS : /* for plain vga display */
#endif
case CGA200 : /* for cga display */
case EGA350 : /* for ega and vga displays */
case VGA480 : /* for ega and vga displays */
case VGA200 : /* for ega and vga displays */
case EGA480 : /* for enhanced ega */
case EVGA640 : /* for Everex EVGA */
case EVGA512 : /* for Everex EVGA */
case EVGA800 : /* for Everex EVGA */
case ATI640 : /* For ATI VGA Wonder */
case ATI800 : /* For ATI VGA Wonder */
case ATI1024 : /* For ATI VGA Wonder */
case PARADISE : /* for Paradise Super VGA */
case TRIDENT : /* for Trident Super VGA */
case VESA : /* VESA SVGA Driver */
case VESA800 : /* VESA SVGA Driver */
case VESA640 : /* VESA SVGA Driver */

_setvideomode( _DEFAULTMODE );
break;

case ORCHID480 : /* for orchid designer */
case ORCHID600 : /* for orchid designer */
case ORCHID768 : /* for orchid designer */

ClearDisplay( 0 ); /* Keep Seiko monitor from */
/* shutting off */
inreg.x.ax = 0x0003;
int86 (0x10, &inreg, &outreg);
break;


case PGA: /* for pga display */

cmd[0] = 0x0D0; cmd[1] = 1;
PGAsend (cmd, 2); /* 'DISPLA 1' */
break;

case EV629 : /* for Everex EV-629 24-bit board */

done629();
break;

}
OneScreen = 0;

}


int WritePixel (int line, int sample, int DN)

/*** WritePixel writes a pixel on the display screen.
Parameter type description
line integer The line coordinate of the pixel
sample integer The sample coordinate of the pixel
DN integer The DN value of the pixel
***/

{
unsigned int x, y;
unsigned int segment;
unsigned long laddress;
int address, bit, mask, useBIOS;
unsigned char cmd[9];
unsigned char far *faraddr;
unsigned int color;

long *pix_adr;
long color24;
unsigned int red_pixel, green_pixel, blue_pixel;

switch (DisplayDevice)
{

case CGA200 : /* for cga display */

line--;
sample--;
bit = 7 - (sample & 7);
DN = (DN & 1) << bit;
mask = ~(1 << bit);

if ((line & 1) == 0)
address = 0x8000 + 40*line + (sample >> 3);
else
address = 0x0A000 + 40*(line-1) + (sample >> 3);
putmem (0x0B000, address, (getmem(0xB000,address) & mask) | DN);
return(0);

case EGA350 : /* for ega and vga displays */
case EGA480 : /* for ega and vga displays */
case VGA480 : /* for ega and vga displays */

WritePixelEGA (line, sample, DN);
return(0);

#ifndef __TURBOC__
case BIOS : /* for ega and vga displays */

_setcolor( DN );
_setpixel( sample, line );
return(0);
#endif

case PGA : /* for pga display */

x = sample - 1;
y = 480 - line;
cmd[0] = 0x0D9;
cmd[1] = y; cmd[2] = y >> 8;
cmd[3] = x; cmd[4] = x >> 8;
cmd[5] = x; cmd[6] = x >> 8;
cmd[7] = 0; cmd[8] = DN;
PGAsend (cmd, 9); /* 'IMAGEW y x x ' */
return(0);

case VGA200 : /* for ega and vga displays */
case ORCHID480 : /* for orchid designer */
case ORCHID600 : /* for orchid designer */
case ORCHID768 : /* for orchid designer */

laddress = ((long)dispns*(long)(line-1))+(long)(sample-1);
segment = laddress >> 16;
laddress = laddress & 0x0FFFF;
faraddr = (unsigned char far *) (0x0a0000000L + laddress);
outp(0x3cd,0x40 | segment);
*(faraddr) = (unsigned char)DN;
return(0);

case EVGA640 : /* for Everex EVGA */
case EVGA512 : /* for Everex EVGA */

EVGAWritePixel256(sample, line, DN);
return(0);

case EVGA800 : /* for Everex EVGA */

useBIOS = 0;
EVGAWritePixelEGA (sample, line, DN, useBIOS);
return(0);

case ATI640 : /* for ATI VGA Wonder */
case ATI800 : /* for ATI VGA Wonder */
case ATI1024: /* for ATI VGA Wonder */

x = (unsigned int) sample;
y = (unsigned int) line;
color = (unsigned int) DN;

ATI_WritePixel(x,y,color);
return(0);

case PARADISE : /* for Super VGA */

WritePixelPAR (line-1, sample-1, DN);
outp( 0x3ce, 0x0000f); /* added - mwm */
return(0);

case TRIDENT: /* for Trident SVGA */

x = (unsigned int) sample;
y = (unsigned int) line;
color = (unsigned int) DN;

WritePixelTRI (y-1, x-1, color);
return(0);

case VESA : /* VESA SVGA Driver */
case VESA800 : /* VESA SVGA Driver */
case VESA640 : /* VESA SVGA Driver */

laddress = ( (long) dispns * (long) (line-1)) + (long) (sample-1);
segment = laddress >> 16; /* find page number */
laddress = laddress & 0x0FFFF; /* find offset */
faraddr = (unsigned char far *) (0x0a0000000L + laddress);

if (segment != LastPage)
LastPage = VESA_Set_Page( segment );

*(faraddr) = (unsigned char)DN;
return(0);


case EV629 : /* for Everex EV-629 24-bit board */

pix_adr = pixaddr( sample-1, line-1) ;
red_pixel = (unsigned) DN;
green_pixel = 0;
blue_pixel = 0;
color24 = buildcolor( red_pixel, green_pixel, blue_pixel);
memcpy( pix_adr, &color24, colorbytes);
return(0);

}
}

int ReadPixel (int line, int sample, int * p_DN)

/*** ReadPixel read a pixel value from the display screen.
Parameter type description
line integer The line coordinate of the pixel
sample integer The sample coordinate of the pixel
p_DN int ptr The DN value of the pixel is returned
**/

{
int address, y, x, mask, bit;
int len;
unsigned int segment;
unsigned long laddress;
unsigned char cmd[256];
unsigned char far *faraddr;

long *pix_adr, color24;
unsigned int red_pixel, green_pixel, blue_pixel;

switch (DisplayDevice)
{
case CGA200 : /* for cga display */

line--;
sample--;
bit = 7 - (sample & 7);

if ((line & 1) == 0)
address = 0x8000 + 40*line + (sample >> 3);
else
address = 0x0A000 + 40*(line-1) + (sample >> 3);

*p_DN = (getmem(0x0B000,address) & (1 << bit)) >> bit;
return(0);

case EGA350 : /* for ega and vga displays */
case EGA480 : /* for ega and vga displays */
case VGA480 : /* for ega and vga displays */
case EVGA640 : /* for Everex EVGA */
case EVGA512 : /* for Everex EVGA */
case EVGA800 : /* for Everex EVGA */

y = line - 1;
x = sample - 1;
address = (y << 6) + (y << 4) + (x >> 3);
mask = 0x80 >> (x & 7);
*p_DN = 0;
for (bit = 3; bit >= 0; bit--)
{
outp (0x3CE, 4);
outp (0x3CF, bit);
if ( (getmem (0x0A000,address) & mask) > 0 )
*p_DN = (*p_DN << 1) | 1;
else
*p_DN = *p_DN << 1;
}
return(0);

#ifndef __TURBOC__
case BIOS : /* for ega and vga displays */

*p_DN = _getpixel(sample, line);
return(0);
#endif

case ATI640 : /* for ATI VGA Wonder */
case ATI800 : /* for ATI VGA Wonder */
case ATI1024: /* for ATI VGA Wonder */

*p_DN = ATI_ReadPixel(sample,line);
return(0);

case PGA : /* for pga display */

x = sample - 1; y = 480 - line;
cmd[0] = 0x0D8;
cmd[1] = y; cmd[2] = y >> 8;
cmd[3] = x; cmd[4] = x >> 8;
cmd[5] = x; cmd[6] = x >> 8;
PGAsend (cmd, 7); /* 'IMAGER y x x ' */
for (x = 0; x < 1000; x++) ; /* delay loop */
PGAreceive (cmd, &len);
*p_DN = cmd[8];
return(0);

case VGA200 : /* for ega and vga displays */
case ORCHID480 : /* for orchid designer */
case ORCHID600 : /* for orchid designer */
case ORCHID768 : /* for orchid designer */

laddress = ((long)dispns*(long)(line-1))+(long)(sample-1);
segment = laddress >> 16;
laddress = laddress & 0x0FFFF;
faraddr = (unsigned char far *) (0x0a0000000L + laddress);
if (tseng == 4000) /* Added 04/22/91 - Ron Baalke */
outp(0x3cd,(0x40 | segment) << 4);
else
outp(0x3cd,0x40 | segment << 3);
*p_DN = *(faraddr);
return(0);

case PARADISE : /* for Super VGA */

ReadPixelPAR( line-1, sample-1, p_DN);
*p_DN &= 0xFF; /* Remove garbage - mwm */
return(0);

case TRIDENT : /* for Super VGA */

ReadPixelTRI( line-1, sample-1, p_DN);
*p_DN &= 0xFF; /* Remove garbage - mwm */
return(0);

case VESA : /* VESA SVGA Driver */
case VESA800 : /* VESA SVGA Driver */
case VESA640 : /* VESA SVGA Driver */

laddress = ( (long) dispns * (long) (line-1)) + (long) (sample-1);
segment = laddress >> 16;
laddress = laddress & 0x0FFFF;
faraddr = (unsigned char far *) (0x0a0000000L + laddress);

if (segment != LastPage)
LastPage = VESA_Set_Page( segment );

*p_DN = *(faraddr);
return(0);

case EV629 : /* for Everex EV-629 24-bit board */

pix_adr = pixaddr( sample-1, line-1) ;
memcpy( &color24, pix_adr, colorbytes);
unbuildcolor( color24, &red_pixel, &green_pixel, &blue_pixel);
*p_DN = red_pixel;
return(0);

}
}

int DisplayLine (unsigned char * buffer, int line, int sample, int ns)

/*** DisplayLine writes a line of pixels on the display screen.
Parameter type description
buffer char ptr The array of pixel values
line integer The line coordinate of the first pixel
sample integer The sample coordinate of the first pixel
ns integer The number of pixels to display
***/

{
unsigned char cmd[7];
unsigned int x,y, x1, x2, len, s;
int i, address, mask, bit;
unsigned int segment;
unsigned long laddress;
unsigned char far *faraddr;
unsigned int color;
long *pix_adr;

switch (DisplayDevice)
{
case CGA200 : /* for cga display */

line--;
sample--;
if ((line & 1) == 0)
address = 0x8000 + 40*line + (sample >> 3);
else
address = 0x0A000 + 40*(line-1) + (sample >> 3);
bit = 7 - (sample & 7);
mask = getmem(0x0B000,address) & ~((1 << (bit+1)) - 1);
for (i = 0; i < ns; i++)
{
mask |= (buffer[i] & 1) << bit;
bit--;
if (bit < 0)
{
putmem(0x0B000,address, mask);
address++;
bit = 7;
mask = 0;
}
}
putmem(0x0B000,address,
mask | (getmem(0x0B000,address) & ((1 << (bit+1)) - 1)) );
return(0);

case EGA350 : /* for ega and vga displays */
case EGA480 : /* for ega and vga displays */
case VGA480 : /* for ega and vga displays */
case EVGA800 : /* for Everex EVGA */

DisplayLineEGA (FP_SEG(buffer),FP_OFF(buffer), line, sample, ns);
return(0);

#ifndef __TURBOC__
case BIOS : /* for ega and vga displays */


y = line;
for (i=0; i {
x = sample + i;
color = (unsigned int)(buffer[i]);
WritePixel( y, x, color);
}
return(0);
#endif

case ATI640 :
case ATI800 :
case ATI1024:

y = line;
for (i=0; i {
x = sample + i;
color = (unsigned int)(buffer[i]);
ATI_WritePixel(x,y,color);
}
return(0);

case PGA : /* for pga display */
y = 480 - line; x1 = sample - 1; x2 = x1 + ns - 1;
cmd[0] = 0x0D9;
cmd[1] = y; cmd[2] = y >> 8;
cmd[3] = x1; cmd[4] = x1 >> 8;
cmd[5] = x2; cmd[6] = x2 >> 8;
PGAsend (cmd, 7); /* 'IMAGEW y x1 x2 ' */
s = 0;
while (s < ns)
{
len = ns - s; if (len > 128) len = 128;
cmd[0] = 127 + len;
PGAsend (cmd, 1);
PGAsend (&buffer[s], len);
s += 128;
}
return(0);

case VGA200 : /* for ega and vga displays */
case ORCHID480 : /* for orchid designer */
case ORCHID600 : /* for orchid designer */
case ORCHID768 : /* for orchid designer */

laddress = ((long)dispns*(long)(line-1))+(long)(sample-1);
segment = laddress >> 16;
laddress = laddress & 0x0FFFF;
if ((laddress + (long)ns) > 65535L)
/* this line will overlap a segment so write it pixel by pixel */
for (i = 0; i < ns; i++) WritePixel(line,sample+i,(int)buffer[i]);
else
{
faraddr = (unsigned char far *) (0x0a0000000L + laddress);
outp(0x3cd,0x40 | segment);
memcpy (faraddr,buffer,ns);
}
return(0);

case EVGA640 : /* for Everex EVGA */
case EVGA512 : /* for Everex EVGA */

laddress = ( (long) dispns * (long) line ) + (long) (sample-1);
segment = laddress >> 16;
laddress = laddress & 0x0FFFF;
if ((laddress + (long)ns) > 65535L)
/* this line will overlap a segment so write it pixel by pixel */
for (i = 0; i < ns; i++)
EVGAWritePixel256(sample+i,line,(int)buffer[i]);
else
{
faraddr = (unsigned char far *) (0x0a0000000L + laddress);
if (segment != LastPage)
{
EVGASetPage(segment);
LastPage = segment;
}
memcpy (faraddr,buffer,ns);
}
return(0);

case PARADISE : /* for Super VGA */

WriteLinePAR (sample-1, ns, line-1, buffer);
outp( 0x3ce, 0x0000f); /* added - mwm */
return(0);

case TRIDENT : /* for Super VGA */

WriteLineTRI (sample-1, ns, line-1, buffer);
return(0);

case VESA : /* VESA SVGA Driver */
case VESA800 : /* VESA SVGA Driver */
case VESA640 : /* VESA SVGA Driver */

laddress = ( (long) dispns * (long) (line-1)) + (long) (sample-1);
segment = laddress >> 16;
laddress = laddress & 0x0FFFF;

if ((laddress + (long)ns) > 65535L)
/* this line will overlap a segment so write it pixel by pixel */
for (i = 0; i < ns; i++)
WritePixel (sample+i, line, (int)buffer[i]);
else
{
faraddr = (unsigned char far *) (0x0a0000000L + laddress);

if (segment != LastPage)
LastPage = VESA_Set_Page( segment );

memcpy (faraddr,buffer,ns);
}
return(0);

case EV629 : /* for Everex EV-629 24-bit board */

y = line;
for (i=0; i {
x = sample + i;
color = (unsigned int)(buffer[i]);
WritePixel( y, x, color);
}
return(0);

}
}

int GetLine (unsigned char * buffer, int line, int sample, int ns)

/*** GetLine reads a line of pixels from the display screen. Will
attempt to retrieve the line from the refresh buffer first if
the refresh buffer is in extended memory.

Written by Ron Baalke - 05/91.

Parameter type description
buffer char ptr The array of pixel values
line integer The line coordinate of the first pixel
sample integer The sample coordinate of the first pixel
ns integer The number of pixels to be read
***/
{
int i;
long offset;
int DN;
unsigned int segment;
unsigned long laddress;
unsigned char far *faraddr;
long *pix_adr;

if ((RefreshLines > 0) && (RefreshLocation != VIRTUAL_FILE))
{
GetRefresh(buffer,line,sample,ns);
return(0);
}

switch (DisplayDevice)
{
case VGA200 : /* for ega and vga displays */
case ORCHID480 : /* for orchid designer */
case ORCHID600 : /* for orchid designer */
case ORCHID768 : /* for orchid designer */

laddress = ((long)dispns*(long)(line-1))+(long)(sample-1);
segment = laddress >> 16;
laddress = laddress & 0x0FFFF;
faraddr = (unsigned char far *) (0x0a0000000L + laddress);
if ((laddress + (long)ns) > 65535L)
{
/* this line will overlap a segment so read it pixel by pixel */
for (i = 0; i < ns; i++)
{
ReadPixel(line,i+sample,&DN);
buffer[i] = DN;
}
}
else
{
faraddr = (unsigned char far *) (0x0a0000000L + laddress);
if (tseng == 4000)
outp(0x3cd,(0x40 | segment) << 4);
else
outp(0x3cd,0x40 | segment << 3);
memcpy (buffer,faraddr,ns);
}
return(0);

case EV629 : /* for Everex EV-629 24-bit board */

pix_adr = pixaddr( sample-1, line-1) ;
memcpy( buffer, pix_adr, colorbytes*ns);
return(0);


default : /* everything else */
for (i=0; i {
ReadPixel(line,i+sample,&DN);
buffer[i] = DN;
}
return(0);
}
}

int FormatLine (unsigned char * buffer, int nsdd, int nsd, int bitshift,
int NoScale, char * status)

/* FormatLine converts the line of pixels in the buffer into
byte format for display. It also performs subsampling
or zooming if needed.
*/

{
int samp, j, k, DN, scale, absbitshift;
int mult;
float fscale;
unsigned char *tmpbuf;
union {
unsigned char *b;
int *i;
} buf;
buf.b = buffer;

if ((tmpbuf = malloc(2048)) == NULL)
{
FatalError( "Not enough memory for pixel buffer.\n");
}

status[0] = 0;
TurnCursorOff = 0; /* always reinitialize the cursor fn to be on */

/* For 16 bit images */
/* scaling is done by dividing by a scale factor if the dn range specified
is greater than the display range and by multiplying if the range
specified is less than the display range
*/
if (bitsperpix == 16 || bitsperpix ==32)
{
fscale = ((float)(DNhigh - DNlow) / (float)numDN);
if (fscale < 1)
{
mult = 1;
scale = 1.0/fscale;
}
else
{
mult = 0;
scale = fscale + 1;
}

if (zoom == 1 )
{
samp = 0;
for (j = 0; j < nsdd; j++)
{
DN = buf.i[samp];
if (DN >= DNhigh)
DN = DNhigh - 1;
else
if (DN <= DNlow)
DN = DNlow;

if (mult)
buf.b[j] = ((long)DN-DNlow) * scale;
else
buf.b[j] = ((long)DN-DNlow) / scale;
samp += subsample;
}
}
else
{
j = nsd*zoom-1;
for (samp = nsd-1; samp >= 0; samp--)
{
DN = buf.i[samp];
if (DN >= DNhigh)
DN = DNhigh - 1;
else
if (DN <= DNlow)
DN = DNlow;
if (mult)
DN = ((long)DN-DNlow) * scale;
else
DN = ((long)DN-DNlow) / scale;

for (k = 1; k <= zoom; k++)
buf.b[j--] = DN;
}
}

}

/* For byte images (no offset) */

else if ( (bitsperpix == 8) && NoScale )
{
if ( (subsample == 1) && (zoom == 1) )
{
if (bitshift > 0)
for (j = 0; j < nsdd; j++)
buf.b[j] >>= bitshift;
}
else if (zoom == 1)
{
samp = 0;
for (j = 0; j < nsdd; j++)
{
buf.b[j] = buf.b[samp] >> bitshift;
samp += subsample;
}
}
else
{
j = nsd*zoom - 1;
for (samp = nsd-1; samp >= 0; samp--)
{
DN = buf.b[samp] >> bitshift;
for (k = 1; k <= zoom; k++)
buf.b[j--] = DN;
}
}
}


/* For byte images (with offset) */

/* scaling is done by dividing by a scale factor if the dn range specified
is greater than the display range and by multiplying if the range
specified is less than the display range
*/
else if ( (bitsperpix == 8) && !NoScale )
{
fscale = ((float)(DNhigh - DNlow) / (float)numDN);
if (fscale < 1)
{
mult = 1;
scale = 1.0/fscale;
}
else
{
mult = 0;
scale = fscale + 1;
}
if (zoom == 1)
{
samp = 0;
for (j = 0; j < nsdd; j++)
{
DN = buf.b[samp];
if (DN >= DNhigh)
DN = DNhigh - 1;
else
if (DN <= DNlow)
DN = DNlow;
if (mult)
buf.b[j] = (DN-DNlow) * scale;
else
buf.b[j] = (DN-DNlow) / scale;
samp += subsample;
}
}
else
{
j = nsd*zoom - 1;
for (samp = nsd-1; samp >= 0; samp--)
{
DN = buf.b[samp];
if (DN >= DNhigh)
DN = DNhigh - 1;
else
if (DN <= DNlow)
DN = DNlow;
if (mult)
buf.b[j] = (DN-DNlow) * scale;
else
DN = (DN-DNlow) / scale;
for (k = 1; k <= zoom; k++)
{ /* 256 color bug fix - Ron Baalke - 07/15/90 */
if ((numDN == 256) && ((DNlow >0) || (DNhigh < 255)))
buf.b[j--] = (DN - DNlow) * scale;
else
buf.b[j--] = DN;
}
}
}

}


/* For 4 bit and 1 bit images */
else
{
absbitshift = abs(bitshift);
ConvertLine (buf.b, tmpbuf, bitsperpix, 8, nsd, status);
if (zoom == 1)
{
samp = 0;
for (j = 0; j < nsdd; j++)
{
if (DisplayDevice == 0)
{
buf.b[j] = tmpbuf[samp];
}
else
{
buf.b[j] = tmpbuf[samp] << absbitshift;
}
samp += subsample;
}
}
else
{
j = nsd*zoom - 1;
for (samp = nsd-1; samp >= 0; samp--)
{
if (DisplayDevice == 0)
{
DN = tmpbuf[samp];
}
else
{
DN = tmpbuf[samp] << absbitshift;
}
for (k = 1; k <= zoom; k++)
buf.b[j--] = DN;
}
}
}
free(tmpbuf);
}


int ClearDisplay (int DN)

/*** ClearDisplay sets the whole display to a particular value.
Parameter type description
DN integer The DN value to set (usually 0)
***/

{
int address, junk;
unsigned char cmd[2];
unsigned int i,j,segment;
unsigned char far *faraddr;
char dummy[80];
int refresh_flag;
int index;
union REGS inreg, outreg;

/* Erase refresh buffer - Ron Baalke - 05/91 */
GetKeywordString (CommandString, "REF", "",dummy, &refresh_flag);
if (refresh_flag != -1)
{
if (RefreshLines > 0)
EraseRefresh();
return(0);
}

/* Erase buffers - Ron Baalke - 06/16/91 */
strcat(CommandString," "); /* kludge */
GetKeywordString (CommandString, "ERA", " ",dummy, &refresh_flag);
if ((refresh_flag) &&
(strlen(dummy) == 1) &&
(dummy[0] >= 'A') &&
(dummy[0] <= 'Z'))
{
index = dummy[0] - 'A';
DeallocBuffer(index);
return(0);
}


switch (DisplayDevice)
{

case CGA200 : /* for cga display */
junk = 0x0FF*(DN & 1);
for (address = 0; address < 8000; address++)
{
putmem(0x0B800,address, junk);
putmem(0x0BA00,address, junk);
}
return(0);

case EGA350 : /* for ega and vga displays */
case EGA480 : /* for ega and vga displays */
case VGA480 : /* for ega and vga displays */

#ifndef __TURBOC__
case BIOS : /* for ega and vga displays */
#endif

ClearDisplayEGA (DN,dispnl);
return(0);

case ATI640 :
case ATI800 :
case ATI1024:

if (DisplayDevice == ATI640)
j = 5;
else
j = 8;

faraddr = (unsigned char far *) 0x0a0000000L ;
for (i=0; i < j; i++)
{
atibank = i;
ATI_Bank();
memset(faraddr,DN,32768);
memset(faraddr+32768L,DN,32768);
}
return(0);

case PGA :

cmd[0] = 0x0F; cmd[1] = DN;
PGAsend (cmd, 2);
return(0);

case VGA200 : /* for ega and vga displays */
case ORCHID480 : /* for orchid designer */
case ORCHID600 : /* for orchid designer */
case ORCHID768 : /* for orchid designer */

faraddr = (unsigned char far *) 0x0a0000000L ;
for (i = 0; i < 5; i++)
{
outp(0x3cd,0x40 | i);
memset(faraddr,'\0',32768);
memset(faraddr+32768L,'\0',32768);
}

if (dispnl > 480)
for (i = 5; i < 8; i++)
{
outp(0x3cd,0x40 | i);
memset(faraddr,'\0',32768);
memset(faraddr+32768L,'\0',32768);
}

/* Added for Orchid with 1MB, March 1991, Ron Baalke */
if (dispnl >= 768)
for (i = 8; i < 12; i++)
{
outp(0x3cd,0x40 | i);
memset(faraddr,'\0',32768);
memset(faraddr+32768L,'\0',32768);
}

return(0);

case EVGA640 : /* for ega and vga displays */
case EVGA512 : /* for ega and vga displays */
case EVGA800 : /* for ega and vga displays */

EVGAClearDisplay(DN);
return(0);

case PARADISE:

ClearDisplayPAR(DN);
return(0);

case TRIDENT :

ClearDisplayTRI(DN);
return(0);

case VESA : /* VESA SVGA Driver */

faraddr = (unsigned char far *) 0x0a0000000L ;
for (i = 0; i < 12; i++)
{

VESA_Set_Page (i);

memset(faraddr,'\0',32768);
memset(faraddr+32768L,'\0',32768);
}
return(0);

case VESA800 : /* VESA SVGA Driver */

faraddr = (unsigned char far *) 0x0a0000000L ;
for (i = 0; i < 8; i++)
{

VESA_Set_Page (i);


memset(faraddr,'\0',32768);
memset(faraddr+32768L,'\0',32768);
}
return(0);


case VESA640 : /* VESA SVGA Driver */

faraddr = (unsigned char far *) 0x0a0000000L ;
for (i = 0; i < 5; i++)
{

VESA_Set_Page (i);

memset(faraddr,'\0',32768);
memset(faraddr+32768L,'\0',32768);
}
return(0);

case EV629 : /* for Everex EV-629 24-bit board */

faraddr = (unsigned char far *) 0x0a0000000L ;
for (i = 0; i < 12; i++)
{

VESA_Set_Page (i);

memset(faraddr,'\0',32768);
memset(faraddr+32768L,'\0',32768);
}
return(0);
}
}


int PGAreceive (unsigned char * answer, int * p_len)
/*
This routine receives data from the PGA device.
Only used by ReadPixel routine.
*/

{
unsigned char i, InWritePtr, InReadPtr, numbytes;

do
{
InReadPtr = getmem (0x0C600,0x0303);
InWritePtr = getmem (0x0C600,0x0302);
numbytes = InWritePtr - InReadPtr;
} while (numbytes == 0);

for (i = 0; i < numbytes; i++)
answer[i] = getmem (0x0C610,InReadPtr++);

putmem (0x0C600, 0x0303, InReadPtr);
*p_len = numbytes;
}

/*
Function:
Determining the Tseng chip

Output parameters:
identity integer containing the chip code
3000 = ET3000
4000 = ET4000

Calling Protocol:
identity = Which_Tseng() */


Which_Tseng()
{
int base;
unsigned char new_value, old_value, value;

if ( (inp(0x3CC) & 0x01) == 1)
base = 0x3D0;
else
base = 0x3B0;

/* get old value */
outp(base+4, 0x33);
old_value = inp(base+5);

/* change value */
value = old_value ^ 0x0f;
outp(base+5, value);
new_value = inp(base+5);

/* restore old value */
outp(base+5, old_value);

if (new_value == value)
return(4000);
else
return(3000);
}


  3 Responses to “Category : C Source Code
Archive   : IMDSRC78.ZIP
Filename : DISPIO.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/