[comp.sources.wanted] Hercules graphic characters

reini@tolsun.oulu.fi (Jukka Reinikainen) (12/08/87)

 
Help wanted: how to create text in Hercules graphic mode?
 
I have a program written in MSC (parts coded with MASM) which does
quite nice things with grapichs but suffers lack of characters.
According to my knowledge the only way to get characters in Herc graphic
mode is to draw them on screen by lightning a set of pixels, right?
 
Somebody *must* have written a program which draws characters and
other symbols, so please help me.  C and/or ASM sources and/or ideas
will be *very* appreciated.
 
       >      Jukka Reinikainen         reini@tolsun.oulu.fi       <

jru@etn-rad.UUCP (John Unekis) (12/18/87)

In article <246@tolsun.oulu.fi> reini@tolsun.oulu.fi (Jukka Reinikainen) writes:
>Help wanted: how to create text in Hercules graphic mode?
>Somebody *must* have written a program which draws characters and
...

Here are some routines for doing character or vector graphics on the
Hercules card. They come from the BLASTEN game, which I will post the 
source from some day. To use these, compile with the LARGE model of 
MSC (the /AL switch).


=========================CUT HERE======================================




int yadd[348];          /* array of start addresses of Herc. lines */
int chinit_done = 0;    /* character array inited flag */
struct cxfx{            /* character bit pattern array */
char cc[8];
} chf[128] = {        /* character bit patterns */
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  
        0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e,  
        0x7e, 0xff, 0xdb, 0xff, 0xc3, 0xe7, 0xff, 0x7e,  
        0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x0,  
        0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x0,  
        0x38, 0x7c, 0x38, 0xfe, 0xfe, 0x7c, 0x38, 0x7c,  
        0x10, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x7c,  
        0x0, 0x0, 0x18, 0x3c, 0x3c, 0x18, 0x0, 0x0,  
        0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff,  
        0x0, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x0,  
        0xff, 0xc3, 0x99, 0xbd, 0xbd, 0x99, 0xc3, 0xff,  
        0xf, 0x7, 0xf, 0x7d, 0xcc, 0xcc, 0xcc, 0x78,  
        0x3c, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18,  
        0x3f, 0x33, 0x3f, 0x30, 0x30, 0x70, 0xf0, 0xe0,  
        0x7f, 0x63, 0x7f, 0x63, 0x63, 0x67, 0xe6, 0xc0,  
        0x99, 0x5a, 0x3c, 0xe7, 0xe7, 0x3c, 0x5a, 0x99,  
        0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x0,  
        0x2, 0xe, 0x3e, 0xfe, 0x3e, 0xe, 0x2, 0x0,  
        0x18, 0x3c, 0x7e, 0x18, 0x18, 0x7e, 0x3c, 0x18,  
        0x66, 0x66, 0x66, 0x66, 0x66, 0x0, 0x66, 0x0,  
        0x7f, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x0,  
        0x3e, 0x63, 0x38, 0x6c, 0x6c, 0x38, 0xcc, 0x78,  
        0x0, 0x0, 0x0, 0x0, 0x7e, 0x7e, 0x7e, 0x0,  
        0x18, 0x3c, 0x7e, 0x18, 0x7e, 0x3c, 0x18, 0xff,  
        0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x0,  
        0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x0,  
        0x0, 0x18, 0xc, 0xfe, 0xc, 0x18, 0x0, 0x0,  
        0x0, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x0, 0x0,  
        0x0, 0x0, 0xc0, 0xc0, 0xc0, 0xfe, 0x0, 0x0,  
        0x0, 0x24, 0x66, 0xff, 0x66, 0x24, 0x0, 0x0,  
        0x0, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x0, 0x0,  
        0x0, 0xff, 0xff, 0x7e, 0x3c, 0x18, 0x0, 0x0,  
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  
        0x30, 0x78, 0x78, 0x30, 0x30, 0x0, 0x30, 0x0,  
        0x6c, 0x6c, 0x6c, 0x0, 0x0, 0x0, 0x0, 0x0,  
        0x6c, 0x6c, 0xfe, 0x6c, 0xfe, 0x6c, 0x6c, 0x0,  
        0x30, 0x7c, 0xc0, 0x78, 0xc, 0xf8, 0x30, 0x0,  
        0x0, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xc6, 0x0,  
        0x38, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0x76, 0x0,  
        0x60, 0x60, 0xc0, 0x0, 0x0, 0x0, 0x0, 0x0,  
        0x18, 0x30, 0x60, 0x60, 0x60, 0x30, 0x18, 0x0,  
        0x60, 0x30, 0x18, 0x18, 0x18, 0x30, 0x60, 0x0,  
        0x0, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x0, 0x0,  
        0x0, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x0, 0x0,  
        0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x30, 0x60,  
        0x0, 0x0, 0x0, 0xfc, 0x0, 0x0, 0x0, 0x0,  
        0x0, 0x0, 0x0, 0x0, 0x0, 0x30, 0x30, 0x0,  
        0x6, 0xc, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x0,  
        0x7c, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0x7c, 0x0,  
        0x30, 0x70, 0x30, 0x30, 0x30, 0x30, 0xfc, 0x0,  
        0x78, 0xcc, 0xc, 0x38, 0x60, 0xcc, 0xfc, 0x0,  
        0x78, 0xcc, 0xc, 0x38, 0xc, 0xcc, 0x78, 0x0,  
        0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0xc, 0x1e, 0x0,  
        0xfc, 0xc0, 0xf8, 0xc, 0xc, 0xcc, 0x78, 0x0,  
        0x38, 0x60, 0xc0, 0xf8, 0xcc, 0xcc, 0x78, 0x0,  
        0xfc, 0xcc, 0xc, 0x18, 0x30, 0x30, 0x30, 0x0,  
        0x78, 0xcc, 0xcc, 0x78, 0xcc, 0xcc, 0x78, 0x0,  
        0x78, 0xcc, 0xcc, 0x7c, 0xc, 0x18, 0x70, 0x0,  
        0x0, 0x30, 0x30, 0x0, 0x0, 0x30, 0x30, 0x0,  
        0x0, 0x30, 0x30, 0x0, 0x0, 0x30, 0x30, 0x60,  
        0x18, 0x30, 0x60, 0xc0, 0x60, 0x30, 0x18, 0x0,  
        0x0, 0x0, 0xfc, 0x0, 0x0, 0xfc, 0x0, 0x0,  
        0x60, 0x30, 0x18, 0xc, 0x18, 0x30, 0x60, 0x0,  
        0x78, 0xcc, 0xc, 0x18, 0x30, 0x0, 0x30, 0x0,  
        0x7c, 0xc6, 0xde, 0xde, 0xde, 0xc0, 0x78, 0x0,  
        0x30, 0x78, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0x0,  
        0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x0,  
        0x3c, 0x66, 0xc0, 0xc0, 0xc0, 0x66, 0x3c, 0x0,  
        0xf8, 0x6c, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x0,  
        0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x0,  
        0xfe, 0x62, 0x68, 0x78, 0x68, 0x60, 0xf0, 0x0,  
        0x3c, 0x66, 0xc0, 0xc0, 0xce, 0x66, 0x3e, 0x0,  
        0xcc, 0xcc, 0xcc, 0xfc, 0xcc, 0xcc, 0xcc, 0x0,  
        0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x0,  
        0x1e, 0xc, 0xc, 0xc, 0xcc, 0xcc, 0x78, 0x0,  
        0xe6, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0xe6, 0x0,  
        0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x0,  
        0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x0,  
        0xc6, 0xe6, 0xf6, 0xde, 0xce, 0xc6, 0xc6, 0x0,  
        0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x0,  
        0xfc, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x0,  
        0x78, 0xcc, 0xcc, 0xcc, 0xdc, 0x78, 0x1c, 0x0,  
        0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x0,  
        0x78, 0xcc, 0xe0, 0x70, 0x1c, 0xcc, 0x78, 0x0,  
        0xfc, 0xb4, 0x30, 0x30, 0x30, 0x30, 0x78, 0x0,  
        0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0x0,  
        0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x0,  
        0xc6, 0xc6, 0xc6, 0xd6, 0xfe, 0xee, 0xc6, 0x0,  
        0xc6, 0xc6, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0x0,  
        0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x30, 0x78, 0x0,  
        0xfe, 0xc6, 0x8c, 0x18, 0x32, 0x66, 0xfe, 0x0,  
        0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x0,  
        0xc0, 0x60, 0x30, 0x18, 0xc, 0x6, 0x2, 0x0,  
        0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x0,  
        0x10, 0x38, 0x6c, 0xc6, 0x0, 0x0, 0x0, 0x0,  
        0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xff,  
        0x30, 0x30, 0x18, 0x0, 0x0, 0x0, 0x0, 0x0,  
        0x0, 0x0, 0x78, 0xc, 0x7c, 0xcc, 0x76, 0x0,  
        0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xdc, 0x0,  
        0x0, 0x0, 0x78, 0xcc, 0xc0, 0xcc, 0x78, 0x0,  
        0x1c, 0xc, 0xc, 0x7c, 0xcc, 0xcc, 0x76, 0x0,  
        0x0, 0x0, 0x78, 0xcc, 0xfc, 0xc0, 0x78, 0x0,  
        0x38, 0x6c, 0x60, 0xf0, 0x60, 0x60, 0xf0, 0x0,  
        0x0, 0x0, 0x76, 0xcc, 0xcc, 0x7c, 0xc, 0xf8,  
        0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0xe6, 0x0,  
        0x30, 0x0, 0x70, 0x30, 0x30, 0x30, 0x78, 0x0,  
        0xc, 0x0, 0xc, 0xc, 0xc, 0xcc, 0xcc, 0x78,  
        0xe0, 0x60, 0x66, 0x6c, 0x78, 0x6c, 0xe6, 0x0,  
        0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x78, 0x0,  
        0x0, 0x0, 0xcc, 0xfe, 0xfe, 0xd6, 0xc6, 0x0,  
        0x0, 0x0, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0x0,  
        0x0, 0x0, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x0,  
        0x0, 0x0, 0xdc, 0x66, 0x66, 0x7c, 0x60, 0xf0,  
        0x0, 0x0, 0x76, 0xcc, 0xcc, 0x7c, 0xc, 0x1e,  
        0x0, 0x0, 0xdc, 0x76, 0x66, 0x60, 0xf0, 0x0,  
        0x0, 0x0, 0x7c, 0xc0, 0x78, 0xc, 0xf8, 0x0,  
        0x10, 0x30, 0x7c, 0x30, 0x30, 0x34, 0x18, 0x0,  
        0x0, 0x0, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x0,  
        0x0, 0x0, 0xcc, 0xcc, 0xcc, 0x78, 0x30, 0x0,  
        0x0, 0x0, 0xc6, 0xd6, 0xfe, 0xfe, 0x6c, 0x0,  
        0x0, 0x0, 0xc6, 0x6c, 0x38, 0x6c, 0xc6, 0x0,  
        0x0, 0x0, 0xcc, 0xcc, 0xcc, 0x7c, 0xc, 0xf8,  
        0x0, 0x0, 0xfc, 0x98, 0x30, 0x64, 0xfc, 0x0,  
        0x1c, 0x30, 0x30, 0xe0, 0x30, 0x30, 0x1c, 0x0,  
        0x18, 0x18, 0x18, 0x0, 0x18, 0x18, 0x18, 0x0,  
        0xe0, 0x30, 0x30, 0x1c, 0x30, 0x30, 0xe0, 0x0,  
        0x76, 0xdc, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,  
        0x0, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0x0   }
        

