25 Years of Programming
An open source source for C, C++, OWL, BASIC, MDB, XLS, DOT, and more...
Home   Projects   Up   Sitemap   Search   Blog   Forum+Chat   About Us   Privacy   Terms of Use   Feedback   FAQ   Images   Services   Payments   Humor   Music  

Heathkit H-100 functions to save and load graphics screens (bitmaps) in DeSmet C

These are DeSmet functions for graphics screen capture on the Heathkit H-100 computer.

I created a ".ZED" device-dependent bitmap format for screen captures. It saves the contents of the color video RAM planes to disk.

  • ZEDSAVE captures a screen to disk.
  • ZEDLOAD loads a captured screen and displays it.
  • PICLOAD loads a captured screen in the .PIC format (format is described in comments below)
  • ROTPLANES, unrelated to the other functions, is a novelty that swaps the video RAM data among the three color planes for interesting color rotation effects.

These functions are used extensively by my DeSmet C color graphics programs for the H-100.

/* ======================================================================= */
/* H100 ROUTINES FOR SAVING AND RELOADING ENTIRE GRAPHICS SCREENS (BITMAPS)*/
/* ======================================================================= */
/* -> These functions are highly specific to the H100 computer hardware, */
/* -> and could have disastrous consequences on any other computer. */
/* ----------------------------------------------------------------------- */
/*	ZEDSAVE()	4-28-93	 10-12-93   */
/*	Copyright (C)1993 Steven Whitney. Published under the */
/*	GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/*	Initially published by http://25yearsofprogramming.com. */
/*	Saves current display (full-sized full-color screen) */
/*	to a disk file called SCREEN.ZED. You must then rename the file if you want to keep it. */
/*	5-2-93 reads video port to see which planes are enabled.  If any are */
/*	disabled, it writes zeroes to disk for the entire plane */
/*	returns TRUE if succeed, FALSE if fail */
/*	These ZED routines are INCREDIBLY fast. You won't believe your H100 could perform */
/*	any graphics operation this fast. It essentially zaps the video RAM data directly */
/*	(well, not quite directly) to and from the disk file. */
/*	11/05/2005: Each H100 color plane uses 64K bytes of RAM,  */
/*	but the actual data only occupies 18000 bytes of that, leaving the rest completely  */
/*	unused. This routine saves to disk only the 18000 bytes for each plane.  */
/*	The complementary routine reads them from disk and loads them back into the  */
/*	memory locations they came from. The calculations are a bit weird because the  */
/*	18000 bytes don't occupy contiguous memory locations.   */
/*	In effect, this is sort of a device-dependent bitmap (DDB) for the H100. */
/* ----------------------------------------------------------------------- */
#define	FALSE	0
#define TRUE	1
#define	NULL	0
#define	ERR		(-1)
typedef int FILE;
int zedsave()			
{
	int i;						/* iteration counter */
	int y;						/* scan line counter */
	int skipflag;				/* flag: whether to write blanks to disk */
								/* instead of data for this video plane */
	unsigned segment;			/* video plane pointer */
	unsigned dseg;				/* holds data segment address */
	unsigned _showds();
	FILE *outfile, *fopen();
	char *buf;					/* 18k buffer for screen image */
	char *buftwo;				/* secondary pointer to buffer */
	char vidportinit;			/* starting video port setting */
	char *calloc(), _inb();
	void _outb(), _setmem(), _lmove(), free();

	if(!(buf = calloc(18000,1)))				/* init. buffer for */
		return(FALSE);							/* screen data */

	if((outfile = fopen("SCREEN.ZED","w")) == NULL)		/* open file */
		return(FALSE);

	dseg = _showds();
	vidportinit = _inb(0xD8);			/* save initial port settings */
	_outb((vidportinit & 0x7F),0xD8);	/* VRAM must be enabled to read */
	for(i = 1 ; i <= 3 ; i++)			/* read all 3 color planes */
	{
		skipflag = FALSE;
		switch(i)
		{
			case 1: 					/* green */
				if(vidportinit & 2)		/* if plane display disabled, */
					skipflag = TRUE;
				segment = 0xE000;
				break;	

			case 2:						/* red */
				if(vidportinit & 1)		/* if plane display disabled, */
					skipflag = TRUE;
				segment = 0xD000;
				break;	

			case 3:						/* blue */
				if(vidportinit & 4)		/* if plane display disabled, */
					skipflag = TRUE;
				segment = 0xC000;
				break;	
		}

		if(skipflag)						/* if plane is disabled, */
			_setmem(buf,18000,0);			/* fill buf with zeroes */
		else
		{
			buftwo = buf;						/* set secondary pointer */
												/* each time through loop */
			for(y = 0 ; y <= 392 ; y++)			/* out of total scan lines, */
			{
				if((y%16) < 9)					/* is this one displayed? */
				{
					_lmove(80,y*128,segment,buftwo,dseg);	/* move line */
					buftwo += 80;							/* into buffer */
				}
			}
		}
		if(fwrite(buf,1,18000,outfile) != 18000)	/* write out the buffer */
			return(FALSE);
	}
	if(fclose(outfile) == ERR)						/* close file */
		return(FALSE);
	_outb(vidportinit,0xD8);			/* restore video port */
	free(buf);							/* free up buffer space allocated */
	return(TRUE);
}

