Xref: utzoo comp.sys.ibm.pc:9653 comp.sources.wanted:2774
Path: utzoo!utgpu!water!watmath!clyde!rutgers!ames!elroy!mahendo!jplgodo!wlbr!etn-rad!jru
From: jru@etn-rad.UUCP (John Unekis)
Newsgroups: comp.sys.ibm.pc,comp.sources.wanted
Subject: Re: Hercules graphic characters
Keywords: hercules, text, MASM, MSC
Message-ID: <319@etn-rad.UUCP>
Date: 18 Dec 87 00:29:46 GMT
References: <246@tolsun.oulu.fi>
Reply-To: jru@etn-rad.UUCP (John Unekis)
Organization: Eaton Inc. IMSD, Westlake Village, CA
Lines: 469

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> 3;
       lp.ppp->c ^= xdot[x1 & 0x0007];
       }
    }
  else
    {
    for(loop=y2;loop> 3;
       lp.ppp->c ^= xdot[x1 & 0x0007];
       }
    }
  }

}