int yaddinit;

xoribmchr(x,y,c)     /* exclusive or character c bit pattern at x,y */
                     /* first time draws character, second erases */
int x;               /* x is byte (character number 0-89) along line */
int y;               /* y is line number 0-348              */
char c;              /* c is character to put up */
{
int i,j,k;
union ccffxx{
char ccc[2];
int iii;
} ccii;
union llll{
long ll;
int li[2];
}il;
char * ppcc;
long ly;

ccii.iii = 0;                /* init array if not already done */
il.ll = 0;
if(yaddinit != 777)
 {
 setxdotyadd();
 }

ccii.ccc[0] = c;
k = ccii.iii;

for(j=0;j<8;j++)               /* chars are 8x8 bit grid, = 8 bytes */
 {
 il.li[0] = x + yadd[y+j];     /* add start of line offset to byte number */
 ly = il.ll + 0xb8000000;      /* add to start of screen memory */
 ppcc = (char *) ly;           /* create a pointer */
 *ppcc ^= chf[k].cc[j];        /* xor in the bit pattern */
 }
}

xoribmstr(x,y,s)               /* exclusive or a string at x,y */
int x,y;
char * s;
{
int i,j,k;
char a,b;
a = *s++;
while(a != 0x00)
 {
 xoribmchr(x,y,a);
 x = x + 1;
 a = *s++;
 }
}

