#include <fpclib.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <math.h>

typedef struct TCell {
                     char Ch,Attr;
                     } TCell;

void ClearTime( void );
void Delay( int num );
void str(int num, int digits, char *st );
char UpCase( char ch );
void DisplayTime( int NTimes );
void TestBorderColor( void );
void TestClrWin( void );
void TestColorMsg( void );
void TestEditSt( void );
void TestFillColAttr( void );
void TestFillColCell( void );
void TestFillColChar( void );
void TestFillFrameAttr( void );
void TestFillFrameCell( void );
void TestFillFrameChar( void );
void TestFillRowAttr( void );
void TestFillRowCell( void );
void TestFillRowChar( void );
void TestGetFrameAttr( void );
void TestGetFrameCell( void );
void TestGetFrameChar( void );
void TestGetScrn( void );
void TestPutScrn( void );
void TestPutFrameAttr( void );
void TestPutFrameCell( void );
void TestPutFrameChar( void );
void TestGetCursorSize( void );
void TestFrameWin( void );
void TestSetCursorSize( void );
void TestRvsAttr( void );
void TestGetVideoMode( void );
void TestInitVideo( void );
void TestGetVideoCols( void );
void TestGetVideoPage( void );
void TestGetVideoInfo( void );
void TestSetVideoPage( void );
void TestWhereXYAbs( void );
void TestScrollLeft( void );
void TestScrollRight( void );
void TestScrollDown( void );
void TestScrollUp( void );
void TestWriteSt( void );
void TestWriteStln( void );
int  GetMenuSelection( void );


char TCSet[32] = {  0,101,  0,0,0,0, 0,24,
                   57,213,192,0,0,0,95, 0,
                    8,  0,  0,0,0,0, 0, 0,
                    0,  0,  0,0,0,0, 0, 0
                 };

char VCSet[32] = {   0,  0,  0,  0,255,255,255,255,
                   255,255,255,255,255,255,255,255,
                   255,255,255,255,255,255,255,255,
                   255,255,255,255,255,255,255,255
                 };

int    i,j,i1,k,ChOfs,TE,
       H1,M1,S1,Sec100_1,
       H2,M2,S2,Sec100_2,
       t1,t2,t3,Total;

char   St[256],Done;


void ClearTime()
{
   H1 = M1 = S1 = Sec100_1 = 0;
   H2 = M2 = S2 = Sec100_2 = 0;
   Total = 0;
}

void Delay(num)
int num;
{
   int i;

   num *= 50;
   for (i = 0; i <= num; i++)
   ;
}

void str(num,digits,st)
char *st;
int  num,digits;
{
   int i;

   *(st+digits) = '\0';
   for (i = digits-1; i >= 0; i--) {
      *(st+i) =  (num % 10) + 48;
      num /= 10;
   }
}

char UpCase(ch)
char ch;
{
   if (ch >= 'a' && ch <= 'z')
      ch -= 32;
   return(ch);
}

void DisplayTime(NTimes)
int  NTimes;
{
   char   st[80];


   WindowFP(15,10,65,14);
   ClrWin( 15, 10, 65, 14, 48 );
   FrameWin('É','»','È','¼','Í','º',48);

   strcpy( st, "Total Time = " );
   itoa( Total, &st[13], 10 );
   ColorMsg( 17, 11, 48, st );

   strcpy( st, "NTimes     = " );
   itoa( NTimes, &st[13], 10 );
   ColorMsg( 17, 12, 48, st );


   strcpy( st, "Average time = " );
   itoa( Total / NTimes , &st[15], 10 );
   strcat( st, " hundredths of a second" );
   ColorMsg( 17, 13, 48, st );

   for (i = 0; i < 3; i++)
      FillRowAttr(16,i+11,50,48);
   ColorMsg(18,14,144," Press any key to continue... ");
   GetKey();
}

