/*                                                 -*-mode:C;tab-width:8-*-
 * 
 * test.c -- incoke low level functions on the driver
 *
 * Copyright (C) 1995 Alessandro Rubini  -- rubini@ipvvis.unipv.it
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "cxdrv.h"


#define DEFAULT_NODE "/dev/cxg0"


static inline int pbytes(char *p)
{
  int i,j;
  for (i=0; i<4; i++)
    {
    putchar('\t');
    for (j=1;j<0x100; j<<=1)
      putchar(p[i]&j ? '#' : '.');
    }
  putchar('\n');
  return 0;
}

static inline void hwinfo(int fd)
{
  static Cxg_Board board;

  if (Cxg_GetHwInfo(fd,&board)<0)
    {perror("gethwinfo"); return;}

  printf("HW: base 0x%04x irq %i irqs %05li use %i ram 0x%x ",
	 board.base,board.irq,board.irq_count,board.usecount,board.ram);

  printf("lowres %i may_ol %i\n",board.lowres,board.may_overlay);
}

static inline void fileinfo(int fd)
{
  static Cxg_Clientdata cd;

  if (Cxg_GetSwInfo(fd,&cd)<0)
    {perror("getfileinfo"); return;}

  printf("FILE: type %i pgm %i rois %p current %p\n",
	 cd.cd_type,cd.cd_ispgm,cd.cd_rois,cd.cd_currRoi);
}


static inline void command(int fd, char *name)
{
struct cmdinfo {char *name;int cmd,arg;};
struct cmdinfo cmds[] = {
  {"lowres",CXG_LOWRES,1},
  {"hires",CXG_LOWRES,0},
  {NULL,0,0}
  };
struct cmdinfo *c;

  for (c=cmds; c->name; c++)
    if (!strcmp(c->name,name))
      break;

  if (!c->name) {fprintf(stderr,"%s: no such ioctl cmd\n",name); return;}

  if (ioctl(fd,c->cmd,c->arg)<0)
    {perror(name); return;}
}



int main(int argc, char **argv)
{
  FILE *f; int i,j;
  int fd;
  char **arg;
  char *node=DEFAULT_NODE;
  unsigned char p[4];

  if (argc>1 && argv[1][0]=='/')
	node=argv[1], argv++,argc--;

  f=fopen(node,"r");
  if (!f) {perror(node); exit(1);}
  fd=fileno(f);

  if (argc==1)
    {
    printf("C = command\ns = set bit\nc = clr bit\ng = getbit\n");
    printf("p = get ports\nt = wait time\nL = loop\n");
    printf("i = set irq\nr = set ram page\n");
    printf("f = get file info\nh = get hw info\n");
    printf("S = set step\nn = set next\n");
    }

  /* loop through the args */

  while (1)
    {
    for (arg=argv+1, i=1; i<argc; arg++,i++)
      {
      j=0;
      sscanf(*arg+1,"%i",&j);
      
      switch(**arg)
	{
	case 'C': printf("cmd %02x  res %02x\n",j,Cxg_Command(fd,j)); break;
	case 's': printf("set %02x\n",j); Cxg_SetBit(fd,j); break;
	case 'c': printf("clr %02x\n",j); Cxg_ClrBit(fd,j); break;
	case 'f': fileinfo(fd); break;
	case 'g': printf("get %02x  res %02x\n",j,Cxg_GetBit(fd,j)); break;
	
	case 'h': hwinfo(fd); break;
	case 'n': Cxg_SetNext(fd,j); break;
	case 'i': printf("irq %i res %i\n",j,Cxg_SetIrq(fd,j)); break;
	
	case 'p': Cxg_GetPorts(fd,p); printf("\t%02x %02x %02x %02x\n",
					     p[0],p[1],p[2],p[3]); break;
	case 'P': Cxg_GetPorts(fd,p); pbytes(p); break;
	case 'S': Cxg_SetStep(fd,j); break;
	case 't': sleep(j); break;
	case 'T': usleep(1000*j); break;
	case 'L': break;
	case 'r': Cxg_RamPage(fd,j); break;
	case '-': command(fd,*arg+1); break;
	default: fprintf(stderr,"Unknown command %c\n",**arg);
	}
      if (**arg=='L') break;
      }
    if (i<argc && **arg=='L') continue;
    break;
    }
  return 0;
}