/* -------------------------------------------------------------- */
/*	ZEDLOAD()	5-22-93 10-12-93 */
/*	Copyright (C)1993 Steven Whitney. Published under the */
/*	GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/*	Initially published by http://25yearsofprogramming.com. */
/*	Copies a .ZED color graphics file to screen display */
/*	5-24-93 returns TRUE if successful, FALSE if not */
/* -------------------------------------------------------------- */
#define TRUE	1
#define FALSE	0
typedef int FILE;
int zedload(fname)
char *fname;
{
int y, i;					/* counters */
FILE *infile, *fopen();		/* input file */
char *buf;					/* memory buffer for fast file -> memory */
char *buftwo;				/* secondary buffer pointer */
unsigned segment; 			/* video plane pointer */
char vidportinit;			/* starting video port setting */
char *calloc(), _inb();
void _outb(), _lmove(), free();
unsigned fread(), _showds();

if(!(buf = calloc(18000,1)))
	return(FALSE);

if(!(infile = fopen(fname,"r")))			/* open input file */
	return(FALSE);

vidportinit = _inb(0xD8);					/* save video port setting */
_outb(0x78,0xD8);							/* enable all planes */
puts("\033x1");								/* enable 25th line */

i = 0;
while(fread(buf,1,18000,infile) != 0)		/* read planes in order */
{											/* (any that are present) */
	i++;
	switch(i)
	{
		case 1: segment = 0xE000; break;	/* green */
		case 2: segment = 0xD000; break;	/* red */
		case 3: segment = 0xC000; break;	/* blue */
	}
	buftwo = buf;							/* set secondary pointer */
	for(y = 0 ; y <= 392 ; y++)				/* total possible scan lines */
		if((y%16) < 9)						/* is this line displayed? */
		{									/* if so, move next 80 chrs */
			_lmove(80,buftwo,_showds(),y*128,segment);	/* into VRAM */
			buftwo += 80;					/* increment buffer pointer */
		}
}
fclose(infile);
free(buf);
_outb(vidportinit,0xD8);
return(TRUE);
}

/* -------------------------------------------------------------- */
/*	PICLOAD.C		DESMET VERSION   9-27-94 */
/*	Copyright (C)1994 Steven Whitney. Published under the */
/*	GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/*	Initially published by http://25yearsofprogramming.com. */
/*	Fills graphics screen from info previously stored with picsave() */
/*	THERE IS CURRENTLY NO VERSION OF PICSAVE() FOR THE H100 */
/*	and there's no reason to create one, since ZED2PIC.C */
/*	will translate any .ZED to .PIC */
/*	In effect, a .PIC is sort of a device-independent bitmap (DIB) for the H100. */
/*	Each byte in a .PIC file specifies the number of a color to use for one pixel.  */
/*	The file consists of header information followed by the bytes.  A 640 by 225 pixel */
/*	display will contain: 640,225\n (a newline char), followed by (640 x 225) bytes. */
/*	data file format:  xsize,ysize\n (xsize * ysize) chars */
/*	Remember the H100 can only display colors 0-7, and a .PIC file produced */
/*	on the Gateway P5-90 may have colors up to 255. */
/*	Could handle this by creating an H100 palette cycling through 0-7. */
/*	This fn returns: highest Z (color) in file if successful, EOF on error */
/*	As I recall, this method of storing graphical data was fairly slow, but it was suited to */
/*	storing escape times from a Mandelbrot program. */
/*	For other graphics purposes, the ZED format is much faster. */
/* -------------------------------------------------------------- */
#define EOF		(-1)
typedef int FILE;
int picload(filename)
char *filename;
{
int x, y, maxx, maxy, color, highcolor;
FILE *infile;

if(!(infile = fopen(filename,"r")))
	return(EOF);
if(fscanf(infile,"%d,%d\n",&maxx,&maxy) != 2)
{
	fclose(infile);
	return(EOF);
}
highcolor = 0;
for(y = 0 ; y < maxy ; y++)
	for(x = 0 ; x < maxx ; x++)
	{
		if((color = fgetc(infile)) == EOF)			/* file too short */
		{
			fclose(infile);
			return(EOF);
		}
		if(color > highcolor)
			highcolor = color;
		pset(x,y,'p',color);
		if(csts())					/* user ^C abort */
			if(ci() == 3)
			{
				fclose(infile);
				return(highcolor);
			}
	}
fclose(infile);
return(highcolor);
}

/* -------------------------------------------------------------- */
/*	ROTPLANES()		6-7-93   10-12-93 */
/*	Copyright (C)1993 Steven Whitney. Published under the */
/*	GNU GPL (General Public License) Version 3, with ABSOLUTELY NO WARRANTY. */
/*	Initially published by http://25yearsofprogramming.com. */
/*	rotate (swap) data in the 3 color planes */
/*	for interesting color effects */
/* -------------------------------------------------------------- */
int rotplanes()
{
int i;									/* counter */
unsigned dseg, _showds();				/* data segment of memory */
char *offset;
char buftwo[80];						/* temp used in swapping planes */
void _lmove();

dseg = _showds();						/* learn data segment */
for(i = 0 ; i <= 392 ; i++)				/* ROTATE THE PLANES */
	if((i % 16) < 9)
	{
		offset = (char *)(i * 128);
		_lmove(80,offset,0xE000,buftwo,dseg);	/* MOVE GREEN TO buf */
		_lmove(80,offset,0xD000,offset,0xE000);	/* MOVE RED TO GREEN */
		_lmove(80,offset,0xC000,offset,0xD000);	/* MOVE BLUE TO RED */
		_lmove(80,buftwo,dseg,offset,0xC000);	/* MOVE buf CONTENTS TO BLUE */
	}
return 1;
}

 


 

Valid HTML 4.01 Transitional
Yahoo! Search
Search the web Search this site
Valid CSS