/*
	vgademo.c

   This example demonstrates the use of a VGA card driven by a Z104 or a
   ZISA board with more than 32 kbytes of RAM.

   Supports the following VGA cards:
        AMPRO PC104 VGA Card
        Trident ISA 8900D VGA Card
        Acumos ISA VGA Card
        Boca ISA VGA006

   ISA VGA Cards are supported by the ZISA card.

   VGAInit(..) returns a -1 if the VGA card used is unsupported or if there
	is no VGA card connected.

	Uncomment #define FINDFONT if the bios font areas are other than the
	hardware values in the z104.lib. If FINDFONT is defined, the bios font
	areas are scaned from the VGA bios.

	Uncomment #define TRIDENT8x256 if your Trident8900D VGA card uses
	8x256 DRAM.
*/

#use "default.h"

#if (BOARD_TYPE!=Z104ISA)
#fatal "This program only runs on the Z104 or ZISA boards."
#endif

#define FINDFONT
// #define TRIDENT8x256

void wait_demo(unsigned long delay);
void demo_txt();
void demo_circle(int nfill);
void demo_polygon(int nfill);
void demo_image();
void demo_block();
void block(int x1, int y1, int x2, int y2, int color);
void demoxsline();
void demoysline();
void demo_getimage();
void demo_largechar();
void demo_time();
float random( int iseed, int first);
struct tm thistime;

main()
{
   int i;
   int data;
   
   random(-1,1);                // load the randow number generator
   if(VGAInit(0x03)==-1) 
   {
      printf("No VGA Card or Unsupported VGA card \n");
      while(1) runwatch();
   }
   printf("Proceeding with Demo Program \n");
   while(1)
   {

      tmc_rd(&thistime);
      VGAInit(0x03);          // demo text mode
      demo_txt();
      wait_demo(30000L);
      VGALoadFont((char *)0, 14, 1, 0);
      VGASelectFont(1);       // select 8x14 font
      wait_demo(30000L);
      VGALoadFont((char *)0, 16, 2, 0);
      VGASelectFont(2);       // select 8x16 font
      wait_demo(30000L);
      VGASelectFont(0);       // select back to 8x8 font
      for(i=0;i<5;i++)        // scroll text up and down for 5 times
      {
         VGAScrollText(2, 10, 16, 60, 5);
         wait_demo(20000L);
         VGAScrollText(2, 10, 16, 60, -5);
         wait_demo(20000L);
      }

      VGAInit(0x12);          // demo graphics mode 0x12
      demo_time(thistime);
      wait_demo(30000L);
      demo_largechar();
      wait_demo(30000L);
      demo_txt();
      wait_demo(30000L);
      demo_block();
      wait_demo(30000L);
      demo_circle(1);
      demo_polygon(1);
      demo_image();
      demoxsline();
      demoysline();
      demo_getimage();
      wait_demo(30000L);
    }

}

// software delay 
void wait_demo(unsigned long delay)
{
   unsigned long count;
   for( count = 0L; count < delay; count++);
}

// show time and date with large graphics character    
void demo_time(struct tm dtime)
{
   char buf[20];
   largestring("time:",0,0,1,3);
   sprintf(buf,"%02d:%02d:%02d",dtime.tm_hour,dtime.tm_min,dtime.tm_sec);
   largestring(buf,64,0,1,4);
   largestring("date:",128,0,1,3);
   sprintf(buf,"%02d-%02d-%2d",dtime.tm_mon, dtime.tm_mday, dtime.tm_year);
   largestring(buf,192,0,1,4);
}

// demo large characters
void demo_largechar()
{
   int i,j;
   VGAClearScrn();
   largestring("hello", 0,  0, 2, 3);
   largestring("world", 128,0, 2, 4);
   largestring("helloworld", 256,0, 1, 5);
   largestring("helloworld", 320,0, 1, 6);
   for(i=0;i<10;i++)
      VGAString("hello world hello world hello world hello world",i+50,0,i+7);
}

