home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Guide
/
c-cplusplus-interactive-guide.iso
/
c_ref
/
csource3
/
110_01
/
chargen.c
< prev
next >
Wrap
Text File
|
1985-08-21
|
15KB
|
620 lines
/* Character Generator/Editor
by Bob Pasky
36 Wiswall Rd.
Newton Centre, MA 02159
Originally written for Imsai VIO video board to create
data in the required format for burning its EPROM
character sets.
The program uses the VIO graphic mode to display an
enlarged version of a character's dot matrix.
The character matrix is 7 dots horizontally by 10 rows
vertically.
Each of the 256 character positions can be displayed, one
at a time, modified as desired, and saved in memory.
Once all changes have been made, the data can be formatted
and saved as a binary file named "CHARSET".
This file, of course, can be retrieved later and unformatted
in order to re-edit the set.
Additionally, the entire character set can be sent to
a line printer for a hard-copy of the character matrices.
To begin, you should "get" the file (type 'y' to confirm),
then "unformat" it. Advance or back up the current character
display until you reach the character code you wish to edit.
"Load" the charater into the display area. Move the cursor
to the desired point in the matrix and strike 'b' or 'd' for
a bright (dot) or dim (no dot) point at that location.
Continue until the graphic is in its desired form, then
"save" it back into the character inventory. Advance or back
up to any other characters to be edited. Load it, edit it, and
save it. When all editing is complete, you must "format" the
inventory before "filing" it to disk.
The inventory must be in "unformatted" form to print it.
Compiled using BDS-C 1.41, the program uses standard library
functions. However, certain addresses may need to be modified
for your particular VIO and display handlers. (I do not have
the Imsai video driver firmware which normally expects the
VIO to be addressed at 0xE000.)
I use several simple graphic characters for the character
display -- open box and solid boxes formed with two adjacent
character positions, and a rule around the character display
area formed by horizontal and vertical rules and matching
corners. If you don't have equivalent graphics, you might try
using the alternative ASCII characters shown in their
"define" statements.
The program should be easily adapted for any
memory-mapped display with 2708/2716-type character ROMs.
I have, in fact, modified this program to output in the
format required for the Hazeltine 1500 series terminals.
*/
#include "bdscio.h"
#define DISPLAY 0xA000 /* VIO display address */
#define CHOME 1 /* command to home VIO cursor */
#define BRKCHR 0x1B /* escape from printer listing */
#define GRAPHMODE 0xc /* graphics mode for VIO ctrlr */
/* cursor character in two parts left & right: */
/* these 2 characters next to one another form an open box */
#define CURLEFT 0xC3 /* alternate: '<' */
#define CURRIGHT 0xC9 /* alternate: '>' */
/* displayed point in two parts left & right: */
/* these 2 characters next to one another form a solid box */
#define DOTLEFT 0x86 /* alternate: '[' */
#define DOTRIGHT 0xB0 /* alternate: ']' */
/* elements of box surrounding display area */
#define CVERT 0xC5 /* alternate: '|' */
#define CHORIZ 0xCA /* alternate: '-' */
#define CTOPLEFT 0xC6 /* alternate: '+' */
#define CTOPRIGHT 0xCC /* alternate: '+' */
#define CBOTLEFT 0xC3 /* alternate: '+' */
#define CBOTRIGHT 0xC9 /* alternate: '+' */
#define BUFSIZ 3072 /* char. description buffer */
#define LISTOUT 5 /* CP/M printer command */
char cset[256][10]; /* character set descriptions */
char garbage[256][2]; /* extra space for unused lines */
int cchar; /* current character displayed */
int topleft; /* address of top left of char */
int cuaddr, /* cursor address */
homeaddr, /* address of home */
cx,cy; /* cursor x,y position */
char cuchleft, /* cursor char. left */
cuchrght; /* cursor char. right */
char hxstr[16]; /* list of hex codes */
main()
{
int x;
init();
home(); /* place cursor at home */
swapcur(); /* turn cursor on */
strcpy (hxstr,"0123456789ABCDEF");
dcchar(); /* display ccurrent char info */
setmem(cset,BUFSIZ,0); /* clear buffer area */
while ( (x=getkbd()) != 'q')
{
if(cuchleft!=CURLEFT) {
poke(cuaddr,cuchleft);
poke(cuaddr+1,cuchrght);
}
switch (x)
{
case 'h': left(); /* move cursor left */
break;
case 'k': right(); /* and right */
break;
case 'j': down(); /* or down */
break;
case 'u': up(); /* or up */
break;
case 'b': bright(); /* place dot at cursor position */
break;
case 'd': dim(); /* remove dot from cursor pos'n */
break;
case 'm': home(); /* home cursor */
break;
case 'x': clrchar(); /* clear all dots from character */
break;
case 's': store(); /* store current character */
break;
case 'l': load(); /* get current character */
break;
case '[': retreat(); /* decrement current character */
break;
case ']': advance(); /* increment current character */
break;
case 'f': file(); /* save as file CHARSET */
break;
case 'g': getfile(); /* get file CHARSET */
break;
case 'p': format(); /* format for output */
break;
case 'o': unformat(); /* unformat for editing */
break;
case 'q': poke (0xa7ff,8); /* changes VIO-C to alpha mode */
exit(); /* quit altogether */
case 'c': convert(); /* list on console or printer */
break;
default: break;
}
swapcur();
}
poke (0xa7ff,8); /* change to alpha mode */
}
getkbd() /* gets char from kbd, keeping the VIO drivers */
/* from cluttering up the screen with the echo */
/* of the keyboard characters. */
{
return tolower (bios(3,0));
}
advance() /* advance the current displayed character */
{
if ((cchar++)>255)cchar=0;
dcchar();
}
retreat() /* go back one displayed character */
{
if ((cchar--)<0)cchar=255;
dcchar();
}
dcchar() /* displays current character info */
{
int i,hx;
txtplot ("CHARACTER IS ",3,10,0);
i=strlen("character is x");
plot(3,10+i,cchar);
hx=hxstr[cchar/16];
plot(3,12+i,hx);
hx=hxstr[cchar%16];
plot(3,13+i,hx);
}
store() /* save current character description */
{
int i,j;
for (i=0;i<10;i++)
cset[cchar][i]=pack(i);
txtplot ("Character Stored ",6,10,0);
}
load() /* load character description */
{
int i,j,x;
clrchar();
while (cy<9) up();
for (i=0; i<10; i++)
{
x=cset[cchar][i];
plot(5,(3*i)+10,hxstr[x/16]);
plot(5,(3*i)+11,hxstr[x%16]);
for (j=0; j<7; j++)
{
if (! ((x>>j)&1) ) bright();
right();
}
while (cx) left();
down();
}
txtplot ("Character Loaded ",6,10,0);
}
pack(i) /* reads single "raster" line of display */
/* returns byte formatted for VIO PROM */
int i;
{
int j,c,x;
c=0;
for (j=0; j<7; j++)
{
c=c>>1;
x=peek(topleft+(80*i)+(2*j)+81);
if (x==DOTLEFT) c+=64;
if (x==DOTRIGHT) c+=64;
}
return ~(c|128);
}
format() /* converts descriptions into proper order */
/* for PROM burning. */
{
char *pp;
int i,j;
char pset[BUFSIZ];
/* format for VIO ROMs:
requires 3 2708 EPROMs:
1. top 8 rows of characters 0-127
2. top 8 rows of characters 128-255
3. bottom 2 rows of characters 0-255
Row one of each of the 128 characters is output, then
row two of each character, etc.
For the 3rd ROM, the 9th row for chars 0-127 is output,
then the 10th row. Blanks fill the next two rows, then
the 9th and 10th rows for chars 128-255. Two more
blank rows complete the 3rd ROM.
The hardware uses negative logic: a 0 turns the dot on,
a 1 means no dot. The left-most dot for each character
is controlled by the lsb of the byte; the right-most dot
is bit 6; bit 7 is always 0.
*/
txtplot ("Formatting data ",6,10,0);
pp=pset;
for (j=0;j<8;j++)
for (i=0;i<128;i++)
{
*pp=cset[i][j];
pp++;
}
for (j=0;j<8;j++)
for (i=128;i<256;i++)
{
*pp=cset[i][j];
pp++;
}
for (j=8;j<10;j++)
for (i=0;i<128;i++)
{
*pp=cset[i][j];
pp++;
}
for (i=0x100;i<0x200;i++)
{
*pp=0xFF;
pp++;
}
for (j=8;j<10;j++)
for (i=128;i<256;i++)
{
*pp=cset[i][j];