/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by John E. Lloyd.			    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/

/* an RCI program that peeks and pokes the rciBus and rciIOpage structures */

#ifdef VXWORKS_CFG
#define main rciProbe_
#endif

#include "../h/rci.h"
#include "../h/ctree.h"
#include "rciProbe.h"

char key_buf [256];
char *keytree;

RCI_DESC *td;
PROBE_BLK *pbk;

extern unsigned char *rciBus;
extern unsigned char *rciIOpage;

enum busSelect {
  	bus,
       	IOpage
};

main()
{
	int addr;
	unsigned long pokeValue;	
	int range;

	enum busSelect busSelect = bus;
	int accessSize = 2;
	unsigned char *base = rciBus;
	char prompt[256];

	setPrompt (prompt, busSelect, accessSize);

	keytree = tree_match_parse("					\
(	quit								\
	peek								\
	 (%x", &addr, ",,,	\"address (hex)\")			\
	poke 								\
	 (%x", &addr, ",,,	\"address (hex)\"			\
	   (%x", &pokeValue, ",,,\"value (hex)\"))			\
	dump 								\
	 (%x", &addr, ",,,	\"address (hex)\"			\
	   (%d", &range, ",0,,	\"range (decimal)\"))			\
	bus								\
	IOpage								\
	byte								\
	word								\
	long								\
)",0);

	if (keytree == 0)
	 { printf ("ERROR/Parse error at %.30s\n", tree_match_err_at());
	   exit (-1);
	 }

	rciSetOptions (EXIT_ON_ERROR);
	td = rciCreate ("DUMMY", 0);
	pbk = (PROBE_BLK*)allocMem (NULL, sizeof(PROBE_BLK), 0);
	base = rciBus;

	putchar ('\n');
	printf ("rciBus at 0x%x\n", rciBus);
	printf ("rciIOpage at 0x%x\n", rciIOpage);
	putchar ('\n');

	do
 	 { 
	   tree_match (keytree, prompt, key_buf);
	   if (COMMAND ("peek"))
	    { unsigned long value;
	      if (addr % accessSize)
	       { printf ("illegal alignment\n");
		 continue;
	       }
	      if (!peek (base, addr, accessSize, &value))
	       { printf ("Bad memory reference\n");
	       }
	      else
	       { printf ("0x%8x 0x%x\n", base + addr, value);
	       }
	    }
	   else if (COMMAND ("dump"))
	    { unsigned long value;
	      int i;
	      if (addr % accessSize)
	       { printf ("illegal alignment\n");
		 continue;
	       }
	      for (i=0; i<range; i++)
	       { 
		 if (!peek (base, addr + i*accessSize, accessSize, &value))
		  { printf ("Bad memory reference\n");
		    break;
		  }
		 else
		  { printf ("0x%8x 0x%x\n", base + addr + i*accessSize, value);
		  }
	       }
	    }
	   else if (COMMAND ("poke"))
	    { unsigned long value;
	      if (addr % accessSize)
	       { printf ("illegal alignment\n");
		 continue;
	       }
	      value = pokeValue;
	      if (!poke (base, addr, accessSize, &value))
	       { printf ("Bad memory reference\n");
	       }
	      else
	       { printf ("0x%8x 0x%x\n", base + addr, value);
	       }
	    }
	   else if (COMMAND ("bus"))
	    { busSelect = bus;
	      base = rciBus;
	      setPrompt (prompt, busSelect, accessSize);
	    }
	   else if (COMMAND ("IOpage"))
	    { busSelect = IOpage;
	      base = rciIOpage;
	      setPrompt (prompt, busSelect, accessSize);
	    }
	   else if (COMMAND ("byte"))
	    { accessSize = 1;
	      setPrompt (prompt, busSelect, accessSize);
	    }
	   else if (COMMAND ("word"))
	    { accessSize = 2;
	      setPrompt (prompt, busSelect, accessSize);
	    }
	   else if (COMMAND ("long"))
	    { accessSize = 4;
	      setPrompt (prompt, busSelect, accessSize);
	    }
	 }
	while (!COMMAND ("quit"));
}

setPrompt (buf, select, accessSize)
char *buf;
enum busSelect select;
int accessSize;
{
	sprintf (buf, "%s (%s) > ",
		 select == bus ? "BUS" : "IOPAGE",
		 accessSize == 1 ? "byte" :
		 accessSize == 2 ? "word" :
		 accessSize == 4 ? "long" : "undef");
}

peek (base, addr, accessSize, value)
unsigned char *base;
int addr;
int accessSize;
unsigned long *value;
{
	int rv;
	extern doPeek();

	pbk->base = base;
	pbk->addr = addr;
	pbk->accessSize = accessSize;

	rciExecute (td, doPeek, (int)pbk, &rv);

	*value = pbk->value;
	return (rv);
}

poke (base, addr, accessSize, value)
unsigned char *base;
int addr;
int accessSize;
unsigned long *value;
{
	int rv;
	extern doPoke();

	pbk->base = base;
	pbk->addr = addr;
	pbk->accessSize = accessSize;
	pbk->value = *value;

	rciExecute (td, doPoke, (int)pbk, &rv);

	*value = pbk->value;
	return (rv);
}