// displays a character string in large character
largestring(char *buf, int prow, int pcol, int magnify,int color)
{
   int i;
   for(i=0;i<strlen(buf);i++)
   {
      VGALargeChar( buf[i],prow, pcol+i*64*magnify, magnify, color);
   }
}

// display text
void demo_txt()
{
   int i,j;

   for(i = 0; i < 25; i++)
   {
      VGAString("Z-World Engineering Z104/ZISA Card",i, 0, i+1);
   }

   i = 7;
   VGAString("Z-World's Z104/ZISA are compact general pur-", 0, 36, i);
   VGAString("pose controllers that complies with the     ", 1, 36, i);
   VGAString("intertionally recognized PC/104 standard.   ", 2, 36, i);
   i = 0x87;
   VGAString("The Z104/ZISA are full-fledged computers    ", 3, 36, i);
   VGAString("that have capabilities of other Z-World con-", 4, 36, i);
   VGAString("trollers. It uses a Z180 microprocessor run-", 5, 36, i);
   VGAString("ning at 18.432 Mhz, and provides RS232 &    ", 6, 36, i);
   VGAString("RS485 communication, programmable timers,   ", 7, 36, i);
   VGAString("large memory space and battery back up. It  ", 8, 36, i);
   VGAString("has Z-World's PLCBus port which allows addi-", 9, 36, i);
   VGAString("tion of expansion cards (such as analog-to- ", 10,36, i);
   VGAString("digital conversion board).                  ", 11,36, i);
   i = 0x93;
   VGAString("The Z104/ZISA are supported by Z-World's C  ", 12,36, i);
   VGAString("development system, Dynamic C, which com-   ", 13,36, i);
   VGAString("bines a text editor, fast compiler and sym- ", 14,36, i);
   VGAString("bolic bugger. Dynamic C comes with dozens of", 15,36, i);
   VGAString("function libraries (including a real time   ", 16,36, i);
   VGAString("kernel) & sample programs, all in source    ", 17,36, i);
   VGAString("code. It is available for DOS and Windows.  ", 18,36, i);
   i = 0xd2;
   VGAString("The Z104/ZISA are best-suited for embedded  ", 19,36, i);
   VGAString("systems with one or two standard PC/104 or  ", 20,36, i);
   VGAString("ISA devices (such as a VGA display interface", 21,36, i);
   VGAString("or modem card.                              ", 22,36, i);

}

// demo graphics mode by drawing circles
void demo_circle(int nfill)
{
      int xc, yc;
      int xold, yold;
      int i;
      VGAClearScrn();
      for(i = 0; i < 200 ; i++)
      {
         xc = 479*random(0,0);
         yc = 639*random(0,0);
         VGAEllipse(xc, yc, 25, 25, xc, nfill);
      }
}

// demo graphics mode by drawing 4 sided polygons
void demo_polygon(int nfill)
{
      int i;
      int npoints[8];
      VGAClearScrn();
      
      npoints[0] = 0;
      npoints[1] = 0;
      npoints[2] = 100;
      npoints[3] = 100;
      npoints[4] = 100;
      npoints[5] = 200;
      npoints[6] = 75;
      npoints[7] = 150;
      for(i = 0; i< 100 ; i++)
      {
         npoints[0] = npoints[2];
         npoints[1] = npoints[3];
         npoints[2] = npoints[4];
         npoints[3] = npoints[5];
         npoints[4] = npoints[6];
         npoints[5] = npoints[7];
         npoints[6] = 479*random(0,0);
         npoints[7] = 639*random(0,0);
         VGAPolygon(npoints, 4, npoints[6], nfill);
      }
}

char zimage[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
                  0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
                  0xe0, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
                  0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x07,
                  0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07,
                  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};


