/* ------------------------------------------------------------------------ */
/*                         testbed for the DPNSS                            */
/* ------------------------------------------------------------------------ */
#include <stdio.h>
#include <string.h>
#include <process.h>
#include <stdlib.h>
#include <dos.h>
#include <stdarg.h>

#include "sstvid.h"
#include "sstwin.h"
#include "sstkey.h"
#include "sstfos.h"


/* ---------- Constants    ------------- */
#define OFFSCREENX(wnd)        ((wnd->_cr+1) > (wnd->_ww-2))
#define OFFSCREENY(wnd,y)      ((wnd->_wh-2) > (y))


/* -------------- Global Variables --------------- */
int port   = F_COM1;      /* default com port     */
int param  = F_B2400|     /* default baud         */
	     F_NORMAL;    /* default character framing  */
int hexmode = 0;          /* Hex interpretation */
int ry      = 0;          /* Cursor y Rx window   */
int ty      = 0;          /* Cursor y Tx window   */

WINDOW *wndRx;            /* main receive window */
WINDOW *wndTx;            /* main transmitt window */
FILE *fp;                 /* capture file pointer */

/* ------------ Function ProtoTypes -------------- */
int OpenFossil(void);
void togglebit(int *w, int n);
void ErrorExit(char *fmt, ...);
void OpenWindows(void);
void ClearWindows(void);
void OutChar(unsigned char ch);
void InChar(unsigned char ch);
void hexcmd(char *str, char *msg);
void main(int argc, char *argv[]);

/* ------------------------------------------------------------------------ */
/*                     toggles a given bit in  a word                       */
/* ------------------------------------------------------------------------ */
void togglebit(int *w, int n)

{
  *w ^= (1 << n);
}

/* ------------------------------------------------------------------------ */
/*                      prints a message and terminates                     */
/* ------------------------------------------------------------------------ */
void ErrorExit(char *fmt, ...)

{
   va_list argptr;

   va_start(argptr, fmt);
   vprintf(fmt, argptr);
   va_end(argptr);
   exit(1);
}

/* ------------------------------------------------------------------------ */
/*                    creates and opens all the windows                     */
/* ------------------------------------------------------------------------ */
void OpenWindows(void)

{
   vpushcur();   /* save cursor pos */
   if (!(wndTx = Westablish(0, 0, 7, SCREENWIDTH -1)))
	     ErrorExit("Memory allocation error.");
   if (!(wndRx = Westablish(0, 7, 17,SCREENWIDTH -1)))
	     ErrorExit("Memory allocation error.");
   Wsetcolour(wndRx,WIN_ALL  , BLACK,LIGHTGRAY,DIM);
   Wsetcolour(wndRx,WIN_TITLE, LIGHTGRAY,RED,DIM);
   Wsetcolour(wndTx,WIN_ALL,   BLACK,LIGHTGRAY,DIM);
   Wsetcolour(wndTx,WIN_TITLE, LIGHTGRAY,RED,DIM);
   Wsettitle(wndRx,"[ Receive ]",JUST_L);
   Wsettitle(wndTx,"[ Transmitt ]",JUST_L);
   Wshow(wndRx);
   Wshow(wndTx);
   ClearWindows();
}

/* ------------------------------------------------------------------------ */
/*                   clears the contents of all the windows                 */
/* ------------------------------------------------------------------------ */
void ClearWindows(void)

{
   ty = ry = 0;
   wndRx->_cr = 0;
   wndTx->_cr = 0;
   Wclear(wndRx);
   Wclear(wndTx);
   Wcursor(wndTx,0,0);
}

/* ------------------------------------------------------------------------ */
/*                    dumps a char to the transmitt window                  */
/* ------------------------------------------------------------------------ */
void OutChar(unsigned char ch)

{
   if ( hexmode ) Wprintf(wndTx,"%02X ",ch);
     else Wputch(wndTx,ch);
     if ( OFFSCREENX(wndTx) || (hexmode && (wndTx->_cr+1 > wndTx->_ww-3))) {
      Wputch(wndTx,'\n');
      if (ty < (wndTx->_wh -3))
	ty++;
      }
   Wcursor(wndTx,wndTx->_cr,ty);
}

/* ------------------------------------------------------------------------ */
/*                     dumps a char to the receive window                   */
/* ------------------------------------------------------------------------ */
void InChar(unsigned char ch)

{
   if ( hexmode ) Wprintf(wndRx,"%02X ",ch);
     else Wputch(wndRx,ch);
     if ( OFFSCREENX(wndRx) || (hexmode && (wndRx->_cr+1 > wndRx->_ww-3))) {
	  Wputch(wndRx,'\n');
	  if (ry < (wndRx->_wh -3))
	  ry++;
	Wcursor(wndRx,wndRx->_cr,ry);
      }
    Wcursor(wndRx,wndRx->_cr,ry);
}

/* ------------------------------------------------------------------------ */
/*                   attempts to initialise the fossil driver               */
/* ------------------------------------------------------------------------ */
int OpenFossil(void)

{
  int s;
  char flagbyte = 0;
  unsigned byte = 0;
  struct fdata fd;

  if ( ffinit(port, &byte, (char far *)&flagbyte) != F_SIGNATURE)
	ErrorExit("Couldn't initialise Fossil Driver\n");

  finfo(port,&fd,sizeof(struct fdata));
  printf("Structure size               : %u\n",fd.fdsize);
  printf("FOSSIL spec version          : %d\n",fd.specver);
  printf("FOSSIL spec driver revision  : %d\n",fd.drvlvl);
  printf("FOSSIL ID                    : %Fs\n",fd.drvid);
  printf("Input buffer size            : %u\n",fd.rxsize);
  printf("Input bytes available        : %u\n",fd.rxavail);
  printf("Output buffer size           : %u\n",fd.txsize);
  printf("Output bytes available       : %u\n",fd.txavail);
  printf("Screen width                 : %d\n",fd.scnwid);
  printf("Screen height                : %d\n",fd.scnlen);
  printf("BAUD rate mask               : %u\n",fd.bdmask);
  getch();

  s = finit(port,param);
  return s;
}


/* ------------------------------------------------------------------------ */
/*                               function main                              */
/* ------------------------------------------------------------------------ */
void main(int argc, char *argv[])

{
  unsigned int c;

  clrscr();
  if (argc>1)
       port=atoi(argv[1])-1;
  OpenFossil();                   /* open fossil driver */
  fpurgein(port);	          /* purge com port */
  OpenWindows();                     /* open all windows */

  for (;;) {                         	/* main dispath loop  */
    if ( fpeek(port) != F_NULL)   {
	  c = fgetch(port);
	  InChar(c);
    }
    if ( fkbdpeek() != F_NULL)  {                  /* grab a keypress */
	       c = fkbdgetch();                     /* get the char */
	       switch(c)   {

		  case 0x2300   : togglebit(&hexmode,1);   /* Alt-H */
				  break;
		  case 0x2E00   : ClearWindows();    /* Alt-C */
				  break;
		  default       : OutChar(c);
				  fputch(port,c);
				  break;
	       }
	       if (c == 0x2D00 || c == 0x011B)  /* Alt-X or ESC */
		     break;
       }
  }
  fdeinit(port);			               /* de-init FOSSIL */
  Wdeleteall();                                  /* close all the windows */
  vpopcur();
}