=============================CUT HERE=====================================


struct ccrruumm{
char c;
};
union lpp{         /* union for parsing address pointers */
long  lll;
int   iii[2];
struct ccrruumm *ppp;
} lp ;
union lpp delt;
union lpp run;
long yadd[348];             /* array of address offsets for screen lines */
char xdot[8];               /* bytes with only bit N turned on */
int yaddinit;               /* init flag */

xorspot(x,y)      /* xor any spot on the 720x348 screen with 1 */
int x,y;
{
if(yaddinit != 777) {
  setxdotyadd();
  }
lp.lll = yadd[y];    /* screen start */
lp.iii[0] += x >> 3;
lp.ppp->c ^= xdot[x & 0x0007];
}

/*    Image memory for the hercules starts at B800:0000 and is divided
      into four banks of 8K each. The display on the screen in graphics
	  mode is built as follows:

	  1st line from bank 1
	  1st line from bank 2
	  1st line from bank 3
	  1st line from bank 4
	  2nd line from bank 1
	  2nd line from bank 2
	  2nd line from bank 3
	  2nd line from bank 4
          3rd line from bank 1
	        ...etc.

			*/


setxdotyadd()            /* set up addresses of each image line */
{                        /* in an array indexed by line number */
char xd;
int i1,i2,i3;
long k1,k2;
xd = 0x01;

yaddinit = 777;
for(i1=7;i1>=0;i1--)
  {
  xdot[i1] = xd;
  xd = xd << 1;
  }
for(i1=0;i1<348;i1++)
  {
  lp.lll = 0xb8000000;     /* base of memory */
  i2 = i1 & 3;
  i2 = i2 * 0x2000;        /* 8k (2000hex) per memory bank */
  lp.iii[0] += i2;
  i2 = i1 >> 2;
  i2 = i2 * 90;            /* length of lines in bytes */
  lp.iii[0] += i2;
  yadd[i1] = lp.lll;
  }
}