void TestBorderColor()
{
   int  i;

   if ( VioMode == 7 ) {
      ClrWin(1,1,80,25,7);
      WindowFP(21,11,60,14);
      ClrWin(21,11,60,14,48);
      FrameWin('É','»','È','¼','Í','º',48);
      ColorMsg(23,12,48,"Not Available on Monochrome monitors");
      ColorMsg(23,13,48,"    Press any key to continue...");
      WindowFP(1,1,80,25);
   }
   else {
      GotoxyAbs(1,1);
      for (i = 1; i <= 15; i++) {
         BorderColor(i);
         WriteStln("Press any key to continue...");
         GetKey();
      }
   }
   GetKey();
   BorderColor(0);
}

void TestClrWin()
{
   int    Color,TopRow,BottomRow,LeftCol,RightCol;

   ClrWin(1,1,80,25,7);
   GotoxyAbs(1,1);
   printf("\nEnter attribute value to clear screen with. 0-255 ==> ");
   scanf("%d",&Color);
   printf("\nEnter top row of area to clear. 1-25 ==> ");
   scanf("%d",&TopRow);
   printf("\nEnter left column of area to clear. 1-80 ==> ");
   scanf("%d",&LeftCol);
   printf("\nEnter bottom row of area to clear. %u-25 ==> ",TopRow);
   scanf("%d",&BottomRow);
   printf("\nEnter right column of area to clear. %u-80 ==> ",LeftCol);
   scanf("%d",&RightCol);

   FillRowCell(1,1,2000,(65 << 8) + 7);
   ColorMsg(1,1,48,"Press any key to clear area");
   GetKey();
   ClrWin(LeftCol,TopRow,RightCol,BottomRow,Color);
   ColorMsg(1,1,48,"Press any key to return to menu");
   GetKey();
}

void TestColorMsg()
{
   char Msg[256];
   int  i,Color,Char_Ofs = 1,TE = 0;

   TextAttr = 7;
   do {
      ClrWin(1,1,80,25,7);
      GotoxyAbs(1,1);
      WindowFP(10,1,69,3);
      FrameWin('É','»','È','¼','Í','º',TextAttr);
      ColorMsg(12,2,TextAttr,
               "Enter 'QUIT' for message when you want to quit this test");
      WindowFP(1,4,60,7);
      FrameWin('É','»','È','¼','Í','º',TextAttr);
      ColorMsg(3,4,TextAttr," ColorMsg data ");
      ColorMsg(3,5,TextAttr,"Enter message to display ==> ");
      for (i = 0; i < 255; Msg[i++] = '\0')
      ;
      EditSt(5,32,59,28,0,32,0,7000,2000,VCSet,TCSet,&Char_Ofs,&TE,Msg);
      ColorMsg(3,6,TextAttr,"Enter the color to display message in ==> ");
      GotoxyAbs(44,6);
      scanf("%d",&Color);

      WindowFP(1,10,50,14);
      FrameWin('É','»','È','¼','Í','º',TextAttr);

      ColorMsg(3,11,Color,Msg);
      RvsAttr(TextAttr);
      ColorMsg(2,13,TextAttr,
               "          Press any key to continue...          ");
      RvsAttr(TextAttr);
      GetKey();
      for (Color = 0; Color < 4; Color++)
         if (Msg[Color] >= 'a' && Msg[Color] <= 'z')
            Msg[Color] -= 32;

   } while (strcmp(Msg,"QUIT"));
}

void TestEditSt()
{
   char  St[256];
   int   i,Char_Ofs,TE;

   ClrWin(1,1,80,25,7);
   ColorMsg(1,10,7,"Enter your name:");
   for (i = 0; i <= 255; St[i++] = '\0')
   ;
   Char_Ofs = 1;
   TE       = 0;
   EditSt(10,18,28,30,1,7,0,7000,2000,VCSet,TCSet,&Char_Ofs,&TE,St);
   RvsAttr(TextAttr);
   GotoxyAbs(1,15);
   WriteSt(St);
   RvsAttr(TextAttr);
   GetKey();
}

