home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
DDJ0190.ZIP
/
ZG_LWLVL.C
< prev
next >
Wrap
C/C++ Source or Header
|
1989-12-26
|
22KB
|
834 lines
/*
Module: ZG_LwLvl (ZipGraph Low-Level functions)
Version 1.10 01-Nov-1989
Language: ANSI C w/MS-DOS extensions
Environ: IBM-PC compatibles w/MDA, CGA, HGC, EGA, MCGA, or VGA
Compilers: Borland Turbo C v2.00
Lattice C v6.01
Microsoft C v5.10 and QuickC v2.01
Zortech C & C++ v2.01
Purpose: Provides low-level graphics routines for detecting graphics
adapters, setting graphics modes, and plotting pixels. This
module is required by the higher-level ZipGraph modules.
Written by: Scott Robert Ladd
705 West Virginia
Gunnison CO 81230
BBS (303)641-6438
FidoNet 1:104/708
*/
#define __ZG_LWLVL_C 1
#if !defined(LATTICE)
#include "conio.h"
#endif
#include "dos.h"
#include "zg_lwlvl.h"
/*-----------------------------
handle compiler differences
-----------------------------*/
#if defined(_MSC) || defined(_QC) || defined(__ZTC__) || defined(LATTICE)
#define OUT_PORT(port,val) outp(port,val)
#elif defined(__TURBOC__)
#define OUT_PORT(port,val) outportb(port,val)
#endif
/*--------------------------
pointer conversion macro
--------------------------*/
#if !defined(MK_FP)
#define MK_FP(seg,off) ((void far *)(((long)(seg) << 16)|(unsigned)(off)))
#endif
/*------------------------------
ZipGraph INTERNAL PROTOTYPES
------------------------------*/
static void DummyPlot(int x, int y, int color);
static int DummyRead(int x, int y);
static void CGA1_Plot(int x, int y, int color);
static void CGA2_Plot(int x, int y, int color);
static void MCGA_Plot(int x, int y, int color);
static void M256_Plot(int x, int y, int color);
static void EVGA_Plot(int x, int y, int color);
static int CGA1_Read(int x, int y);
static int CGA2_Read(int x, int y);
static int MCGA_Read(int x, int y);
static int M256_Read(int x, int y);
static int EVGA_Read(int x, int y);
static void HGC_GraphMode(void);
static void HGC_TextMode(void);
static void HGC_Plot(int x, int y, int color);
static int HGC_Read(int x, int y);
/*---------------------------
ZipGraph PUBLIC VARIABLES
---------------------------*/
struct
{
int Type;
int Monitor;
int Mode;
int Xwidth;
int Ylength;
int NoColors;
}
ZG_VideoInfo;
void (* ZG_PlotPixel)(int x, int y, int color) = DummyPlot;
int (* ZG_ReadPixel)(int x, int y) = DummyRead;
/*----------------------------------------
ZipGraph INTERNAL TABLES and VARIABLES
----------------------------------------*/
static const struct
{
int BestRes;
int MostColor;
unsigned long ModeList;
}
VideoTable[06] =
{
{ 0, 0, 0x00000000L},
{ ZG_MOD_640x200x2, ZG_MOD_320x200x4, 0x00000006L},
{ ZG_MOD_720x348x2, ZG_MOD_720x348x2, 0x00000001L},
{ ZG_MOD_640x350x16, ZG_MOD_640x350x16, 0x0000007EL},
{ ZG_MOD_640x480x2, ZG_MOD_320x200x256, 0x00000486L},
{ ZG_MOD_640x480x16, ZG_MOD_320x200x256, 0x000003FEL}
};
static const struct
{
char ActualMode;
void (* PixelProc)(int x, int y, int color);
int (* ReadProc)(int x, int y);
int Xwidth;
int Ylength;
int NoColors;
}
ModeData[10] =
{
{ 0x00, HGC_Plot, HGC_Read, 720, 348, 2 },
{ 0x04, CGA2_Plot, CGA2_Read, 320, 200, 4 },
{ 0x06, CGA1_Plot, CGA1_Read, 640, 200, 2 },
{ 0x0D, MCGA_Plot, MCGA_Read, 320, 200, 16 },
{ 0x0E, EVGA_Plot, EVGA_Read, 640, 200, 16 },
{ 0x0F, EVGA_Plot, EVGA_Read, 640, 350, 4 },
{ 0x10, EVGA_Plot, EVGA_Read, 640, 350, 16 },
{ 0x11, EVGA_Plot, EVGA_Read, 640, 480, 2 },
{ 0x12, EVGA_Plot, EVGA_Read, 640, 480, 16 },
{ 0x13, M256_Plot, M256_Read, 320, 200, 256}
};
static unsigned char OriginalMode = 0;
static int PixelMode = ZG_PXL_SET;
static int ZG_Inited = 0;
/*------------------------------
IBM-type adapter global data
------------------------------*/
#define CGA_VID_SEG 0xB800
#define EVGA_VID_SEG 0xA000
/*-------------------------
MDA and HGC global data
-------------------------*/
/* Hercules video RAM segment */
#define HGC_VID_SEG 0xB000
/* Monochrome 6845 Video Controller ports */
#define HGC_IDX_PORT 0x03B4
#define HGC_DAT_PORT 0x03B5
#define HGC_CTL_PORT 0x03B8
#define HGC_CFG_PORT 0x03BF
/*----------------------------
ZipGraph PUBLIC FUNCTIONS!
----------------------------*/
int ZG_Init(void)
{
union REGS regs;
int i, status_changed;
unsigned char orig_status;
ZG_VideoInfo.Type = ZG_ERROR;
ZG_VideoInfo.Monitor = ZG_ERROR;
ZG_VideoInfo.Mode = ZG_ERROR;
ZG_VideoInfo.Xwidth = 0;
ZG_VideoInfo.Ylength = 0;
ZG_VideoInfo.NoColors = 0;
regs.h.ah = 0x1A; /* VGA Identifier Adapter Service */
regs.h.al = 0;
int86(0x10,®s,®s);
if (regs.h.al == 0x1A)
{
switch (regs.h.bl)
{
case 1 : ZG_VideoInfo.Type = ZG_VID_MDA;
ZG_VideoInfo.Monitor = ZG_MTR_MONO;
break;
case 2 : ZG_VideoInfo.Type = ZG_VID_CGA;
ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
break;
case 4 : ZG_VideoInfo.Type = ZG_VID_EGA;
ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
break;
case 5 : ZG_VideoInfo.Type = ZG_VID_EGA;
ZG_VideoInfo.Monitor = ZG_MTR_MONO;
break;
case 7 : ZG_VideoInfo.Type = ZG_VID_VGA;
ZG_VideoInfo.Monitor = ZG_MTR_MONO;
break;
case 8 : ZG_VideoInfo.Type = ZG_VID_VGA;
ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
break;
case 10: ZG_VideoInfo.Type = ZG_VID_MCGA;
ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
break;
case 11: ZG_VideoInfo.Type = ZG_VID_MCGA;
ZG_VideoInfo.Monitor = ZG_MTR_MONO;
break;
case 12: ZG_VideoInfo.Type = ZG_VID_MCGA;
ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
break;
default:
return 1;
}
}
else
{
/* check for an EGA */
regs.h.ah = 0x12;
regs.x.bx = 0x0010;
int86(0x10,®s,®s);
if (regs.x.bx != 0x10)
{
ZG_VideoInfo.Type = ZG_VID_EGA;
regs.h.ah = 0x12;
regs.x.bx = 0x0010;
int86(0x10,®s,®s);
if (regs.h.bh == 0)
ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
else
ZG_VideoInfo.Monitor = ZG_MTR_MONO;
}
else
{
int86(0x11,®s,®s);
switch ((regs.h.al & 0x30) >> 4)
{
case 0 :
return 1;
case 1 :
case 2 :
ZG_VideoInfo.Type = ZG_VID_CGA;
ZG_VideoInfo.Monitor = ZG_MTR_COLOR;
break;
case 3 :
status_changed = 0;
orig_status = (unsigned char)(inp(0x03BA) & 0x80);
for (i = 0; (i < 30000) && (!status_changed); ++i)
if (orig_status != (unsigned char)(inp(0x03BA) & 0x80))
status_changed = 1;
if (status_changed)
ZG_VideoInfo.Type = ZG_VID_HGC;
else
ZG_VideoInfo.Type = ZG_VID_MDA;
ZG_VideoInfo.Monitor = ZG_MTR_MONO;
}
}
}
if (ZG_VideoInfo.Type != ZG_VID_HGC)
{
regs.h.ah = 0x0F;
int86(0x10,®s,®s);
OriginalMode = regs.h.al;
}
ZG_Inited = 1;
return 0;
}
int ZG_SetMode(int VideoMode)
{
union REGS regs;
if (VideoMode < 0)
return 1;
if (VideoMode == ZG_MOD_BESTRES)
VideoMode = VideoTable[ZG_VideoInfo.Type].BestRes;
else
if (VideoMode == ZG_MOD_MOSTCOLOR)
VideoMode = VideoTable[ZG_VideoInfo.Type].MostColor;
if ((VideoMode > ZG_MOD_320x200x256)
|| (!(VideoTable[ZG_VideoInfo.Type].ModeList & (1 << VideoMode))))
return 1;
ZG_PlotPixel = ModeData[VideoMode].PixelProc;
ZG_ReadPixel = ModeData[VideoMode].ReadProc;
if (VideoMode == ZG_MOD_720x348x2)
HGC_GraphMode();
else
{
regs.h.ah = 0;
regs.h.al = ModeData[VideoMode].ActualMode;
int86(0x10,®s,®s);
}
ZG_VideoInfo.Mode = VideoMode;
ZG_VideoInfo.Xwidth = ModeData[VideoMode].Xwidth;
ZG_VideoInfo.Ylength = ModeData[VideoMode].Ylength;
ZG_VideoInfo.NoColors = ModeData[VideoMode].NoColors;
return 0;
}
int ZG_Done(void)
{
union REGS regs;
if (!ZG_Inited)
return 1;
if (ZG_VideoInfo.Type == ZG_VID_HGC)
HGC_TextMode();
else
{
regs.h.ah = 0;
regs.h.al = OriginalMode;
int86(0x10,®s,®s);
}
return 0;
}
int ZG_SetPixelMode(int PixMode)
{
if ((PixMode < ZG_PXL_SET) || (PixMode > ZG_PXL_XOR))
return 1;
PixelMode = PixMode;
return 0;
}
int ZG_SetCGAPalette(char PaletteNo)
{
union REGS regs;
if (ZG_VideoInfo.Type != ZG_VID_CGA)
return 1;
regs.h.ah = 0x0B;
regs.h.bl = PaletteNo;
regs.h.bh = 0x01;
int86(0x10,®s,®s);
return 0;
}
int ZG_SetEVGAPalette(char Palette, char Color)
{
union REGS regs;
if ((ZG_VideoInfo.Type != ZG_VID_EGA) && (ZG_VideoInfo.Type != ZG_VID_VGA))
return 1;
regs.h.ah = 0x10;
regs.h.al = 0x00;
regs.h.bh = Color;
regs.h.bl = Palette;
int86(0x10,®s,®s);
return 0;
}
/*--------------------------------
Dummy pixel plotter and reader
--------------------------------*/
static void DummyPlot(int x, int y, int color)
{
/* it does nothing */
}
static int DummyRead(int x, int y)
{
/* it does nothing */
return 0;
}
/*---------------------------------------------
CGA, EGA, MCGA, VGA pixel plotting functions
---------------------------------------------*/
static void CGA1_Plot(int x, int y, int color)
{
/* this routine used for CGA 640x200x2 mode */
unsigned int pixel_mask;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(CGA_VID_SEG, 0x2000 * (y&1) + 0x50 * (y/2) + (x >> 3));
/* calculate bit mask */
pixel_mask = 0x80 >> (x & 7);
/* set pixel */
switch (PixelMode)
{
case ZG_PXL_SET :
if (color)
*pixel_byte |= pixel_mask;
else
*pixel_byte &= ~pixel_mask;
break;
case ZG_PXL_AND :
if (color)
*pixel_byte &= pixel_mask;
break;
case ZG_PXL_OR :
if (!color)
*pixel_byte |= pixel_mask;
break;
case ZG_PXL_XOR :
if (!color)
*pixel_byte ^= pixel_mask;
}
}
static void CGA2_Plot(int x, int y, int color)
{
/* this routine used for CGA 320x200x4 mode */
unsigned int pixel_mask, alt_mask;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(CGA_VID_SEG,0x2000 * (y & 1) + 80 * (y >> 1) + (x >> 2));
pixel_mask = (color & 3) << (6 - ((x & 3) << 1));
switch (PixelMode)
{
case ZG_PXL_SET :
/* clear the appropriate bits */
alt_mask = 0xC0 >> ((x & 3) << 1);
*pixel_byte &= ~alt_mask;
/* insert the bits for the specified color */
*pixel_byte |= pixel_mask;
break;
case ZG_PXL_AND :
*pixel_byte &= pixel_mask;
break;
case ZG_PXL_OR :
*pixel_byte |= pixel_mask;
break;
case ZG_PXL_XOR :
*pixel_byte ^= pixel_mask;
}
}
static void MCGA_Plot(int x, int y, int color)
{
/* this routine used for MCGA/VGA 320x200 16-color mode */
unsigned char pixel_mask;
volatile unsigned char dummy;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(EVGA_VID_SEG, (y * 40) + (x >> 3));
/* set up mask */
pixel_mask = (char)(0x80 >> (x & 7));
/* set-up video controller */
OUT_PORT(0x03CE, 8);
OUT_PORT(0x03CF, pixel_mask);
OUT_PORT(0x03CE, 3);
OUT_PORT(0x03CF, (char)(PixelMode << 3));
OUT_PORT(0x03C4, 2);
OUT_PORT(0x03C5, 0x0F);
/* do a dummy read to load latches */
dummy = *pixel_byte;
/* clear latches */
*pixel_byte = 0;
/* set bit planes */
OUT_PORT(0x03C4, 2);
OUT_PORT(0x03C5, (char)color);
*pixel_byte = 0xFF;
/* finish up */
OUT_PORT(0x03C4, 2);
OUT_PORT(0x03C5, 0x0F);
OUT_PORT(0x03CE, 3);
OUT_PORT(0x03CF, 0);
OUT_PORT(0x03CE, 8);
OUT_PORT(0x03CF, 0xFF);
}
static void M256_Plot(int x, int y, int color)
{
/* this routine used for MCGA/VGA 320x200x256 mode */
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(EVGA_VID_SEG, (y << 8) + (y << 6) + x);
/* set pixel */
switch (PixelMode)
{
case ZG_PXL_SET :
*pixel_byte = (unsigned char)color;
break;
case ZG_PXL_AND :
*pixel_byte &= (unsigned char)color;
break;
case ZG_PXL_OR :
*pixel_byte |= (unsigned char)color;
break;
case ZG_PXL_XOR :
*pixel_byte ^= (unsigned char)color;
}
}
static void EVGA_Plot(int x, int y, int color)
{
/* this routine used for all EGA/VGA modes expect 256-color modes */
unsigned char pixel_mask;
volatile unsigned char dummy;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(EVGA_VID_SEG, (y * 80) + (x >> 3));
/* set up mask */
pixel_mask = (char)(0x80 >> (x & 7));
/* set-up video controller */
OUT_PORT(0x03CE, 8);
OUT_PORT(0x03CF, pixel_mask);
OUT_PORT(0x03CE, 3);
OUT_PORT(0x03CF, (char)(PixelMode << 3));
OUT_PORT(0x03C4, 2);
OUT_PORT(0x03C5, 0x0F);
/* do a dummy read to load latches */
dummy = *pixel_byte;
/* clear latches */
*pixel_byte = 0;
/* set bit planes */
OUT_PORT(0x03C4, 2);
OUT_PORT(0x03C5, (char)color);
*pixel_byte = 0xFF;
/* finish up */
OUT_PORT(0x03C4, 2);
OUT_PORT(0x03C5, 0x0F);
OUT_PORT(0x03CE, 3);
OUT_PORT(0x03CF, 0);
OUT_PORT(0x03CE, 8);
OUT_PORT(0x03CF, 0xFF);
}
/*---------------------------------------------
CGA, EGA, MCGA, VGA pixel reading functions
---------------------------------------------*/
static int CGA1_Read(int x, int y)
{
/* this routine used for CGA 640x200x2 mode */
unsigned int pixel_mask;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(CGA_VID_SEG,0x2000 * (y & 3) + 80 * (y >> 1) + (x >> 3));
/* calculate bit mask */
pixel_mask = 0x80 >> (x & 7);
/* read pixel */
if (pixel_mask & *pixel_byte)
return 1;
else
return 0;
}
static int CGA2_Read(int x, int y)
{
/* this routine used for CGA 320x200x4 mode */
unsigned int pixel_mask;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(CGA_VID_SEG,0x2000 * (y & 1) + 80 * (y >> 1) + (x >> 2));
pixel_mask = 3 << (6 - ((x & 3) << 1));
return (int)((*pixel_byte & pixel_mask) >> (6 - ((x & 3) << 1)));
}
static int MCGA_Read(int x, int y)
{
/* this routine used for all EGA/VGA modes expect 256-color modes */
char i;
int color = 0;
unsigned int pixel_mask;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(EVGA_VID_SEG, (y * 40) + (x >> 3));
/* set up mask */
pixel_mask = 0x80 >> (x & 7);
/* read the color bits */
for (i = 0; i < 4; ++i)
{
OUT_PORT(0x3CE, 4);
OUT_PORT(0x3CF, i);
OUT_PORT(0x3CE, 5);
OUT_PORT(0x3CF, 0);
if (*pixel_byte & pixel_mask)
color |= 1 << i;
}
return color;
}
static int M256_Read(int x, int y)
{
/* this routine used for MCGA/VGA 320x200x256 mode */
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(EVGA_VID_SEG, (y << 8) + (y << 6) + x);
/* return pixel value */
return *pixel_byte;
}
static int EVGA_Read(int x, int y)
{
/* this routine used for all EGA/VGA modes expect 256-color modes */
char i;
int color = 0;
unsigned int pixel_mask;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(EVGA_VID_SEG, (y * 80 + (x >> 3)));
/* set up mask */
pixel_mask = 0x80 >> (x & 7);
/* read the color bits */
for (i = 0; i < 4; ++i)
{
OUT_PORT(0x3CE, 4);
OUT_PORT(0x3CF, i);
OUT_PORT(0x3CE, 5);
OUT_PORT(0x3CF, 0);
if (*pixel_byte & pixel_mask)
color |= 1 << i;
}
return color;
}
/*---------------
HGC functions
---------------*/
static void HGC_GraphMode(void)
{
/* Codes to be loaded to Hercules 6845 to set graphics mode */
static const unsigned char HGC_GRAPH_CODES[12] =
{0x35,0x2D,0x2E,0x07,0x5B,0x02,0x57,0x57,0x02,0x03,0x00,0x00};
unsigned int i;
unsigned char far * screen;
OUT_PORT(HGC_CFG_PORT,3);
screen = MK_FP(HGC_VID_SEG,0);
OUT_PORT(HGC_CTL_PORT,2); /* set control port */
for (i = 0; i < sizeof(HGC_GRAPH_CODES); ++i)
{
OUT_PORT(HGC_IDX_PORT, (char)i);
OUT_PORT(HGC_DAT_PORT, HGC_GRAPH_CODES[i]);
}
for (i = 0; i <= 32767; ++i)
{
*screen = '\x00';
++screen;
}
OUT_PORT(HGC_CTL_PORT,10); /* set control port */
}
static void HGC_TextMode(void)
{
/* Codes to be loaded to Hercules 6845 to set text mode */
static const unsigned char HGC_TEXT_CODES[12] =
{0x61,0x50,0x52,0x0F,0x19,0x06,0x19,0x19,0x02,0x0D,0x0B,0x0C};
unsigned int i;
unsigned char far * screen;
OUT_PORT(HGC_CFG_PORT,3);
screen = MK_FP(HGC_VID_SEG,0);
OUT_PORT(HGC_CTL_PORT,0x20); /* set control port */
for (i = 0; i < sizeof(HGC_TEXT_CODES); ++i)
{
OUT_PORT(HGC_IDX_PORT, (char)i);
OUT_PORT(HGC_DAT_PORT, HGC_TEXT_CODES[i]);
}
for (i = 0; i <= 32767; ++i)
{
if (i % 2 == 1)
*screen = '\x07';
else
*screen = '\x20';
++screen;
}
OUT_PORT(HGC_CTL_PORT,0x28); /* set control port */
}
static void HGC_Plot(int x, int y, int color)
{
/* this routine used for HGC 720x348x2 mode */
unsigned int pixel_mask;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(HGC_VID_SEG,0x2000 * (y & 3) + 90 * (y >> 2) + (x >> 3));
/* calculate bit mask */
pixel_mask = 0x80 >> (x & 7);
/* set pixel */
switch (PixelMode)
{
case ZG_PXL_SET :
if (color)
*pixel_byte |= pixel_mask;
else
*pixel_byte &= ~pixel_mask;
break;
case ZG_PXL_AND :
if (color)
*pixel_byte &= pixel_mask;
break;
case ZG_PXL_OR :
if (!color)
*pixel_byte |= pixel_mask;
break;
case ZG_PXL_XOR :
if (!color)
*pixel_byte ^= pixel_mask;
}
}
static int HGC_Read(int x, int y)
{
/* this routine used for HGC 720x348x2 mode */
unsigned int pixel_mask;
unsigned char far * pixel_byte;
/* find the byte containing our pixel */
pixel_byte = MK_FP(HGC_VID_SEG,0x2000 * (y & 3) + 90 * (y >> 2) + (x >> 3));
/* calculate bit mask */
pixel_mask = 0x80 >> (x & 7);
/* read pixel */
if (pixel_mask & *pixel_byte)
return 1;
else
return 0;
}