xorvect(x1,y1,x2,y2)   /* xor dots along a vector with 1's */
int x1,y1,x2,y2;       /*  vector endpoints on 720x348 screen */
                       /*  vector must be < 128 pixels long  */
{
int dx,dy,j1,j2,j3;
register int loop;

if(yaddinit != 777) {
  setxdotyadd();
  }
run.lll = 0;
lp.lll = 0;
delt.lll = 0;


if(x2 > x1)
  {
  dx = x2 - x1;
  if(y2 > y1)
    {
    dy = y2 - y1;
    if(dx > dy)
       {
       delt.iii[1] = dy;    /* use fixed point 8.8 bit math to emulate */
       lp.iii[0] = dx;      /* floating point math   */
       delt.lll = delt.lll / lp.lll;
       run.iii[1] = y1;
       for(loop=x1;loop<=x2;loop++)
         {
         lp.lll = yadd[run.iii[1]]; /* start of line */ 
         lp.iii[0] += loop >> 3;   /* byte number */
         lp.ppp->c ^= xdot[loop & 0x0007];  /* xor bit within byte */
         run.lll += delt.lll;      /* increment running fixed point */
         }
       }
    else
       {
       delt.iii[1] = dx;
       lp.iii[0] = dy;
       delt.lll = delt.lll / lp.lll;
       run.iii[1] = x1;
       for(loop=y1;loop<=y2;loop++)
         {
         lp.lll = yadd[loop];
         lp.iii[0] += run.iii[1] >> 3;
         lp.ppp->c ^= xdot[run.iii[1] & 0x0007];
         run.lll += delt.lll;
         }
       }
    }
  else if(y1 > y2)
    {
    dy = y1 - y2;
    if(dx > dy)
       {
       delt.iii[1] = dy;
       lp.iii[0] = dx;
       delt.lll = delt.lll / lp.lll;
       run.iii[1] = y1;
       for(loop=x1;loop<=x2;loop++)
         {
         lp.lll = yadd[run.iii[1]];
         lp.iii[0] += loop >> 3;
         lp.ppp->c ^= xdot[loop & 0x0007];
         run.lll -= delt.lll;
         }
       }
    else
       {
       delt.iii[1] = dx;
       lp.iii[0] = dy;
       delt.lll = delt.lll / lp.lll;
       run.iii[1] = x1;
       for(loop=y1;loop>=y2;loop--)
         {
         lp.lll = yadd[loop];
         lp.iii[0] += run.iii[1] >> 3;
         lp.ppp->c ^= xdot[run.iii[1] & 0x0007];
         run.lll += delt.lll;
         }
       }
    }
  else if(y1 == y2)
    {
    for(loop=x1;loop<=x2;loop++)
      {
      lp.lll = yadd[y1];
      lp.iii[0] += loop >> 3;
      lp.ppp->c ^= xdot[loop & 0x0007];
      }
    }
  }
else if(x1 > x2)
  {
  dx = x1 - x2;
  if(y2 > y1)
    {
    dy = y2 - y1;
    if(dx > dy)
       {
       delt.iii[1] = dy;
       lp.iii[0] = dx;
       delt.lll = delt.lll / lp.lll;
       run.iii[1] = y1;
       for(loop=x1;loop>=x2;loop--)
         {
         lp.lll = yadd[run.iii[1]];
         lp.iii[0] += loop >> 3;
         lp.ppp->c ^= xdot[loop & 0x0007];
         run.lll += delt.lll;
         }
       }
    else
       {
       delt.iii[1] = dx;
       lp.iii[0] = dy;
       delt.lll = delt.lll / lp.lll;
       run.iii[1] = x1;
       for(loop=y1;loop<=y2;loop++)
         {
         lp.lll = yadd[loop];
         lp.iii[0] += run.iii[1] >> 3;
         lp.ppp->c ^= xdot[run.iii[1] & 0x0007];
         run.lll -= delt.lll;
         }
       }
    }
  else if(y1 > y2)
    {
    dy = y1 - y2;
    if(dx > dy)
       {
       delt.iii[1] = dy;
       lp.iii[0] = dx;
       delt.lll = delt.lll / lp.lll;
       run.iii[1] = y2;
       for(loop=x2;loop<=x1;loop++)
         {
         lp.lll = yadd[run.iii[1]];
         lp.iii[0] += loop >> 3;
         lp.ppp->c ^= xdot[loop & 0x0007];
         run.lll += delt.lll;
         }
       }
    else
       {
       delt.iii[1] = dx;
       lp.iii[0] = dy;
       delt.lll = delt.lll / lp.lll;
       run.iii[1] = x2;
       for(loop=y2;loop<=y1;loop++)
         {
         lp.lll = yadd[loop];
         lp.iii[0] += run.iii[1] >> 3;
         lp.ppp->c ^= xdot[run.iii[1] & 0x0007];
         run.lll += delt.lll;
         }
       }
    }
  else if(y1 == y2)
    {
    for(loop=x2;loop<=x1;loop++)
      {
      lp.lll = yadd[y1];
      lp.iii[0] += loop >> 3;
      lp.ppp->c ^= xdot[loop & 0x0007];
      }
    }
  }
else if(x1 == x2)
  {
  if(y2 > y1)
    {
    for(loop=y1;loop<y2;loop++)
       {
       lp.lll = yadd[loop];
       lp.iii[0] += x1 >> 3;
       lp.ppp->c ^= xdot[x1 & 0x0007];
       }
    }
  else
    {
    for(loop=y2;loop<y1;loop++)
       {
       lp.lll = yadd[loop];
       lp.iii[0] += x1 >> 3;
       lp.ppp->c ^= xdot[x1 & 0x0007];
       }
    }
  }

}