/**********************************************************************/
/* The following is a demonstration of remapping characters vio BIOS. */
/* As many of you know, Peter Norton does alot of this in his text    */
/* based programs, and this demonstrates two of his creations, an     */
/* empty circle and a filled circle, used for choice indicators.  I   */
/* have incorporated these and many others into my text based work,   */
/* and it is very slick.                                              */
/*                                                                    */
/* Note that I am using the 8x16 VGA font here.  I know this will not */
/* work perfectly in aanything using 43 or 50 line mode, but anything */
/* using 25 line mode should* be OK.  My driver has a 132x25 mode and */
/* the code worked great.  Use at your own risk, however.             */
/*                                                                    */
/* Released to the public domain by John S. Crouch, 27 May 1993.      */
/**********************************************************************/

#include <stdio.h>
#include <dos.h>

typedef unsigned char MAP[16];

MAP gEmptyLeft =
{
    { '\x00' },             /*  1 =                   */
    { '\x07' },             /*  2 =            x x x  */
    { '\x18' },             /*  3 =        x x        */
    { '\x20' },             /*  4 =      x            */
    { '\x20' },             /*  5 =      x            */
    { '\x40' },             /*  6 =    x              */
    { '\x40' },             /*  7 =    x              */
    { '\x40' },             /*  8 =    x              */
    { '\x40' },             /*  9 =    x              */
    { '\x20' },             /* 10 =      x            */
    { '\x20' },             /* 11 =      x            */
    { '\x18' },             /* 12 =        x x        */
    { '\x07' },             /* 13 =            x x x  */
    { '\x00' },             /* 14 =                   */
    { '\x00' },             /* 15 =                   */
    { '\x00' }              /* 16 =                   */
};

MAP gEmptyRight =
{
    { '\x00' },             /*  1 =                   */
    { '\xe0' },             /*  2 =  x x x            */
    { '\x18' },             /*  3 =        x x        */
    { '\x04' },             /*  4 =            x      */
    { '\x04' },             /*  5 =            x      */
    { '\x02' },             /*  6 =              x    */
    { '\x02' },             /*  7 =              x    */
    { '\x02' },             /*  8 =              x    */
    { '\x02' },             /*  9 =              x    */
    { '\x04' },             /* 10 =            x      */
    { '\x04' },             /* 11 =            x      */
    { '\x18' },             /* 12 =        x x        */
    { '\xe0' },             /* 13 =  x x x            */
    { '\x00' },             /* 14 =                   */
    { '\x00' },             /* 15 =                   */
    { '\x00' }              /* 16 =                   */
};

MAP gFilledLeft =
{
    { '\x00' },             /*  1 =                   */
    { '\x07' },             /*  2 =            x x x  */
    { '\x18' },             /*  3 =        x x        */
    { '\x20' },             /*  4 =      x            */
    { '\x23' },             /*  5 =      x       x x  */
    { '\x47' },             /*  6 =    x       x x x  */
    { '\x47' },             /*  7 =    x       x x x  */
    { '\x47' },             /*  8 =    x       x x x  */
    { '\x47' },             /*  9 =    x       x x x  */
    { '\x23' },             /* 10 =      x       x x  */
    { '\x20' },             /* 11 =      x            */
    { '\x18' },             /* 12 =        x x        */
    { '\x07' },             /* 13 =            x x x  */
    { '\x00' },             /* 14 =                   */
    { '\x00' },             /* 15 =                   */
    { '\x00' }              /* 16 =                   */
};

MAP gFilledRight =
{
    { '\x00' },             /*  1 =                   */
    { '\xe0' },             /*  2 =  x x x            */
    { '\x18' },             /*  3 =        x x        */
    { '\x04' },             /*  4 =            x      */
    { '\xc4' },             /*  5 =  x x       x      */
    { '\xe2' },             /*  6 =  x x x       x    */
    { '\xe2' },             /*  7 =  x x x       x    */
    { '\xe2' },             /*  8 =  x x x       x    */
    { '\xe2' },             /*  9 =  x x x       x    */
    { '\xc4' },             /* 10 =  x x       x      */
    { '\x04' },             /* 11 =            x      */
    { '\x18' },             /* 12 =        x x        */
    { '\xe0' },             /* 13 =  x x x            */
    { '\x00' },             /* 14 =                   */
    { '\x00' },             /* 15 =                   */
    { '\x00' }              /* 16 =                   */
};

void zRemapChar(unsigned char pCh, MAP pChMap);

/*
** Simple demo main.
*/

int main(void)
{
   zRemapChar('\xDB',gEmptyLeft);
   zRemapChar('\xDC',gEmptyRight);
   zRemapChar('\xDD',gFilledLeft);
   zRemapChar('\xDE',gFilledRight);

   printf("\n\nThis is an empty circle: \xDB\xDC\n");
   printf("This is a filled circle: \xDD\xDE\n\n");

   printf("\n");
   printf("\xDB\xDC Open Window\n");
   printf("\xDB\xDC Close Window\n");
   printf("\xDD\xDE Exit to DOS\n");
   printf("\xDB\xDC Execute Dos Command\n");
   printf("\xDB\xDC Save as...\n");


   return(0);
}

/*
** Routine that does the remapping.  Pass it the character to be mapped,
** and the array holding the new character.
*/

void zRemapChar(unsigned char pCh,MAP pChMap)
{
   struct REGPACK regs;

   regs.r_ax = 0x1100;
   regs.r_bx = 0x1000;
   regs.r_cx = 0x0001;
   regs.r_dx = (unsigned int) pCh;
   regs.r_es = _DS;
   regs.r_bp = (unsigned int) pChMap;
   intr(0x10, &regs);
}