void TestFillColAttr()
{
   int   i,NTimes = 80;

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FillColAttr(i,1,25,i*16);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestFillColCell()
{
   int i,
       NTimes = 80;

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FillColCell(i,1,25,((i+64) << 8) + i);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestFillColChar()
{
   int i,
       NTimes = 80;

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FillColChar(i,1,25,i+64);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestFillFrameAttr()
{
   int i,
       NTimes = 15;

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FillFrameAttr(1,1,80,25,i << 4);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestFillFrameCell()
{
   int i,
       NTimes = 15;

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FillFrameCell(1,1,80,25,((i+64) << 8) + i);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestFillFrameChar()
{
   int i,
       NTimes = 15;

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FillFrameChar(1,1,80,25,(i+64));
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestFillRowAttr()
{
   int i,NTimes = 15;

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FillRowAttr(1,1,2000,i*16);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestFillRowCell()
{
   int  i,NTimes = 15;

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FillRowCell(1,1,2000,((64+i) << 8) + i);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestFillRowChar()
{
   int  i,NTimes = 15;

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FillRowChar(1,1,2000,(i+64));
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestGetFrameAttr()
{
   int  i,NTimes = 15;
   char Buffer[26][80];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      FillRowCell(1,1,2000,((i+64) << 8) + i*16);

      GetTime(&H1,&M1,&S1,&Sec100_1);
      GetFrameAttr(1,1,80,25,Buffer[0]);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestGetFrameCell()
{
   int  i,NTimes = 15;
   char Buffer[25][160];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {
      FillRowCell(1,1,2000,((i+64) << 8) + i*16);

      GetTime(&H1,&M1,&S1,&Sec100_1);
      GetFrameCell(1,1,80,25,Buffer[0]);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestGetFrameChar()
{
   int  i,NTimes = 15;
   char Buffer[25][80];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {
      FillRowCell(1,1,2000,((i+64) << 8) + i*16);

      GetTime(&H1,&M1,&S1,&Sec100_1);
      GetFrameChar(1,1,80,25,Buffer[0]);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestGetScrn()
{
   int  i,NTimes = 30;
   char Buffer[25][160];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      FillRowChar(1,1,2000,(i+64));
      GetTime(&H1,&M1,&S1,&Sec100_1);
      GetScrn(1,1,2000,Buffer[0]);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);

}

void TestPutScrn()
{
   int  i,NTimes = 30;
   char Buffer[25][160];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {

      FillRowChar(1,1,2000,(i+64));
      GetScrn(1,1,2000,Buffer[0]);
      FillRowChar(1,1,2000,0);

      GetTime(&H1,&M1,&S1,&Sec100_1);
      PutScrn(1,1,2000,Buffer[0]);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestPutFrameAttr()
{
   int  i,NTimes = 15;
   char Buffer[25][80];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {
      FillRowCell(1,1,2000,((i+64) << 8) + i*16);
      GetFrameAttr(1,1,80,25,Buffer[0]);
      ClrWin(1,1,80,25,7);

      GetTime(&H1,&M1,&S1,&Sec100_1);
      PutFrameAttr(1,1,80,25,Buffer[0]);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestPutFrameCell()
{
   int  i,NTimes = 15;
   char Buffer[25][160];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {
      FillRowCell(1,1,2000,((i+64) << 8) + i);
      GetFrameCell(1,1,80,25,Buffer[0]);

      GetTime(&H1,&M1,&S1,&Sec100_1);
      PutFrameCell(1,1,80,25,Buffer[0]);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestPutFrameChar()
{
   int  i,NTimes = 15;
   char Buffer[25][80];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for (i = 1; i <= NTimes; i++) {
      FillRowCell(1,1,2000,((i+64) << 8) + i*16);
      GetFrameChar(1,1,80,25,Buffer[0]);
      ClrWin(1,1,80,25,7);

      GetTime(&H1,&M1,&S1,&Sec100_1);
      PutFrameChar(1,1,80,25,Buffer[0]);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestGetCursorSize()
{
   char St1[256],St2[256];
   int  size;

   ClrWin(1,1,80,25,7);
   WindowFP(24,10,55,14);
   ClrWin(24,10,55,14,48);
   FrameWin('É','»','È','¼','Í','º',48);
   GotoxyAbs(1,1);
   ColorMsg(26,10,48," GetCursorSize ");
   size = GetCursorSize();

   itoa(size & 0xff,St2,10);
   strcpy(St1," Starting scan line = ");
   strcat(St1,St2);
   ColorMsg(25,11,48,St1);

   itoa(size >> 8,St2,10);
   strcpy(St1," Ending scan line   = ");
   strcat(St1,St2);
   ColorMsg(25,12,48,St1);

   ColorMsg(25,14,144," Press any key to continue... ");
   GetKey();
   WindowFP(1,1,80,25);
}

void TestFrameWin()
{
   int    i,NTimes = 10,t1 = 0;

   ClrWin(1,1,80,25,7);
   ClearTime();
   WindowFP(1,1,80,25);
   for (i = 1; i <= NTimes; i++) {

      GetTime(&H1,&M1,&S1,&Sec100_1);
      FrameWin('Ú','¿','À','Ù','Ä','³',7);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      };
   };
   DisplayTime(NTimes);
}

void TestSetCursorSize()
{
   int    StScan,SpScan;

   ClrWin(1,1,80,25,7);
   WindowFP(24,10,58,14);
   ClrWin(24,10,58,14,48);
   FrameWin('É','»','È','¼','Í','º',48);
   GotoxyAbs(1,1);
   ColorMsg(26,10,48," GetCursorSize ");

   ColorMsg(26,11,48,"Enter Starting scan line ==> ");
   GotoxyAbs(55,11);
   scanf("%d",&StScan);

   ColorMsg(26,12,48,"Ending scan line         ==> ");
   GotoxyAbs(55,12);
   scanf("%d",&SpScan);

   SetCursorSize(StScan,SpScan);
   ColorMsg(26,14,144," Press any key to continue...");
   GetKey();
}

void TestRvsAttr()
{
   char  St1[256],St2[256];
   int   i,j,k,HiCur,LoCur;

   HiCur = (VioCursor >> 8);
   LoCur = (VioCursor & 0xff);
   SetCursorSize(32,32);
   ClrWin(1,1,80,25,7);

   WindowFP(5,2,40,19);
   FrameWin('É','»','È','¼','Í','º',7);
   ColorMsg(7,2,7," Text with normal attributes ");

   WindowFP(45,2,80,19);
   FrameWin('É','»','È','¼','Í','º',7);
   ColorMsg(47,2,7," Text with reverse attributes ");

   for (k = 0, j = 1; j <= 16; j++) {
      ClrWin(6,3,39,18,7);
      ClrWin(46,3,79,18,7);
      for (i = 0; i <= 15; i++) {

         str(k,3,St2);
         strupr(St2);
         strcpy(St1,"        TextAttr = ");
         strcat(St1,St2);
         strcat(St1,"            ");
         ColorMsg(6,i+3,k,St1);

         RvsAttr(TextAttr);
         str(k,3,St2);
         strupr(St2);
         strcpy(St1,"        TextAttr = ");
         strcat(St1,St2);
         strcat(St1,"            ");
         ColorMsg(46,i+3,k,St1);
         k = k + 1;
      }
      WindowFP(25,22,56,24);
      FrameWin('É','»','È','¼','Í','º',7);
      ColorMsg(26,23,144," Press any key to continue... ");
      GetKey();
      ClrWin(25,22,56,24,7);
      Delay(200);
   }
   TextAttr = 6;
   SetCursorSize(LoCur,HiCur);
}


void TestGetVideoMode()
{
   char St[256];
   int  i;

   ClrWin(1,1,80,25,7);
   WindowFP(20,11,60,13);
   FrameWin('É','»','È','¼','Í','º',7);
   i = GetVideoMode();
   switch (i) {
      case 0 : strcpy(St,"0 - CGA - Text b/w Medium resolution");
               break;

      case 1 : strcpy(St,"1 - CGA - Text color Medium resolution");
               break;

      case 2 : strcpy(St,"2 - CGA - Text b/w High resolution");
               break;

      case 3 : strcpy(St,"3 - CGA - Text color High resolution");
               break;

      case 7 : strcpy(St,"7 - Monochrome monitor");
   }

   ColorMsg(22,11,TextAttr," Current video mode ");
   ColorMsg(22,12,TextAttr,St);
   ColorMsg(25,13,144,"Press any key to continue...");
   GetKey();
}


void TestInitVideo()
{
   char  St[256],Error;
   int   OldMode,NewMode,i;

   OldMode = GetVideoMode();
   do {
      InitVideo(OldMode);
      ClrWin(1,1,80,25,7);
      WindowFP(10,1,60,20);
      FrameWin('É','»','È','¼','Í','º',7);
      ColorMsg(12,1,TextAttr," SetVideoMode ");
      ColorMsg(12,2,TextAttr," 0 - CGA - Text b/w Medium resolution");
      ColorMsg(12,3,TextAttr," 1 - CGA - Text color Medium resolution");
      ColorMsg(12,4,TextAttr," 2 - CGA - Text b/w High resolution");
      ColorMsg(12,5,TextAttr," 3 - CGA - Text color High resolution");
      ColorMsg(12,6,TextAttr," 4 - CGA - Graphics Medium resolution");
      ColorMsg(12,7,TextAttr," 5 - CGA - Graphics Medium resolution");
      ColorMsg(12,8,TextAttr," 6 - CGA - Graphics High resolution");
      ColorMsg(12,9,TextAttr," 7 - Monochrome monitor");
      ColorMsg(12,10,TextAttr," 8 - PCjr - Graphics Low resolution");
      ColorMsg(12,11,TextAttr," 9 - PCjr - Graphics Medium resolution");
      ColorMsg(12,12,TextAttr,"10 - PCjr,EGA - Graphics High resolution");
      ColorMsg(12,13,TextAttr,"13 - EGA - Graphics Medium resolution");
      ColorMsg(12,14,TextAttr,"14 - EGA - Graphics High resolution");
      ColorMsg(12,15,TextAttr,"15 - EGA - Graphics Extra high resolution");
      ColorMsg(12,16,TextAttr,"16 - Quit");
      ColorMsg(12,18,TextAttr,"Select mode to initialize ==> ");
      GotoxyAbs(42,18);
      scanf("%d",&NewMode);
      ClrWin(1,1,80,25,7);

      Error = 0;
      if (OldMode == 7) {
         if (NewMode != 7 && NewMode != 16)
            Error++;
      } else if (NewMode > 7 && NewMode < 16)
         Error++;

      if (Error) {
         strcpy(St,"Invalid mode was entered.  Press any key to continue");
         ColorMsg(1,19,TextAttr,St);
            GetKey();
      } else if (NewMode != 16) {
         ClrWin(1,1,80,25,7);
         InitVideo(NewMode);
         if ((NewMode >= 4  && NewMode <= 6)  ||
             (NewMode >= 8  && NewMode <= 10) ||
             (NewMode >= 13 && NewMode <= 15)) {
            for (i = 0; i <= 15; i++)
               printf("This is the new video mode\n");
         } else if (NewMode >= 0 && NewMode <= 3)
            for (i = 0; i <= 15; i++)
               WriteStln("This is the new video mode");
         printf("\n\nPress any key to continue...");
         GetKey();
      }

   } while (NewMode != 16);
}

void TestGetVideoCols()
{
   char St1[256],St2[256];

   ClrWin(1,1,80,25,7);
   WindowFP(24,10,57,13);
   ClrWin(24,10,57,13,48);
   FrameWin('É','»','È','¼','Í','º',48);
   GotoxyAbs(1,1);
   TextAttr = 48;
   ColorMsg(26,10,48," GetVideoCols ");
   itoa(GetVideoCols(),St2,10);
   strcpy(St1," Number of columns = ");
   strcat(St1,St2);
   ColorMsg(26,11,48,St1);
   ColorMsg(26,13,144," Press any key to continue...");
   GetKey();
   TextAttr = 7;
}

void TestGetVideoPage()
{
   char  St1[256],St2[256];

   ClrWin(1,1,80,25,7);
   WindowFP(24,10,57,13);
   ClrWin(24,10,57,13,48);
   FrameWin('É','»','È','¼','Í','º',48);
   ColorMsg(26,10,48," GetVideoPage ");

   itoa(GetVideoPage(),St2,10);
   strcpy(St1," Current video page number = ");
   strcat(St1,St2);
   ColorMsg(25,11,48,St1);
   ColorMsg(25,12,48," Press any key to continue...");
   GetKey();
   TextAttr = 7;
}

void TestGetVideoInfo()
{
   char St1[256],St2[256];

   ClrWin(1,1,80,25,7);
   WindowFP(24,9,57,17);
   ClrWin(24,9,57,17,48);
   FrameWin('É','»','È','¼','Í','º',48);
   ColorMsg(26,9,48," GetVideoInfo ");

   itoa(GetVideoMode(),St2,10);
   strcpy(St1," Current mode         = ");
   strcat(St1,St2);
   ColorMsg(25,10,48,St1);

   itoa(GetVideoPage(),St2,10);
   strcpy(St1," Active page          = ");
   strcat(St1,St2);
   ColorMsg(25,11,48,St1);

   itoa(GetVideoCols(),St2,10);
   strcpy(St1," Number cols          = ");
   strcat(St1,St2);
   ColorMsg(25,12,48,St1);

   itoa(TextAttr,St2,10);
   strcpy(St1," Text attribute       = ");
   strcat(St1,St2);
   ColorMsg(25,13,48,St1);

   itoa(VioBaseSeg,St2,16);
   strupr(St2);
   strcpy(St1," Base Segment Address = ");
   strcat(St1,St2);
   ColorMsg(25,14,48,St1);

   ColorMsg(25,16,48," Press any key to continue...");
   GetKey();
}


void TestSetVideoPage()
{
   char St1[256],St2[256];
   int  PgNo;

   ClrWin(1,1,80,25,7);
   WindowFP(24,8,57,17);
   ClrWin(24,8,57,17,48);
   FrameWin('É','»','È','¼','Í','º',48);
   GotoxyAbs(25,10);
   ColorMsg(26,8,48," SetVideoPage ");

   itoa(GetVideoPage(),St2,10);
   strcpy(St1," Current video page number = ");
   strcat(St1,St2);
   ColorMsg(25,9,48,St1);

   if (VioMode >= 0 && VioMode <= 3) {
      do {
         ColorMsg(25,10,48," Enter new page number ==> ");
         GotoxyAbs(53,10);
         scanf("%d",&PgNo);
      } while (PgNo < 0 || PgNo > 3);
      SetVideoPage(PgNo);
      GotoxyAbs(1,1);

   } else if ( VioMode == 7 ) {
      ClrWin(25,9,56,16,48);
      ColorMsg(25,11,48," This is the only page allowed ");
      ColorMsg(25,12,48," for a Monochrome monitor ");
      ColorMsg(25,14,48,"Press any key to continue...");
      GetKey();
   }
}


void TestWhereXYAbs()
{
   char St1[256],St2[256];
   int  Ch,Row,Col,done = 0;

   ClrWin(1,1,80,25,7);
   FillColChar(1,1,25,'+');
   FillRowCell(1,3,80,('-' << 8) + 48);
   Col = 5;
   for (Col = 5; Col <= 80; Col += 5)
      FillRowChar(Col,3,1,'+');

   ColorMsg(5,6,TextAttr, "Press one of the following keys ");
   ColorMsg(5,7,TextAttr, "to move the cursor:");
   ColorMsg(5,8,TextAttr, "    U - move cursor up one line");
   ColorMsg(5,9,TextAttr, "    D - move cursor down one line");
   ColorMsg(5,10,TextAttr,"    R - move cursor right one column");
   ColorMsg(5,11,TextAttr,"    L - move cursor left one column");
   ColorMsg(5,12,TextAttr,"   <ENTER> - to return to menu");
   Row = 12;
   Col = 40;

   do {
      GotoxyAbs(Col,Row);


      itoa(WhereXAbs(),St2,10);
      strcpy(St1,"WhereXAbs = ");
      strcat(St1,St2);
      strcat(St1,"   ");
      ColorMsg(1,1,TextAttr,St1);


      itoa(WhereYAbs(),St2,10);
      strcpy(St1,"WhereYAbs = ");
      strcat(St1,St2);
      strcat(St1,"   ");
      ColorMsg(1,2,TextAttr,St1);

      Ch = GetKey();
      Ch = ( Ch > 132 ) ? Ch - 132 : Ch;
      Ch = UpCase( Ch );
      switch ( Ch ) {
         case 'U' : Row--;
                    if (Row < 1)
                       Row = 25;
                    break;

         case 'D' : Row++;
                    if (Row > 25)
                       Row = 1;
                    break;

         case 'L' : Col--;
                    if (Col < 1)
                       Col = 80;
                    break;

         case 'R' : Col++;
                    if (Col > 80)
                       Col = 1;
                    break;

         case '\r': done++;
      }

   } while (!done);
}

void TestScrollLeft()
{
   int   i,j,NTimes = 15;
   TCell Buffer[25][80];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for ( i = 0; i < 25; i++ )
      for ( j = 0; j < 80; j++ ) {
         Buffer[i][j].Ch   = i+64;
         Buffer[i][j].Attr = i;
      }

   for (i = 1; i <= NTimes; i++) {
      PutScrn( 1, 1, 2000, Buffer[0] );
      GetKey();

      GetTime(&H1,&M1,&S1,&Sec100_1);
      ScrollLeft(1,1,80,25,TextAttr,i);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      GetKey();

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      }
   }
   DisplayTime(NTimes);
}

void TestScrollRight()
{
   int   i,j,NTimes = 15;
   TCell Buffer[25][80];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for ( i = 0; i < 25; i++ )
      for ( j = 0; j < 80; j++ ) {
         Buffer[i][j].Ch   = i+64;
         Buffer[i][j].Attr = i;
      }
   for (i = 1; i <= NTimes; i++) {
      PutScrn( 1, 1, 2000, Buffer[0] );
      GetKey();

      GetTime(&H1,&M1,&S1,&Sec100_1);
      ScrollRight(1,1,80,25,TextAttr,i);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      GetKey();

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      }
   }
   DisplayTime(NTimes);
}

void TestScrollDown()
{
   int   i,j,NTimes = 15;
   TCell Buffer[25][80];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for ( i = 0; i < 25; i++ )
      for ( j = 0; j < 80; j++ ) {
         Buffer[i][j].Ch   = i+64;
         Buffer[i][j].Attr = i;
      }

   for (i = 1; i <= NTimes; i++) {
      PutScrn( 1, 1, 2000, Buffer[0] );
      GetKey();

      GetTime(&H1,&M1,&S1,&Sec100_1);
      ScrollDown(1,1,80,25,TextAttr,i);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      GetKey();

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      }
   }
   DisplayTime(NTimes);
}

void TestScrollUp()
{
   int   i,j,NTimes = 15;
   TCell Buffer[25][80];

   ClrWin(1,1,80,25,7);
   ClearTime();
   for ( i = 0; i < 25; i++ )
      for ( j = 0; j < 80; j++ ) {
         Buffer[i][j].Ch   = i+64;
         Buffer[i][j].Attr = i;
      }

   for (i = 1; i <= NTimes; i++) {
      PutScrn( 1, 1, 2000, Buffer[0] );
      GetKey();

      GetTime(&H1,&M1,&S1,&Sec100_1);
      ScrollUp(1,1,80,25,TextAttr,i);
      GetTime(&H2,&M2,&S2,&Sec100_2);

      GetKey();

      if ((Sec100_2 > Sec100_1) || ((S1 == S2) && (Sec100_1 == Sec100_2)))
         Total = Total + (Sec100_2 - Sec100_1);
      else {
         t1 = 100 - Sec100_1 + Sec100_2;
         Total = Total + t1;
      }
   }
   DisplayTime(NTimes);
}

void TestWriteSt()
{
   int  i;

   ClrWin(1,1,80,25,7);
   GotoxyAbs(1,1);
   for (i = 1; i <= 80; i++)
      WriteSt("This is a test...");
   GetKey();
}

void TestWriteStln()
{
   int  i;

   ClrWin(1,1,80,25,7);
   GotoxyAbs(1,1);
   for (i = 1; i <= 24; i++)
      WriteStln("This is a test...");
   GetKey();
}

GetMenuSelection()
{
   int Item = 0,
       result = 0;

   TextAttr = 7;
   do {
      ClrWin(1,1,80,25,7);
      WindowFP(1,1,80,25);
      GotoxyAbs(1,1);
      WriteStln(" ");
      WriteStln(" 1. BorderColor       2. ClrWin             3. ColorMsg");
      WriteStln(" 4. EditSt");
      WriteStln(" 5. FillColAttr       6. FillColCell        7. FillColChar");
      WriteStln(" 8. FillFrameAttr     9. FillFrameCell     10. FillFrameChar");
      WriteStln("11. FillRowAttr      12. FillRowCell       13. FillRowChar");
      WriteStln("14. GetFrameAttr     15. GetFrameCell      16. GetFrameChar");
      WriteStln("17. GetScrn          18. PutScrn");
      WriteStln("19. PutFrameAttr     20. PutFrameCell      21. PutFrameChar");
      WriteStln("22. GetCursorSize    23. SetCursorSize     24. FrameWin");
      WriteStln("25. RvsAttr          26. GetVideoMode      27. GetVideoCols");
      WriteStln("28. GetVideoPage     29. GetVideoInfo      30. InitVideo");
      WriteStln("31. SetVideoPage     32. GotoxyAbs");
      WriteStln("33. WhereXAbs        34. WhereYAbs");
      WriteStln("35. ScrollLeft       36. ScrollRight");
      WriteStln("37. ScrollDown       38. ScrollUp");
      WriteStln("39. WriteSt          40. WriteStln");
      WriteStln("41. Quit");
      WriteStln(" ");
      WriteSt("Enter selection to test ==> ");
      scanf("%u",&Item);

      while (Item < 1 || Item > 41) {
         result = scanf("%d",&Item);
         if (result != 1)
            Item = 0;
      }

   } while (Item < 1 || Item > 41);
   return(Item);
}


void main( void )
{
   int   done = 0;

   VioInit();
   ClrWin(1,1,80,25,7);
   GotoxyAbs(1,1);
   while (!done) {
      switch (GetMenuSelection()) {
         case  1 : TestBorderColor();
                   break;

         case  2 : TestClrWin();
                   break;

         case  3 : TestColorMsg();
                   break;

         case  4 : TestEditSt();
                   break;

         case  5 : TestFillColAttr();
                   break;

         case  6 : TestFillColCell();
                   break;

         case  7 : TestFillColChar();
                   break;

         case  8 : TestFillFrameAttr();
                   break;

         case  9 : TestFillFrameCell();
                   break;

         case 10 : TestFillFrameChar();
                   break;

         case 11 : TestFillRowAttr();
                   break;

         case 12 : TestFillRowCell();
                   break;

         case 13 : TestFillRowChar();
                   break;

         case 14 : TestGetFrameAttr();
                   break;

         case 15 : TestGetFrameCell();
                   break;

         case 16 : TestGetFrameChar();
                   break;

         case 17 : TestGetScrn();
                   break;

         case 18 : TestPutScrn();
                   break;

         case 19 : TestPutFrameAttr();
                   break;

         case 20 : TestPutFrameCell();
                   break;

         case 21 : TestPutFrameChar();
                   break;

         case 22 : TestGetCursorSize();
                   break;

         case 23 : TestSetCursorSize();
                   break;

         case 24 : TestFrameWin();
                   break;

         case 25 : TestRvsAttr();
                   break;

         case 26 : TestGetVideoMode();
                   break;

         case 27 : TestGetVideoCols();
                   break;

         case 28 : TestGetVideoPage();
                   break;

         case 29 : TestGetVideoInfo();
                   break;

         case 30 : TestInitVideo();
                   break;

         case 31 : TestSetVideoPage();
                   break;

         case 32 : TestWhereXYAbs();
                   break;

         case 33 : TestWhereXYAbs();
                   break;

         case 34 : TestWhereXYAbs();
                   break;

         case 35 : TestScrollLeft();
                   break;

         case 36 : TestScrollRight();
                   break;

         case 37 : TestScrollDown();
                   break;

         case 38 : TestScrollUp();
                   break;

         case 39 : TestWriteSt();
                   break;

         case 40 : TestWriteStln();
                   break;

         case 41 : done++;
      };
   };
}