// demo graphics mode by displaying bit map image
void demo_image()
{
      int i, x, y;
      
      VGAClearScrn();
      for( i = 0; i < 1000; i++)
      {
         x = 489*random(0,0);
         y = 639*random(0,0);
         VGAPutPixel(x,y,x);
      }
      VGAWriteMode(0x03);           // put in xor mode
      for(i = 0; i < 50; i++ )
      {
          x = 489*random(0,0);
          y = 639*random(0,0);
          VGAPutImage(x, y, zimage, 8, 8, x);
          wait_demo(4000L);
          VGAPutImage(x, y, zimage, 8, 8, x);
      }
      VGAWriteMode(0x00);
}

// demo graphics mode by displaying color blocks
void demo_block()
{
       int i,j,k;
       VGAClearScrn();
       k = 0;
       for(i=50;i<400;i=i+100)
            for(j=60;j<520;j=j+140)
                block(i,j,i+90,j+100,k++);
}

// use horizontal line draw to create blocks
void block(int x1, int y1, int x2, int y2, int color)
{
      int i;
      for(i=x1; i<=x2;i++)VGAHline(i,y1,i,y2,color); 
}

// demo graphics mode by drawing x sloping line 
void demoxsline()
{
   int i;
   VGAClearScrn();
   for(i = 0; i<=639; i++)
   {
      VGAline( 0, 319, 479, i, i);
   }
   for(i = 0; i<=639; i++)
   {
      VGAline( 479, 319, 0, i, i);
   }

}

// demo graphics mode by drawing y sloping line
void demoysline()
{
   int i;
   VGAClearScrn();
   for(i = 0; i<=479; i++)
   {
      VGAline( 240, 0, i, 639, i);
   }
   for(i = 0; i<=479; i++)
   {
      VGAline( 240, 639, i, 0, i);
   }

}

// demo_getimage()
void demo_getimage()
{
    char myimage[410];  // 41 rows x 10 columns byte image
    int i,j,k;
    VGAClearScrn();
    VGAEllipse(100,100,10,40,3,1); // draw horizontal ellipse
    VGAEllipse(100,100,15,15,3,1); // draw center circle
    VGAline(80,80,120,80,3);        // draw vertical line
    VGAline(120,80,120,120,3);      // draw horizontal line
    VGAline(120,120,80,120,3);      // draw vertical line
    VGAline(80,120,80,80,3);        // draw horizontal line
    VGAline(80,80,120,120,3);       // draw diagonal
    VGAline(80,120,120,80,3);       // draw diagonal
    VGAGetImage(80,60,myimage,41,10,3);

    VGAClearScrn();
    for(k=1;k<20;k++)
    {
      for(i=0;i<6;i++)             // draw the image
         for(j=0;j<6;j++)
            VGAPutImage(20+i*100,30+j*100,myimage,41,10,k+i+j);
    }
}

#define MBIG 1000000000
#define MSEED 161803398
#define MZ 0
#define FAC (1.0/MBIG)

// Random number generator, has to seed first with random(-1,1) before 
// using.
// Returns number from 0.000 to 1.000.
nodebug
float random(int iseed, int ifirst)
{
   static int inext, inextp;
   static long ma[56];
   long mj, mk;
   int i, ii, k;

   if(iseed < 0 || ifirst==1)
    {
      mj = MSEED - (iseed < 0 ? -iseed : iseed);
      mj %= MBIG;
      ma[55] = mj;
      mk = 1;
      for(i=1;i<=54;i++)
      {
        ii = (21*i) % 55;
        ma[ii] = mk;
        mk = mj - mk;
        if(mk < MZ) mk += MBIG;
        mj = ma[ii];
      }
      for(k=1;k<=4;k++)
      {
        for (i=1;i<=55;i++)
          {
            ma[i] -=ma[1+(i+30) % 55];
            if(ma[i] < MZ) ma[i] += MBIG;
          }
       }
       inext = 0;
       inextp = 31;
     }
    if(++inext == 56) inext = 1;
    if(++inextp == 56) inextp = 1;
    mj = ma[inext] - ma[inextp];
    if(mj < MZ) mj+= MBIG;
    ma[inext] = mj;
    return mj*FAC;
 }


